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 c25f73fa458 Support parsing MySQL stored procedure syntax - part 8
(#38017)
c25f73fa458 is described below
commit c25f73fa45826006f99c2d7f9dfa3ccf880dd70d
Author: Claire <[email protected]>
AuthorDate: Thu Feb 12 16:29:14 2026 +0800
Support parsing MySQL stored procedure syntax - part 8 (#38017)
* support new statement
* release-notes
* support new function
* release-notes
* release-notes
---
RELEASE-NOTES.md | 1 +
.../src/main/antlr4/imports/mysql/BaseRule.g4 | 2 +-
.../src/main/antlr4/imports/mysql/DDLStatement.g4 | 8 +++--
.../src/main/antlr4/imports/mysql/Literals.g4 | 4 +++
.../src/main/antlr4/imports/mysql/MySQLKeyword.g4 | 4 +++
.../statement/type/MySQLDDLStatementVisitor.java | 9 ++++-
.../main/resources/case/ddl/create-procedure.xml | 39 ++++++++++++++++++++++
.../sql/supported/ddl/create-procedure.xml | 4 +++
8 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 7029301d88c..0f29327e3a4 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -52,6 +52,7 @@
1. SQL Parser: Fix parsing error for SQLServer session `SET QUOTED_IDENTIFIER`
and `SET TEXTSIZE` statements -
[#38005](https://github.com/apache/shardingsphere/pull/38005)
1. SQL Parser: Support '2'::int statement in PostgreSQL and openGauss -
[#37962](https://github.com/apache/shardingsphere/pull/37962)
1. SQL Parser: Support range type constructor functions in PostgreSQL without
quotes - [#37994](https://github.com/apache/shardingsphere/pull/37994)
+1. SQL Parser: Support parsing MySQL stored procedure syntax -
[#38017](https://github.com/apache/shardingsphere/pull/38017)
1. SQL Binder: Support to bind more SQL statements -
[#36697](https://github.com/apache/shardingsphere/pull/36697)
1. SQL Binder: Add ALTER TABLE metadata check -
[#35877](https://github.com/apache/shardingsphere/pull/35877)
1. SQL Binder: Support Grant statement SQL bind -
[#36207](https://github.com/apache/shardingsphere/pull/36207)
diff --git
a/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
b/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
index fb814cec894..342da79612e 100644
--- a/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
+++ b/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
@@ -126,7 +126,7 @@ identifier
unreservedWord
: MAX | MIN | SUM | COUNT | GROUP_CONCAT | CAST | POSITION | SUBSTRING |
SUBSTR | MID | EXTRACT | TRIM | LAST_DAY | TRADITIONAL | TREE | MYSQL_MAIN |
MYSQL_ADMIN | INSTANT | INPLACE | COPY | UL_BINARY | AUTOCOMMIT | REDO_LOG |
DELIMITER | ARCHIVE | BLACKHOLE | CSV | FEDERATED | INNODB | MEMORY |
MRG_MYISAM | MYISAM | NDB | NDBCLUSTER | PERFORMANCE_SCHEMA | TOKUDB
- | ACCESSIBLE | ACCOUNT | ACTION | ACTIVE | ADD | ADMIN | AFTER | AGAINST |
AGGREGATE | ALGORITHM | ALL | ALTER | ALWAYS | ANALYZE | AND | ANY | ARRAY | AS
| ASC | ASCII | ASENSITIVE | AT | ATTRIBUTE | AUTOEXTEND_SIZE | AUTHENTICATION
| AUTO | AUTO_INCREMENT | AVG | ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS |
BIT_XOR | AVG_ROW_LENGTH | BACKUP | BEFORE | BERNOULLI | BEGIN | BETWEEN |
BIGINT | BINARY | BINLOG | BIT | BLOB | BLOCK | BOOL | BOOLEAN | BOTH | BTREE |
BUCKETS | BULK | BY | BYTE [...]
+ | ACCESSIBLE | ACCOUNT | ACTION | ACTIVE | ADD | ADMIN | AFTER | AGAINST |
AGGREGATE | ALGORITHM | ALL | ALTER | ALWAYS | ANALYZE | AND | ANY | ARRAY | AS
| ASC | ASCII | ASENSITIVE | AT | ATTRIBUTE | AUTOEXTEND_SIZE | AUTHENTICATION
| AUTO | AUTO_INCREMENT | AVG | ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS |
BIT_XOR | AVG_ROW_LENGTH | BACKUP | BEFORE | BERNOULLI | BEGIN | BETWEEN |
BIGINT | BINARY | BINLOG | BIT | BLOB | BLOCK | BOOL | BOOLEAN | BOTH | BTREE |
BUCKETS | BULK | BY | BYTE [...]
;
textOrIdentifier
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 59e1d904b9b..0d262774ab1 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
@@ -295,7 +295,7 @@ createProcedure
: CREATE ownerStatement?
PROCEDURE ifNotExists? functionName LP_ procedureParameter? (COMMA_
procedureParameter)* RP_
routineOption*
- routineBody
+ (routineBody | AS dollarQuotedBody)
;
alterProcedure
@@ -655,12 +655,16 @@ serverOption
routineOption
: COMMENT string_
- | LANGUAGE SQL
+ | LANGUAGE (SQL | JAVASCRIPT)
| NOT? DETERMINISTIC
| (CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA)
| SQL SECURITY (DEFINER | INVOKER)
;
+dollarQuotedBody
+ : DOLLAR_QUOTED_TEXT
+ ;
+
procedureParameter
: (IN | OUT | INOUT)? identifier dataType
;
diff --git
a/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/Literals.g4
b/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/Literals.g4
index ae3814a59a5..972896f3733 100644
--- a/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/Literals.g4
+++ b/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/Literals.g4
@@ -69,6 +69,10 @@ BIT_NUM_
: '0b' ('0' | '1')+ | B SQ_ ('0' | '1')+ SQ_
;
+DOLLAR_QUOTED_TEXT
+ : '$$' .*? '$$'
+ ;
+
IDENTIFIER_
:
[A-Za-z_$0-9\u0080-\uFFFF]*?[A-Za-z_$\u0080-\uFFFF]+?[A-Za-z_$0-9\u0080-\uFFFF]*
| BQ_ ~'`'+ BQ_
diff --git
a/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/MySQLKeyword.g4
b/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/MySQLKeyword.g4
index e92fcd5b13f..98101b24610 100644
---
a/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/MySQLKeyword.g4
+++
b/parser/sql/engine/dialect/mysql/src/main/antlr4/imports/mysql/MySQLKeyword.g4
@@ -1171,6 +1171,10 @@ ITERATE
: I T E R A T E
;
+JAVASCRIPT
+ : J A V A S C R I P T
+ ;
+
JOIN
: J O I N
;
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 69e9c41fdee..036cf59ed2c 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
@@ -214,8 +214,11 @@ import java.util.Optional;
*/
public final class MySQLDDLStatementVisitor extends MySQLStatementVisitor
implements DDLStatementVisitor {
+ private final MySQLDALStatementVisitor dalStatementVisitor;
+
public MySQLDDLStatementVisitor(final DatabaseType databaseType) {
super(databaseType);
+ dalStatementVisitor = new MySQLDALStatementVisitor(databaseType);
}
@Override
@@ -759,7 +762,9 @@ public final class MySQLDDLStatementVisitor extends
MySQLStatementVisitor implem
public ASTNode visitCreateProcedure(final CreateProcedureContext ctx) {
CreateProcedureStatement result = new
CreateProcedureStatement(getDatabaseType());
result.setProcedureName((FunctionNameSegment)
visit(ctx.functionName()));
- result.setRoutineBody((RoutineBodySegment) visit(ctx.routineBody()));
+ if (null != ctx.routineBody()) {
+ result.setRoutineBody((RoutineBodySegment)
visit(ctx.routineBody()));
+ }
return result;
}
@@ -859,6 +864,8 @@ 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.setVariable()) {
+ sqlStatement = (SQLStatement)
dalStatementVisitor.visitSetVariable(ctx.setVariable());
} else if (null != ctx.doStatement()) {
sqlStatement = (DoStatement) visit(ctx.doStatement());
} else if (null != ctx.explain()) {
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 b2ae38741fd..2a03eb6dcb3 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
@@ -182,4 +182,43 @@
</sql-statements>
</create-procedure>
<create-procedure sql-case-id="create_procedure_doris_control_flow" />
+ <create-procedure
sql-case-id="create_procedure_keywords_declare_select_into">
+ <procedure-name name="p1" />
+ <sql-statements>
+ <sql-statement start-index="135" stop-index="172"
statement-class-simple-name="SelectStatement" />
+ <sql-statement start-index="174" stop-index="217"
statement-class-simple-name="SelectStatement" />
+ <sql-statement start-index="219" stop-index="282"
statement-class-simple-name="SelectStatement" />
+ <sql-statement start-index="284" stop-index="359"
statement-class-simple-name="SelectStatement" />
+ <sql-statement start-index="361" stop-index="425"
statement-class-simple-name="SelectStatement" />
+ </sql-statements>
+ </create-procedure>
+ <create-procedure sql-case-id="create_procedure_keywords_labeled_while">
+ <procedure-name name="p2" />
+ <sql-statements>
+ <sql-statement start-index="77" stop-index="89"
statement-class-simple-name="SetStatement" />
+ <sql-statement start-index="110" stop-index="119"
statement-class-simple-name="SetStatement" />
+ <sql-statement start-index="142" stop-index="154"
statement-class-simple-name="SetStatement" />
+ <sql-statement start-index="172" stop-index="181"
statement-class-simple-name="SetStatement" />
+ <sql-statement start-index="217" stop-index="229"
statement-class-simple-name="SetStatement" />
+ <sql-statement start-index="260" stop-index="269"
statement-class-simple-name="SetStatement" />
+ <sql-statement start-index="311" stop-index="323"
statement-class-simple-name="SetStatement" />
+ </sql-statements>
+ </create-procedure>
+ <create-procedure sql-case-id="create_procedure_check_warnings">
+ <procedure-name name="check_warnings" />
+ <sql-statements>
+ <sql-statement start-index="108" stop-index="125"
statement-class-simple-name="SetStatement" />
+ <sql-statement start-index="127" stop-index="239"
statement-class-simple-name="UpdateStatement" />
+ <sql-statement start-index="241" stop-index="351"
statement-class-simple-name="UpdateStatement" />
+ <sql-statement start-index="353" stop-index="421"
statement-class-simple-name="SelectStatement" />
+ <sql-statement start-index="449" stop-index="494"
statement-class-simple-name="SelectStatement" />
+ <sql-statement start-index="496" stop-index="516"
statement-class-simple-name="SelectStatement" />
+ <sql-statement start-index="523" stop-index="543"
statement-class-simple-name="SelectStatement" />
+ <sql-statement start-index="553" stop-index="579"
statement-class-simple-name="TruncateStatement" />
+ <sql-statement start-index="581" stop-index="601"
statement-class-simple-name="DropTableStatement" />
+ </sql-statements>
+ </create-procedure>
+ <create-procedure sql-case-id="create_procedure_lib_uses_both">
+ <procedure-name name="lib_uses_both" />
+ </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 1f903eeb05f..5e8114e444f 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
@@ -68,4 +68,8 @@
<sql-case id="create_procedure_with_analyze_table_update" value="CREATE
PROCEDURE p() ANALYZE TABLE v UPDATE HISTOGRAM ON w;" db-types="MySQL"/>
<sql-case id="create_procedure_with_analyze_table" value="CREATE PROCEDURE
p() BEGIN ANALYZE TABLE v; END;" db-types="MySQL"/>
<sql-case id="create_procedure_doris_control_flow" value="CREATE PROCEDURE
doris_proc_control() BEGIN DECLARE a INT DEFAULT 0; IF a = 0 THEN SET a = 1;
ELSE SET a = 2; END IF; WHILE a < 3 DO SET a = a + 1; END WHILE; REPEAT SET
a = a - 1; UNTIL a = 0 END REPEAT; loop_label: LOOP LEAVE loop_label; END LOOP;
CASE a WHEN 0 THEN SET a = 0; ELSE SET a = 1; END CASE; SELECT a; END"
db-types="Doris"/>
+ <sql-case id="create_procedure_keywords_declare_select_into" value="CREATE
PROCEDURE p1() BEGIN DECLARE slow INT; DECLARE general INT; DECLARE
ignore_server_ids INT; DECLARE source_heartbeat_period INT; SELECT max(t1.slow)
INTO slow FROM t1; SELECT max(t1.general) INTO general FROM t1; SELECT
max(t1.ignore_server_ids) INTO ignore_server_ids FROM t1; SELECT
max(t1.source_heartbeat_period) INTO source_heartbeat_period FROM t1; SELECT
slow, general, ignore_server_ids, source_heartbeat_p [...]
+ <sql-case id="create_procedure_keywords_labeled_while" value="CREATE
PROCEDURE p2() BEGIN DECLARE n INT DEFAULT 2; general: WHILE n > 0 DO SET n
= n -1; END WHILE general; SET n = 2; slow: WHILE n > 0 DO SET n = n -1; END
WHILE slow; SET n = 2; ignore_server_ids: WHILE n > 0 DO SET n = n -1; END
WHILE ignore_server_ids; SET n = 2; source_heartbeat_period: WHILE n > 0 DO
SET n = n -1; END WHILE source_heartbeat_period; END" db-types="MySQL" />
+ <sql-case id="create_procedure_check_warnings" value="CREATE
DEFINER=root@localhost PROCEDURE check_warnings(OUT result INT) BEGIN DECLARE
`pos` bigint unsigned; SET SQL_LOG_BIN=0; UPDATE error_log el,
global_suppressions gs SET suspicious=0 WHERE el.suspicious=1 AND el.line
REGEXP gs.pattern; UPDATE error_log el, test_suppressions ts SET suspicious=0
WHERE el.suspicious=1 AND el.line REGEXP ts.pattern; SELECT COUNT(*) INTO
@num_warnings FROM error_log WHERE suspicious=1; IF @num_war [...]
+ <sql-case id="create_procedure_lib_uses_both" value="CREATE PROCEDURE
lib_uses_both() LANGUAGE JAVASCRIPT AS $$ console.log("Hello world")
$$" db-types="MySQL" />
</sql-cases>