use of com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan in project fdb-record-layer by FoundationDB.
the class PushDistinctThroughFetchRule method onMatch.
@Override
public void onMatch(@Nonnull PlannerRuleCall call) {
final PlannerBindings bindings = call.getBindings();
final RecordQueryFetchFromPartialRecordPlan fetchPlan = bindings.get(fetchPlanMatcher);
final RecordQueryPlan innerPlan = bindings.get(innerPlanMatcher);
final CorrelationIdentifier newInnerAlias = CorrelationIdentifier.uniqueID();
final Quantifier.Physical newInnerQuantifier = Quantifier.physical(GroupExpressionRef.of(innerPlan), newInnerAlias);
final RecordQueryUnorderedPrimaryKeyDistinctPlan pushedDistinctPlan = new RecordQueryUnorderedPrimaryKeyDistinctPlan(newInnerQuantifier);
final RecordQueryFetchFromPartialRecordPlan newFetchPlan = new RecordQueryFetchFromPartialRecordPlan(pushedDistinctPlan, fetchPlan.getPushValueFunction());
// case 2
call.yield(call.ref(newFetchPlan));
}
use of com.apple.foundationdb.record.query.plan.plans.RecordQueryFetchFromPartialRecordPlan in project fdb-record-layer by FoundationDB.
the class PushFilterThroughFetchRule method onMatch.
@Override
public void onMatch(@Nonnull PlannerRuleCall call) {
final PlannerBindings bindings = call.getBindings();
final RecordQueryPredicatesFilterPlan filterPlan = bindings.get(root);
final RecordQueryFetchFromPartialRecordPlan fetchPlan = bindings.get(fetchPlanMatcher);
final Quantifier.Physical quantifierOverFetch = bindings.get(quantifierOverFetchMatcher);
final RecordQueryPlan innerPlan = bindings.get(innerPlanMatcher);
final List<? extends QueryPredicate> queryPredicates = filterPlan.getPredicates();
final ImmutableList.Builder<QueryPredicate> pushedPredicatesBuilder = ImmutableList.builder();
final ImmutableList.Builder<QueryPredicate> residualPredicatesBuilder = ImmutableList.builder();
final CorrelationIdentifier newInnerAlias = CorrelationIdentifier.uniqueID();
for (final QueryPredicate queryPredicate : queryPredicates) {
final Optional<QueryPredicate> pushedPredicateOptional = queryPredicate.replaceLeavesMaybe(leafPredicate -> pushLeafPredicate(fetchPlan, newInnerAlias, leafPredicate));
if (pushedPredicateOptional.isPresent()) {
pushedPredicatesBuilder.add(pushedPredicateOptional.get());
} else {
residualPredicatesBuilder.add(queryPredicate);
}
}
final ImmutableList<QueryPredicate> pushedPredicates = pushedPredicatesBuilder.build();
final ImmutableList<QueryPredicate> residualPredicates = residualPredicatesBuilder.build();
Verify.verify(pushedPredicates.size() + residualPredicates.size() == queryPredicates.size());
// case 1
if (pushedPredicates.isEmpty()) {
return;
}
// for case 2 and case 3 we can at least build a FILTER(inner, pushedPredicates) as that is
// required both for case 2 nd 3
final Quantifier.Physical newInnerQuantifier = Quantifier.physical(GroupExpressionRef.of(innerPlan), newInnerAlias);
final RecordQueryPredicatesFilterPlan pushedFilterPlan = new RecordQueryPredicatesFilterPlan(newInnerQuantifier, pushedPredicates);
final RecordQueryFetchFromPartialRecordPlan newFetchPlan = new RecordQueryFetchFromPartialRecordPlan(pushedFilterPlan, fetchPlan.getPushValueFunction());
if (residualPredicates.isEmpty()) {
// case 2
call.yield(call.ref(newFetchPlan));
} else {
// case 3
// create yet another physical quantifier on top of the fetch
final Quantifier.Physical newQuantifierOverFetch = Quantifier.physical(GroupExpressionRef.of(newFetchPlan));
final AliasMap translationMap = AliasMap.of(quantifierOverFetch.getAlias(), newQuantifierOverFetch.getAlias());
// rebase all residual predicates to use that quantifier's alias
final ImmutableList<QueryPredicate> rebasedResidualPredicates = residualPredicates.stream().map(residualPredicate -> residualPredicate.rebase(translationMap)).collect(ImmutableList.toImmutableList());
call.yield(GroupExpressionRef.of(new RecordQueryPredicatesFilterPlan(newQuantifierOverFetch, rebasedResidualPredicates)));
}
}
Aggregations