This is an automated email from the ASF dual-hosted git repository.

duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new f015abb3d61 Fix variable was not parsed into VariableSegment (#25200)
f015abb3d61 is described below

commit f015abb3d617b4877afa687649c7b4b96e089db5
Author: 吴伟杰 <[email protected]>
AuthorDate: Tue Apr 18 09:38:55 2023 +0800

    Fix variable was not parsed into VariableSegment (#25200)
    
    * Fix variable was not parsed into VariableSegment
    
    * Refactor VariableSegment
    
    * Complete tests for VariableSegment
    
    * Fix failed to parse scope of system variable
    
    * Add parser test cases for select system variable
---
 .../admin/MySQLSetVariableAdminExecutor.java       |  4 +-
 .../MySQLSetVariableAdminExecutorTest.java         |  6 +--
 .../PostgreSQLSetVariableAdminExecutorTest.java    |  3 +-
 .../command/query/extended/PortalTest.java         |  2 +-
 .../src/main/antlr4/imports/mysql/BaseRule.g4      |  7 ++-
 .../visitor/format/impl/MySQLFormatSQLVisitor.java |  7 +--
 .../impl/MySQLDALStatementSQLVisitor.java          | 57 +++++-----------------
 .../statement/impl/MySQLStatementSQLVisitor.java   | 31 ++++++++++++
 .../impl/OpenGaussDALStatementSQLVisitor.java      |  6 +--
 .../impl/PostgreSQLDALStatementSQLVisitor.java     | 10 +---
 .../sql/common/segment/dal/VariableSegment.java    | 23 +++++++--
 .../segment/expression/ExpressionAssert.java       | 13 +++++
 .../dal/impl/SetParameterStatementAssert.java      |  2 +-
 .../jaxb/segment/impl/expr/ExpectedExpression.java |  3 ++
 .../segment/impl/expr/ExpectedVariableSegment.java | 16 +++---
 .../main/resources/case/dml/select-expression.xml  |  2 +-
 .../parser/src/main/resources/case/dml/select.xml  | 20 ++++++++
 .../main/resources/sql/supported/dml/select.xml    |  1 +
 18 files changed, 128 insertions(+), 85 deletions(-)

diff --git 
a/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLSetVariableAdminExecutor.java
 
b/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLSetVariableAdminExecutor.java
index c8bf5f8e2f5..31759684e2e 100644
--- 
a/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLSetVariableAdminExecutor.java
+++ 
b/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLSetVariableAdminExecutor.java
@@ -62,12 +62,12 @@ public final class MySQLSetVariableAdminExecutor implements 
DatabaseAdminExecuto
     }
     
     private Map<String, String> extractSessionVariables() {
-        return setStatement.getVariableAssigns().stream().filter(each -> 
!"global".equalsIgnoreCase(each.getVariable().getScope()))
+        return setStatement.getVariableAssigns().stream().filter(each -> 
!"global".equalsIgnoreCase(each.getVariable().getScope().orElse("")))
                 .collect(Collectors.toMap(each -> 
each.getVariable().getVariable(), VariableAssignSegment::getAssignValue));
     }
     
     private Map<String, String> extractGlobalVariables() {
-        return setStatement.getVariableAssigns().stream().filter(each -> 
"global".equalsIgnoreCase(each.getVariable().getScope()))
+        return setStatement.getVariableAssigns().stream().filter(each -> 
"global".equalsIgnoreCase(each.getVariable().getScope().orElse("")))
                 .collect(Collectors.toMap(each -> 
each.getVariable().getVariable(), VariableAssignSegment::getAssignValue, 
(oldValue, newValue) -> newValue, LinkedHashMap::new));
     }
     
diff --git 
a/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetVariableAdminExecutorTest.java
 
b/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetVariableAdminExecutorTest.java
index 7e9e1597b28..d54286cb6e0 100644
--- 
a/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetVariableAdminExecutorTest.java
+++ 
b/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetVariableAdminExecutorTest.java
@@ -71,14 +71,12 @@ class MySQLSetVariableAdminExecutorTest {
     
     private SetStatement prepareSetStatement() {
         VariableAssignSegment setGlobalMaxConnectionAssignSegment = new 
VariableAssignSegment();
-        VariableSegment maxConnectionVariableSegment = new VariableSegment();
+        VariableSegment maxConnectionVariableSegment = new VariableSegment(0, 
0, "max_connections");
         maxConnectionVariableSegment.setScope("global");
-        maxConnectionVariableSegment.setVariable("max_connections");
         
setGlobalMaxConnectionAssignSegment.setVariable(maxConnectionVariableSegment);
         setGlobalMaxConnectionAssignSegment.setAssignValue("151");
         VariableAssignSegment setTestFixtureAssignSegment = new 
VariableAssignSegment();
-        VariableSegment testFixtureSegment = new VariableSegment();
-        testFixtureSegment.setVariable("test_fixture");
+        VariableSegment testFixtureSegment = new VariableSegment(0, 0, 
"test_fixture");
         setTestFixtureAssignSegment.setVariable(testFixtureSegment);
         setTestFixtureAssignSegment.setAssignValue("'value'");
         SetStatement result = new MySQLSetStatement();
diff --git 
a/proxy/backend/type/postgresql/src/test/java/org/apache/shardingsphere/proxy/backend/postgresql/handler/admin/PostgreSQLSetVariableAdminExecutorTest.java
 
b/proxy/backend/type/postgresql/src/test/java/org/apache/shardingsphere/proxy/backend/postgresql/handler/admin/PostgreSQLSetVariableAdminExecutorTest.java
index b0cae497ff3..d049ab866b1 100644
--- 
a/proxy/backend/type/postgresql/src/test/java/org/apache/shardingsphere/proxy/backend/postgresql/handler/admin/PostgreSQLSetVariableAdminExecutorTest.java
+++ 
b/proxy/backend/type/postgresql/src/test/java/org/apache/shardingsphere/proxy/backend/postgresql/handler/admin/PostgreSQLSetVariableAdminExecutorTest.java
@@ -33,8 +33,7 @@ class PostgreSQLSetVariableAdminExecutorTest {
     @Test
     void assertExecute() {
         VariableAssignSegment variableAssignSegment = new 
VariableAssignSegment();
-        VariableSegment variable = new VariableSegment();
-        variable.setVariable("key");
+        VariableSegment variable = new VariableSegment(0, 0, "key");
         variableAssignSegment.setVariable(variable);
         variableAssignSegment.setAssignValue("value");
         PostgreSQLSetStatement setStatement = new PostgreSQLSetStatement();
diff --git 
a/proxy/frontend/type/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PortalTest.java
 
b/proxy/frontend/type/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PortalTest.java
index a738374a738..76e32ac8b05 100644
--- 
a/proxy/frontend/type/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PortalTest.java
+++ 
b/proxy/frontend/type/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PortalTest.java
@@ -226,7 +226,7 @@ class PortalTest {
         String sql = "set client_encoding = utf8";
         PostgreSQLSetStatement setStatement = new PostgreSQLSetStatement();
         VariableAssignSegment variableAssignSegment = new 
VariableAssignSegment();
-        variableAssignSegment.setVariable(new VariableSegment());
+        variableAssignSegment.setVariable(new VariableSegment(0, 0, 
"client_encoding"));
         setStatement.getVariableAssigns().add(variableAssignSegment);
         PostgreSQLServerPreparedStatement preparedStatement = new 
PostgreSQLServerPreparedStatement(sql, new 
CommonSQLStatementContext<>(setStatement), Collections.emptyList());
         Portal portal = new Portal("", preparedStatement, 
Collections.emptyList(), Collections.emptyList(), backendConnection);
diff --git a/sql-parser/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4 
b/sql-parser/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
index 800281055bc..c261f1434c1 100644
--- a/sql-parser/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
+++ b/sql-parser/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
@@ -582,7 +582,12 @@ userVariable
     ;
     
 systemVariable
-    : AT_ AT_ systemVariableScope=(GLOBAL | SESSION | LOCAL)? textOrIdentifier 
(DOT_ identifier)?
+    : AT_ AT_ (systemVariableScope=(GLOBAL | SESSION | LOCAL) DOT_)? 
rvalueSystemVariable
+    ;
+    
+rvalueSystemVariable
+    : textOrIdentifier
+    | textOrIdentifier DOT_ identifier
     ;
     
 setSystemVariable
diff --git 
a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLFormatSQLVisitor.java
 
b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLFormatSQLVisitor.java
index 3d0a9d8acf1..cd7b92f80af 100644
--- 
a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLFormatSQLVisitor.java
+++ 
b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/impl/MySQLFormatSQLVisitor.java
@@ -690,11 +690,12 @@ public abstract class MySQLFormatSQLVisitor extends 
MySQLStatementBaseVisitor<St
         formatPrint("@@");
         if (null != ctx.systemVariableScope) {
             formatPrint(upperCase ? 
ctx.systemVariableScope.getText().toUpperCase() : 
ctx.systemVariableScope.getText().toLowerCase());
+            formatPrint(".");
         }
-        visit(ctx.textOrIdentifier());
-        if (null != ctx.DOT_()) {
+        visit(ctx.rvalueSystemVariable().textOrIdentifier());
+        if (null != ctx.rvalueSystemVariable().DOT_()) {
             formatPrint(".");
-            visit(ctx.identifier());
+            visit(ctx.rvalueSystemVariable().identifier());
         }
         return result.toString();
     }
diff --git 
a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLDALStatementSQLVisitor.java
 
b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLDALStatementSQLVisitor.java
index d05a6202ca5..3fe201370bc 100644
--- 
a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLDALStatementSQLVisitor.java
+++ 
b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLDALStatementSQLVisitor.java
@@ -112,14 +112,11 @@ import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ShowVar
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ShowWarningsContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ShowWhereClauseContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ShutdownContext;
-import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SystemVariableContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TableNameContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TablesOptionContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.UninstallComponentContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.UninstallPluginContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.UseContext;
-import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.UserVariableContext;
-import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.VariableContext;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dal.FromSchemaSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dal.FromTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dal.ShowFilterSegment;
@@ -912,9 +909,8 @@ public final class MySQLDALStatementSQLVisitor extends 
MySQLStatementSQLVisitor
             VariableAssignSegment variableAssign = new VariableAssignSegment();
             variableAssign.setStartIndex(ctx.start.getStartIndex());
             
variableAssign.setStopIndex(ctx.setExprOrDefault().stop.getStopIndex());
-            VariableSegment variable = new VariableSegment();
+            VariableSegment variable = new 
VariableSegment(ctx.internalVariableName().start.getStartIndex(), 
ctx.internalVariableName().stop.getStopIndex(), 
ctx.internalVariableName().getText());
             variable.setScope(ctx.optionType().getText());
-            variable.setVariable(ctx.internalVariableName().getText());
             variableAssign.setVariable(variable);
             variableAssign.setAssignValue(ctx.setExprOrDefault().getText());
             result.add(variableAssign);
@@ -931,21 +927,18 @@ public final class MySQLDALStatementSQLVisitor extends 
MySQLStatementSQLVisitor
         VariableAssignSegment result = new VariableAssignSegment();
         result.setStartIndex(ctx.start.getStartIndex());
         result.setStopIndex(ctx.stop.getStopIndex());
-        VariableSegment variable = new VariableSegment();
         if (null != ctx.NAMES()) {
-            variable.setVariable("charset");
-            result.setVariable(variable);
+            result.setVariable(new 
VariableSegment(ctx.NAMES().getSymbol().getStartIndex(), 
ctx.NAMES().getSymbol().getStopIndex(), "charset"));
             result.setAssignValue(ctx.charsetName().getText());
         } else if (null != ctx.internalVariableName()) {
-            variable.setVariable(ctx.internalVariableName().getText());
-            result.setVariable(variable);
+            result.setVariable(new 
VariableSegment(ctx.internalVariableName().start.getStartIndex(), 
ctx.internalVariableName().stop.getStopIndex(), 
ctx.internalVariableName().getText()));
             result.setAssignValue(ctx.setExprOrDefault().getText());
         } else if (null != ctx.userVariable()) {
-            variable.setVariable(ctx.userVariable().getText());
-            result.setVariable(variable);
+            result.setVariable(new 
VariableSegment(ctx.userVariable().start.getStartIndex(), 
ctx.userVariable().stop.getStopIndex(), ctx.userVariable().getText()));
             result.setAssignValue(ctx.expr().getText());
         } else if (null != ctx.setSystemVariable()) {
-            
variable.setVariable(ctx.setSystemVariable().internalVariableName().getText());
+            VariableSegment variable = new VariableSegment(
+                    ctx.setSystemVariable().start.getStartIndex(), 
ctx.setSystemVariable().stop.getStopIndex(), 
ctx.setSystemVariable().internalVariableName().getText());
             result.setVariable(variable);
             result.setAssignValue(ctx.setExprOrDefault().getText());
             OptionTypeContext optionType = 
ctx.setSystemVariable().optionType();
@@ -955,15 +948,14 @@ public final class MySQLDALStatementSQLVisitor extends 
MySQLStatementSQLVisitor
     }
     
     private VariableAssignSegment getVariableAssign(final OptionValueContext 
ctx) {
-        VariableAssignSegment result = new VariableAssignSegment();
-        result.setStartIndex(ctx.start.getStartIndex());
-        result.setStopIndex(ctx.stop.getStopIndex());
-        VariableSegment variable = new VariableSegment();
         if (null != ctx.optionValueNoOptionType()) {
             return getVariableAssign(ctx.optionValueNoOptionType());
         }
+        VariableAssignSegment result = new VariableAssignSegment();
+        result.setStartIndex(ctx.start.getStartIndex());
+        result.setStopIndex(ctx.stop.getStopIndex());
+        VariableSegment variable = new 
VariableSegment(ctx.internalVariableName().start.getStartIndex(), 
ctx.internalVariableName().stop.getStopIndex(), 
ctx.internalVariableName().getText());
         variable.setScope(ctx.optionType().getText());
-        variable.setVariable(ctx.internalVariableName().getText());
         result.setVariable(variable);
         result.setAssignValue(ctx.setExprOrDefault().getText());
         return result;
@@ -972,9 +964,10 @@ public final class MySQLDALStatementSQLVisitor extends 
MySQLStatementSQLVisitor
     @Override
     public ASTNode visitSetCharacter(final SetCharacterContext ctx) {
         VariableAssignSegment characterSet = new VariableAssignSegment();
-        VariableSegment variable = new VariableSegment();
+        int startIndex = null != ctx.CHARSET() ? 
ctx.CHARSET().getSymbol().getStartIndex() : 
ctx.CHARACTER().getSymbol().getStartIndex();
+        int stopIndex = null != ctx.CHARSET() ? 
ctx.CHARSET().getSymbol().getStopIndex() : 
ctx.SET(1).getSymbol().getStopIndex();
         String variableName = (null != ctx.CHARSET()) ? 
ctx.CHARSET().getText() : "charset";
-        variable.setVariable(variableName);
+        VariableSegment variable = new VariableSegment(startIndex, stopIndex, 
variableName);
         characterSet.setVariable(variable);
         String assignValue = (null != ctx.DEFAULT()) ? ctx.DEFAULT().getText() 
: ctx.charsetName().getText();
         characterSet.setAssignValue(assignValue);
@@ -983,30 +976,6 @@ public final class MySQLDALStatementSQLVisitor extends 
MySQLStatementSQLVisitor
         return result;
     }
     
-    @Override
-    public ASTNode visitVariable(final VariableContext ctx) {
-        return super.visitVariable(ctx);
-    }
-    
-    @Override
-    public ASTNode visitUserVariable(final UserVariableContext ctx) {
-        VariableSegment result = new VariableSegment();
-        result.setStartIndex(ctx.start.getStartIndex());
-        result.setStopIndex(ctx.stop.getStopIndex());
-        result.setVariable(ctx.textOrIdentifier().getText());
-        return result;
-    }
-    
-    @Override
-    public ASTNode visitSystemVariable(final SystemVariableContext ctx) {
-        VariableSegment result = new VariableSegment();
-        result.setScope(ctx.systemVariableScope.getText());
-        result.setStartIndex(ctx.start.getStartIndex());
-        result.setStopIndex(ctx.stop.getStopIndex());
-        result.setVariable(ctx.textOrIdentifier().getText());
-        return result;
-    }
-    
     @Override
     public ASTNode visitFromSchema(final FromSchemaContext ctx) {
         return new FromSchemaSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), (DatabaseSegment) visit(ctx.schemaName()));
diff --git 
a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
 
b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
index 95e399d57f2..ea06e1e665d 100644
--- 
a/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
+++ 
b/sql-parser/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
@@ -119,6 +119,7 @@ import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.StringL
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.String_Context;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SubqueryContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SubstringFunctionContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SystemVariableContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TableAliasRefListContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TableFactorContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TableIdentOptWildContext;
@@ -131,7 +132,9 @@ import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.Tempora
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TrimFunctionContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TypeDatetimePrecisionContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.UpdateContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.UserVariableContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ValuesFunctionContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.VariableContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ViewNameContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ViewNamesContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WeightStringFunctionContext;
@@ -143,6 +146,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.enums.CombineType;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.JoinType;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.OrderDirection;
 import 
org.apache.shardingsphere.sql.parser.sql.common.enums.ParameterMarkerType;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dal.VariableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.constraint.ConstraintSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexNameSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexSegment;
@@ -1042,6 +1046,9 @@ public abstract class MySQLStatementSQLVisitor extends 
MySQLStatementBaseVisitor
         if (null != ctx.BINARY()) {
             return visit(ctx.simpleExpr(0));
         }
+        if (null != ctx.variable()) {
+            return visit(ctx.variable());
+        }
         for (ExprContext each : ctx.expr()) {
             visit(each);
         }
@@ -1065,6 +1072,25 @@ public abstract class MySQLStatementSQLVisitor extends 
MySQLStatementBaseVisitor
         return new CaseWhenExpression(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), caseExpr, whenExprs, thenExprs, elseExpr);
     }
     
+    @Override
+    public ASTNode visitVariable(final VariableContext ctx) {
+        return null != ctx.systemVariable() ? visit(ctx.systemVariable()) : 
visit(ctx.userVariable());
+    }
+    
+    @Override
+    public ASTNode visitUserVariable(final UserVariableContext ctx) {
+        return new VariableSegment(ctx.start.getStartIndex(), 
ctx.stop.getStopIndex(), ctx.textOrIdentifier().getText());
+    }
+    
+    @Override
+    public ASTNode visitSystemVariable(final SystemVariableContext ctx) {
+        VariableSegment result = new 
VariableSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), 
ctx.rvalueSystemVariable().getText());
+        if (null != ctx.systemVariableScope) {
+            result.setScope(ctx.systemVariableScope.getText());
+        }
+        return result;
+    }
+    
     @Override
     public final ASTNode visitMatchExpression(final MatchExpressionContext 
ctx) {
         visit(ctx.expr());
@@ -1568,6 +1594,11 @@ public abstract class MySQLStatementSQLVisitor extends 
MySQLStatementBaseVisitor
             result.setAlias(alias);
             return result;
         }
+        if (projection instanceof VariableSegment) {
+            ExpressionProjectionSegment result = new 
ExpressionProjectionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), 
getOriginalText(ctx.expr()), (VariableSegment) projection);
+            result.setAlias(alias);
+            return result;
+        }
         LiteralExpressionSegment column = (LiteralExpressionSegment) 
