Skip to content

Commit c8b1f75

Browse files
authored
[feat](Nereids) support set var in hint when parse sql (#41331) (#42335)
pick: #41331 set var hint need to be enable to use before analyze, so it need to be set when parsing sql now it would set twice when parse and begin of analyze ## Proposed changes Issue Number: close #xxx <!--Describe your changes.-->
1 parent be56e40 commit c8b1f75

File tree

5 files changed

+56
-38
lines changed

5 files changed

+56
-38
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1834,7 +1834,9 @@ private LogicalPlan withSelectHint(LogicalPlan logicalPlan, List<ParserRuleConte
18341834
parameters.put(parameterName, value);
18351835
}
18361836
}
1837-
hints.put(hintName, new SelectHintSetVar(hintName, parameters));
1837+
SelectHintSetVar setVar = new SelectHintSetVar(hintName, parameters);
1838+
setVar.setVarOnceInSql(ConnectContext.get().getStatementContext());
1839+
hints.put(hintName, setVar);
18381840
break;
18391841
case "leading":
18401842
List<String> leadingParameters = new ArrayList<String>();

fe/fe-core/src/main/java/org/apache/doris/nereids/properties/SelectHintSetVar.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717

1818
package org.apache.doris.nereids.properties;
1919

20+
import org.apache.doris.analysis.SetVar;
21+
import org.apache.doris.analysis.StringLiteral;
22+
import org.apache.doris.nereids.StatementContext;
23+
import org.apache.doris.nereids.exceptions.AnalysisException;
24+
import org.apache.doris.qe.SessionVariable;
25+
import org.apache.doris.qe.VariableMgr;
26+
2027
import java.util.Map;
2128
import java.util.Optional;
2229
import java.util.stream.Collectors;
@@ -38,6 +45,42 @@ public Map<String, Optional<String>> getParameters() {
3845
return parameters;
3946
}
4047

