Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat](Nereids) support set var in hint when parse sql (#41331) #42335

Merged
merged 3 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1834,7 +1834,9 @@ private LogicalPlan withSelectHint(LogicalPlan logicalPlan, List<ParserRuleConte
parameters.put(parameterName, value);
}
}
hints.put(hintName, new SelectHintSetVar(hintName, parameters));
SelectHintSetVar setVar = new SelectHintSetVar(hintName, parameters);
setVar.setVarOnceInSql(ConnectContext.get().getStatementContext());
hints.put(hintName, setVar);
break;
case "leading":
List<String> leadingParameters = new ArrayList<String>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@

package org.apache.doris.nereids.properties;

import org.apache.doris.analysis.SetVar;
import org.apache.doris.analysis.StringLiteral;
import org.apache.doris.nereids.StatementContext;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.qe.SessionVariable;
import org.apache.doris.qe.VariableMgr;

import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
Expand All @@ -38,6 +45,42 @@ public Map<String, Optional<String>> getParameters() {
return parameters;
}

/**
* set session variable in sql level
* @param context statement context
*/
public void setVarOnceInSql(StatementContext context) {
if (context == null) {
return;
}
SessionVariable sessionVariable = context.getConnectContext().getSessionVariable();
// set temporary session value, and then revert value in the 'finally block' of StmtExecutor#execute
sessionVariable.setIsSingleSetVar(true);
for (Map.Entry<String, Optional<String>> kv : getParameters().entrySet()) {
String key = kv.getKey();
Optional<String> value = kv.getValue();
if (value.isPresent()) {
try {
VariableMgr.setVar(sessionVariable, new SetVar(key, new StringLiteral(value.get())));
} catch (Throwable t) {
throw new AnalysisException("Can not set session variable '"
+ key + "' = '" + value.get() + "'", t);
}
}
}
// if sv set enable_nereids_planner=true and hint set enable_nereids_planner=false, we should set
// enable_fallback_to_original_planner=true and revert it after executing.
// throw exception to fall back to original planner
if (!sessionVariable.isEnableNereidsPlanner()) {
try {
sessionVariable.enableFallbackToOriginalPlannerOnce();
} catch (Throwable t) {
throw new AnalysisException("failed to set fallback to original planner to true", t);
}
throw new AnalysisException("The nereids is disabled in this sql, fallback to original planner");
}
}

@Override
public String toString() {
String kvString = parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@

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

import org.apache.doris.analysis.SetVar;
import org.apache.doris.analysis.StringLiteral;
import org.apache.doris.common.DdlException;
import org.apache.doris.nereids.CascadesContext;
import org.apache.doris.nereids.StatementContext;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.hint.Hint;
import org.apache.doris.nereids.hint.LeadingHint;
import org.apache.doris.nereids.hint.OrderedHint;
Expand All @@ -35,15 +32,12 @@
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalSelectHint;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.SessionVariable;
import org.apache.doris.qe.VariableMgr;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;

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

private void setVar(SelectHintSetVar selectHint, StatementContext context) {
SessionVariable sessionVariable = context.getConnectContext().getSessionVariable();
// set temporary session value, and then revert value in the 'finally block' of StmtExecutor#execute
sessionVariable.setIsSingleSetVar(true);
for (Entry<String, Optional<String>> kv : selectHint.getParameters().entrySet()) {
String key = kv.getKey();
Optional<String> value = kv.getValue();
if (value.isPresent()) {
try {
VariableMgr.setVar(sessionVariable, new SetVar(key, new StringLiteral(value.get())));
} catch (Throwable t) {
throw new AnalysisException("Can not set session variable '"
+ key + "' = '" + value.get() + "'", t);
}
}
}
// if sv set enable_nereids_planner=true and hint set enable_nereids_planner=false, we should set
// enable_fallback_to_original_planner=true and revert it after executing.
// throw exception to fall back to original planner
if (!sessionVariable.isEnableNereidsPlanner()) {
try {
sessionVariable.enableFallbackToOriginalPlannerOnce();
} catch (Throwable t) {
throw new AnalysisException("failed to set fallback to original planner to true", t);
}
throw new AnalysisException("The nereids is disabled in this sql, fallback to original planner");
}
}

private void extractLeading(SelectHintLeading selectHint, CascadesContext context,
StatementContext statementContext, Map<String, SelectHint> hints) {
LeadingHint hint = new LeadingHint("Leading", selectHint.getParameters(), selectHint.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.doris.common.util.ProfileManager;
import org.apache.doris.common.util.RuntimeProfile;
import org.apache.doris.load.ExportJob;
import org.apache.doris.nereids.parser.NereidsParser;
import org.apache.doris.task.ExportExportingTask;
import org.apache.doris.thrift.TQueryOptions;
import org.apache.doris.utframe.TestWithFeService;
Expand Down Expand Up @@ -229,4 +230,11 @@ public void testDisableProfile() {
}

}

@Test
public void testSetVarInHint() {
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";
new NereidsParser().parseSQL(sql);
Assertions.assertEquals(false, connectContext.getSessionVariable().enableNereidsDmlWithPipeline);
}
}
2 changes: 1 addition & 1 deletion regression-test/suites/nereids_syntax_p0/system_var.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ suite("nereids_sys_var") {
// set an invalid parameter, and throw an exception
test {
sql "select /*+SET_VAR(runtime_filter_type=10000)*/ * from supplier limit 10"
exception "Unexpected exception: Can not set session variable"
exception "errCode"
}

sql "select @@session.time_zone"
Expand Down
Loading