projection;
         ExpressionProjectionSegment result = null == alias
                 ? new ExpressionProjectionSegment(column.getStartIndex(), 
column.getStopIndex(), String.valueOf(column.getLiterals()), column)
diff --git 
a/sql-parser/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/opengauss/visitor/statement/impl/OpenGaussDALStatementSQLVisitor.java
 
b/sql-parser/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/opengauss/visitor/statement/impl/OpenGaussDALStatementSQLVisitor.java
index 508643bea9e..b4cd2ab1229 100644
--- 
a/sql-parser/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/opengauss/visitor/statement/impl/OpenGaussDALStatementSQLVisitor.java
+++ 
b/sql-parser/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/opengauss/visitor/statement/impl/OpenGaussDALStatementSQLVisitor.java
@@ -101,11 +101,7 @@ public final class OpenGaussDALStatementSQLVisitor extends 
OpenGaussStatementSQL
         VariableAssignSegment result = new VariableAssignSegment();
         result.setStartIndex(ctx.start.getStartIndex());
         result.setStopIndex(ctx.stop.getStopIndex());
-        VariableSegment variable = new VariableSegment();
-        variable.setStartIndex(ctx.varName().start.getStartIndex());
-        variable.setStopIndex(ctx.varName().stop.getStopIndex());
-        variable.setVariable(ctx.varName().getText());
-        result.setVariable(variable);
+        result.setVariable(new 
VariableSegment(ctx.varName().start.getStartIndex(), 
ctx.varName().stop.getStopIndex(), ctx.varName().getText()));
         if (null != ctx.varList()) {
             result.setAssignValue(ctx.varList().getText());
         }
