@Test
  public void testSchema() throws Exception {
    translator = new ODataExecutionFactory();
    translator.start();

    MetadataFactory mf = tripPinMetadata();
    TransformationMetadata metadata = getTransformationMetadata(mf, this.translator);

    String ddl = DDLStringVisitor.getDDLString(mf.getSchema(), null, null);
    // System.out.println(ddl);

    MetadataFactory mf2 =
        new MetadataFactory(
            null,
            1,
            "northwind",
            SystemMetadata.getInstance().getRuntimeTypeMap(),
            new Properties(),
            null);
    QueryParser.getQueryParser().parseDDL(mf2, ddl);

    Procedure p = mf.getSchema().getProcedure("ResetDataSource");
    assertNotNull(p);
    assertEquals(0, p.getParameters().size());
  }
 private ProcedureParameter getReturnParameter(Procedure procedure) {
   for (ProcedureParameter pp : procedure.getParameters()) {
     if (pp.getType() == ProcedureParameter.Type.ReturnValue) {
       return pp;
     }
   }
   return null;
 }
예제 #3
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());
  }
예제 #4
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);
  }
예제 #5
0
  @Test
  public void testAlterProcedureOptions() throws Exception {
    String ddl =
        "CREATE FOREIGN 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');"
            + "ALTER FOREIGN PROCEDURE myProc OPTIONS(SET NAMEINSOURCE 'x')"
            + "ALTER FOREIGN PROCEDURE myProc ALTER PARAMETER p2 OPTIONS (ADD x 'y');"
            + "ALTER FOREIGN PROCEDURE myProc OPTIONS(DROP UPDATECOUNT);";

    Schema s = helpParse(ddl, "model").getSchema();
    Procedure proc = s.getProcedure("myProc");
    assertNotNull(proc);

    assertEquals("x", proc.getNameInSource());
    assertEquals("p2", proc.getParameters().get(1).getName());
    assertEquals("y", proc.getParameters().get(1).getProperty("x", false));
    assertEquals(1, proc.getUpdateCount());
  }
