예제 #1
0
  private void visit(Procedure procedure) {
    if (this.filter != null && !filter.matcher(procedure.getName()).matches()) {
      return;
    }

    append(CREATE).append(SPACE);
    if (procedure.isVirtual()) {
      append(VIRTUAL);
    } else {
      append(FOREIGN);
    }
    append(SPACE)
        .append(procedure.isFunction() ? FUNCTION : PROCEDURE)
        .append(SPACE)
        .append(SQLStringVisitor.escapeSinglePart(procedure.getName()));
    append(LPAREN);

    boolean first = true;
    for (ProcedureParameter pp : procedure.getParameters()) {
      if (first) {
        first = false;
      } else {
        append(COMMA).append(SPACE);
      }
      visit(pp);
    }
    append(RPAREN);

    if (procedure.getResultSet() != null) {
      append(SPACE).append(RETURNS);
      appendOptions(procedure.getResultSet());
      append(SPACE).append(TABLE).append(SPACE);
      addColumns(procedure.getResultSet().getColumns(), true);
    }
    /* The parser treats the RETURN clause as optional for a procedure if using the RESULT param
      for (ProcedureParameter pp: procedure.getParameters()) {
    	if (pp.getType().equals(Type.ReturnValue)) {
    		append(SPACE).append(RETURNS).append(SPACE);
    		appendColumn(buffer, pp, false, true);
    		break;
    	}
    }*/

    // options
    String options = buildProcedureOptions(procedure);
    if (!options.isEmpty()) {
      append(NEWLINE).append(OPTIONS).append(SPACE).append(LPAREN).append(options).append(RPAREN);
    }
    // block
    if (procedure.isVirtual()) {
      append(NEWLINE).append(SQLConstants.Reserved.AS).append(NEWLINE);
      String plan = procedure.getQueryPlan();
      append(plan);
    }

    append(SEMICOLON);
  }
