private FunctionMethod addFunction(Method method, TeiidFunction f, String name) { FunctionMethod func = MetadataFactory.createFunctionFromMethod(name, method); func.setDescription(QueryPlugin.Util.getString(QueryPlugin.Util.getString("SystemSource." + name.toLowerCase() + "_description"))); //$NON-NLS-1$ //$NON-NLS-2$ func.setCategory(f.category()); for (int i = 0; i < func.getInputParameterCount(); i++) { func.getInputParameters().get(i).setDescription(QueryPlugin.Util.getString("SystemSource." + name.toLowerCase() + "_param" + (i+1))); //$NON-NLS-1$ //$NON-NLS-2$ } func.getOutputParameter().setDescription(QueryPlugin.Util.getString("SystemSource." + name.toLowerCase() + "_result")); //$NON-NLS-1$ //$NON-NLS-2$ if (f.nullOnNull()) { func.setNullOnNull(true); } func.setDeterminism(f.determinism()); func.setPushdown(f.pushdown()); functions.add(func); return func; }
private void addRandFunction() { // With Seed FunctionMethod rand = new FunctionMethod(SourceSystemFunctions.RAND, QueryPlugin.Util.getString("SystemSource.Rand_desc"), NUMERIC, FUNCTION_CLASS, "rand", //$NON-NLS-1$ //$NON-NLS-2$ new FunctionParameter[] {new FunctionParameter("seed", DataTypeManager.DefaultDataTypes.INTEGER, QueryPlugin.Util.getString("SystemSource.Rand_arg")) }, //$NON-NLS-1$ //$NON-NLS-2$ new FunctionParameter("result", DataTypeManager.DefaultDataTypes.DOUBLE, QueryPlugin.Util.getString("SystemSource.Rand_result_desc")) ); //$NON-NLS-1$ //$NON-NLS-2$ rand.setNullOnNull(false); rand.setDeterminism(Determinism.NONDETERMINISTIC); //seed handling varies greatly by source rand.setPushdown(PushDown.CANNOT_PUSHDOWN); functions.add(rand); // Without Seed rand = new FunctionMethod(SourceSystemFunctions.RAND, QueryPlugin.Util.getString("SystemSource.Rand_desc"), NUMERIC, FUNCTION_CLASS, "rand", //$NON-NLS-1$ //$NON-NLS-2$ new FunctionParameter[] {}, new FunctionParameter("result", DataTypeManager.DefaultDataTypes.DOUBLE, QueryPlugin.Util.getString("SystemSource.Rand_result_desc")) ); //$NON-NLS-1$ //$NON-NLS-2$ rand.setDeterminism(Determinism.NONDETERMINISTIC); functions.add(rand); }
private String buildFunctionOptions(FunctionMethod function) { StringBuilder options = new StringBuilder(); addCommonOptions(options, function); if (function.getCategory() != null) { addOption(options, CATEGORY, function.getCategory()); } if (!function.getDeterminism().equals(Determinism.DETERMINISTIC)) { addOption(options, DETERMINISM, function.getDeterminism().name()); } if (function.getInvocationClass() != null) { addOption(options, JAVA_CLASS, function.getInvocationClass()); } if (function.getInvocationMethod() != null) { addOption(options, JAVA_METHOD, function.getInvocationMethod()); } if (!function.getProperties().isEmpty()) { for (String key:function.getProperties().keySet()) { addOption(options, key, function.getProperty(key, false)); } } return options.toString(); }
public FunctionMethod(String name, String description, String category, PushDown pushdown, String invocationClass, String invocationMethod, List<FunctionParameter> inputParams, FunctionParameter outputParam, boolean nullOnNull, Determinism deterministic) { setName(name); setDescription(description); setCategory(category); setPushdown(pushdown); setInvocationClass(invocationClass); setInvocationMethod(invocationMethod); setInputParameters(inputParams); setOutputParameter(outputParam); setNullOnNull(nullOnNull); setDeterminism(deterministic); }
@Override protected Collection<? extends FunctionParameter> getChildren(final FunctionMethod parent, CommandContext cc) { ArrayList<FunctionParameter> result = new ArrayList<FunctionParameter>(parent.getInputParameters().size() + 1); result.addAll(parent.getInputParameters()); result.add(parent.getOutputParameter()); return result; }
public List<FunctionMethod> removeFunctions(String functionName) { ArrayList<FunctionMethod> funcs = new ArrayList<FunctionMethod>(); for (FunctionMethod fm : this.functions.values()){ if (fm.getName().equalsIgnoreCase(functionName)){ funcs.add(fm); } } for (FunctionMethod func:funcs) { this.functions.remove(func.getUUID()); } return funcs; }
public static FunctionMethod createFunctionMethod(Procedure proc) { FunctionMethod method = new FunctionMethod(); method.setName(proc.getName()); method.setPushdown(proc.isVirtual()?FunctionMethod.PushDown.CAN_PUSHDOWN:FunctionMethod.PushDown.MUST_PUSHDOWN); fp.setPosition(ins.size()); } else { method.setOutputParameter(fp); fp.setPosition(0); method.setInputParameters(ins); if (proc.getResultSet() != null || method.getOutputParameter() == null) { throw new MetadataException(QueryPlugin.Util.getString("SQLParser.function_return", proc.getName())); //$NON-NLS-1$ method.setAnnotation(proc.getAnnotation()); method.setNameInSource(proc.getNameInSource()); method.setUUID(proc.getUUID()); method.setCategory(value); method.setDeterminism(FunctionMethod.Determinism.valueOf(value.toUpperCase())); method.setInvocationClass(value); method.setInvocationMethod(value); method.setProperty(key, value); FunctionMethod.convertExtensionMetadata(proc, method);
validateName(method.getName()); validateDescription(method.getDescription()); validateCategory(method.getCategory()); validateInvocationMethod(method.getInvocationClass(), method.getInvocationMethod(), method.getPushdown()); List<FunctionParameter> params = method.getInputParameters(); if(params != null && !params.isEmpty()) { for(int i=0; i<params.size(); i++) { validateFunctionParameter(method.getOutputParameter()); method.getOutputParameter().setPosition(0); MetadataFactory.setDataType(method.getOutputParameter().getRuntimeType(), method.getOutputParameter(), runtimeTypeMap, true); } catch(FunctionMetadataException e) { updateReport(report, method, e.getMessage());
FunctionParameter outputParam = method.getOutputParameter(); Class<?> outputType = null; if(outputParam != null) { if (method.isVarArgs()) { inputTypes.set(inputTypes.size() - 1, DataTypeManager.getArrayType(inputTypes.get(inputTypes.size() - 1))); Method invocationMethod = method.getMethod(); boolean requiresContext = false; if (validateClass && (method.getPushdown() == PushDown.CAN_PUSHDOWN || method.getPushdown() == PushDown.CANNOT_PUSHDOWN)) { if (invocationMethod == null) { if (method.getInvocationClass() == null || method.getInvocationMethod() == null) { throw new MetadataException(QueryPlugin.Event.TEIID31123, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31123, method.getName())); Class<?> methodClass = source.getInvocationClass(method.getInvocationClass()); ReflectionHelper helper = new ReflectionHelper(methodClass); try { invocationMethod = helper.findBestMethodWithSignature(method.getInvocationMethod(), inputTypes); } catch (NoSuchMethodException e) { inputTypes.add(0, CommandContext.class); invocationMethod = helper.findBestMethodWithSignature(method.getInvocationMethod(), inputTypes); requiresContext = true; throw new MetadataException(QueryPlugin.Event.TEIID30387, e,QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30387, method.getName(), method.getInvocationClass())); } catch (NoSuchMethodException e) { throw new MetadataException(QueryPlugin.Event.TEIID30388, e,QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30388, method, method.getInvocationClass(), method.getInvocationMethod())); } catch (Exception e) { throw new MetadataException(QueryPlugin.Event.TEIID30389, e,QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30389, method, method.getInvocationClass(), method.getInvocationMethod()));
String categoryKey = method.getCategory(); if (categoryKey == null) { method.setCategory(FunctionCategoryConstants.MISCELLANEOUS); categoryKey = FunctionCategoryConstants.MISCELLANEOUS; String methodName = schema + AbstractMetadataRecord.NAME_DELIM_CHAR + method.getName(); List<FunctionParameter> inputParams = method.getInputParameters(); Class<?>[] types = null; if(inputParams != null) { setUuid(method.getOutputParameter()); functionsByUuid.put(method.getUUID(), method); while(true) { node.put(pathPart, children); if (method.isVarArgs() && pathIndex == types.length - 1) { node.put(DESCRIPTOR_KEY, descriptor); Map<Object, Object> alternate = new HashMap<Object, Object>(2); if (method.isVarArgs()) { node.put(types[types.length - 1], node);
String javaClass = procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "java-class", true); //$NON-NLS-1$ String javaMethod = procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "java-method", true); //$NON-NLS-1$ if (function.getInvocationClass() == null) { function.setInvocationClass(javaClass); if (function.getInvocationMethod() == null) { function.setInvocationMethod(javaMethod); function.setProperties(procedureRecord.getProperties()); function.setDeterminism(Boolean.valueOf(deterministic)?Determinism.DETERMINISTIC:Determinism.NONDETERMINISTIC); function.setNullOnNull(nullOnNull); if (varargs != null && !function.getInputParameters().isEmpty()) { function.getInputParameters().get(function.getInputParameterCount() - 1).setVarArg(Boolean.valueOf(varargs)); aa.setAllowsDistinct(allowsDistinct); aa.setDecomposable(decomposable); function.setAggregateAttributes(aa);
@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().getRuntimeType()); assertEquals(FunctionMethod.PushDown.CAN_PUSHDOWN, fm.getPushdown()); assertEquals(2, fm.getInputParameterCount()); assertEquals("flag", fm.getInputParameters().get(0).getName()); assertEquals("boolean", fm.getInputParameters().get(0).getRuntimeType()); assertEquals("msg", fm.getInputParameters().get(1).getName()); assertEquals("string", fm.getInputParameters().get(1).getRuntimeType()); 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")); }
private FunctionMethod addAgg(Schema s, String name, Class<?> clazz, String returns) { FunctionMethod fm = new FunctionMethod(); fm.setName(name); fm.setInvocationClass(clazz.getName()); fm.setInvocationMethod("addInput"); FunctionParameter fp = new FunctionParameter(); fp.setType(DataTypeManager.DefaultDataTypes.INTEGER); fp.setName("arg"); fp.setVarArg(true); fm.getInputParameters().add(fp); FunctionParameter fpout = new FunctionParameter(); fpout.setType(returns); fpout.setName("outp"); fm.setOutputParameter(fpout); AggregateAttributes aa = new AggregateAttributes(); fm.setAggregateAttributes(aa); s.getFunctions().put(fm.getName(), fm); return fm; }
@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().getRuntimeType()); assertEquals(FunctionMethod.PushDown.CAN_PUSHDOWN, fm.getPushdown()); assertEquals(2, fm.getInputParameterCount()); assertEquals("flag", fm.getInputParameters().get(0).getName()); assertEquals("boolean", fm.getInputParameters().get(0).getRuntimeType()); assertEquals("msg", fm.getInputParameters().get(1).getName()); assertEquals("string", fm.getInputParameters().get(1).getRuntimeType()); 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()); }
paramTypes = Arrays.copyOfRange(paramTypes, 1, paramTypes.length); FunctionMethod func = FunctionMethod.createFunctionMethod(name, null, null, returnType, paramTypes); func.setAggregateAttributes(aa); func.setInvocationMethod(method.getName()); func.setPushdown(PushDown.CAN_PUSHDOWN); func.setMethod(method); func.setInvocationClass(method.getDeclaringClass().getName()); func.setNullOnNull(nullOnNull); if (method.isVarArgs()) { func.setVarArgs(method.isVarArgs());
FunctionMethod function = new FunctionMethod(procedureRecord.getName(), procedureRecord.getAnnotation(), model.getName(), procedureRecord.isVirtual()?PushDown.CAN_PUSHDOWN:PushDown.MUST_PUSHDOWN, null, null, args, outputParam, false, Determinism.DETERMINISTIC); function.setUUID(procedureRecord.getUUID()); FunctionMethod.convertExtensionMetadata(procedureRecord, function); if (function.getInvocationMethod() != null) { function.setPushdown(PushDown.CAN_PUSHDOWN);
private void addIfNullFunction(String valueType) { FunctionMethod nvl = new FunctionMethod("ifnull", QueryPlugin.Util.getString("SystemSource.Ifnull_desc"), MISCELLANEOUS, FUNCTION_CLASS, "ifnull", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ new FunctionParameter[] { new FunctionParameter("value", valueType, QueryPlugin.Util.getString("SystemSource.Ifnull_arg1")), //$NON-NLS-1$ //$NON-NLS-2$ new FunctionParameter("valueIfNull", valueType, QueryPlugin.Util.getString("SystemSource.Ifnull_arg2")) }, //$NON-NLS-1$ //$NON-NLS-2$ new FunctionParameter("result", valueType, QueryPlugin.Util.getString("SystemSource.Ifnull_result")) ); //$NON-NLS-1$ //$NON-NLS-2$ nvl.setNullOnNull(false); functions.add(nvl); }
@Test public void testFunctionMetadata() throws Exception { TransformationMetadata tm = VDBMetadataFactory.getVDBMetadata(UnitTestUtil.getTestDataPath() + "/TEIIDDES992_VDB.vdb"); Map<String, FunctionMethod> functions = tm.getMetadataStore().getSchema("TEIIDDES992").getFunctions(); assertEquals(1, functions.size()); FunctionMethod fm = functions.values().iterator().next(); assertEquals("mmuuid:5c2cede9-0e18-4e4c-a531-34507abf0ff8", fm.getUUID()); assertEquals("sampleFunction", fm.getName()); assertEquals(1, fm.getInputParameters().size()); assertEquals("mmuuid:f9ded2ae-9652-414e-b5a9-74185f8703c0", fm.getOutputParameter().getUUID()); assertNotNull(fm.getInputParameters().get(0).getParent()); }
/** * Date functions a marked as command deterministic, since we prefer pre-evaluation rather than row-by-row * evaluation. */ private void addConstantDateFunction(String name, String description, String methodName, String returnType, Determinism determinism) { FunctionMethod method = new FunctionMethod(name, description, DATETIME, FUNCTION_CLASS, methodName, new FunctionParameter[] {}, new FunctionParameter("result", returnType, description)); //$NON-NLS-1$ method.setDeterminism(determinism); functions.add(method); }
add_infoSchemaTableConstraints(); addFunction("regClass", "regclass").setNullOnNull(true); //$NON-NLS-1$ //$NON-NLS-2$ addFunction("encode", "encode").setPushdown(PushDown.CAN_PUSHDOWN); //$NON-NLS-1$ //$NON-NLS-2$ addFunction("objDescription", "obj_description"); //$NON-NLS-1$ //$NON-NLS-2$ addFunction("hasSchemaPrivilege", "has_schema_privilege").setNullOnNull(true); //$NON-NLS-1$ //$NON-NLS-2$ addFunction("hasTablePrivilege", "has_table_privilege").setNullOnNull(true); //$NON-NLS-1$ //$NON-NLS-2$ addFunction("formatType", "format_type").setNullOnNull(true); //$NON-NLS-1$ //$NON-NLS-2$ addFunction("currentSchema", "current_schema"); //$NON-NLS-1$ //$NON-NLS-2$ addFunction("getUserById", "pg_get_userbyid"); //$NON-NLS-1$ //$NON-NLS-2$ addFunction("pg_encoding_to_char", "pg_encoding_to_char"); //$NON-NLS-1$ //$NON-NLS-2$ FunctionMethod func = addFunction("asPGVector", "asPGVector"); //$NON-NLS-1$ //$NON-NLS-2$ func.setProperty(ResolverVisitor.TEIID_PASS_THROUGH_TYPE, Boolean.TRUE.toString()); addFunction("getOid", "getOid").setNullOnNull(true);; //$NON-NLS-1$ //$NON-NLS-2$ addFunction("version", "version"); //$NON-NLS-1$ //$NON-NLS-2$ func = addFunction("pg_client_encoding", "pg_client_encoding"); //$NON-NLS-1$ //$NON-NLS-2$ func.setDeterminism(Determinism.COMMAND_DETERMINISTIC); addFunction("current_schemas", "current_schemas"); //$NON-NLS-1$ //$NON-NLS-2$ addFunction("pg_get_indexdef", "pg_get_indexdef"); //$NON-NLS-1$ //$NON-NLS-2$