use of io.crate.planner.operators.Filter in project crate by crate.
the class MergeFilters method apply.
@Override
public Filter apply(Filter plan, Captures captures, TableStats tableStats, TransactionContext txnCtx, NodeContext nodeCtx) {
Filter childFilter = captures.get(child);
Symbol parentQuery = plan.query();
Symbol childQuery = childFilter.query();
return new Filter(childFilter.source(), AndOperator.of(parentQuery, childQuery));
}
use of io.crate.planner.operators.Filter 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));
}
use of io.crate.planner.operators.Filter in project crate by crate.
the class MoveFilterBeneathProjectSet method apply.
@Override
public LogicalPlan apply(Filter filter, Captures captures, TableStats tableStats, TransactionContext txnCtx, NodeContext nodeCtx) {
var projectSet = captures.get(projectSetCapture);
var queryParts = AndOperator.split(filter.query());
ArrayList<Symbol> toPushDown = new ArrayList<>();
ArrayList<Symbol> toKeep = new ArrayList<>();
for (var part : queryParts) {
if (!SymbolVisitors.any(MoveFilterBeneathProjectSet::isTableFunction, part) && projectSet.standaloneOutputs().containsAll(extractColumns(part))) {
toPushDown.add(part);
} else {
toKeep.add(part);
}
}
if (toPushDown.isEmpty()) {
return null;
} else if (toKeep.isEmpty()) {
return transpose(filter, projectSet);
} else {
var newProjectSet = projectSet.replaceSources(List.of(new Filter(projectSet.source(), AndOperator.join(toPushDown))));
return new Filter(newProjectSet, AndOperator.join(toKeep));
}
}
use of io.crate.planner.operators.Filter in project crate by crate.
the class MergeFiltersTest method testMergeFiltersMatchesOnAFilterWithAnotherFilterAsChild.
@Test
public void testMergeFiltersMatchesOnAFilterWithAnotherFilterAsChild() {
Collect source = new Collect(tr1, Collections.emptyList(), WhereClause.MATCH_ALL, 100, 10);
Filter sourceFilter = new Filter(source, e.asSymbol("x > 10"));
Filter parentFilter = new Filter(sourceFilter, e.asSymbol("y > 10"));
MergeFilters mergeFilters = new MergeFilters();
Match<Filter> match = mergeFilters.pattern().accept(parentFilter, Captures.empty());
assertThat(match.isPresent(), Matchers.is(true));
assertThat(match.value(), Matchers.sameInstance(parentFilter));
Filter mergedFilter = mergeFilters.apply(match.value(), match.captures(), new TableStats(), CoordinatorTxnCtx.systemTransactionContext(), e.nodeCtx);
assertThat(mergedFilter.query(), isSQL("((doc.t2.y > 10) AND (doc.t1.x > 10))"));
}
Aggregations