예제 #2
0
  @Test
  public void testVirtualProcedure() throws Exception {
    String ddl =
        "CREATE VIRTUAL PROCEDURE myProc(OUT p1 boolean, p2 varchar, INOUT p3 decimal) "
            + "RETURNS (r1 varchar, r2 decimal) "
            + "OPTIONS(RANDOM 'any', UUID 'uuid', NAMEINSOURCE 'nis', ANNOTATION 'desc', UPDATECOUNT '2') "
            + "AS /*+ cache */ BEGIN select * from foo; END";

    Schema s = helpParse(ddl, "model").getSchema();

    Procedure proc = s.getProcedure("myProc");
    assertNotNull(proc);

    assertTrue(proc.isVirtual());
    assertFalse(proc.isFunction());

    assertEquals(3, proc.getParameters().size());
    assertEquals("p1", proc.getParameters().get(0).getName());
    assertEquals("boolean", proc.getParameters().get(0).getDatatype().getName());
    assertEquals(ProcedureParameter.Type.Out, proc.getParameters().get(0).getType());

    assertEquals("p2", proc.getParameters().get(1).getName());
    assertEquals("string", proc.getParameters().get(1).getDatatype().getName());
    assertEquals(ProcedureParameter.Type.In, proc.getParameters().get(1).getType());

    assertEquals("p3", proc.getParameters().get(2).getName());
    assertEquals("bigdecimal", proc.getParameters().get(2).getDatatype().getName());
    assertEquals(ProcedureParameter.Type.InOut, proc.getParameters().get(2).getType());

    ColumnSet<Procedure> ret = proc.getResultSet();
    assertNotNull(ret);
    assertEquals(2, ret.getColumns().size());
    assertEquals("r1", ret.getColumns().get(0).getName());
    assertEquals("string", ret.getColumns().get(0).getDatatype().getName());
    assertEquals("r2", ret.getColumns().get(1).getName());
    assertEquals("bigdecimal", ret.getColumns().get(1).getDatatype().getName());

    assertEquals("uuid", proc.getUUID());
    assertEquals("nis", proc.getNameInSource());
    assertEquals("desc", proc.getAnnotation());
    assertEquals(2, proc.getUpdateCount());
    assertEquals("any", proc.getProperties().get("RANDOM"));

    assertEquals("/*+ cache */ BEGIN\nSELECT * FROM foo;\nEND", proc.getQueryPlan());
  }
    @Override
    public void execute(
        VDBMetaData vdb,
        MetadataStore store,
        ValidatorReport report,
        MetadataValidator metadataValidator) {
      IQueryMetadataInterface metadata = vdb.getAttachment(IQueryMetadataInterface.class);
      metadata = new TempMetadataAdapter(metadata, new TempMetadataStore());
      for (Schema schema : store.getSchemaList()) {
        if (vdb.getImportedModels().contains(schema.getName())) {
          continue;
        }
        ModelMetaData model = vdb.getModel(schema.getName());
        MetadataFactory mf =
            new MetadataFactory(
                teiidVersion, vdb.getName(), vdb.getVersion(), metadataValidator.typeMap, model) {
              @Override
              protected void setUUID(AbstractMetadataRecord record) {
                if (count >= 0) {
                  count = Integer.MIN_VALUE;
                }
                super.setUUID(record);
              }
            };
        mf.setBuiltinDataTypes(store.getDatatypes());
        for (AbstractMetadataRecord record : schema.getResolvingOrder()) {
          if (record instanceof Table) {
            Table t = (Table) record;
            // no need to verify the transformation of the xml mapping document,
            // as this is very specific and designer already validates it.
            if (t.getTableType() == Table.Type.Document
                || t.getTableType() == Table.Type.XmlMappingClass
                || t.getTableType() == Table.Type.XmlStagingTable) {
              continue;
            }
            if (t.isVirtual() && t.getTableType() != Table.Type.TemporaryTable) {
              if (t.getSelectTransformation() == null) {
                metadataValidator.log(
                    report,
                    model,
                    Messages.gs(Messages.TEIID.TEIID31079, t.getFullName(), model.getName()));
              } else {
                metadataValidator.validate(vdb, model, t, report, metadata, mf);
              }
            }
          } else if (record instanceof Procedure) {
            Procedure p = (Procedure) record;

            boolean test = p.isVirtual();
            if (teiidVersion.isLessThan(Version.TEIID_8_11)) test = test && !p.isFunction();

            if (test) {
              if (p.getQueryPlan() == null) {
                metadataValidator.log(
                    report,
                    model,
                    Messages.gs(Messages.TEIID.TEIID31081, p.getFullName(), model.getName()));
              } else {
                metadataValidator.validate(vdb, model, p, report, metadata, mf);
              }
            }
          }
        }
      }
    }
    @Override
    public void execute(
        VDBMetaData vdb,
        MetadataStore store,
        ValidatorReport report,
        MetadataValidator metadataValidator) {
      for (Schema schema : store.getSchemaList()) {
        if (vdb.getImportedModels().contains(schema.getName())) {
          continue;
        }
        ModelMetaData model = vdb.getModel(schema.getName());
        for (Table t : schema.getTables().values()) {
          if (t.isPhysical() && !model.isSource()) {
            metadataValidator.log(
                report,
                model,
                Messages.gs(Messages.TEIID.TEIID31075, t.getFullName(), model.getName()));
          }
        }

        Set<String> names = new HashSet<String>();
        for (Procedure p : schema.getProcedures().values()) {
          boolean hasReturn = false;
          names.clear();
          for (int i = 0; i < p.getParameters().size(); i++) {
            ProcedureParameter param = p.getParameters().get(i);
            if (param.isVarArg() && param != p.getParameters().get(p.getParameters().size() - 1)) {
              // check that the rest of the parameters are optional
              // this accommodates variadic multi-source procedures
              // effective this and the resolving logic ensure that you can used named parameters
              // for everything,
              // or call the vararg procedure as normal
              if (isTeiidOrGreater(Version.TEIID_8_10)) {
                for (int j = i + 1; j < p.getParameters().size(); j++) {
                  ProcedureParameter param1 = p.getParameters().get(j);
                  if ((param1.getType() == Type.In || param1.getType() == Type.InOut)
                      && (param1.isVarArg()
                          || (param1.getNullType() != NullType.Nullable
                              && param1.getDefaultValue() == null))) {
                    metadataValidator.log(
                        report, model, Messages.gs(Messages.TEIID.TEIID31112, p.getFullName()));
                  }
                }
              } else {
                metadataValidator.log(
                    report, model, Messages.gs(Messages.TEIID.TEIID31112, p.getFullName()));
              }
            }
            if (param.getType() == ProcedureParameter.Type.ReturnValue) {
              if (hasReturn) {
                metadataValidator.log(
                    report, model, Messages.gs(Messages.TEIID.TEIID31107, p.getFullName()));
              }
              hasReturn = true;
            } else if (p.isFunction()
                && param.getType() != ProcedureParameter.Type.In
                && teiidVersion.isGreaterThanOrEqualTo(Version.TEIID_8_11)) {
              metadataValidator.log(
                  report,
                  model,
                  Messages.gs(Messages.TEIID.TEIID31165, p.getFullName(), param.getFullName()));
            }
            if (!names.add(param.getName())) {
              metadataValidator.log(
                  report,
                  model,
                  Messages.gs(Messages.TEIID.TEIID31106, p.getFullName(), param.getFullName()));
            }
          }
          if (!p.isVirtual() && !model.isSource()) {
            metadataValidator.log(
                report,
                model,
                Messages.gs(Messages.TEIID.TEIID31077, p.getFullName(), model.getName()));
          }

          if (p.isFunction() && teiidVersion.isGreaterThanOrEqualTo(Version.TEIID_8_11)) {
            if (!hasReturn) {
              metadataValidator.log(
                  report, model, Messages.gs(Messages.TEIID.TEIID31166, p.getFullName()));
            }
            if (p.isVirtual() && p.getQueryPlan() == null) {
              metadataValidator.log(
                  report, model, Messages.gs(Messages.TEIID.TEIID31167, p.getFullName()));
            }
          }
        }

        for (FunctionMethod func : schema.getFunctions().values()) {
          for (FunctionParameter param : func.getInputParameters()) {
            if (param.isVarArg()
                && param != func.getInputParameters().get(func.getInputParameterCount() - 1)) {
              metadataValidator.log(
                  report, model, Messages.gs(Messages.TEIID.TEIID31112, func.getFullName()));
            }
          }
          if (func.getPushdown().equals(FunctionMethod.PushDown.MUST_PUSHDOWN)
              && !model.isSource()) {
            metadataValidator.log(
                report,
                model,
                Messages.gs(Messages.TEIID.TEIID31078, func.getFullName(), model.getName()));
          }
        }
      }
    }