|
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