/** * Return a deep copy of this object */ public Object clone() { AggregateSymbol copy = new AggregateSymbol(getName(), getAggregateFunction(), isDistinct(), LanguageObject.Util.deepClone(getArgs())); if (orderBy != null) { copy.setOrderBy(orderBy.clone()); } if (condition != null) { copy.setCondition((Expression) condition.clone()); } copy.isWindowed = this.isWindowed; copy.type = this.type; copy.setFunctionDescriptor(getFunctionDescriptor()); return copy; }
public void testEquals4() { AggregateSymbol as1 = new AggregateSymbol(NonReserved.COUNT, false, null); //$NON-NLS-1$ AggregateSymbol as2 = (AggregateSymbol) as1.clone(); helpEquals(as1, as2, true); }
private Expression rewriteExpression(AggregateSymbol expression) throws TeiidComponentException, TeiidProcessingException { if (expression.isBoolean()) { if (expression.getAggregateFunction() == Type.EVERY) { expression.setAggregateFunction(Type.MIN); } else { expression.setAggregateFunction(Type.MAX); if ((expression.getAggregateFunction() == Type.MAX || expression.getAggregateFunction() == Type.MIN || expression.getAggregateFunction() == Type.AVG)) { if (expression.getAggregateFunction() != Type.AVG && expression.isDistinct()) { expression.setDistinct(false); if (rewriteAggs && expression.getArg(0) != null && EvaluatableVisitor.willBecomeConstant(expression.getArg(0))) { return expression.getArg(0); if (expression.isDistinct() && expression.getAggregateFunction() == Type.USER_DEFINED && expression.getFunctionDescriptor().getMethod().getAggregateAttributes().usesDistinctRows()) { expression.setDistinct(false); Expression[] args = expression.getArgs(); if (args.length == 1 && expression.getCondition() != null && !expression.respectsNulls()) { Expression cond = expression.getCondition(); Expression ex = expression.getArg(0); if (!(cond instanceof Criteria)) { cond = new ExpressionCriteria(cond); expression.setCondition(null); expression.setArgs(new Expression[] {sce}); args = expression.getArgs(); args[i] = rewriteExpressionDirect(expression.getArg(i));
private static boolean isCountStar(AggregateSymbol as) { return as.getAggregateFunction() == Type.COUNT && (as.getArgs().length == 0 || EvaluatableVisitor.willBecomeConstant(as.getArg(0))); }
AggregateFunction translate(AggregateSymbol symbol) { List<org.teiid.language.Expression> params = new ArrayList<org.teiid.language.Expression>(symbol.getArgs().length); for (Expression expression : symbol.getArgs()) { params.add(translate(expression)); } String name = symbol.getAggregateFunction().name(); if (symbol.getAggregateFunction() == AggregateSymbol.Type.USER_DEFINED) { name = symbol.getName(); } AggregateFunction af = new AggregateFunction(name, symbol.isDistinct(), params, symbol.getType()); af.setCondition(translate(symbol.getCondition())); af.setOrderBy(translate(symbol.getOrderBy(), false)); return af; }
@Override public void visit(AggregateSymbol obj) { if (obj.getCondition() != null) { try { obj.setCondition(ResolverUtil.convertExpression(obj.getCondition(), DataTypeManager.DefaultDataTypes.BOOLEAN, metadata)); } catch (QueryResolverException e) { handleException(e); switch (obj.getAggregateFunction()) { case USER_DEFINED: visit((Function)obj); case LEAD: case LAG: if (obj.getArgs().length > 1) { obj.getArgs()[1] = ResolverUtil.convertExpression(obj.getArg(1), DataTypeManager.DefaultDataTypes.INTEGER, metadata); } catch (QueryResolverException e) { handleException(e); if (obj.getArgs().length > 2) { try { if (obj.getArgs()[0].getType() == DataTypeManager.DefaultDataClasses.NULL) { obj.getArgs()[0] = ResolverUtil.convertExpression(obj.getArg(0), DataTypeManager.getDataTypeName(obj.getArg(2).getType()), metadata); } else { obj.getArgs()[2] = ResolverUtil.convertExpression(obj.getArg(2), DataTypeManager.getDataTypeName(obj.getArg(0).getType()), metadata); if (obj.getArgs().length != 1) { throw new QueryResolverException(QueryPlugin.Event.TEIID31278, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31278, obj));
public Query selectQuery() throws TeiidException { if (!this.exceptions.isEmpty()) { throw this.exceptions.get(0); } Query query = this.context.buildQuery(); if (this.countQuery) { AggregateSymbol aggregateSymbol = new AggregateSymbol(AggregateSymbol.Type.COUNT.name(), false, null); Select select = new Select(Arrays.asList(aggregateSymbol)); query.setSelect(select); } else if (this.orderBy != null) { if (this.context.getIterator() != null) { //currently this doesn't matter as the ordering can only be based upon the parent entity ((AggregateSymbol)((AliasSymbol)query.getSelect().getSymbol(query.getSelect().getProjectedSymbols().size() - 1)).getSymbol()).setOrderBy(this.orderBy); } else { query.setOrderBy(this.orderBy); } } if (this.expandOption != null) { processExpandOption(this.expandOption, this.context, query, 1, null); } return query; }
return COUNT_TYPE; case SUM: Class<?> expressionType = this.getArg(0).getType(); return SUM_TYPES.get(expressionType); case AVG: expressionType = this.getArg(0).getType(); return AVG_TYPES.get(expressionType); case ARRAY_AGG: if (this.getArg(0) == null) { return null; return DataTypeManager.getArrayType(this.getArg(0).getType()); case TEXTAGG: return DataTypeManager.DefaultDataClasses.BLOB; case USER_DEFINED: if (this.getFunctionDescriptor() == null) { return null; return this.getFunctionDescriptor().getReturnType(); case JSONARRAY_AGG: return DataTypeManager.DefaultDataClasses.CLOB; if (isBoolean()) { return DataTypeManager.DefaultDataClasses.BOOLEAN; if (isEnhancedNumeric()) { return DataTypeManager.DefaultDataClasses.DOUBLE; if (isAnalytical()) {
agg = (AggregateSymbol)agg.clone(); if (agg.isCount()) { if (isCountStar(agg)) { allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", newLiteral(1, agg.getType()))); //$NON-NLS-1$ } else { SearchedCaseExpression count = new SearchedCaseExpression(Arrays.asList(new IsNullCriteria(agg.getArg(0))), Arrays.asList(newLiteral(0, agg.getType()))); count.setElseExpression(newLiteral(1, agg.getType())); count.setType(agg.getType()); allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", count)); //$NON-NLS-1$ assert agg.getArgs().length == 1; //prior canStage should ensure this is true Expression ex = agg.getArg(0); ex = ResolverUtil.convertExpression(ex, DataTypeManager.getDataTypeName(agg.getType()), metadata); allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", ex)); //$NON-NLS-1$
if (aggs) { AggregateSymbol as = (AggregateSymbol)aggregateSymbol; if ((!as.canStage() && as.isCardinalityDependent())) { return null; if (as.getAggregateFunction() == Type.AVG || as.isEnhancedNumeric()) { continue; //don't need to map these, they will just become constants if (aggs && ((AggregateSymbol)aggregateSymbol).isCardinalityDependent()) { return null; if (aggs && ((AggregateSymbol)aggregateSymbol).isDistinct()) {
private void addEmptyFilter(Collection<AggregateSymbol> aggregates, PlanNode stageGroup, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, Object modelId) throws QueryMetadataException, TeiidComponentException { PlanNode selectNode = NodeFactory.getNewNode(NodeConstants.Types.SELECT); AggregateSymbol count = new AggregateSymbol(NonReserved.COUNT, false, null); aggregates.add(count); //consider the count aggregate for the push down call below Criteria crit = new CompareCriteria(count, CompareCriteria.GT, new Constant(new Integer(0))); selectNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, crit); selectNode.setProperty(NodeConstants.Info.IS_HAVING, Boolean.TRUE); stageGroup.addAsParent(selectNode); }
public void visit(AggregateSymbol obj) { preVisitVisitor(obj); Expression[] args = obj.getArgs(); if(args != null) { for(int i=0; i<args.length; i++) { visitNode(args[i]); } } visitNode(obj.getOrderBy()); visitNode(obj.getCondition()); postVisitVisitor(obj); } public void visit(AliasSymbol obj) {
return COUNT_TYPE; case SUM: Class<?> expressionType = this.getArg(0).getType(); return SUM_TYPES.get(expressionType); case AVG: expressionType = this.getArg(0).getType(); return AVG_TYPES.get(expressionType); case ARRAY_AGG: if (this.getArg(0) == null) { return null; return DataTypeManager.getArrayType(this.getArg(0).getType()); case TEXTAGG: return DataTypeManager.DefaultDataClasses.BLOB; if (isBoolean()) { return DataTypeManager.DefaultDataClasses.BOOLEAN; if (isEnhancedNumeric()) { return DataTypeManager.DefaultDataClasses.DOUBLE; if (isRanking()) { return super.getType(); if (this.getArgs().length == 0) { return null; return this.getArg(0).getType();
agg = (AggregateSymbol)agg.clone(); if (agg.getAggregateFunction() == Type.COUNT) { if (isCountStar(agg)) { allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", new Constant(1))); //$NON-NLS-1$ } else { SearchedCaseExpression count = new SearchedCaseExpression(Arrays.asList(new IsNullCriteria(agg.getArg(0))), Arrays.asList(new Constant(Integer.valueOf(0)))); count.setElseExpression(new Constant(Integer.valueOf(1))); count.setType(DataTypeManager.DefaultDataClasses.INTEGER); assert agg.getArgs().length == 1; //prior canStage should ensure this is true Expression ex = agg.getArg(0); ex = ResolverUtil.convertExpression(ex, DataTypeManager.getDataTypeName(agg.getType()), metadata); allSymbols.addSymbol(new ExpressionSymbol("stagedAgg", ex)); //$NON-NLS-1$
public Expression replaceExpression(Expression element) { if (element instanceof Function && !(element instanceof AggregateSymbol) && ((Function) element).isAggregate()) { Function f = (Function)element; AggregateSymbol as = new AggregateSymbol(f.getName(), false, f.getArgs(), null); as.setType(f.getType()); as.setFunctionDescriptor(f.getFunctionDescriptor()); return as; } return element; } };
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; }
if (symbol.getArgs().length != 1 || symbol.isCardinalityDependent()) { continue; Expression expr = symbol.getArg(0); if (stagedGroupingSymbols.contains(expr)) { iterator.remove();
@Test public void testAggFilter() throws Exception { String sql = "select count(*) filter (where x = 1) from g"; Query query = new Query(); AggregateSymbol aggregateSymbol = new AggregateSymbol(AggregateSymbol.Type.COUNT.name(), false, null); aggregateSymbol.setCondition(new CompareCriteria(new ElementSymbol("x"), CompareCriteria.EQ, new Constant(1))); query.setSelect(new Select(Arrays.asList(aggregateSymbol))); query.setFrom(new From(Arrays.asList(new UnaryFromClause(new GroupSymbol("g"))))); helpTest(sql, "SELECT COUNT(*) FILTER(WHERE x = 1) FROM g", query); }
public void visit(AggregateSymbol obj) { visit((Function)obj); if (obj.getCondition() != null) { obj.setCondition(replaceExpression(obj.getCondition())); } }