예제 #6
0
  @Test
  public void testStreaming() throws Exception {
    WSExecutionFactory ef = new WSExecutionFactory();
    MetadataFactory mf =
        new MetadataFactory(
            "vdb",
            1,
            "x",
            SystemMetadata.getInstance().getRuntimeTypeMap(),
            new Properties(),
            null);
    ef.getMetadata(mf, null);
    Procedure p = mf.getSchema().getProcedure(WSExecutionFactory.INVOKE_HTTP);
    assertEquals(7, p.getParameters().size());

    TransformationMetadata tm =
        RealMetadataFactory.createTransformationMetadata(mf.asMetadataStore(), "vdb");
    RuntimeMetadataImpl rm = new RuntimeMetadataImpl(tm);
    WSConnection mockConnection = Mockito.mock(WSConnection.class);
    Dispatch<Object> mockDispatch = mockDispatch();
    DataSource mock = Mockito.mock(DataSource.class);
    ByteArrayInputStream baos = new ByteArrayInputStream(new byte[100]);
    Mockito.stub(mock.getInputStream()).toReturn(baos);
    Mockito.stub(mockDispatch.invoke(Mockito.any(DataSource.class))).toReturn(mock);
    Mockito.stub(
            mockConnection.createDispatch(
                Mockito.any(String.class),
                Mockito.any(String.class),
                Mockito.any(Class.class),
                Mockito.any(Service.Mode.class)))
        .toReturn(mockDispatch);
    CommandBuilder cb = new CommandBuilder(tm);

    Call call = (Call) cb.getCommand("call invokeHttp('GET', null, null, true)");
    BinaryWSProcedureExecution pe =
        new BinaryWSProcedureExecution(
            call, rm, Mockito.mock(ExecutionContext.class), ef, mockConnection);
    pe.execute();
    List<?> result = pe.getOutputParameterValues();

    Blob b = (Blob) result.get(0);
    assertEquals(100, ObjectConverterUtil.convertToByteArray(b.getBinaryStream()).length);
    try {
      ObjectConverterUtil.convertToByteArray(b.getBinaryStream());
      fail();
    } catch (SQLException e) {
      // should only be able to read once
    }
  }
  @Test
  public void testAction() throws Exception {
    CsdlReturnType returnType = new CsdlReturnType();
    returnType.setType("Edm.String");

    MetadataFactory mf = actionMetadata("invoke", returnType, null);
    Procedure p = mf.getSchema().getProcedure("invoke");
    assertNotNull(p);
    assertEquals(3, p.getParameters().size());
    assertNull(p.getResultSet());
    assertNotNull(getReturnParameter(p));
    ProcedureParameter pp = getReturnParameter(p);
    assertEquals("string", pp.getRuntimeType());
    ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false));
    assertEquals(ODataType.ACTION, type);
  }
  @Test
  public void testFunctionReturnComplex() throws Exception {
    CsdlComplexType complex = complexType("Address");

    CsdlReturnType returnType = new CsdlReturnType();
    returnType.setType("namespace.Address");

    MetadataFactory mf = functionMetadata("invoke", returnType, complex);
    Procedure p = mf.getSchema().getProcedure("invoke");
    assertNotNull(p);
    assertEquals(2, p.getParameters().size());
    assertNotNull(p.getResultSet());
    assertNull(getReturnParameter(p));
    ColumnSet<Procedure> table = p.getResultSet();
    ODataType type = ODataType.valueOf(p.getProperty(ODataMetadataProcessor.ODATA_TYPE, false));
    assertEquals(ODataType.FUNCTION, type);

    type = ODataType.valueOf(table.getProperty(ODataMetadataProcessor.ODATA_TYPE, false));
    assertEquals(ODataType.COMPLEX, type);
  }
  private static void buildFunctionImports(MetadataStore metadataStore, List<Builder> edmSchemas) {
    for (Schema schema : metadataStore.getSchemaList()) {

      EdmSchema.Builder odataSchema = findSchema(edmSchemas, schema.getName());
      EdmEntityContainer.Builder entityContainer =
          findEntityContainer(edmSchemas, schema.getName());

      // procedures
      for (Procedure proc : schema.getProcedures().values()) {
        EdmFunctionImport.Builder edmProcedure = EdmFunctionImport.newBuilder();
        edmProcedure.setName(proc.getName());
        String httpMethod = "POST";

        for (ProcedureParameter pp : proc.getParameters()) {
          if (pp.getName().equals("return")) {
            httpMethod = "GET";
            edmProcedure.setReturnType(
                ODataTypeManager.odataType(pp.getDatatype().getRuntimeTypeName()));
            continue;
          }

          EdmFunctionParameter.Builder param = EdmFunctionParameter.newBuilder();
          param.setName(pp.getName());
          param.setType(ODataTypeManager.odataType(pp.getDatatype().getRuntimeTypeName()));

          if (pp.getType() == ProcedureParameter.Type.In) {
            param.setMode(Mode.In);
          } else if (pp.getType() == ProcedureParameter.Type.InOut) {
            param.setMode(Mode.InOut);
          } else if (pp.getType() == ProcedureParameter.Type.Out) {
            param.setMode(Mode.Out);
          }

          param.setNullable(pp.getNullType() == NullType.Nullable);
          edmProcedure.addParameters(param);
        }

        // add a complex type for return resultset.
        ColumnSet<Procedure> returnColumns = proc.getResultSet();
        if (returnColumns != null) {
          httpMethod = "GET";
          EdmComplexType.Builder complexType = EdmComplexType.newBuilder();
          complexType.setName(proc.getName() + "_" + returnColumns.getName());
          complexType.setNamespace(schema.getName());
          for (Column c : returnColumns.getColumns()) {
            EdmProperty.Builder property =
                EdmProperty.newBuilder(c.getName())
                    .setType(ODataTypeManager.odataType(c.getDatatype().getRuntimeTypeName()))
                    .setNullable(c.getNullType() == NullType.Nullable);
            if (c.getDatatype()
                .getRuntimeTypeName()
                .equals(DataTypeManager.DefaultDataTypes.STRING)) {
              property
                  .setFixedLength(c.isFixedLength())
                  .setMaxLength(c.getLength())
                  .setUnicode(true);
            }
            complexType.addProperties(property);
          }
          odataSchema.addComplexTypes(complexType);
          edmProcedure.setIsCollection(true);
          edmProcedure.setReturnType(
              EdmCollectionType.newBuilder()
                  .setCollectionType(complexType)
                  .setKind(CollectionKind.Collection));
        }
        edmProcedure.setHttpMethod(httpMethod);
        entityContainer.addFunctionImports(edmProcedure);
      }
    }
  }