48+
/**
49+
* set session variable in sql level
50+
* @param context statement context
51+
*/
52+
public void setVarOnceInSql(StatementContext context) {
53+
if (context == null) {
54+
return;
55+
}
56+
SessionVariable sessionVariable = context.getConnectContext().getSessionVariable();
57+
// set temporary session value, and then revert value in the 'finally block' of StmtExecutor#execute
58+
sessionVariable.setIsSingleSetVar(true);
59+
for (Map.Entry<String, Optional<String>> kv : getParameters().entrySet()) {
60+
String key = kv.getKey();
61+
Optional<String> value = kv.getValue();
62+
if (value.isPresent()) {
63+
try {
64+
VariableMgr.setVar(sessionVariable, new SetVar(key, new StringLiteral(value.get())));
65+
} catch (Throwable t) {
66+
throw new AnalysisException("Can not set session variable '"
67+
+ key + "' = '" + value.get() + "'", t);
68+
}
69+
}
70+
}
71+
// if sv set enable_nereids_planner=true and hint set enable_nereids_planner=false, we should set
72+
// enable_fallback_to_original_planner=true and revert it after executing.
73+
// throw exception to fall back to original planner
74+
if (!sessionVariable.isEnableNereidsPlanner()) {
75+
try {
76+
sessionVariable.enableFallbackToOriginalPlannerOnce();
77+
} catch (Throwable t) {
78+
throw new AnalysisException("failed to set fallback to original planner to true", t);
79+
}
80+
throw new AnalysisException("The nereids is disabled in this sql, fallback to original planner");
81+
}
82+
}
83+
4184
@Override
4285
public String toString() {
4386
String kvString = parameters

fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/EliminateLogicalSelectHint.java

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,9 @@
1717

1818
package org.apache.doris.nereids.rules.analysis;
1919

20-
import org.apache.doris.analysis.SetVar;
21-
import org.apache.doris.analysis.StringLiteral;
2220
import org.apache.doris.common.DdlException;
2321
import org.apache.doris.nereids.CascadesContext;
2422
import org.apache.doris.nereids.StatementContext;
25-
import org.apache.doris.nereids.exceptions.AnalysisException;
2623
import org.apache.doris.nereids.hint.Hint;
2724
import org.apache.doris.nereids.hint.LeadingHint;
2825
import org.apache.doris.nereids.hint.OrderedHint;
@@ -35,15 +32,12 @@
3532
import org.apache.doris.nereids.trees.plans.Plan;
3633
import org.apache.doris.nereids.trees.plans.logical.LogicalSelectHint;
3734
import org.apache.doris.qe.ConnectContext;
38-
import org.apache.doris.qe.SessionVariable;
39-
import org.apache.doris.qe.VariableMgr;
4035

4136
import org.slf4j.Logger;
4237
import org.slf4j.LoggerFactory;
4338

4439
import java.util.Map;
4540
import java.util.Map.Entry;
46-
import java.util.Optional;
4741

4842
/**
4943
* eliminate logical select hint and set them to cascade context
@@ -58,7 +52,7 @@ public Rule build() {
5852
for (Entry<String, SelectHint> hint : selectHintPlan.getHints().entrySet()) {
5953
String hintName = hint.getKey();
6054
if (hintName.equalsIgnoreCase("SET_VAR")) {
61-
setVar((SelectHintSetVar) hint.getValue(), ctx.statementContext);
55+
((SelectHintSetVar) hint.getValue()).setVarOnceInSql(ctx.statementContext);
6256
} else if (hintName.equalsIgnoreCase("ORDERED")) {
6357
try {
6458
ctx.cascadesContext.getConnectContext().getSessionVariable()
@@ -81,35 +75,6 @@ public Rule build() {
8175
}).toRule(RuleType.ELIMINATE_LOGICAL_SELECT_HINT);
8276
}
8377

84-
private void setVar(SelectHintSetVar selectHint, StatementContext context) {
85-
SessionVariable sessionVariable = context.getConnectContext().getSessionVariable();
86-
// set temporary session value, and then revert value in the 'finally block' of StmtExecutor#execute
87-
sessionVariable.setIsSingleSetVar(true);
88-
for (Entry<String, Optional<String>> kv : selectHint.getParameters().entrySet()) {
89-
String key = kv.getKey();
90-
Optional<String> value = kv.getValue();
91-
if (value.isPresent()) {
92-
try {
93-
VariableMgr.setVar(sessionVariable, new SetVar(key, new StringLiteral(value.get())));
94-
} catch (Throwable t) {
95-
throw new AnalysisException("Can not set session variable '"
96-
+ key + "' = '" + value.get() + "'", t);
97-
}
98-
}
99-
}
100-
// if sv set enable_nereids_planner=true and hint set enable_nereids_planner=false, we should set
101-
// enable_fallback_to_original_planner=true and revert it after executing.
102-
// throw exception to fall back to original planner
103-
if (!sessionVariable.isEnableNereidsPlanner()) {
104-
try {
105-
sessionVariable.enableFallbackToOriginalPlannerOnce();
106-
} catch (Throwable t) {
107-
throw new AnalysisException("failed to set fallback to original planner to true", t);
108-
}
109-
throw new AnalysisException("The nereids is disabled in this sql, fallback to original planner");
110-
}
111-
}
112-
11378
private void extractLeading(SelectHintLeading selectHint, CascadesContext context,
11479
StatementContext statementContext, Map<String, SelectHint> hints) {
11580
LeadingHint hint = new LeadingHint("Leading", selectHint.getParameters(), selectHint.toString());

fe/fe-core/src/test/java/org/apache/doris/qe/SessionVariablesTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.doris.common.util.ProfileManager;
3131
import org.apache.doris.common.util.RuntimeProfile;
3232
import org.apache.doris.load.ExportJob;
33+
import org.apache.doris.nereids.parser.NereidsParser;
3334
import org.apache.doris.task.ExportExportingTask;
3435
import org.apache.doris.thrift.TQueryOptions;
3536
import org.apache.doris.utframe.TestWithFeService;
@@ -229,4 +230,11 @@ public void testDisableProfile() {
229230
}
230231

231232
}
233+
234+
@Test
235+
public void testSetVarInHint() {
236+
String sql = "insert into test_t1 select /*+ set_var(enable_nereids_dml_with_pipeline=false)*/ * from test_t1 where enable_nereids_dml_with_pipeline=true";
237+
new NereidsParser().parseSQL(sql);
238+
Assertions.assertEquals(false, connectContext.getSessionVariable().enableNereidsDmlWithPipeline);
239+
}
232240
}

regression-test/suites/nereids_syntax_p0/system_var.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ suite("nereids_sys_var") {
3838
// set an invalid parameter, and throw an exception
3939
test {
4040
sql "select /*+SET_VAR(runtime_filter_type=10000)*/ * from supplier limit 10"
41-
exception "Unexpected exception: Can not set session variable"
41+
exception "errCode"
4242
}
4343

4444
sql "select @@session.time_zone"

0 commit comments

Comments
 (0)