use of io.crate.planner.ExecutionPlan in project crate by crate.
the class NodeOperationTreeGenerator method visitMerge.
@Override
public Void visitMerge(Merge merge, NodeOperationTreeContext context) {
ExecutionPlan subExecutionPlan = merge.subPlan();
boolean useDirectResponse = context.noPreviousPhases() && subExecutionPlan instanceof Collect && !Paging.shouldPage(subExecutionPlan.resultDescription().maxRowsPerNode());
context.addPhase(merge.mergePhase());
if (useDirectResponse) {
context.addPhase(((Collect) subExecutionPlan).collectPhase(), true);
} else {
process(subExecutionPlan, context);
}
return null;
}
use of io.crate.planner.ExecutionPlan in project crate by crate.
the class Limit method build.
@Override
public ExecutionPlan build(PlannerContext plannerContext, Set<PlanHint> planHints, ProjectionBuilder projectionBuilder, int limitHint, int offsetHint, @Nullable OrderBy order, @Nullable Integer pageSizeHint, Row params, SubQueryResults subQueryResults) {
int limit = Objects.requireNonNullElse(DataTypes.INTEGER.sanitizeValue(evaluate(plannerContext.transactionContext(), plannerContext.nodeContext(), this.limit, params, subQueryResults)), NO_LIMIT);
int offset = Objects.requireNonNullElse(DataTypes.INTEGER.sanitizeValue(evaluate(plannerContext.transactionContext(), plannerContext.nodeContext(), this.offset, params, subQueryResults)), 0);
ExecutionPlan executionPlan = source.build(plannerContext, planHints, projectionBuilder, limit, offset, order, pageSizeHint, params, subQueryResults);
List<DataType<?>> sourceTypes = Symbols.typeView(source.outputs());
ResultDescription resultDescription = executionPlan.resultDescription();
if (resultDescription.hasRemainingLimitOrOffset() && (resultDescription.limit() != limit || resultDescription.offset() != offset)) {
executionPlan = Merge.ensureOnHandler(executionPlan, plannerContext);
resultDescription = executionPlan.resultDescription();
}
if (ExecutionPhases.executesOnHandler(plannerContext.handlerNode(), resultDescription.nodeIds())) {
executionPlan.addProjection(new TopNProjection(limit, offset, sourceTypes), TopN.NO_LIMIT, 0, resultDescription.orderBy());
} else if (resultDescription.limit() != limit || resultDescription.offset() != 0) {
executionPlan.addProjection(new TopNProjection(limit + offset, 0, sourceTypes), limit, offset, resultDescription.orderBy());
}
return executionPlan;
}
use of io.crate.planner.ExecutionPlan in project crate by crate.
the class ExplainPlan method executeOrFail.
@Override
public void executeOrFail(DependencyCarrier dependencies, PlannerContext plannerContext, RowConsumer consumer, Row params, SubQueryResults subQueryResults) {
if (context != null) {
assert subPlan instanceof LogicalPlan : "subPlan must be a LogicalPlan";
LogicalPlan plan = (LogicalPlan) subPlan;
/**
* EXPLAIN ANALYZE does not support analyzing {@link io.crate.planner.MultiPhasePlan}s
*/
if (plan.dependencies().isEmpty()) {
UUID jobId = plannerContext.jobId();
BaseResultReceiver resultReceiver = new BaseResultReceiver();
RowConsumer noopRowConsumer = new RowConsumerToResultReceiver(resultReceiver, 0, t -> {
});
Timer timer = context.createTimer(Phase.Execute.name());
timer.start();
NodeOperationTree operationTree = LogicalPlanner.getNodeOperationTree(plan, dependencies, plannerContext, params, subQueryResults);
resultReceiver.completionFuture().whenComplete(createResultConsumer(dependencies, consumer, jobId, timer, operationTree));
LogicalPlanner.executeNodeOpTree(dependencies, plannerContext.transactionContext(), jobId, noopRowConsumer, true, operationTree);
} else {
consumer.accept(null, new UnsupportedOperationException("EXPLAIN ANALYZE does not support profiling multi-phase plans, " + "such as queries with scalar subselects."));
}
} else {
if (subPlan instanceof LogicalPlan) {
PrintContext printContext = new PrintContext();
((LogicalPlan) subPlan).print(printContext);
consumer.accept(InMemoryBatchIterator.of(new Row1(printContext.toString()), SENTINEL), null);
} else if (subPlan instanceof CopyFromPlan) {
ExecutionPlan executionPlan = CopyFromPlan.planCopyFromExecution(((CopyFromPlan) subPlan).copyFrom(), dependencies.clusterService().state().nodes(), plannerContext, params, subQueryResults);
String planAsJson = DataTypes.STRING.implicitCast(PlanPrinter.objectMap(executionPlan));
consumer.accept(InMemoryBatchIterator.of(new Row1(planAsJson), SENTINEL), null);
} else {
consumer.accept(InMemoryBatchIterator.of(new Row1("EXPLAIN not supported for " + subPlan.getClass().getSimpleName()), SENTINEL), null);
}
}
}
use of io.crate.planner.ExecutionPlan in project crate by crate.
the class Filter method build.
@Override
public ExecutionPlan build(PlannerContext plannerContext, Set<PlanHint> planHints, ProjectionBuilder projectionBuilder, int limit, int offset, @Nullable OrderBy order, @Nullable Integer pageSizeHint, Row params, SubQueryResults subQueryResults) {
ExecutionPlan executionPlan = source.build(plannerContext, planHints, projectionBuilder, limit, offset, order, pageSizeHint, params, subQueryResults);
Symbol boundQuery = SubQueryAndParamBinder.convert(query, params, subQueryResults);
FilterProjection filterProjection = ProjectionBuilder.filterProjection(source.outputs(), boundQuery);
if (executionPlan.resultDescription().executesOnShard()) {
filterProjection.requiredGranularity(RowGranularity.SHARD);
}
executionPlan.addProjection(filterProjection);
return executionPlan;
}
use of io.crate.planner.ExecutionPlan in project crate by crate.
the class Insert method build.
@Override
public ExecutionPlan build(PlannerContext plannerContext, Set<PlanHint> planHints, ProjectionBuilder projectionBuilder, int limit, int offset, @Nullable OrderBy order, @Nullable Integer pageSizeHint, Row params, SubQueryResults subQueryResults) {
ExecutionPlan sourcePlan = source.build(plannerContext, EnumSet.of(PlanHint.PREFER_SOURCE_LOOKUP), projectionBuilder, limit, offset, order, pageSizeHint, params, subQueryResults);
if (applyCasts != null) {
sourcePlan.addProjection(applyCasts);
}
var boundIndexWriterProjection = writeToTable.bind(x -> SubQueryAndParamBinder.convert(x, params, subQueryResults));
if (sourcePlan.resultDescription().hasRemainingLimitOrOffset()) {
ExecutionPlan localMerge = Merge.ensureOnHandler(sourcePlan, plannerContext);
localMerge.addProjection(boundIndexWriterProjection);
return localMerge;
} else {
sourcePlan.addProjection(boundIndexWriterProjection);
ExecutionPlan localMerge = Merge.ensureOnHandler(sourcePlan, plannerContext);
if (sourcePlan != localMerge) {
localMerge.addProjection(MergeCountProjection.INSTANCE);
}
return localMerge;
}
}
Aggregations