예제 #10
0
  @Test
  public void testPre81Procedure() throws Exception {
    WSExecutionFactory ef = new WSExecutionFactory();
    MetadataFactory mf =
        new MetadataFactory(
            "vdb",
            1,
            "x",
            SystemMetadata.getInstance().getRuntimeTypeMap(),
            new Properties(),
            null);
    ef.getMetadata(mf, null);
    Procedure p = mf.getSchema().getProcedure(WSExecutionFactory.INVOKE_HTTP);
    assertEquals(7, p.getParameters().size());
    p.getParameters().remove(4);
    p.getParameters().remove(5);
    p = mf.getSchema().getProcedure("invoke");
    assertEquals(6, p.getParameters().size());
    p.getParameters().remove(5);
    // designer treated the result as an out parameter
    p.getParameters().get(0).setType(Type.Out);
    p.getParameters().add(p.getParameters().remove(0));
    for (int i = 0; i < p.getParameters().size(); i++) {
      p.getParameters().get(i).setPosition(i + 1);
    }

    TransformationMetadata tm =
        RealMetadataFactory.createTransformationMetadata(mf.asMetadataStore(), "vdb");
    RuntimeMetadataImpl rm = new RuntimeMetadataImpl(tm);
    WSConnection mockConnection = Mockito.mock(WSConnection.class);
    Dispatch<Object> mockDispatch = mockDispatch();
    DataSource source = Mockito.mock(DataSource.class);
    Mockito.stub(mockDispatch.invoke(Mockito.any(DataSource.class))).toReturn(source);
    Mockito.stub(
            mockConnection.createDispatch(
                Mockito.any(String.class),
                Mockito.any(String.class),
                Mockito.any(Class.class),
                Mockito.any(Service.Mode.class)))
        .toReturn(mockDispatch);
    CommandBuilder cb = new CommandBuilder(tm);

    Call call = (Call) cb.getCommand("call invokeHttp('GET', null, null)");
    BinaryWSProcedureExecution pe =
        new BinaryWSProcedureExecution(
            call, rm, Mockito.mock(ExecutionContext.class), ef, mockConnection);
    pe.execute();
    pe.getOutputParameterValues();

    mockConnection = Mockito.mock(WSConnection.class);
    mockDispatch = Mockito.mock(Dispatch.class);
    StAXSource ssource = Mockito.mock(StAXSource.class);
    Mockito.stub(mockDispatch.invoke(Mockito.any(StAXSource.class))).toReturn(ssource);
    Mockito.stub(
            mockConnection.createDispatch(
                Mockito.any(String.class),
                Mockito.any(String.class),
                Mockito.any(Class.class),
                Mockito.any(Service.Mode.class)))
        .toReturn(mockDispatch);
    call = (Call) cb.getCommand("call invoke()");
    WSProcedureExecution wpe =
        new WSProcedureExecution(
            call, rm, Mockito.mock(ExecutionContext.class), ef, mockConnection);
    wpe.execute();
    wpe.getOutputParameterValues();
  }
    @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()));
          }
        }
      }
    }