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

zhangliang 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 f14047bc68c Support for the explain and do keywords in Stored 
Procedures (#37376)
f14047bc68c is described below

commit f14047bc68c638bf67c1fa40f297fb71c6d74ada
Author: cxy <[email protected]>
AuthorDate: Mon Dec 15 17:38:33 2025 +0800

    Support for the explain and do keywords in Stored Procedures (#37376)
    
    * Support for the explain and do keywords in Stored Procedures
    
    * Support for the explain and do keywords in Stored Procedures
    
    * Support for the explain and do keywords in Stored Procedures
    
    * Support for the explain and do keywords in Stored Procedures
---
 .../src/main/antlr4/imports/mysql/DDLStatement.g4  |  2 +-
 .../statement/type/MySQLDDLStatementVisitor.java   | 54 ++++++++++++++++++++++
 .../main/resources/case/ddl/create-procedure.xml   | 26 +++++++++++
 .../sql/supported/ddl/create-procedure.xml         |  4 ++
 4 files changed, 85 insertions(+), 1 deletion(-)

diff --git 
a/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/DDLStatement.g4 
b/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/DDLStatement.g4
index ae78ec4c370..2329c6c66bc 100644
--- 
a/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/DDLStatement.g4
+++ 
b/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/DDLStatement.g4
@@ -683,7 +683,7 @@ validStatement
     | createView | prepare | executeStmt | commit | deallocate
     | setVariable | beginStatement | declareStatement | flowControlStatement | 
cursorStatement | conditionHandlingStatement
     | setStatement | showStatement | showCreateTable | startTransaction | 
rollback | commit | show
-    | alterEvent | dropEvent) SEMI_?
+    | alterEvent | dropEvent | doStatement | explain) SEMI_?
     ;
 
 showStatement
diff --git 
a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
 
b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
index 9284b644a95..1d06f158fba 100644
--- 
a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
+++ 
b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
@@ -109,6 +109,8 @@ import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TextOrI
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TruncateTableContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ValidStatementContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WhileStatementContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.DoStatementContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ExplainContext;
 import 
org.apache.shardingsphere.sql.parser.engine.mysql.visitor.statement.MySQLStatementVisitor;
 import 
org.apache.shardingsphere.sql.parser.statement.core.enums.AlgorithmOption;
 import 
org.apache.shardingsphere.sql.parser.statement.core.enums.LockTableOption;
@@ -150,7 +152,9 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.Comme
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.DataTypeSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dal.ExplainStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.DeallocateStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.ExecuteStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.PrepareStatement;
@@ -185,6 +189,7 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.De
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.InsertStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.UpdateStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.DoStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.core.value.collection.CollectionValue;
 import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 import 
org.apache.shardingsphere.sql.parser.statement.mysql.ddl.event.MySQLAlterEventStatement;
@@ -194,6 +199,7 @@ import 
org.apache.shardingsphere.sql.parser.statement.mysql.ddl.instance.MySQLAl
 import 
org.apache.shardingsphere.sql.parser.statement.mysql.ddl.logfile.MySQLAlterLogfileGroupStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.mysql.ddl.logfile.MySQLCreateLogfileGroupStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.mysql.ddl.logfile.MySQLDropLogfileGroupStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.mysql.dal.show.column.MySQLDescribeStatement;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -851,11 +857,59 @@ public final class MySQLDDLStatementVisitor extends 
MySQLStatementVisitor implem
             sqlStatement = (DeleteStatement) visit(ctx.delete());
         } else if (null != ctx.select()) {
             sqlStatement = (SelectStatement) visit(ctx.select());
+        } else if (null != ctx.doStatement()) {
+            sqlStatement = (DoStatement) visit(ctx.doStatement());
+        } else if (null != ctx.explain()) {
+            sqlStatement = (SQLStatement) visit(ctx.explain());
         }
         result.setSqlStatement(sqlStatement);
         return result;
     }
     
