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

jianbin pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git


The following commit(s) were added to refs/heads/2.x by this push:
     new cbc6ac5ad0 optimize: Druid SQL parser throws ParserException for 
unsupported REPLACE statement (#7456)
cbc6ac5ad0 is described below

commit cbc6ac5ad0aa89e0085d06817f995b6bf949d767
Author: maple <gsk525...@163.com>
AuthorDate: Mon Jun 23 14:46:12 2025 +0800

    optimize: Druid SQL parser throws ParserException for unsupported REPLACE 
statement (#7456)
---
 changes/en-us/2.x.md                               |  1 +
 changes/zh-cn/2.x.md                               |  1 +
 .../druid/DruidSQLRecognizerFactoryImpl.java       | 56 +++++++++++++++-------
 .../druid/DruidSQLRecognizerFactoryTest.java       |  8 +---
 4 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index 483bcd2b67..e78723e74f 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -61,6 +61,7 @@ Add changes here for all PR submitted to the 2.x branch.
 - [[#7445](https://github.com/apache/incubator-seata/pull/7432)] separate the 
license from the server and namingserver
 - [[#7426](https://github.com/apache/incubator-seata/pull/7426)] add some 
license header
 - [[#7450](https://github.com/apache/incubator-seata/pull/7450)] Apply 
Spotless to the entire codebase
+- [[#7456](https://github.com/apache/incubator-seata/pull/7456)] Druid SQL 
parser throws ParserException for unsupported REPLACE statement
 
 
 ### security:
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index 29bb3d6c75..18bb174686 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -60,6 +60,7 @@
 - [[#7445](https://github.com/apache/incubator-seata/pull/7432)] 
分离license到server和namingserver
 - [[#7426](https://github.com/apache/incubator-seata/pull/7426)] 添加 license 
header
 - [[#7450](https://github.com/apache/incubator-seata/pull/7450)] 将 Spotless 
应用于整个代码库
+- [[#7456](https://github.com/apache/incubator-seata/pull/7456)] Druid SQL 
解析器因不支持的 REPLACE 语句而抛出 ParserException
 
 
 ### security:
diff --git 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/DruidSQLRecognizerFactoryImpl.java
 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/DruidSQLRecognizerFactoryImpl.java
index d4ee5a5361..02d8ada742 100644
--- 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/DruidSQLRecognizerFactoryImpl.java
+++ 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/DruidSQLRecognizerFactoryImpl.java
@@ -38,36 +38,48 @@ import java.util.List;
 class DruidSQLRecognizerFactoryImpl implements SQLRecognizerFactory {
     @Override
     public List<SQLRecognizer> create(String sql, String dbType) {
-        List<SQLStatement> asts = SQLUtils.parseStatements(sql, 
DruidDbTypeAdapter.getAdaptiveDbType(dbType));
-        if (CollectionUtils.isEmpty(asts)) {
+        List<SQLStatement> sqlStatements;
+        try {
+            sqlStatements = SQLUtils.parseStatements(sql, 
DruidDbTypeAdapter.getAdaptiveDbType(dbType));
+        } catch (RuntimeException e) {
+            if (isParserException(e)) {
+                throw new NotSupportYetException(
+                        "not support the sql syntax: " + sql
+                                + "\nplease see the doc about SQL restrictions 
https://seata.apache.org/zh-cn/docs/user/sqlreference/dml";,
+                        e);
+            }
+            throw e;
+        }
+
+        if (CollectionUtils.isEmpty(sqlStatements)) {
             throw new UnsupportedOperationException("Unsupported SQL: " + sql);
         }
-        if (asts.size() > 1
-                && !(asts.stream().allMatch(statement -> statement instanceof 
SQLUpdateStatement)
-                        || asts.stream().allMatch(statement -> statement 
instanceof SQLDeleteStatement))) {
+        if (sqlStatements.size() > 1
+                && !(sqlStatements.stream().allMatch(statement -> statement 
instanceof SQLUpdateStatement)
+                        || sqlStatements.stream().allMatch(statement -> 
statement instanceof SQLDeleteStatement))) {
             throw new UnsupportedOperationException("ONLY SUPPORT SAME TYPE 
(UPDATE OR DELETE) MULTI SQL -" + sql);
         }
         List<SQLRecognizer> recognizers = null;
         SQLRecognizer recognizer = null;
-        for (SQLStatement ast : asts) {
+        for (SQLStatement sqlStatement : sqlStatements) {
             SQLOperateRecognizerHolder recognizerHolder =
                     
SQLOperateRecognizerHolderFactory.getSQLRecognizerHolder(dbType.toLowerCase());
-            if (ast instanceof SQLInsertStatement) {
-                recognizer = recognizerHolder.getInsertRecognizer(sql, ast);
-            } else if (ast instanceof SQLUpdateStatement) {
-                recognizer = recognizerHolder.getUpdateRecognizer(sql, ast);
-            } else if (ast instanceof SQLDeleteStatement) {
-                recognizer = recognizerHolder.getDeleteRecognizer(sql, ast);
-            } else if (ast instanceof SQLSelectStatement) {
-                recognizer = 
recognizerHolder.getSelectForUpdateRecognizer(sql, ast);
+            if (sqlStatement instanceof SQLInsertStatement) {
+                recognizer = recognizerHolder.getInsertRecognizer(sql, 
sqlStatement);
+            } else if (sqlStatement instanceof SQLUpdateStatement) {
+                recognizer = recognizerHolder.getUpdateRecognizer(sql, 
sqlStatement);
+            } else if (sqlStatement instanceof SQLDeleteStatement) {
+                recognizer = recognizerHolder.getDeleteRecognizer(sql, 
sqlStatement);
+            } else if (sqlStatement instanceof SQLSelectStatement) {
+                recognizer = 
recognizerHolder.getSelectForUpdateRecognizer(sql, sqlStatement);
             }
 
             // When recognizer is null, it indicates that recognizerHolder 
cannot allocate unsupported syntax, like
             // merge and replace
-            if (ast instanceof SQLReplaceStatement) {
+            if (sqlStatement instanceof SQLReplaceStatement) {
                 // just like:replace into t (id,dr) values (1,'2'), (2,'3')
                 throw new NotSupportYetException(
-                        "not support the sql syntax with ReplaceStatement:" + 
ast
+                        "not support the sql syntax with ReplaceStatement:" + 
sqlStatement
                                 + "\nplease see the doc about SQL restrictions 
https://seata.apache.org/zh-cn/docs/user/sqlreference/dml";);
             }
 
@@ -80,4 +92,16 @@ class DruidSQLRecognizerFactoryImpl implements 
SQLRecognizerFactory {
         }
         return recognizers;
     }
+
+    /**
+     * Check if the exception is a Druid ParserException
+     * Use class name comparison to avoid directly referencing the 
ParserException class
+     */
+    private boolean isParserException(Throwable e) {
+        if (e == null) {
+            return false;
+        }
+        String className = e.getClass().getName();
+        return 
"com.alibaba.druid.sql.parser.ParserException".equals(className);
+    }
 }
diff --git 
a/sqlparser/seata-sqlparser-druid/src/test/java/org/apache/seata/sqlparser/druid/DruidSQLRecognizerFactoryTest.java
 
b/sqlparser/seata-sqlparser-druid/src/test/java/org/apache/seata/sqlparser/druid/DruidSQLRecognizerFactoryTest.java
index 7666638813..741e411d90 100644
--- 
a/sqlparser/seata-sqlparser-druid/src/test/java/org/apache/seata/sqlparser/druid/DruidSQLRecognizerFactoryTest.java
+++ 
b/sqlparser/seata-sqlparser-druid/src/test/java/org/apache/seata/sqlparser/druid/DruidSQLRecognizerFactoryTest.java
@@ -166,13 +166,7 @@ public class DruidSQLRecognizerFactoryTest {
                 NotSupportYetException.class, () -> 
recognizerFactory.create(sql3, JdbcConstants.MARIADB));
         Assertions.assertThrows(
                 NotSupportYetException.class, () -> 
recognizerFactory.create(sql3, JdbcConstants.POLARDBX));
-
-        // When dbtype are DM and SQLSERVER, druid cannot parse the sql syntax 
'replace'
-        try {
-            recognizerFactory.create(sql3, JdbcConstants.DM);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+        Assertions.assertThrows(NotSupportYetException.class, () -> 
recognizerFactory.create(sql3, JdbcConstants.DM));
 
         String sql5 = "insert into a select * from b";
         Assertions.assertThrows(


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org
For additional commands, e-mail: notifications-h...@seata.apache.org

Reply via email to