use of io.crate.planner.projection.Projection in project crate by crate.
the class ProjectingBatchConsumer method accept.
@Override
public void accept(BatchIterator iterator, @Nullable Throwable failure) {
if (failure == null) {
for (Projection projection : projections) {
Projector projector = projectorFactory.create(projection, ramAccountingContext, jobId);
iterator = projector.apply(iterator);
}
consumer.accept(iterator, null);
} else {
consumer.accept(iterator, failure);
}
}
use of io.crate.planner.projection.Projection in project crate by crate.
the class Merge method ensureOnHandler.
/**
* Wrap the subPlan into a Merge plan if it isn't executed on the handler.
* @param projections projections to be applied on the subPlan or merge plan.
* These projections must not affect the limit, offset, order by or numOutputs
*
* If the subPlan contains a limit/offset or orderBy in its resultDescription this method will
* add a TopNProjection AFTER the projections.
*/
public static Plan ensureOnHandler(Plan subPlan, Planner.Context plannerContext, List<Projection> projections) {
ResultDescription resultDescription = subPlan.resultDescription();
assert resultDescription != null : "all plans must have a result description. Plan without: " + subPlan;
// If a sub-Plan applies a limit it is usually limit+offset
// So even if the execution is on the handler the limit may be too large and the final limit needs to be applied as well
Projection topN = ProjectionBuilder.topNOrEvalIfNeeded(resultDescription.limit(), resultDescription.offset(), resultDescription.numOutputs(), resultDescription.streamOutputs());
if (ExecutionPhases.executesOnHandler(plannerContext.handlerNode(), resultDescription.nodeIds())) {
return addProjections(subPlan, projections, resultDescription, topN);
}
Collection<String> handlerNodeIds = getHandlerNodeIds(subPlan, plannerContext, resultDescription);
MergePhase mergePhase = new MergePhase(plannerContext.jobId(), plannerContext.nextExecutionPhaseId(), "mergeOnHandler", resultDescription.nodeIds().size(), handlerNodeIds, resultDescription.streamOutputs(), addProjection(projections, topN), DistributionInfo.DEFAULT_SAME_NODE, resultDescription.orderBy());
return new Merge(subPlan, mergePhase, TopN.NO_LIMIT, 0, resultDescription.numOutputs(), resultDescription.limit(), null);
}
use of io.crate.planner.projection.Projection in project crate by crate.
the class GlobalAggregateConsumer method addAggregations.
/**
* Add aggregation/having/topN projections to the plan.
* Either directly or by wrapping it into a Merge plan.
*/
static Plan addAggregations(QuerySpec qs, ProjectionBuilder projectionBuilder, SplitPoints splitPoints, Planner.Context plannerContext, Plan plan) {
ResultDescription resultDescription = plan.resultDescription();
if (resultDescription.limit() > TopN.NO_LIMIT || resultDescription.orderBy() != null) {
plan = Merge.ensureOnHandler(plan, plannerContext);
resultDescription = plan.resultDescription();
}
WhereClause where = qs.where();
if (where != WhereClause.MATCH_ALL) {
FilterProjection whereFilter = ProjectionBuilder.filterProjection(splitPoints.toCollect(), where);
plan.addProjection(whereFilter, null, null, null, null);
}
List<Projection> postAggregationProjections = createPostAggregationProjections(qs, splitPoints, plannerContext);
if (ExecutionPhases.executesOnHandler(plannerContext.handlerNode(), resultDescription.nodeIds())) {
AggregationProjection finalAggregation = projectionBuilder.aggregationProjection(splitPoints.toCollect(), splitPoints.aggregates(), Aggregation.Step.ITER, Aggregation.Step.FINAL, RowGranularity.CLUSTER);
plan.addProjection(finalAggregation, null, null, splitPoints.aggregates().size(), null);
for (Projection postAggregationProjection : postAggregationProjections) {
plan.addProjection(postAggregationProjection, null, null, null, null);
}
return plan;
} else {
AggregationProjection partialAggregation = projectionBuilder.aggregationProjection(splitPoints.toCollect(), splitPoints.aggregates(), Aggregation.Step.ITER, Aggregation.Step.PARTIAL, RowGranularity.CLUSTER);
plan.addProjection(partialAggregation, null, null, splitPoints.aggregates().size(), null);
AggregationProjection finalAggregation = projectionBuilder.aggregationProjection(splitPoints.aggregates(), splitPoints.aggregates(), Aggregation.Step.PARTIAL, Aggregation.Step.FINAL, RowGranularity.CLUSTER);
postAggregationProjections.add(0, finalAggregation);
}
return createMerge(plan, plannerContext, postAggregationProjections);
}
use of io.crate.planner.projection.Projection in project crate by crate.
the class GlobalAggregateConsumer method globalAggregates.
/**
* Create a Merge(Collect) plan.
*
* iter->partial aggregations on use {@code projectionGranularity} granularity
*/
private static Plan globalAggregates(Functions functions, QueriedTableRelation table, ConsumerContext context, RowGranularity projectionGranularity) {
QuerySpec querySpec = table.querySpec();
if (querySpec.groupBy().isPresent() || !querySpec.hasAggregates()) {
return null;
}
// global aggregate: collect and partial aggregate on C and final agg on H
Planner.Context plannerContext = context.plannerContext();
validateAggregationOutputs(table.tableRelation(), querySpec.outputs());
ProjectionBuilder projectionBuilder = new ProjectionBuilder(functions, querySpec);
SplitPoints splitPoints = projectionBuilder.getSplitPoints();
AggregationProjection ap = projectionBuilder.aggregationProjection(splitPoints.leaves(), splitPoints.aggregates(), Aggregation.Step.ITER, Aggregation.Step.PARTIAL, projectionGranularity);
RoutedCollectPhase collectPhase = RoutedCollectPhase.forQueriedTable(plannerContext, table, splitPoints.leaves(), ImmutableList.of(ap));
Collect collect = new Collect(collectPhase, TopN.NO_LIMIT, 0, ap.outputs().size(), 1, null);
AggregationProjection aggregationProjection = projectionBuilder.aggregationProjection(splitPoints.aggregates(), splitPoints.aggregates(), Aggregation.Step.PARTIAL, Aggregation.Step.FINAL, RowGranularity.CLUSTER);
List<Projection> postAggregationProjections = createPostAggregationProjections(querySpec, splitPoints, plannerContext);
postAggregationProjections.add(0, aggregationProjection);
return createMerge(collect, plannerContext, postAggregationProjections);
}
use of io.crate.planner.projection.Projection in project crate by crate.
the class GlobalAggregateConsumer method createMerge.
private static Plan createMerge(Plan plan, Planner.Context plannerContext, List<Projection> mergeProjections) {
ResultDescription resultDescription = plan.resultDescription();
MergePhase mergePhase = new MergePhase(plannerContext.jobId(), plannerContext.nextExecutionPhaseId(), "mergeOnHandler", resultDescription.nodeIds().size(), Collections.singletonList(plannerContext.handlerNode()), resultDescription.streamOutputs(), mergeProjections, DistributionInfo.DEFAULT_SAME_NODE, null);
Projection lastProjection = mergeProjections.get(mergeProjections.size() - 1);
return new Merge(plan, mergePhase, TopN.NO_LIMIT, 0, lastProjection.outputs().size(), 1, null);
}
Aggregations