+    @Override
+    public ASTNode visitDoStatement(final DoStatementContext ctx) {
+        List<ExpressionSegment> expressions = new LinkedList<>();
+        for (int i = 0; i < ctx.expr().size(); i++) {
+            expressions.add((ExpressionSegment) visit(ctx.expr(i)));
+        }
+        return new DoStatement(getDatabaseType(), expressions);
+    }
+    
+    @Override
+    public ASTNode visitExplain(final ExplainContext ctx) {
+        return null == ctx.tableName() ? new 
ExplainStatement(getDatabaseType(), 
getExplainableSQLStatement(ctx).orElse(null))
+                : new MySQLDescribeStatement(getDatabaseType(), 
(SimpleTableSegment) visit(ctx.tableName()), getColumnWildcard(ctx));
+    }
+    
+    private Optional<SQLStatement> getExplainableSQLStatement(final 
ExplainContext ctx) {
+        if (null != ctx.explainableStatement()) {
+            return Optional.of((SQLStatement) 
visit(ctx.explainableStatement()));
+        }
+        if (null != ctx.select()) {
+            return Optional.of((SQLStatement) visit(ctx.select()));
+        }
+        if (null != ctx.delete()) {
+            return Optional.of((SQLStatement) visit(ctx.delete()));
+        }
+        if (null != ctx.update()) {
+            return Optional.of((SQLStatement) visit(ctx.update()));
+        }
+        if (null != ctx.insert()) {
+            return Optional.of((SQLStatement) visit(ctx.insert()));
+        }
+        return Optional.empty();
+    }
+    
+    private ColumnSegment getColumnWildcard(final ExplainContext ctx) {
+        if (null != ctx.columnRef()) {
+            return (ColumnSegment) visit(ctx.columnRef());
+        }
+        if (null != ctx.textString()) {
+            return (ColumnSegment) visit(ctx.textString());
+        }
+        return null;
+    }
+    
     @SuppressWarnings("unchecked")
     @Override
     public ASTNode visitFlowControlStatement(final FlowControlStatementContext 
ctx) {
diff --git a/test/it/parser/src/main/resources/case/ddl/create-procedure.xml 
b/test/it/parser/src/main/resources/case/ddl/create-procedure.xml
index 3a61e85bdca..1113a9375c5 100644
--- a/test/it/parser/src/main/resources/case/ddl/create-procedure.xml
+++ b/test/it/parser/src/main/resources/case/ddl/create-procedure.xml
@@ -143,4 +143,30 @@
             <sql-statement start-index="28" stop-index="40" 
statement-class-simple-name="MySQLDropEventStatement" />
         </sql-statements>
     </create-procedure>
+    <create-procedure sql-case-id="create_procedure_with_begin_explain">
+        <procedure-name name="sub1" />
+        <sql-statements>
+            <sql-statement start-index="63" stop-index="128" 
statement-class-simple-name="SelectStatement" />
+            <sql-statement start-index="131" stop-index="204" 
statement-class-simple-name="ExplainStatement" />
+        </sql-statements>
+    </create-procedure>
+    <create-procedure sql-case-id="create_procedure_with_begin_do">
+        <procedure-name name="t_sysdate" />
+        <sql-statements>
+            <sql-statement start-index="35" stop-index="58" 
statement-class-simple-name="SelectStatement" />
+            <sql-statement start-index="61" stop-index="71" 
statement-class-simple-name="DoStatement" />
+        </sql-statements>
+    </create-procedure>
+    <create-procedure sql-case-id="create_procedure_with_describe_table">
+        <procedure-name name="p1" />
+        <sql-statements>
+            <sql-statement start-index="28" stop-index="39" 
statement-class-simple-name="MySQLDescribeStatement" />
+        </sql-statements>
+    </create-procedure>
+    <create-procedure sql-case-id="create_procedure_with_explain_table">
+        <procedure-name name="p1" />
+        <sql-statements>
+            <sql-statement start-index="28" stop-index="38" 
statement-class-simple-name="MySQLDescribeStatement" />
+        </sql-statements>
+    </create-procedure>
 </sql-parser-test-cases>
diff --git 
a/test/it/parser/src/main/resources/sql/supported/ddl/create-procedure.xml 
b/test/it/parser/src/main/resources/sql/supported/ddl/create-procedure.xml
index 6694eaa42de..70f31a75061 100644
--- a/test/it/parser/src/main/resources/sql/supported/ddl/create-procedure.xml
+++ b/test/it/parser/src/main/resources/sql/supported/ddl/create-procedure.xml
@@ -61,4 +61,8 @@
     <sql-case id="create_procedure_with_custom_collation_and_insert" 
value="create procedure p () begin declare a varchar(1) charset utf8mb4 collate 
utf8mb4_test_ci; set @a = 'a' collate utf8mb4_test_ci; create table tp (t 
varchar(1) collate utf8mb4_test_ci); insert into t values (@a); end;" 
db-types="MySQL"/>
     <sql-case id="create_procedure_with_alter_event" value="create procedure 
p1() begin alter event e1 rename to e2; end;" db-types="MySQL"/>
     <sql-case id="create_procedure_with_drop_event" value="create procedure 
p1() begin drop event e1; end;" db-types="MySQL"/>
+    <sql-case id="create_procedure_with_begin_explain" value="CREATE PROCEDURE 
sub1(id CHAR(10) CHARACTER SET utf8mb3) BEGIN SELECT * FROM view1 WHERE 
table_name=id COLLATE utf8mb3_tolower_ci; EXPLAIN SELECT * FROM view1 WHERE 
table_name=id COLLATE utf8mb3_tolower_ci; END" db-types="MySQL"/>
+    <sql-case id="create_procedure_with_begin_do" value="create procedure 
t_sysdate() begin select sysdate() into @a; do sleep(2); end;" 
db-types="MySQL"/>
+    <sql-case id="create_procedure_with_describe_table" value="create 
procedure p1() begin describe t1; end;" db-types="MySQL"/>
+    <sql-case id="create_procedure_with_explain_table" value="create procedure 
p1() begin explain t1; end;" db-types="MySQL"/>
 </sql-cases>

Reply via email to