|
459 | 459 | import org.apache.doris.nereids.trees.plans.logical.LogicalJoin; |
460 | 460 | import org.apache.doris.nereids.trees.plans.logical.LogicalLimit; |
461 | 461 | import org.apache.doris.nereids.trees.plans.logical.LogicalPlan; |
| 462 | +import org.apache.doris.nereids.trees.plans.logical.LogicalPreAggOnHint; |
462 | 463 | import org.apache.doris.nereids.trees.plans.logical.LogicalProject; |
463 | 464 | import org.apache.doris.nereids.trees.plans.logical.LogicalRepeat; |
464 | 465 | import org.apache.doris.nereids.trees.plans.logical.LogicalSelectHint; |
@@ -1460,12 +1461,15 @@ public LogicalPlan visitRegularQuerySpecification(RegularQuerySpecificationConte |
1460 | 1461 | return selectPlan; |
1461 | 1462 | } |
1462 | 1463 | List<ParserRuleContext> selectHintContexts = Lists.newArrayList(); |
| 1464 | + List<ParserRuleContext> preAggOnHintContexts = Lists.newArrayList(); |
1463 | 1465 | for (Integer key : selectHintMap.keySet()) { |
1464 | 1466 | if (key > selectCtx.getStart().getStopIndex() && key < selectCtx.getStop().getStartIndex()) { |
1465 | 1467 | selectHintContexts.add(selectHintMap.get(key)); |
| 1468 | + } else { |
| 1469 | + preAggOnHintContexts.add(selectHintMap.get(key)); |
1466 | 1470 | } |
1467 | 1471 | } |
1468 | | - return withSelectHint(selectPlan, selectHintContexts); |
| 1472 | + return withHints(selectPlan, selectHintContexts, preAggOnHintContexts); |
1469 | 1473 | }); |
1470 | 1474 | } |
1471 | 1475 |
|
@@ -3274,73 +3278,93 @@ private LogicalPlan withJoinRelations(LogicalPlan input, RelationContext ctx) { |
3274 | 3278 | return last; |
3275 | 3279 | } |
3276 | 3280 |
|
3277 | | - private LogicalPlan withSelectHint(LogicalPlan logicalPlan, List<ParserRuleContext> hintContexts) { |
3278 | | - if (hintContexts.isEmpty()) { |
| 3281 | + private LogicalPlan withHints(LogicalPlan logicalPlan, List<ParserRuleContext> selectHintContexts, |
| 3282 | + List<ParserRuleContext> preAggOnHintContexts) { |
| 3283 | + if (selectHintContexts.isEmpty() && preAggOnHintContexts.isEmpty()) { |
3279 | 3284 | return logicalPlan; |
3280 | 3285 | } |
3281 | | - Map<String, SelectHint> hints = Maps.newLinkedHashMap(); |
3282 | | - for (ParserRuleContext hintContext : hintContexts) { |
3283 | | - SelectHintContext selectHintContext = (SelectHintContext) hintContext; |
3284 | | - for (HintStatementContext hintStatement : selectHintContext.hintStatements) { |
3285 | | - String hintName = hintStatement.hintName.getText().toLowerCase(Locale.ROOT); |
3286 | | - switch (hintName) { |
3287 | | - case "set_var": |
3288 | | - Map<String, Optional<String>> parameters = Maps.newLinkedHashMap(); |
3289 | | - for (HintAssignmentContext kv : hintStatement.parameters) { |
3290 | | - if (kv.key != null) { |
3291 | | - String parameterName = visitIdentifierOrText(kv.key); |
3292 | | - Optional<String> value = Optional.empty(); |
3293 | | - if (kv.constantValue != null) { |
3294 | | - Literal literal = (Literal) visit(kv.constantValue); |
3295 | | - value = Optional.ofNullable(literal.toLegacyLiteral().getStringValue()); |
3296 | | - } else if (kv.identifierValue != null) { |
3297 | | - // maybe we should throw exception when the identifierValue is quoted identifier |
3298 | | - value = Optional.ofNullable(kv.identifierValue.getText()); |
| 3286 | + LogicalPlan newPlan = logicalPlan; |
| 3287 | + if (!selectHintContexts.isEmpty()) { |
| 3288 | + Map<String, SelectHint> hints = Maps.newLinkedHashMap(); |
| 3289 | + for (ParserRuleContext hintContext : selectHintContexts) { |
| 3290 | + SelectHintContext selectHintContext = (SelectHintContext) hintContext; |
| 3291 | + for (HintStatementContext hintStatement : selectHintContext.hintStatements) { |
| 3292 | + String hintName = hintStatement.hintName.getText().toLowerCase(Locale.ROOT); |
| 3293 | + switch (hintName) { |
| 3294 | + case "set_var": |
| 3295 | + Map<String, Optional<String>> parameters = Maps.newLinkedHashMap(); |
| 3296 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3297 | + if (kv.key != null) { |
| 3298 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3299 | + Optional<String> value = Optional.empty(); |
| 3300 | + if (kv.constantValue != null) { |
| 3301 | + Literal literal = (Literal) visit(kv.constantValue); |
| 3302 | + value = Optional.ofNullable(literal.toLegacyLiteral().getStringValue()); |
| 3303 | + } else if (kv.identifierValue != null) { |
| 3304 | + // maybe we should throw exception when the identifierValue is quoted identifier |
| 3305 | + value = Optional.ofNullable(kv.identifierValue.getText()); |
| 3306 | + } |
| 3307 | + parameters.put(parameterName, value); |
3299 | 3308 | } |
3300 | | - parameters.put(parameterName, value); |
3301 | 3309 | } |
3302 | | - } |
3303 | | - hints.put(hintName, new SelectHintSetVar(hintName, parameters)); |
3304 | | - break; |
3305 | | - case "leading": |
3306 | | - List<String> leadingParameters = new ArrayList<>(); |
3307 | | - for (HintAssignmentContext kv : hintStatement.parameters) { |
3308 | | - if (kv.key != null) { |
3309 | | - String parameterName = visitIdentifierOrText(kv.key); |
3310 | | - leadingParameters.add(parameterName); |
| 3310 | + hints.put(hintName, new SelectHintSetVar(hintName, parameters)); |
| 3311 | + break; |
| 3312 | + case "leading": |
| 3313 | + List<String> leadingParameters = new ArrayList<>(); |
| 3314 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3315 | + if (kv.key != null) { |
| 3316 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3317 | + leadingParameters.add(parameterName); |
| 3318 | + } |
3311 | 3319 | } |
3312 | | - } |
3313 | | - hints.put(hintName, new SelectHintLeading(hintName, leadingParameters)); |
3314 | | - break; |
3315 | | - case "ordered": |
3316 | | - hints.put(hintName, new SelectHintOrdered(hintName)); |
3317 | | - break; |
3318 | | - case "use_cbo_rule": |
3319 | | - List<String> useRuleParameters = new ArrayList<>(); |
3320 | | - for (HintAssignmentContext kv : hintStatement.parameters) { |
3321 | | - if (kv.key != null) { |
3322 | | - String parameterName = visitIdentifierOrText(kv.key); |
3323 | | - useRuleParameters.add(parameterName); |
| 3320 | + hints.put(hintName, new SelectHintLeading(hintName, leadingParameters)); |
| 3321 | + break; |
| 3322 | + case "ordered": |
| 3323 | + hints.put(hintName, new SelectHintOrdered(hintName)); |
| 3324 | + break; |
| 3325 | + case "use_cbo_rule": |
| 3326 | + List<String> useRuleParameters = new ArrayList<>(); |
| 3327 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3328 | + if (kv.key != null) { |
| 3329 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3330 | + useRuleParameters.add(parameterName); |
| 3331 | + } |
3324 | 3332 | } |
3325 | | - } |
3326 | | - hints.put(hintName, new SelectHintUseCboRule(hintName, useRuleParameters, false)); |
3327 | | - break; |
3328 | | - case "no_use_cbo_rule": |
3329 | | - List<String> noUseRuleParameters = new ArrayList<>(); |
3330 | | - for (HintAssignmentContext kv : hintStatement.parameters) { |
3331 | | - String parameterName = visitIdentifierOrText(kv.key); |
3332 | | - if (kv.key != null) { |
3333 | | - noUseRuleParameters.add(parameterName); |
| 3333 | + hints.put(hintName, new SelectHintUseCboRule(hintName, useRuleParameters, false)); |
| 3334 | + break; |
| 3335 | + case "no_use_cbo_rule": |
| 3336 | + List<String> noUseRuleParameters = new ArrayList<>(); |
| 3337 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3338 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3339 | + if (kv.key != null) { |
| 3340 | + noUseRuleParameters.add(parameterName); |
| 3341 | + } |
3334 | 3342 | } |
| 3343 | + hints.put(hintName, new SelectHintUseCboRule(hintName, noUseRuleParameters, true)); |
| 3344 | + break; |
| 3345 | + default: |
| 3346 | + break; |
| 3347 | + } |
| 3348 | + } |
| 3349 | + } |
| 3350 | + newPlan = new LogicalSelectHint<>(hints, newPlan); |
| 3351 | + } |
| 3352 | + if (!preAggOnHintContexts.isEmpty()) { |
| 3353 | + for (ParserRuleContext hintContext : preAggOnHintContexts) { |
| 3354 | + if (hintContext instanceof SelectHintContext) { |
| 3355 | + SelectHintContext preAggOnHintContext = (SelectHintContext) hintContext; |
| 3356 | + if (preAggOnHintContext.hintStatement != null |
| 3357 | + && preAggOnHintContext.hintStatement.hintName != null) { |
| 3358 | + String text = preAggOnHintContext.hintStatement.hintName.getText(); |
| 3359 | + if (text.equalsIgnoreCase("PREAGGOPEN")) { |
| 3360 | + newPlan = new LogicalPreAggOnHint<>(newPlan); |
| 3361 | + break; |
3335 | 3362 | } |
3336 | | - hints.put(hintName, new SelectHintUseCboRule(hintName, noUseRuleParameters, true)); |
3337 | | - break; |
3338 | | - default: |
3339 | | - break; |
| 3363 | + } |
3340 | 3364 | } |
3341 | 3365 | } |
3342 | 3366 | } |
3343 | | - return new LogicalSelectHint<>(hints, logicalPlan); |
| 3367 | + return newPlan; |
3344 | 3368 | } |
3345 | 3369 |
|
3346 | 3370 | @Override |
|
0 commit comments