|
829 | 829 | import org.apache.doris.nereids.trees.plans.commands.use.UseCommand; |
830 | 830 | import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate; |
831 | 831 | import org.apache.doris.nereids.trees.plans.logical.LogicalCTE; |
| 832 | +import org.apache.doris.nereids.trees.plans.logical.LogicalCommonHint; |
832 | 833 | import org.apache.doris.nereids.trees.plans.logical.LogicalExcept; |
833 | 834 | import org.apache.doris.nereids.trees.plans.logical.LogicalFileSink; |
834 | 835 | import org.apache.doris.nereids.trees.plans.logical.LogicalFilter; |
@@ -2041,12 +2042,15 @@ public LogicalPlan visitRegularQuerySpecification(RegularQuerySpecificationConte |
2041 | 2042 | return selectPlan; |
2042 | 2043 | } |
2043 | 2044 | List<ParserRuleContext> selectHintContexts = Lists.newArrayList(); |
| 2045 | + List<ParserRuleContext> commonHintContexts = Lists.newArrayList(); |
2044 | 2046 | for (Integer key : selectHintMap.keySet()) { |
2045 | 2047 | if (key > selectCtx.getStart().getStopIndex() && key < selectCtx.getStop().getStartIndex()) { |
2046 | 2048 | selectHintContexts.add(selectHintMap.get(key)); |
| 2049 | + } else { |
| 2050 | + commonHintContexts.add(selectHintMap.get(key)); |
2047 | 2051 | } |
2048 | 2052 | } |
2049 | | - return withSelectHint(selectPlan, selectHintContexts); |
| 2053 | + return withHints(selectPlan, selectHintContexts, commonHintContexts); |
2050 | 2054 | }); |
2051 | 2055 | } |
2052 | 2056 |
|
@@ -3702,82 +3706,101 @@ private List<List<String>> getTableList(List<MultipartIdentifierContext> ctx) { |
3702 | 3706 | return tableList; |
3703 | 3707 | } |
3704 | 3708 |
|
3705 | | - private LogicalPlan withSelectHint(LogicalPlan logicalPlan, List<ParserRuleContext> hintContexts) { |
3706 | | - if (hintContexts.isEmpty()) { |
| 3709 | + private LogicalPlan withHints(LogicalPlan logicalPlan, List<ParserRuleContext> selectHintContexts, |
| 3710 | + List<ParserRuleContext> commonHintContexts) { |
| 3711 | + if (selectHintContexts.isEmpty() && commonHintContexts.isEmpty()) { |
3707 | 3712 | return logicalPlan; |
3708 | 3713 | } |
3709 | | - ImmutableList.Builder<SelectHint> hints = ImmutableList.builder(); |
3710 | | - for (ParserRuleContext hintContext : hintContexts) { |
3711 | | - SelectHintContext selectHintContext = (SelectHintContext) hintContext; |
3712 | | - for (HintStatementContext hintStatement : selectHintContext.hintStatements) { |
3713 | | - if (hintStatement.USE_MV() != null) { |
3714 | | - hints.add(new SelectHintUseMv("USE_MV", getTableList(hintStatement.tableList), true)); |
3715 | | - continue; |
3716 | | - } else if (hintStatement.NO_USE_MV() != null) { |
3717 | | - hints.add(new SelectHintUseMv("NO_USE_MV", getTableList(hintStatement.tableList), false)); |
3718 | | - continue; |
3719 | | - } |
3720 | | - String hintName = hintStatement.hintName.getText().toLowerCase(Locale.ROOT); |
3721 | | - switch (hintName) { |
3722 | | - case "set_var": |
3723 | | - Map<String, Optional<String>> parameters = Maps.newLinkedHashMap(); |
3724 | | - for (HintAssignmentContext kv : hintStatement.parameters) { |
3725 | | - if (kv.key != null) { |
3726 | | - String parameterName = visitIdentifierOrText(kv.key); |
3727 | | - Optional<String> value = Optional.empty(); |
3728 | | - if (kv.constantValue != null) { |
3729 | | - Literal literal = (Literal) visit(kv.constantValue); |
3730 | | - value = Optional.ofNullable(literal.toLegacyLiteral().getStringValue()); |
3731 | | - } else if (kv.identifierValue != null) { |
3732 | | - // maybe we should throw exception when the identifierValue is quoted identifier |
3733 | | - value = Optional.ofNullable(kv.identifierValue.getText()); |
| 3714 | + LogicalPlan newPlan = logicalPlan; |
| 3715 | + if (!selectHintContexts.isEmpty()) { |
| 3716 | + ImmutableList.Builder<SelectHint> hints = ImmutableList.builder(); |
| 3717 | + for (ParserRuleContext hintContext : selectHintContexts) { |
| 3718 | + SelectHintContext selectHintContext = (SelectHintContext) hintContext; |
| 3719 | + for (HintStatementContext hintStatement : selectHintContext.hintStatements) { |
| 3720 | + if (hintStatement.USE_MV() != null) { |
| 3721 | + hints.add(new SelectHintUseMv("USE_MV", getTableList(hintStatement.tableList), true)); |
| 3722 | + continue; |
| 3723 | + } else if (hintStatement.NO_USE_MV() != null) { |
| 3724 | + hints.add(new SelectHintUseMv("NO_USE_MV", getTableList(hintStatement.tableList), false)); |
| 3725 | + continue; |
| 3726 | + } |
| 3727 | + String hintName = hintStatement.hintName.getText().toLowerCase(Locale.ROOT); |
| 3728 | + switch (hintName) { |
| 3729 | + case "set_var": |
| 3730 | + Map<String, Optional<String>> parameters = Maps.newLinkedHashMap(); |
| 3731 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3732 | + if (kv.key != null) { |
| 3733 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3734 | + Optional<String> value = Optional.empty(); |
| 3735 | + if (kv.constantValue != null) { |
| 3736 | + Literal literal = (Literal) visit(kv.constantValue); |
| 3737 | + value = Optional.ofNullable(literal.toLegacyLiteral().getStringValue()); |
| 3738 | + } else if (kv.identifierValue != null) { |
| 3739 | + // maybe we should throw exception when the identifierValue is quoted identifier |
| 3740 | + value = Optional.ofNullable(kv.identifierValue.getText()); |
| 3741 | + } |
| 3742 | + parameters.put(parameterName, value); |
3734 | 3743 | } |
3735 | | - parameters.put(parameterName, value); |
3736 | 3744 | } |
3737 | | - } |
3738 | | - SelectHintSetVar setVar = new SelectHintSetVar(hintName, parameters); |
3739 | | - setVar.setVarOnceInSql(ConnectContext.get().getStatementContext()); |
3740 | | - hints.add(setVar); |
3741 | | - break; |
3742 | | - case "leading": |
3743 | | - List<String> leadingParameters = new ArrayList<>(); |
3744 | | - for (HintAssignmentContext kv : hintStatement.parameters) { |
3745 | | - if (kv.key != null) { |
3746 | | - String parameterName = visitIdentifierOrText(kv.key); |
3747 | | - leadingParameters.add(parameterName); |
| 3745 | + SelectHintSetVar setVar = new SelectHintSetVar(hintName, parameters); |
| 3746 | + setVar.setVarOnceInSql(ConnectContext.get().getStatementContext()); |
| 3747 | + hints.add(setVar); |
| 3748 | + break; |
| 3749 | + case "leading": |
| 3750 | + List<String> leadingParameters = new ArrayList<>(); |
| 3751 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3752 | + if (kv.key != null) { |
| 3753 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3754 | + leadingParameters.add(parameterName); |
| 3755 | + } |
3748 | 3756 | } |
3749 | | - } |
3750 | | - hints.add(new SelectHintLeading(hintName, leadingParameters)); |
3751 | | - break; |
3752 | | - case "ordered": |
3753 | | - hints.add(new SelectHintOrdered(hintName)); |
3754 | | - break; |
3755 | | - case "use_cbo_rule": |
3756 | | - List<String> useRuleParameters = new ArrayList<>(); |
3757 | | - for (HintAssignmentContext kv : hintStatement.parameters) { |
3758 | | - if (kv.key != null) { |
3759 | | - String parameterName = visitIdentifierOrText(kv.key); |
3760 | | - useRuleParameters.add(parameterName); |
| 3757 | + hints.add(new SelectHintLeading(hintName, leadingParameters)); |
| 3758 | + break; |
| 3759 | + case "ordered": |
| 3760 | + hints.add(new SelectHintOrdered(hintName)); |
| 3761 | + break; |
| 3762 | + case "use_cbo_rule": |
| 3763 | + List<String> useRuleParameters = new ArrayList<>(); |
| 3764 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3765 | + if (kv.key != null) { |
| 3766 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3767 | + useRuleParameters.add(parameterName); |
| 3768 | + } |
3761 | 3769 | } |
3762 | | - } |
3763 | | - hints.add(new SelectHintUseCboRule(hintName, useRuleParameters, false)); |
3764 | | - break; |
3765 | | - case "no_use_cbo_rule": |
3766 | | - List<String> noUseRuleParameters = new ArrayList<>(); |
3767 | | - for (HintAssignmentContext kv : hintStatement.parameters) { |
3768 | | - String parameterName = visitIdentifierOrText(kv.key); |
3769 | | - if (kv.key != null) { |
3770 | | - noUseRuleParameters.add(parameterName); |
| 3770 | + hints.add(new SelectHintUseCboRule(hintName, useRuleParameters, false)); |
| 3771 | + break; |
| 3772 | + case "no_use_cbo_rule": |
| 3773 | + List<String> noUseRuleParameters = new ArrayList<>(); |
| 3774 | + for (HintAssignmentContext kv : hintStatement.parameters) { |
| 3775 | + String parameterName = visitIdentifierOrText(kv.key); |
| 3776 | + if (kv.key != null) { |
| 3777 | + noUseRuleParameters.add(parameterName); |
| 3778 | + } |
3771 | 3779 | } |
| 3780 | + hints.add(new SelectHintUseCboRule(hintName, noUseRuleParameters, true)); |
| 3781 | + break; |
| 3782 | + default: |
| 3783 | + break; |
| 3784 | + } |
| 3785 | + } |
| 3786 | + } |
| 3787 | + newPlan = new LogicalSelectHint<>(hints.build(), newPlan); |
| 3788 | + } |
| 3789 | + if (!commonHintContexts.isEmpty()) { |
| 3790 | + for (ParserRuleContext hintContext : commonHintContexts) { |
| 3791 | + if (hintContext instanceof SelectHintContext) { |
| 3792 | + SelectHintContext commonHintContext = (SelectHintContext) hintContext; |
| 3793 | + if (commonHintContext.hintStatement != null && commonHintContext.hintStatement.hintName != null) { |
| 3794 | + String text = commonHintContext.hintStatement.hintName.getText(); |
| 3795 | + if (text.equalsIgnoreCase("PREAGGOPEN")) { |
| 3796 | + newPlan = new LogicalCommonHint<>(newPlan); |
| 3797 | + break; |
3772 | 3798 | } |
3773 | | - hints.add(new SelectHintUseCboRule(hintName, noUseRuleParameters, true)); |
3774 | | - break; |
3775 | | - default: |
3776 | | - break; |
| 3799 | + } |
3777 | 3800 | } |
3778 | 3801 | } |
3779 | 3802 | } |
3780 | | - return new LogicalSelectHint<>(hints.build(), logicalPlan); |
| 3803 | + return newPlan; |
3781 | 3804 | } |
3782 | 3805 |
|
3783 | 3806 | @Override |
|
0 commit comments