|
445 | 445 | import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
|
446 | 446 | import org.apache.doris.nereids.trees.plans.logical.LogicalLimit;
|
447 | 447 | import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
|
| 448 | +import org.apache.doris.nereids.trees.plans.logical.LogicalPreAggOnHint; |
448 | 449 | import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
|
449 | 450 | import org.apache.doris.nereids.trees.plans.logical.LogicalRepeat;
|
450 | 451 | import org.apache.doris.nereids.trees.plans.logical.LogicalSelectHint;
|
@@ -1412,12 +1413,15 @@ public LogicalPlan visitRegularQuerySpecification(RegularQuerySpecificationConte
|
1412 | 1413 | return selectPlan;
|
1413 | 1414 | }
|
1414 | 1415 | List<ParserRuleContext> selectHintContexts = Lists.newArrayList();
|
| 1416 | + List<ParserRuleContext> preAggOnHintContexts = Lists.newArrayList(); |
1415 | 1417 | for (Integer key : selectHintMap.keySet()) {
|
1416 | 1418 | if (key > selectCtx.getStart().getStopIndex() && key < selectCtx.getStop().getStartIndex()) {
|
1417 | 1419 | selectHintContexts.add(selectHintMap.get(key));
|
| 1420 | + } else { |
| 1421 | + preAggOnHintContexts.add(selectHintMap.get(key)); |
1418 | 1422 | }
|
1419 | 1423 | }
|
1420 |
| - return withSelectHint(selectPlan, selectHintContexts); |
| 1424 | + return withHints(selectPlan, selectHintContexts, preAggOnHintContexts); |
1421 | 1425 | });
|
1422 | 1426 | }
|
1423 | 1427 |
|
@@ -3195,91 +3199,111 @@ private LogicalPlan withJoinRelations(LogicalPlan input, RelationContext ctx) {
|
3195 | 3199 | return last;
|
3196 | 3200 | }
|
3197 | 3201 |
|
3198 |
| - private LogicalPlan withSelectHint(LogicalPlan logicalPlan, List<ParserRuleContext> hintContexts) { |
3199 |
| - if (hintContexts.isEmpty()) { |
| 3202 | + private LogicalPlan withHints(LogicalPlan logicalPlan, List<ParserRuleContext> selectHintContexts, |
| 3203 | + List<ParserRuleContext> preAggOnHintContexts) { |
| 3204 | + if (selectHintContexts.isEmpty() && preAggOnHintContexts.isEmpty()) { |
3200 | 3205 | return logicalPlan;
|
3201 | 3206 | }
|
3202 |
| - ImmutableList.Builder<SelectHint> hints = ImmutableList.builder(); |
3203 |
| - for (ParserRuleContext hintContext : hintContexts) { |
3204 |
| - SelectHintContext selectHintContext = (SelectHintContext) hintContext; |
3205 |
| - for (HintStatementContext hintStatement : selectHintContext.hintStatements) { |
3206 |
| - String hintName = hintStatement.hintName.getText().toLowerCase(Locale.ROOT); |
3207 |
| - switch (hintName) { |
3208 |
| - case "set_var": |
3209 |
| - Map<String, Optional<String>> parameters = Maps.newLinkedHashMap(); |
3210 |
| - for (HintAssignmentContext kv : hintStatement.parameters) { |
3211 |
| - if (kv.key != null) { |
3212 |
| - String parameterName = visitIdentifierOrText(kv.key); |
3213 |
| - Optional<String> value = Optional.empty(); |
3214 |
| - if (kv.constantValue != null) { |
3215 |
| - Literal literal = (Literal) visit(kv.constantValue); |
3216 |
| - value = Optional.ofNullable(literal.toLegacyLiteral().getStringValue()); |
3217 |
| - } else if (kv.identifierValue != null) { |
3218 |
| - // maybe we should throw exception when the identifierValue is quoted identifier |
3219 |
| - value = Optional.ofNullable(kv.identifierValue.getText()); |
| 3207 | + LogicalPlan newPlan = logicalPlan; |
| 3208 | + if (!selectHintContexts.isEmpty()) { |
| 3209 | + ImmutableList.Builder<SelectHint> hints = ImmutableList.builder(); |
| 3210 | + for (ParserRuleContext hintContext : selectHintContexts) { |
| 3211 | + SelectHintContext selectHintContext = (SelectHintContext) hintContext; |
| 3212 | + for (HintStatementContext hintStatement : selectHintContext.hintStatements) { |
| 3213 | + String hintName = hintStatement.hintName.getText().toLowerCase(Locale.ROOT); |
| 3214 | + switch (hintName) { |
| 3215 | + case "set_var": |
| 3216 | + Map<String, Optional<String>> parameters = Maps.newLinkedHashMap(); |
| 3217 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3218 | + if (kv.key != null) { |
| 3219 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3220 | + Optional<String> value = Optional.empty(); |
| 3221 | + if (kv.constantValue != null) { |
| 3222 | + Literal literal = (Literal) visit(kv.constantValue); |
| 3223 | + value = Optional.ofNullable(literal.toLegacyLiteral().getStringValue()); |
| 3224 | + } else if (kv.identifierValue != null) { |
| 3225 | + // maybe we should throw exception when the identifierValue is quoted identifier |
| 3226 | + value = Optional.ofNullable(kv.identifierValue.getText()); |
| 3227 | + } |
| 3228 | + parameters.put(parameterName, value); |
3220 | 3229 | }
|
3221 |
| - parameters.put(parameterName, value); |
3222 | 3230 | }
|
3223 |
| - } |
3224 |
| - SelectHintSetVar setVar = new SelectHintSetVar(hintName, parameters); |
3225 |
| - setVar.setVarOnceInSql(ConnectContext.get().getStatementContext()); |
3226 |
| - hints.add(setVar); |
3227 |
| - break; |
3228 |
| - case "leading": |
3229 |
| - List<String> leadingParameters = new ArrayList<String>(); |
3230 |
| - for (HintAssignmentContext kv : hintStatement.parameters) { |
3231 |
| - if (kv.key != null) { |
| 3231 | + SelectHintSetVar setVar = new SelectHintSetVar(hintName, parameters); |
| 3232 | + setVar.setVarOnceInSql(ConnectContext.get().getStatementContext()); |
| 3233 | + hints.add(setVar); |
| 3234 | + break; |
| 3235 | + case "leading": |
| 3236 | + List<String> leadingParameters = new ArrayList<String>(); |
| 3237 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3238 | + if (kv.key != null) { |
| 3239 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3240 | + leadingParameters.add(parameterName); |
| 3241 | + } |
| 3242 | + } |
| 3243 | + hints.add(new SelectHintLeading(hintName, leadingParameters)); |
| 3244 | + break; |
| 3245 | + case "ordered": |
| 3246 | + hints.add(new SelectHintOrdered(hintName)); |
| 3247 | + break; |
| 3248 | + case "use_cbo_rule": |
| 3249 | + List<String> useRuleParameters = new ArrayList<String>(); |
| 3250 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
3232 | 3251 | String parameterName = visitIdentifierOrText(kv.key);
|
3233 |
| - leadingParameters.add(parameterName); |
| 3252 | + useRuleParameters.add(parameterName); |
3234 | 3253 | }
|
3235 |
| - } |
3236 |
| - hints.add(new SelectHintLeading(hintName, leadingParameters)); |
3237 |
| - break; |
3238 |
| - case "ordered": |
3239 |
| - hints.add(new SelectHintOrdered(hintName)); |
3240 |
| - break; |
3241 |
| - case "use_cbo_rule": |
3242 |
| - List<String> useRuleParameters = new ArrayList<String>(); |
3243 |
| - for (HintAssignmentContext kv : hintStatement.parameters) { |
3244 |
| - String parameterName = visitIdentifierOrText(kv.key); |
3245 |
| - useRuleParameters.add(parameterName); |
3246 |
| - } |
3247 |
| - hints.add(new SelectHintUseCboRule(hintName, useRuleParameters, false)); |
3248 |
| - break; |
3249 |
| - case "no_use_cbo_rule": |
3250 |
| - List<String> noUseRuleParameters = new ArrayList<String>(); |
3251 |
| - for (HintAssignmentContext kv : hintStatement.parameters) { |
3252 |
| - String parameterName = visitIdentifierOrText(kv.key); |
3253 |
| - noUseRuleParameters.add(parameterName); |
3254 |
| - } |
3255 |
| - hints.add(new SelectHintUseCboRule(hintName, noUseRuleParameters, true)); |
3256 |
| - break; |
3257 |
| - case "use_mv": |
3258 |
| - List<String> useIndexParameters = new ArrayList<String>(); |
3259 |
| - for (HintAssignmentContext kv : hintStatement.parameters) { |
3260 |
| - String parameterName = visitIdentifierOrText(kv.key); |
3261 |
| - if (kv.key != null) { |
3262 |
| - useIndexParameters.add(parameterName); |
| 3254 | + hints.add(new SelectHintUseCboRule(hintName, useRuleParameters, false)); |
| 3255 | + break; |
| 3256 | + case "no_use_cbo_rule": |
| 3257 | + List<String> noUseRuleParameters = new ArrayList<String>(); |
| 3258 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3259 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3260 | + noUseRuleParameters.add(parameterName); |
3263 | 3261 | }
|
3264 |
| - } |
3265 |
| - hints.add(new SelectHintUseMv(hintName, useIndexParameters, true)); |
3266 |
| - break; |
3267 |
| - case "no_use_mv": |
3268 |
| - List<String> noUseIndexParameters = new ArrayList<String>(); |
3269 |
| - for (HintAssignmentContext kv : hintStatement.parameters) { |
3270 |
| - String parameterName = visitIdentifierOrText(kv.key); |
3271 |
| - if (kv.key != null) { |
3272 |
| - noUseIndexParameters.add(parameterName); |
| 3262 | + hints.add(new SelectHintUseCboRule(hintName, noUseRuleParameters, true)); |
| 3263 | + break; |
| 3264 | + case "use_mv": |
| 3265 | + List<String> useIndexParameters = new ArrayList<String>(); |
| 3266 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3267 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3268 | + if (kv.key != null) { |
| 3269 | + useIndexParameters.add(parameterName); |
| 3270 | + } |
| 3271 | + } |
| 3272 | + hints.add(new SelectHintUseMv(hintName, useIndexParameters, true)); |
| 3273 | + break; |
| 3274 | + case "no_use_mv": |
| 3275 | + List<String> noUseIndexParameters = new ArrayList<String>(); |
| 3276 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3277 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3278 | + if (kv.key != null) { |
| 3279 | + noUseIndexParameters.add(parameterName); |
| 3280 | + } |
3273 | 3281 | }
|
| 3282 | + hints.add(new SelectHintUseMv(hintName, noUseIndexParameters, false)); |
| 3283 | + break; |
| 3284 | + default: |
| 3285 | + break; |
| 3286 | + } |
| 3287 | + } |
| 3288 | + } |
| 3289 | + newPlan = new LogicalSelectHint<>(hints.build(), newPlan); |
| 3290 | + } |
| 3291 | + if (!preAggOnHintContexts.isEmpty()) { |
| 3292 | + for (ParserRuleContext hintContext : preAggOnHintContexts) { |
| 3293 | + if (hintContext instanceof SelectHintContext) { |
| 3294 | + SelectHintContext preAggOnHintContext = (SelectHintContext) hintContext; |
| 3295 | + if (preAggOnHintContext.hintStatement != null |
| 3296 | + && preAggOnHintContext.hintStatement.hintName != null) { |
| 3297 | + String text = preAggOnHintContext.hintStatement.hintName.getText(); |
| 3298 | + if (text.equalsIgnoreCase("PREAGGOPEN")) { |
| 3299 | + newPlan = new LogicalPreAggOnHint<>(newPlan); |
| 3300 | + break; |
3274 | 3301 | }
|
3275 |
| - hints.add(new SelectHintUseMv(hintName, noUseIndexParameters, false)); |
3276 |
| - break; |
3277 |
| - default: |
3278 |
| - break; |
| 3302 | + } |
3279 | 3303 | }
|
3280 | 3304 | }
|
3281 | 3305 | }
|
3282 |
| - return new LogicalSelectHint<>(hints.build(), logicalPlan); |
| 3306 | + return newPlan; |
3283 | 3307 | }
|
3284 | 3308 |
|
3285 | 3309 | @Override
|
|
0 commit comments