This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.0 by this push:
new 8df819e08e9 [fix](Nereids) store user variable in connect context
(#26655) (#26920)
8df819e08e9 is described below
commit 8df819e08e9926e66c9562923304ff9762c74039
Author: 谢健 <[email protected]>
AuthorDate: Thu Nov 16 19:03:57 2023 +0800
[fix](Nereids) store user variable in connect context (#26655) (#26920)
pick from master #26655
1. user variable should be case insensitive
2. user variable should be cleared after the connection reset
---
.../org/apache/doris/analysis/VariableExpr.java | 3 +-
.../doris/nereids/rules/analysis/SlotBinder.java | 2 +-
.../java/org/apache/doris/qe/ConnectContext.java | 86 ++++++++++++++++++++++
.../main/java/org/apache/doris/qe/SetExecutor.java | 2 +-
.../main/java/org/apache/doris/qe/VariableMgr.java | 64 ----------------
.../data/query_p0/set/test_user_var.out | 6 ++
.../suites/query_p0/set/test_user_var.groovy | 5 ++
7 files changed, 101 insertions(+), 67 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/analysis/VariableExpr.java
b/fe/fe-core/src/main/java/org/apache/doris/analysis/VariableExpr.java
index 093a7861173..85204952e55 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/VariableExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/VariableExpr.java
@@ -21,6 +21,7 @@ import org.apache.doris.catalog.Type;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.ErrorReport;
+import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.VariableMgr;
import org.apache.doris.qe.VariableVarConverters;
import org.apache.doris.thrift.TBoolLiteral;
@@ -77,7 +78,7 @@ public class VariableExpr extends Expr {
@Override
public void analyzeImpl(Analyzer analyzer) throws AnalysisException {
if (setType == SetType.USER) {
- VariableMgr.fillValueForUserDefinedVar(this);
+ ConnectContext.get().fillValueForUserDefinedVar(this);
} else {
VariableMgr.fillValue(analyzer.getContext().getSessionVariable(),
this);
if (!Strings.isNullOrEmpty(name) &&
VariableVarConverters.hasConverter(name)) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SlotBinder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SlotBinder.java
index 4b5b977b0aa..57d84610cfd 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SlotBinder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SlotBinder.java
@@ -94,7 +94,7 @@ class SlotBinder extends SubExprAnalyzer {
} else if (unboundVariable.getType() == VariableType.GLOBAL) {
literal = VariableMgr.getLiteral(sessionVariable, name,
SetType.GLOBAL);
} else if (unboundVariable.getType() == VariableType.USER) {
- literal = VariableMgr.getLiteralForUserVar(name);
+ literal = ConnectContext.get().getLiteralForUserVar(name);
}
if (literal == null) {
throw new AnalysisException("Unsupported system variable: " +
unboundVariable.getName());
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java
b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java
index cfb41d3b819..d6c0aaf820b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java
@@ -17,11 +17,21 @@
package org.apache.doris.qe;
+import org.apache.doris.analysis.BoolLiteral;
+import org.apache.doris.analysis.DecimalLiteral;
+import org.apache.doris.analysis.FloatLiteral;
+import org.apache.doris.analysis.IntLiteral;
+import org.apache.doris.analysis.LiteralExpr;
+import org.apache.doris.analysis.NullLiteral;
+import org.apache.doris.analysis.SetVar;
+import org.apache.doris.analysis.StringLiteral;
import org.apache.doris.analysis.UserIdentity;
+import org.apache.doris.analysis.VariableExpr;
import org.apache.doris.catalog.DatabaseIf;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.FunctionRegistry;
import org.apache.doris.catalog.TableIf;
+import org.apache.doris.catalog.Type;
import org.apache.doris.cluster.ClusterNamespace;
import org.apache.doris.common.Config;
import org.apache.doris.common.telemetry.Telemetry;
@@ -37,6 +47,7 @@ import org.apache.doris.mysql.MysqlCommand;
import org.apache.doris.mysql.MysqlSslContext;
import org.apache.doris.nereids.StatementContext;
import org.apache.doris.nereids.stats.StatsErrorEstimator;
+import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.plugin.AuditEvent.AuditEventBuilder;
import org.apache.doris.resource.Tag;
import org.apache.doris.statistics.ColumnStatistic;
@@ -61,6 +72,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import javax.annotation.Nullable;
// When one client connect in, we create a connect context for it.
// We store session information here. Meanwhile ConnectScheduler all
@@ -112,6 +124,8 @@ public class ConnectContext {
protected volatile UserIdentity currentUserIdentity;
// Variables belong to this session.
protected volatile SessionVariable sessionVariable;
+ // Store user variable in this connection
+ private Map<String, LiteralExpr> userVars = new HashMap<>();
// Scheduler this connection belongs to
protected volatile ConnectScheduler connectScheduler;
// Executor
@@ -162,6 +176,7 @@ public class ConnectContext {
private SessionContext sessionContext;
+
// This context is used for SSL connection between server and mysql client.
private final MysqlSslContext mysqlSslContext = new
MysqlSslContext(SSL_PROTOCOL);
@@ -253,6 +268,18 @@ public class ConnectContext {
return notEvalNondeterministicFunction;
}
+ public void init() {
+ state = new QueryState();
+ returnRows = 0;
+ isKilled = false;
+ sessionVariable = VariableMgr.newSessionVariable();
+ userVars = new HashMap<>();
+ command = MysqlCommand.COM_SLEEP;
+ if (Config.use_fuzzy_session_variable) {
+ sessionVariable.initFuzzyModeVariables();
+ }
+ }
+
public ConnectContext() {
this(null);
}
@@ -378,6 +405,65 @@ public class ConnectContext {
defaultCatalog = env.getInternalCatalog().getName();
}
+ public void setUserVar(SetVar setVar) {
+ userVars.put(setVar.getVariable().toLowerCase(), setVar.getResult());
+ }
+
+ public @Nullable Literal getLiteralForUserVar(String varName) {
+ varName = varName.toLowerCase();
+ if (userVars.containsKey(varName)) {
+ LiteralExpr literalExpr = userVars.get(varName);
+ if (literalExpr instanceof BoolLiteral) {
+ return Literal.of(((BoolLiteral) literalExpr).getValue());
+ } else if (literalExpr instanceof IntLiteral) {
+ return Literal.of(((IntLiteral) literalExpr).getValue());
+ } else if (literalExpr instanceof FloatLiteral) {
+ return Literal.of(((FloatLiteral) literalExpr).getValue());
+ } else if (literalExpr instanceof DecimalLiteral) {
+ return Literal.of(((DecimalLiteral) literalExpr).getValue());
+ } else if (literalExpr instanceof StringLiteral) {
+ return Literal.of(((StringLiteral) literalExpr).getValue());
+ } else if (literalExpr instanceof NullLiteral) {
+ return Literal.of(null);
+ } else {
+ return Literal.of("");
+ }
+ } else {
+ // If there are no such user defined var, just return the NULL
value.
+ return Literal.of(null);
+ }
+ }
+
+ // Get variable value through variable name, used to satisfy statement
like `SELECT @@comment_version`
+ public void fillValueForUserDefinedVar(VariableExpr desc) {
+ String varName = desc.getName().toLowerCase();
+ if (userVars.containsKey(varName)) {
+ LiteralExpr literalExpr = userVars.get(varName);
+ desc.setType(literalExpr.getType());
+ if (literalExpr instanceof BoolLiteral) {
+ desc.setBoolValue(((BoolLiteral) literalExpr).getValue());
+ } else if (literalExpr instanceof IntLiteral) {
+ desc.setIntValue(((IntLiteral) literalExpr).getValue());
+ } else if (literalExpr instanceof FloatLiteral) {
+ desc.setFloatValue(((FloatLiteral) literalExpr).getValue());
+ } else if (literalExpr instanceof DecimalLiteral) {
+ desc.setDecimalValue(((DecimalLiteral)
literalExpr).getValue());
+ } else if (literalExpr instanceof StringLiteral) {
+ desc.setStringValue(((StringLiteral) literalExpr).getValue());
+ } else if (literalExpr instanceof NullLiteral) {
+ desc.setType(Type.NULL);
+ desc.setIsNull();
+ } else {
+ desc.setType(Type.VARCHAR);
+ desc.setStringValue("");
+ }
+ } else {
+ // If there are no such user defined var, just fill the NULL value.
+ desc.setType(Type.NULL);
+ desc.setIsNull();
+ }
+ }
+
public Env getEnv() {
return env;
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SetExecutor.java
b/fe/fe-core/src/main/java/org/apache/doris/qe/SetExecutor.java
index 9dbe9ca8a98..673f01562ce 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/SetExecutor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SetExecutor.java
@@ -56,7 +56,7 @@ public class SetExecutor {
// do nothing
return;
} else if (var instanceof SetUserDefinedVar) {
- VariableMgr.setUserVar(var);
+ ConnectContext.get().setUserVar(var);
} else {
VariableMgr.setVar(ctx.getSessionVariable(), var);
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
b/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
index 80cf288a32a..c729f0a444c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
@@ -17,15 +17,9 @@
package org.apache.doris.qe;
-import org.apache.doris.analysis.BoolLiteral;
-import org.apache.doris.analysis.DecimalLiteral;
-import org.apache.doris.analysis.FloatLiteral;
-import org.apache.doris.analysis.IntLiteral;
import org.apache.doris.analysis.LiteralExpr;
-import org.apache.doris.analysis.NullLiteral;
import org.apache.doris.analysis.SetType;
import org.apache.doris.analysis.SetVar;
-import org.apache.doris.analysis.StringLiteral;
import org.apache.doris.analysis.VariableExpr;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.Type;
@@ -272,10 +266,6 @@ public class VariableMgr {
}
}
- public static void setUserVar(SetVar setVar) {
- userVars.put(setVar.getVariable(), setVar.getResult());
- }
-
// Entry of handling SetVarStmt
// Input:
// sessionVariable: the variable of current session
@@ -517,36 +507,6 @@ public class VariableMgr {
}
}
- // Get variable value through variable name, used to satisfy statement
like `SELECT @@comment_version`
- public static void fillValueForUserDefinedVar(VariableExpr desc) {
- String varName = desc.getName();
- if (userVars.containsKey(varName)) {
- LiteralExpr literalExpr = userVars.get(varName);
- desc.setType(literalExpr.getType());
- if (literalExpr instanceof BoolLiteral) {
- desc.setBoolValue(((BoolLiteral) literalExpr).getValue());
- } else if (literalExpr instanceof IntLiteral) {
- desc.setIntValue(((IntLiteral) literalExpr).getValue());
- } else if (literalExpr instanceof FloatLiteral) {
- desc.setFloatValue(((FloatLiteral) literalExpr).getValue());
- } else if (literalExpr instanceof DecimalLiteral) {
- desc.setDecimalValue(((DecimalLiteral)
literalExpr).getValue());
- } else if (literalExpr instanceof StringLiteral) {
- desc.setStringValue(((StringLiteral) literalExpr).getValue());
- } else if (literalExpr instanceof NullLiteral) {
- desc.setType(Type.NULL);
- desc.setIsNull();
- } else {
- desc.setType(Type.VARCHAR);
- desc.setStringValue("");
- }
- } else {
- // If there are no such user defined var, just fill the NULL value.
- desc.setType(Type.NULL);
- desc.setIsNull();
- }
- }
-
private static String getValue(SessionVariable var, String name, SetType
setType) throws AnalysisException {
VarContext ctx = ctxByVarName.get(name);
if (ctx == null) {
@@ -618,30 +578,6 @@ public class VariableMgr {
return Literal.of("");
}
- public static @Nullable Literal getLiteralForUserVar(String varName) {
- if (userVars.containsKey(varName)) {
- LiteralExpr literalExpr = userVars.get(varName);
- if (literalExpr instanceof BoolLiteral) {
- return Literal.of(((BoolLiteral) literalExpr).getValue());
- } else if (literalExpr instanceof IntLiteral) {
- return Literal.of(((IntLiteral) literalExpr).getValue());
- } else if (literalExpr instanceof FloatLiteral) {
- return Literal.of(((FloatLiteral) literalExpr).getValue());
- } else if (literalExpr instanceof DecimalLiteral) {
- return Literal.of(((DecimalLiteral) literalExpr).getValue());
- } else if (literalExpr instanceof StringLiteral) {
- return Literal.of(((StringLiteral) literalExpr).getValue());
- } else if (literalExpr instanceof NullLiteral) {
- return Literal.of(null);
- } else {
- return Literal.of("");
- }
- } else {
- // If there are no such user defined var, just return the NULL
value.
- return Literal.of(null);
- }
- }
-
private static String getValue(Object obj, Field field) {
try {
switch (field.getType().getSimpleName()) {
diff --git a/regression-test/data/query_p0/set/test_user_var.out
b/regression-test/data/query_p0/set/test_user_var.out
index 41aebfe022d..3a1c1760567 100644
--- a/regression-test/data/query_p0/set/test_user_var.out
+++ b/regression-test/data/query_p0/set/test_user_var.out
@@ -14,3 +14,9 @@ true false
-- !select5 --
\N \N
+-- !select6 --
+2
+
+-- !select7 --
+1
+
diff --git a/regression-test/suites/query_p0/set/test_user_var.groovy
b/regression-test/suites/query_p0/set/test_user_var.groovy
index af2d2caadc9..e653fe3e801 100644
--- a/regression-test/suites/query_p0/set/test_user_var.groovy
+++ b/regression-test/suites/query_p0/set/test_user_var.groovy
@@ -27,4 +27,9 @@ suite("test_user_var") {
qt_select3 'select @c1, @c2;'
qt_select4 'select @d1, @d2;'
qt_select5 'select @f1, @f2;'
+
+ sql "SET @A1=2"
+ qt_select6 'select @a1'
+ sql "SET @a1 = 1"
+ qt_select7 'select @A1'
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]