diff --git 
a/sql-parser/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLDALStatementSQLVisitor.java
 
b/sql-parser/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLDALStatementSQLVisitor.java
index dc60842fbe8..20815848fa7 100644
--- 
a/sql-parser/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLDALStatementSQLVisitor.java
+++ 
b/sql-parser/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/postgresql/visitor/statement/impl/PostgreSQLDALStatementSQLVisitor.java
@@ -94,9 +94,7 @@ public final class PostgreSQLDALStatementSQLVisitor extends 
PostgreSQLStatementS
         }
         if (null != ctx.encoding()) {
             VariableAssignSegment variableAssignSegment = new 
VariableAssignSegment();
-            VariableSegment variableSegment = new VariableSegment();
-            variableSegment.setVariable("client_encoding");
-            variableAssignSegment.setVariable(variableSegment);
+            variableAssignSegment.setVariable(new 
VariableSegment(ctx.NAMES().getSymbol().getStartIndex(), 
ctx.NAMES().getSymbol().getStopIndex(), "client_encoding"));
             String value = ctx.encoding().getText();
             variableAssignSegment.setAssignValue(value);
             variableAssigns.add(variableAssignSegment);
@@ -110,11 +108,7 @@ public final class PostgreSQLDALStatementSQLVisitor 
extends PostgreSQLStatementS
         VariableAssignSegment result = new VariableAssignSegment();
         result.setStartIndex(ctx.start.getStartIndex());
         result.setStopIndex(ctx.stop.getStopIndex());
-        VariableSegment variable = new VariableSegment();
-        variable.setStartIndex(ctx.varName().start.getStartIndex());
-        variable.setStopIndex(ctx.varName().stop.getStopIndex());
-        variable.setVariable(ctx.varName().getText());
-        result.setVariable(variable);
+        result.setVariable(new 
VariableSegment(ctx.varName().start.getStartIndex(), 
ctx.varName().stop.getStopIndex(), ctx.varName().getText()));
         if (null != ctx.varList()) {
             result.setAssignValue(ctx.varList().getText());
         }
diff --git 
a/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dal/VariableSegment.java
 
b/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dal/VariableSegment.java
index f37c9b8ebf5..f6edb248019 100644
--- 
a/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dal/VariableSegment.java
+++ 
b/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dal/VariableSegment.java
@@ -18,21 +18,34 @@
 package org.apache.shardingsphere.sql.parser.sql.common.segment.dal;
 
 import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 import lombok.Setter;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+
+import java.util.Optional;
 
 /**
  * Variable segment.
  */
+@RequiredArgsConstructor
 @Getter
 @Setter
-public final class VariableSegment implements SQLSegment {
+public final class VariableSegment implements ExpressionSegment {
+    
+    private final int startIndex;
     
-    private int startIndex;
+    private final int stopIndex;
     
-    private int stopIndex;
+    private final String variable;
     
     private String scope;
     
-    private String variable;
+    /**
+     * Get scope.
+     *
+     * @return scope
+     */
+    public Optional<String> getScope() {
+        return Optional.ofNullable(scope);
+    }
 }
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
index 896ddb4c860..43ebb719ea9 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
@@ -19,6 +19,7 @@ package 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.ex
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dal.VariableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenExpression;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
@@ -57,6 +58,7 @@ import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.s
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedListExpression;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedNotExpression;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedTypeCastExpression;
+import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedVariableSegment;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.complex.ExpectedCommonExpression;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.simple.ExpectedLiteralExpression;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.simple.ExpectedParameterMarkerExpression;
@@ -361,6 +363,15 @@ public final class ExpressionAssert {
         assertExpression(assertContext, actual.getExpression(), 
expected.getExpression());
     }
     
+    private static void assertVariableSegment(final SQLCaseAssertContext 
assertContext, final VariableSegment actual, final ExpectedVariableSegment 
expected) {
+        if (null == expected) {
+            assertNull(actual, assertContext.getText("Variable segment should 
not exist."));
+            return;
+        }
+        assertThat(assertContext.getText("Actual scope is different with 
expected scope."), actual.getScope().orElse(null), is(expected.getScope()));
+        assertThat(assertContext.getText("Actual variable is different with 
expected variable."), actual.getVariable(), is(expected.getVariable()));
+    }
+    
     /**
      * Assert expression by actual expression segment class type.
      *
@@ -412,6 +423,8 @@ public final class ExpressionAssert {
             assertCaseWhenExpression(assertContext, (CaseWhenExpression) 
actual, expected.getCaseWhenExpression());
         } else if (actual instanceof TypeCastExpression) {
             assertTypeCastExpression(assertContext, (TypeCastExpression) 
actual, expected.getTypeCastExpression());
+        } else if (actual instanceof VariableSegment) {
+            assertVariableSegment(assertContext, (VariableSegment) actual, 
expected.getVariableSegment());
         } else {
             throw new UnsupportedOperationException(String.format("Unsupported 
expression: %s", actual.getClass().getName()));
         }
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dal/impl/SetParameterStatementAssert.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dal/impl/SetParameterStatementAssert.java
index d6a0fa9bda2..ee9a05ae60b 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dal/impl/SetParameterStatementAssert.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/dal/impl/SetParameterStatementAssert.java
@@ -53,6 +53,6 @@ public final class SetParameterStatementAssert {
     
     private static void assertVariable(final SQLCaseAssertContext 
assertContext, final VariableSegment actual, final ExpectedVariable expected) {
         assertThat(assertContext.getText("variable assertion error: "), 
actual.getVariable(), is(expected.getName()));
-        assertThat(assertContext.getText("scope assertion error: "), 
actual.getScope(), is(expected.getScope()));
+        assertThat(assertContext.getText("scope assertion error: "), 
actual.getScope().orElse(null), is(expected.getScope()));
     }
 }
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedExpression.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedExpression.java
index a5fa04ed7be..032c17e8192 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedExpression.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedExpression.java
@@ -92,4 +92,7 @@ public final class ExpectedExpression extends 
AbstractExpectedSQLSegment {
     
     @XmlElement(name = "type-cast-expression")
     private ExpectedTypeCastExpression typeCastExpression;
+    
+    @XmlElement(name = "variable-segment")
+    private ExpectedVariableSegment variableSegment;
 }
diff --git 
a/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dal/VariableSegment.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedVariableSegment.java
similarity index 69%
copy from 
sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dal/VariableSegment.java
copy to 
test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedVariableSegment.java
index f37c9b8ebf5..1b90357e1fe 100644
--- 
a/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dal/VariableSegment.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/ExpectedVariableSegment.java
@@ -15,24 +15,24 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sql.parser.sql.common.segment.dal;
+package 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr;
 
 import lombok.Getter;
 import lombok.Setter;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
+import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedSQLSegment;
+
+import javax.xml.bind.annotation.XmlAttribute;
 
 /**
- * Variable segment.
+ * Expected variable segment.
  */
 @Getter
 @Setter
-public final class VariableSegment implements SQLSegment {
-    
-    private int startIndex;
-    
-    private int stopIndex;
+public final class ExpectedVariableSegment extends AbstractExpectedSQLSegment {
     
+    @XmlAttribute
     private String scope;
     
+    @XmlAttribute
     private String variable;
 }
diff --git a/test/it/parser/src/main/resources/case/dml/select-expression.xml 
b/test/it/parser/src/main/resources/case/dml/select-expression.xml
index 574d59db415..4f5c3bb9ac9 100644
--- a/test/it/parser/src/main/resources/case/dml/select-expression.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-expression.xml
@@ -1434,7 +1434,7 @@
             <expr>
                 <binary-operation-expression start-index="28" stop-index="55">
                     <left>
-                        <common-expression text="@@max_connections" 
start-index="28" stop-index="44" />
+                        <variable-segment text="@@max_connections" 
start-index="28" stop-index="44" variable="max_connections" />
                     </left>
                     <operator>&lt;</operator>
                     <right>
diff --git a/test/it/parser/src/main/resources/case/dml/select.xml 
b/test/it/parser/src/main/resources/case/dml/select.xml
index b9a4ad1a2bf..dc3634cf070 100644
--- a/test/it/parser/src/main/resources/case/dml/select.xml
+++ b/test/it/parser/src/main/resources/case/dml/select.xml
@@ -73,6 +73,26 @@
             </expression-projection>
         </projections>
     </select>
+    
+    <select sql-case-id="select_system_variables" >
+        <projections start-index="7" stop-index="121">
+            <expression-projection text="@@session.auto_increment_increment" 
alias="auto_increment_increment" start-index="7" stop-index="65">
+                <expr>
+                    <variable-segment 
text="@@session.auto_increment_increment" start-index="7" stop-index="40" 
scope="session" variable="auto_increment_increment" />
+                </expr>
+            </expression-projection>
+            <expression-projection text="@@global.max_connections" 
alias="max_connections" start-index="68" stop-index="107">
+                <expr>
+                    <variable-segment text="@@global.max_connections" 
start-index="68" stop-index="91" scope="global" variable="max_connections" />
+                </expr>
+            </expression-projection>
+            <expression-projection text="@@autocommit" start-index="110" 
stop-index="121">
+                <expr>
+                    <variable-segment text="@@autocommit" start-index="110" 
stop-index="121" variable="autocommit" />
+                </expr>
+            </expression-projection>
+        </projections>
+    </select>
 
     <select sql-case-id="select_sqlmode_ansi_quotes" >
         <projections start-index="7" stop-index="10">
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/select.xml 
b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
index b3a2ebd9c8e..843d70ca529 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
@@ -21,6 +21,7 @@
     <sql-case id="select_with_operator_ilike" value="SELECT id from t_order 
where name !~ '^pg_toast'" db-types="PostgreSQL,openGauss" />
     <sql-case id="select_with_binary_operation_of_aggregation_expr" 
value="SELECT (count(*)+1) as a" db-types="MySQL" />
     <sql-case id="select_with_schema_func" value="SELECT schema(), database()" 
db-types="MySQL" />
+    <sql-case id="select_system_variables" value="SELECT 
@@session.auto_increment_increment auto_increment_increment, 
@@global.max_connections max_connections, @@autocommit" db-types="MySQL" />
     <sql-case id="select_sqlmode_ansi_quotes" value='select "id" from 
"t_order" where "t_order"."id"=10' db-types="MySQL" />
     <sql-case id="select_with_function_name" value="SELECT current_timestamp" 
db-types="MySQL" />
     <sql-case id="select_with_same_table_name_and_alias" value="SELECT 
t_order.* FROM t_order t_order WHERE user_id = ? AND order_id = ?" />


Reply via email to