use of io.crate.planner.operators.GroupHashAggregate in project crate by crate.
the class MoveFilterBeneathGroupBy method apply.
@Override
public LogicalPlan apply(Filter filter, Captures captures, TableStats tableStats, TransactionContext txnCtx, NodeContext nodeCtx) {
// Since something like `SELECT x, sum(y) FROM t GROUP BY x HAVING y > 10` is not valid
// (y would have to be declared as group key) any parts of a HAVING that is not an aggregation can be moved.
Symbol predicate = filter.query();
List<Symbol> parts = AndOperator.split(predicate);
ArrayList<Symbol> withAggregates = new ArrayList<>();
ArrayList<Symbol> withoutAggregates = new ArrayList<>();
for (Symbol part : parts) {
if (SymbolVisitors.any(Symbols::isAggregate, part)) {
withAggregates.add(part);
} else {
withoutAggregates.add(part);
}
}
if (withoutAggregates.isEmpty()) {
return null;
}
GroupHashAggregate groupBy = captures.get(groupByCapture);
if (withoutAggregates.size() == parts.size()) {
return transpose(filter, groupBy);
}
/* HAVING `count(*) > 1 AND x = 10`
* withAggregates: [count(*) > 1]
* withoutAggregates: [x = 10]
*
* Filter
* |
* GroupBy
*
* transforms to
*
* Filter (count(*) > 1)
* |
* GroupBy
* |
* Filter (x = 10)
*/
LogicalPlan newGroupBy = groupBy.replaceSources(List.of(new Filter(groupBy.source(), AndOperator.join(withoutAggregates))));
return new Filter(newGroupBy, AndOperator.join(withAggregates));
}
Aggregations