@Test public void testUDF() throws Exception { String ddl = "CREATE VIRTUAL FUNCTION SourceFunc(flag boolean, msg varchar) RETURNS varchar " + "OPTIONS(CATEGORY 'misc', DETERMINISM 'DETERMINISTIC', " + "\"NULL-ON-NULL\" 'true', JAVA_CLASS 'foo', JAVA_METHOD 'bar', RANDOM 'any', UUID 'x')"; Schema s = helpParse(ddl, "model").getSchema(); FunctionMethod fm = s.getFunction("x"); assertNotNull(fm); assertEquals("string", fm.getOutputParameter().getType()); assertEquals(FunctionMethod.PushDown.CAN_PUSHDOWN, fm.getPushdown()); assertEquals(2, fm.getInputParameterCount()); assertEquals("flag", fm.getInputParameters().get(0).getName()); assertEquals("boolean", fm.getInputParameters().get(0).getType()); assertEquals("msg", fm.getInputParameters().get(1).getName()); assertEquals("string", fm.getInputParameters().get(1).getType()); assertFalse(fm.getInputParameters().get(1).isVarArg()); assertEquals(FunctionMethod.Determinism.DETERMINISTIC, fm.getDeterminism()); assertEquals("misc", fm.getCategory()); assertEquals(true, fm.isNullOnNull()); assertEquals("foo", fm.getInvocationClass()); assertEquals("bar", fm.getInvocationMethod()); assertEquals("any", fm.getProperties().get("RANDOM")); }
@Test public void testUDAggregate() throws Exception { String ddl = "CREATE VIRTUAL FUNCTION SourceFunc(flag boolean, msg varchar) RETURNS varchar " + "OPTIONS(CATEGORY 'misc', AGGREGATE 'true', \"allows-distinct\" 'true', UUID 'y')"; Schema s = helpParse(ddl, "model").getSchema(); FunctionMethod fm = s.getFunction("y"); assertNotNull(fm); assertEquals("string", fm.getOutputParameter().getType()); assertEquals(FunctionMethod.PushDown.CAN_PUSHDOWN, fm.getPushdown()); assertEquals(2, fm.getInputParameterCount()); assertEquals("flag", fm.getInputParameters().get(0).getName()); assertEquals("boolean", fm.getInputParameters().get(0).getType()); assertEquals("msg", fm.getInputParameters().get(1).getName()); assertEquals("string", fm.getInputParameters().get(1).getType()); assertFalse(fm.getInputParameters().get(1).isVarArg()); assertNotNull(fm.getAggregateAttributes()); assertTrue(fm.getAggregateAttributes().allowsDistinct()); assertEquals(FunctionMethod.Determinism.DETERMINISTIC, fm.getDeterminism()); assertEquals("misc", fm.getCategory()); assertFalse(fm.isNullOnNull()); }
@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())); } } } }