use of io.crate.execution.dsl.projection.TopNProjection in project crate by crate.
the class TopNDistinct 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) {
var executionPlan = source.build(plannerContext, planHints, projectionBuilder, TopN.NO_LIMIT, TopN.NO_OFFSET, null, null, params, subQueryResults);
if (executionPlan.resultDescription().hasRemainingLimitOrOffset()) {
executionPlan = Merge.ensureOnHandler(executionPlan, plannerContext);
}
if (!source.outputs().equals(outputs)) {
EvalProjection evalProjection = new EvalProjection(InputColumns.create(outputs, new InputColumns.SourceSymbols(source.outputs())));
executionPlan.addProjection(evalProjection);
}
int limit = DataTypes.INTEGER.sanitizeValue(evaluate(plannerContext.transactionContext(), plannerContext.nodeContext(), this.limit, params, subQueryResults));
int offset = DataTypes.INTEGER.sanitizeValue(evaluate(plannerContext.transactionContext(), plannerContext.nodeContext(), this.offset, params, subQueryResults));
var inputColOutputs = InputColumn.mapToInputColumns(outputs);
executionPlan.addProjection(new TopNDistinctProjection(limit + offset, inputColOutputs, source.preferShardProjections() ? RowGranularity.SHARD : RowGranularity.CLUSTER));
boolean onHandler = ExecutionPhases.executesOnHandler(plannerContext.handlerNode(), executionPlan.resultDescription().nodeIds());
if (!onHandler || source.preferShardProjections()) {
if (!onHandler) {
executionPlan = Merge.ensureOnHandler(executionPlan, plannerContext);
}
TopNDistinctProjection topNDistinct = new TopNDistinctProjection(limit + offset, inputColOutputs, RowGranularity.CLUSTER);
executionPlan.addProjection(topNDistinct);
}
if (offset > 0) {
// TopNDistinctProjection outputs a distinct result-set,
// That allows us to use the TopNProjection to apply the offset
executionPlan.addProjection(new TopNProjection(limit, offset, Symbols.typeView(inputColOutputs)));
}
return executionPlan;
}
use of io.crate.execution.dsl.projection.TopNProjection in project crate by crate.
the class GroupByPlannerTest method testGroupByHavingAndNoSelectListReOrderingWithLimit.
@Test
public void testGroupByHavingAndNoSelectListReOrderingWithLimit() throws Exception {
var e = SQLExecutor.builder(clusterService, 2, RandomizedTest.getRandom(), List.of()).addTable(TableDefinitions.USER_TABLE_DEFINITION).build();
Merge planNode = e.plan("select name, count(*) from users group by name having count(*) > 1 limit 100");
Merge reducerMerge = (Merge) planNode.subPlan();
MergePhase reducePhase = reducerMerge.mergePhase();
// group projection
// outputs: name, count(*)
// filter projection
// outputs: name, count(*)
// topN projection
// outputs: name, count(*)
Projection projection = reducePhase.projections().get(1);
assertThat(projection, instanceOf(FilterProjection.class));
FilterProjection filterProjection = (FilterProjection) projection;
Symbol countArgument = ((Function) filterProjection.query()).arguments().get(0);
assertThat(countArgument, instanceOf(InputColumn.class));
// pointing to second output from group projection
assertThat(((InputColumn) countArgument).index(), is(1));
// outputs: name, count(*)
assertThat(((InputColumn) filterProjection.outputs().get(0)).index(), is(0));
assertThat(((InputColumn) filterProjection.outputs().get(1)).index(), is(1));
// outputs: name, count(*)
TopNProjection topN = (TopNProjection) reducePhase.projections().get(2);
assertThat(((InputColumn) topN.outputs().get(0)).index(), is(0));
assertThat(((InputColumn) topN.outputs().get(1)).index(), is(1));
MergePhase localMerge = planNode.mergePhase();
// topN projection
// outputs: name, count(*)
topN = (TopNProjection) localMerge.projections().get(0);
assertThat(((InputColumn) topN.outputs().get(0)).index(), is(0));
assertThat(((InputColumn) topN.outputs().get(1)).index(), is(1));
}
use of io.crate.execution.dsl.projection.TopNProjection 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.execution.dsl.projection.TopNProjection in project crate by crate.
the class JoinPhaseTest method setup.
@Before
public void setup() {
topNProjection = new TopNProjection(10, 0, Collections.emptyList());
jobId = UUID.randomUUID();
mp1 = new MergePhase(jobId, 2, "merge", 1, 1, Collections.emptyList(), List.of(DataTypes.STRING), List.of(), DistributionInfo.DEFAULT_BROADCAST, null);
mp2 = new MergePhase(jobId, 3, "merge", 1, 1, Collections.emptyList(), List.of(DataTypes.STRING), List.of(), DistributionInfo.DEFAULT_BROADCAST, null);
joinCondition = new Function(EqOperator.SIGNATURE, List.of(new InputColumn(0, DataTypes.STRING), new InputColumn(1, DataTypes.STRING)), EqOperator.RETURN_TYPE);
}
use of io.crate.execution.dsl.projection.TopNProjection in project crate by crate.
the class GroupByPlannerTest method testGroupByWithHavingAndLimit.
@Test
public void testGroupByWithHavingAndLimit() throws Exception {
var e = SQLExecutor.builder(clusterService, 2, RandomizedTest.getRandom(), List.of()).addTable(TableDefinitions.USER_TABLE_DEFINITION).build();
Merge planNode = e.plan("select count(*), name from users group by name having count(*) > 1 limit 100");
Merge reducerMerge = (Merge) planNode.subPlan();
// reducer
MergePhase mergePhase = reducerMerge.mergePhase();
Projection projection = mergePhase.projections().get(1);
assertThat(projection, instanceOf(FilterProjection.class));
FilterProjection filterProjection = (FilterProjection) projection;
Symbol countArgument = ((Function) filterProjection.query()).arguments().get(0);
assertThat(countArgument, instanceOf(InputColumn.class));
// pointing to second output from group projection
assertThat(((InputColumn) countArgument).index(), is(1));
// outputs: name, count(*)
TopNProjection topN = (TopNProjection) mergePhase.projections().get(2);
assertThat(topN.outputs().get(0).valueType(), Is.is(DataTypes.STRING));
assertThat(topN.outputs().get(1).valueType(), Is.<DataType>is(DataTypes.LONG));
MergePhase localMerge = planNode.mergePhase();
// topN projection
// outputs: count(*), name
topN = (TopNProjection) localMerge.projections().get(0);
assertThat(topN.outputs().get(0).valueType(), Is.<DataType>is(DataTypes.LONG));
assertThat(topN.outputs().get(1).valueType(), Is.<DataType>is(DataTypes.STRING));
}
Aggregations