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 i
(ExecutionPlan subExecutionPlan, PlannerContext plannerContext, List<Projection> projections)
| 63 | * add a {@link LimitAndOffset} AFTER the projections. |
| 64 | */ |
| 65 | public static ExecutionPlan ensureOnHandler(ExecutionPlan subExecutionPlan, PlannerContext plannerContext, List<Projection> projections) { |
| 66 | ResultDescription resultDescription = subExecutionPlan.resultDescription(); |
| 67 | assert resultDescription != null : "all plans must have a result description. Plan without: " + |
| 68 | subExecutionPlan; |
| 69 | |
| 70 | // If a sub-Plan applies a limit it is usually limit+offset |
| 71 | // 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 |
| 72 | Projection limitAndOffset = ProjectionBuilder.limitAndOffsetOrEvalIfNeeded( |
| 73 | resultDescription.limit(), |
| 74 | resultDescription.offset(), |
| 75 | resultDescription.numOutputs(), |
| 76 | resultDescription.streamOutputs()); |
| 77 | if (ExecutionPhases.executesOnHandler(plannerContext.handlerNode(), resultDescription.nodeIds())) { |
| 78 | return addProjections(subExecutionPlan, projections, resultDescription, limitAndOffset); |
| 79 | } |
| 80 | maybeUpdatePageSizeHint(subExecutionPlan, resultDescription.maxRowsPerNode()); |
| 81 | Collection<String> handlerNodeIds = Collections.singletonList(plannerContext.handlerNode()); |
| 82 | |
| 83 | MergePhase mergePhase = new MergePhase( |
| 84 | plannerContext.jobId(), |
| 85 | plannerContext.nextExecutionPhaseId(), |
| 86 | "mergeOnHandler", |
| 87 | resultDescription.nodeIds().size(), |
| 88 | 1, |
| 89 | handlerNodeIds, |
| 90 | resultDescription.streamOutputs(), |
| 91 | addProjection(projections, limitAndOffset), |
| 92 | resultDescription.nodeIds(), |
| 93 | DistributionInfo.DEFAULT_BROADCAST, |
| 94 | resultDescription.orderBy() |
| 95 | ); |
| 96 | return new Merge( |
| 97 | subExecutionPlan, |
| 98 | mergePhase, |
| 99 | LimitAndOffset.NO_LIMIT, |
| 100 | 0, |
| 101 | resultDescription.numOutputs(), |
| 102 | resultDescription.limit(), |
| 103 | resultDescription.orderBy() |
| 104 | ); |
| 105 | } |
| 106 | |
| 107 | private static void maybeUpdatePageSizeHint(ExecutionPlan subExecutionPlan, int maxRowsPerNode) { |
| 108 | if (Paging.shouldPage(maxRowsPerNode)) { |
no test coverage detected