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>