AggregateAttributes aa = new AggregateAttributes(); String returnType = null; String[] argTypes = null; aa.setAllowsDistinct(true); switch (type) { case TEXTAGG: aa.setAllowsDistinct(false); aa.setAnalytic(true); returnType = DataTypeManager.DefaultDataTypes.INTEGER; argTypes = new String[] {}; returnType = DataTypeManager.DefaultDataTypes.OBJECT; argTypes = new String[] {DataTypeManager.DefaultDataTypes.OBJECT}; aa.setAllowsOrderBy(true); break; case ARRAY_AGG: returnType = DataTypeManager.DefaultDataTypes.OBJECT; argTypes = new String[] {DataTypeManager.getDataTypeName(DataTypeManager.getArrayType(DataTypeManager.DefaultDataClasses.OBJECT))}; aa.setAllowsOrderBy(true); aa.setAllowsDistinct(false); break; case JSONARRAY_AGG: returnType = DataTypeManager.DefaultDataTypes.CLOB; argTypes = new String[] {DataTypeManager.DefaultDataTypes.OBJECT}; aa.setAllowsOrderBy(true); aa.setAllowsDistinct(false); break; case XMLAGG:
public boolean canStage() { if (orderBy != null) { return false; } switch (this.aggregate) { case TEXTAGG: case ARRAY_AGG: case JSONARRAY_AGG: case STRING_AGG: return false; case USER_DEFINED: return this.getArgs().length == 1 && this.getFunctionDescriptor().getMethod().getAggregateAttributes().isDecomposable(); } return true; }
boolean allowsDistinct = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "allows-distinct", true)); //$NON-NLS-1$ boolean decomposable = Boolean.valueOf(procedureRecord.getProperty(AbstractMetadataRecord.RELATIONAL_URI + "decomposable", true)); //$NON-NLS-1$ AggregateAttributes aa = new AggregateAttributes(); aa.setAnalytic(analytic); aa.setAllowsOrderBy(allowsOrderBy); aa.setUsesDistinctRows(usesDistinctRows); aa.setAllowsDistinct(allowsDistinct); aa.setDecomposable(decomposable); function.setAggregateAttributes(aa);
@Override public void initCapabilities(Connection connection) throws TranslatorException { super.initCapabilities(connection); if (getVersion().compareTo(ELEVEN_2) >= 0) { AggregateAttributes aa = new AggregateAttributes(); aa.setAllowsOrderBy(true); addPushDownFunction(ORACLE, LISTAGG, STRING, STRING, STRING).setAggregateAttributes(aa); addPushDownFunction(ORACLE, LISTAGG, STRING, STRING).setAggregateAttributes(aa); } }
TestValidator.helpValidate("SELECT myagg(ALL e2, e2) over () from pm1.g1", new String[] {}, metadata); aa.setAllowsDistinct(true); aa.setAllowsOrderBy(true); aa.setAnalytic(true); aa.setAnalytic(false);
if (!aa.allowsDistinct() && obj.isDistinct()) { handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.uda_not_allowed", "DISTINCT", obj), obj); //$NON-NLS-1$ //$NON-NLS-2$ if (!aa.allowsOrderBy() && obj.getOrderBy() != null) { handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.uda_not_allowed", "ORDER BY", obj), obj); //$NON-NLS-1$ //$NON-NLS-2$ if (aa.isAnalytic() && !obj.isWindowed()) { handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.uda_analytic", obj), obj); //$NON-NLS-1$
aa = new AggregateAttributes(); Method m; try {
public boolean isCardinalityDependent() { if (isDistinct()) { return false; } switch (getAggregateFunction()) { case MAX: case MIN: case ANY: case SOME: case EVERY: return false; case USER_DEFINED: return !getFunctionDescriptor().getMethod().getAggregateAttributes().usesDistinctRows(); } return true; }
FunctionMethod fm = addAgg(s, "myagg", CustomSum.class, DataTypeManager.DefaultDataTypes.STRING); fm.setNullOnNull(false); fm.getAggregateAttributes().setDecomposable(true); TransformationMetadata metadata = RealMetadataFactory.createTransformationMetadata(ms, "test");
@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()); }
if (!aa.allowsDistinct() && obj.isDistinct()) { handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.uda_not_allowed", "DISTINCT", obj), obj); //$NON-NLS-1$ //$NON-NLS-2$ if (!aa.allowsOrderBy() && obj.getOrderBy() != null) { handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.uda_not_allowed", "ORDER BY", obj), obj); //$NON-NLS-1$ //$NON-NLS-2$ if (aa.isAnalytic() && !obj.isWindowed()) { handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.uda_analytic", obj), obj); //$NON-NLS-1$
public Collection<org.teiid.metadata.FunctionMethod> getFunctionMethods() { List<org.teiid.metadata.FunctionMethod> methods = new ArrayList<org.teiid.metadata.FunctionMethod>(); methods.add(new FunctionMethod("xyz", "", "misc", PushDown.MUST_PUSHDOWN, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ FakeFunctionMetadataSource.class.getName(), "xyz", //$NON-NLS-1$ null, new FunctionParameter("out", "integer"), true, Determinism.DETERMINISTIC)); //$NON-NLS-1$ //$NON-NLS-2$ FunctionParameter p1 = new FunctionParameter("astring", "string"); //$NON-NLS-1$ //$NON-NLS-2$ FunctionParameter result = new FunctionParameter("trimstring", "string"); //$NON-NLS-1$ //$NON-NLS-2$ FunctionMethod method = new FunctionMethod("MYRTRIM", "", "", FakeFunctionMetadataSource.class.getName(), "myrtrim", new FunctionParameter[] {p1}, result); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ method.setPushdown(PushDown.CAN_PUSHDOWN); methods.add(method); FunctionMethod method2 = new FunctionMethod("misc.namespace.func", "", "", null, null, new FunctionParameter[] {p1}, result); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ method2.setPushdown(PushDown.MUST_PUSHDOWN); methods.add(method2); FunctionMethod method3 = new FunctionMethod("parsedate_", "", "", null, null, new FunctionParameter[] {p1}, new FunctionParameter("", DataTypeManager.DefaultDataTypes.DATE)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ method3.setPushdown(PushDown.MUST_PUSHDOWN); methods.add(method3); FunctionMethod method4 = new FunctionMethod("FIRST_VALUE", "", "", null, null, new FunctionParameter[] {p1},result); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ method4.setPushdown(PushDown.MUST_PUSHDOWN); method4.setAggregateAttributes(new AggregateAttributes()); methods.add(method4); return methods; }
public boolean isCardinalityDependent() { if (isDistinct()) { return false; } switch (getAggregateFunction()) { case MAX: case MIN: case ANY: case SOME: case EVERY: return false; case USER_DEFINED: return !getFunctionDescriptor().getMethod().getAggregateAttributes().usesDistinctRows(); } return true; }
FunctionMethod fm = addAgg(s, "myagg", SumAll.class, DataTypeManager.DefaultDataTypes.INTEGER); fm.setNullOnNull(false); fm.getAggregateAttributes().setDecomposable(true); TransformationMetadata metadata = RealMetadataFactory.createTransformationMetadata(ms, "test");
AggregateAttributes aa = new AggregateAttributes(); if (type.isAnalytical()) { if (!includeAnalytic) { continue; aa.setAnalytic(true); aa.setAllowsDistinct(false); aa.setAllowsOrderBy(false); aa.setAllowsDistinct(true); switch (type) { case TEXTAGG: case RANK: case ROW_NUMBER: aa.setAllowsDistinct(false); returnType = AggregateSymbol.LONG_RANKS?DataTypeManager.DefaultDataTypes.LONG:DataTypeManager.DefaultDataTypes.INTEGER; argTypes = new String[] {}; returnType = DataTypeManager.DefaultDataTypes.OBJECT; argTypes = new String[] {DataTypeManager.DefaultDataTypes.OBJECT}; aa.setAllowsOrderBy(true); break; case ARRAY_AGG: returnType = DataTypeManager.DefaultDataTypes.OBJECT; argTypes = new String[] {DataTypeManager.getDataTypeName(DataTypeManager.getArrayType(DataTypeManager.DefaultDataClasses.OBJECT))}; aa.setAllowsOrderBy(true); aa.setAllowsDistinct(false); break;
if (!aa.allowsDistinct() && obj.isDistinct()) { handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.uda_not_allowed", "DISTINCT", obj), obj); //$NON-NLS-1$ //$NON-NLS-2$ if (!aa.allowsOrderBy() && obj.getOrderBy() != null) { handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.uda_not_allowed", "ORDER BY", obj), obj); //$NON-NLS-1$ //$NON-NLS-2$ if (aa.isAnalytic() && !obj.isWindowed()) { handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.uda_analytic", obj), obj); //$NON-NLS-1$
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; }
public boolean isCardinalityDependent() { if (isDistinct()) { return false; } switch (getAggregateFunction()) { case MAX: case MIN: case ANY: case SOME: case EVERY: return false; case USER_DEFINED: return !getFunctionDescriptor().getMethod().getAggregateAttributes().usesDistinctRows(); } return true; }
public boolean canStage() { if (orderBy != null) { return false; } switch (this.aggregate) { case TEXTAGG: case ARRAY_AGG: case JSONARRAY_AGG: case STRING_AGG: return false; case USER_DEFINED: return this.getArgs().length == 1 && this.getFunctionDescriptor().getMethod().getAggregateAttributes().isDecomposable(); } return true; }
@Test public void testNullDependentAgg() throws Exception { MetadataStore ms = RealMetadataFactory.example1Store(); Schema s = ms.getSchemas().get("PM1"); FunctionMethod fm = addAgg(s, "myagg", SumAll.class, DataTypeManager.DefaultDataTypes.INTEGER); fm.setNullOnNull(false); fm.getAggregateAttributes().setDecomposable(true); TransformationMetadata metadata = RealMetadataFactory.createTransformationMetadata(ms, "test"); final String userSql = "SELECT myagg(e2) FROM (select e2, e1 as source_name from pm1.g1 union all select e2, e1 from pm2.g1) x"; //$NON-NLS-1$ BasicSourceCapabilities caps = TestAggregatePushdown.getAggregateCapabilities(); caps.setFunctionSupport("myagg", true); ProcessorPlan plan = TestOptimizer.helpPlan(userSql, metadata, new String[] {"SELECT myagg(ALL g_0.e2) FROM pm1.g1 AS g_0 HAVING COUNT(*) > 0", "SELECT myagg(ALL g_0.e2) FROM pm2.g1 AS g_0 HAVING COUNT(*) > 0"}, new DefaultCapabilitiesFinder(caps), ComparisonMode.EXACT_COMMAND_STRING); TestOptimizer.checkNodeTypes(plan, new int[] { 2, // Access 0, // DependentAccess 0, // DependentSelect 0, // DependentProject 0, // DupRemove 1, // Grouping 0, // NestedLoopJoinStrategy 0, // MergeJoinStrategy 0, // Null 0, // PlanExecution 1, // Project 0, // Select 0, // Sort 1 // UnionAll }); }