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 340ea9218c optimize: When the number of primary keys exceeds 1000, use 
union to concatenate the SQL #6957 (#7012)
340ea9218c is described below

commit 340ea9218cf2616d4cea3fc74e75632fcd284137
Author: remind <[email protected]>
AuthorDate: Wed Dec 25 15:01:11 2024 +0800

    optimize: When the number of primary keys exceeds 1000, use union to 
concatenate the SQL #6957 (#7012)
---
 changes/en-us/2.x.md                               |  2 +
 changes/zh-cn/2.x.md                               |  2 +
 .../rm/datasource/mock/MockExecuteHandlerImpl.java |  2 +-
 .../seata/rm/datasource/SqlGenerateUtils.java      | 86 ++++++++++++++++++----
 .../datasource/exec/BaseTransactionalExecutor.java |  5 +-
 .../rm/datasource/exec/MultiUpdateExecutor.java    |  7 +-
 .../seata/rm/datasource/exec/UpdateExecutor.java   |  8 +-
 .../exec/mysql/MySQLUpdateJoinExecutor.java        | 10 +--
 .../rm/datasource/undo/AbstractUndoExecutor.java   | 46 ++++++------
 .../seata/rm/datasource/SqlGenerateUtilsTest.java  | 47 ++++++++----
 .../rm/datasource/exec/UpdateJoinExecutorTest.java |  3 +-
 .../rm/datasource/mock/MockExecuteHandlerImpl.java |  2 +-
 .../datasource/undo/AbstractUndoExecutorTest.java  | 24 +++---
 .../druid/dm/DmSelectForUpdateRecognizer.java      |  2 +-
 .../mysql/MySQLSelectForUpdateRecognizer.java      |  2 +-
 .../oracle/OracleSelectForUpdateRecognizer.java    |  2 +-
 .../PostgresqlSelectForUpdateRecognizer.java       |  2 +-
 .../SqlServerOperateRecognizerHolder.java          |  2 +-
 18 files changed, 165 insertions(+), 89 deletions(-)

diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index 6156d31007..4f725b4c96 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -13,6 +13,7 @@ Add changes here for all PR submitted to the 2.x branch.
 ### optimize:
 
 - [[#6828](https://github.com/apache/incubator-seata/pull/6828)] spring boot 
compatible with file.conf and registry.conf
+- [[#7012](https://github.com/apache/incubator-seata/pull/7012)] When the 
number of primary keys exceeds 1000, use union to concatenate the SQL
 
 ### security:
 
@@ -32,5 +33,6 @@ Thanks to these contributors for their code commits. Please 
report an unintended
 
 - [slievrly](https://github.com/slievrly)
 - [lyl2008dsg](https://github.com/lyl2008dsg)
+- [remind](https://github.com/remind)
 
 Also, we receive many valuable issues, questions and advices from our 
community. Thanks for you all.
\ No newline at end of file
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index 0b91dae095..dc2be11967 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -13,6 +13,7 @@
 ### optimize:
 
 - [[#6828](https://github.com/apache/incubator-seata/pull/6828)] 
seata-spring-boot-starter兼容file.conf和registry.conf
+- [[#7012](https://github.com/apache/incubator-seata/pull/7012)] 
当主键超过1000个时,使用union拼接sql,可以使用索引
 
 ### security:
 
@@ -32,5 +33,6 @@
 
 - [slievrly](https://github.com/slievrly)
 - [lyl2008dsg](https://github.com/lyl2008dsg)
+- [remind](https://github.com/remind)
 
 同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。
\ No newline at end of file
diff --git 
a/compatible/src/test/java/io/seata/rm/datasource/mock/MockExecuteHandlerImpl.java
 
b/compatible/src/test/java/io/seata/rm/datasource/mock/MockExecuteHandlerImpl.java
index 6739869493..abbd81edce 100644
--- 
a/compatible/src/test/java/io/seata/rm/datasource/mock/MockExecuteHandlerImpl.java
+++ 
b/compatible/src/test/java/io/seata/rm/datasource/mock/MockExecuteHandlerImpl.java
@@ -71,7 +71,7 @@ public class MockExecuteHandlerImpl implements 
MockExecuteHandler {
         List<Object[]> metas = new ArrayList<>();
         if(asts.get(0) instanceof SQLSelectStatement) {
             SQLSelectStatement ast = (SQLSelectStatement) asts.get(0);
-            SQLSelectQueryBlock queryBlock = ast.getSelect().getQueryBlock();
+            SQLSelectQueryBlock queryBlock = 
ast.getSelect().getFirstQueryBlock();
             String tableName = "";
             if (queryBlock.getFrom() instanceof SQLExprTableSource) {
                 MySQLSelectForUpdateRecognizer recognizer = new 
MySQLSelectForUpdateRecognizer(sql, ast);
diff --git 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/SqlGenerateUtils.java
 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/SqlGenerateUtils.java
index 90d61226f3..04b7b5b89c 100644
--- 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/SqlGenerateUtils.java
+++ 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/SqlGenerateUtils.java
@@ -18,8 +18,10 @@ package org.apache.seata.rm.datasource;
 
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.StringJoiner;
 
 import org.apache.seata.rm.datasource.sql.struct.Field;
 import org.apache.seata.sqlparser.util.ColumnUtils;
@@ -36,32 +38,51 @@ public class SqlGenerateUtils {
 
     }
 
-    public static String buildWhereConditionByPKs(List<String> pkNameList, int 
rowSize, String dbType)
-        throws SQLException {
-        return buildWhereConditionByPKs(pkNameList, rowSize, dbType, 
MAX_IN_SIZE);
-
+    /**
+     * build full sql by pks.
+     * @param sqlPrefix sql prefix
+     * @param suffix sql suffix
+     * @param pkNameList pk column name list
+     * @param rowSize the row size of records
+     * @param dbType the type of database
+     * @return full sql
+     */
+    public static String buildSQLByPKs(String sqlPrefix, String suffix, 
List<String> pkNameList, int rowSize, String dbType) {
+        List<WhereSql> whereList = buildWhereConditionListByPKs(pkNameList, 
rowSize, dbType, MAX_IN_SIZE);
+        StringJoiner sqlJoiner = new StringJoiner(" UNION ");
+        whereList.forEach(whereSql -> sqlJoiner.add(sqlPrefix + " " + 
whereSql.getSql() + " " + suffix));
+        return sqlJoiner.toString();
     }
     /**
-     * each pk is a condition.the result will like :" (id,userCode) in 
((?,?),(?,?)) or (id,userCode) in ((?,?),(?,?)
-     * ) or (id,userCode) in ((?,?))"
+     * each pk is a condition.the result will like :" [(id,userCode) in 
((?,?),(?,?)), (id,userCode) in ((?,?),(?,?)
+     * ), (id,userCode) in ((?,?))]"
+     * Build where condition by pks string. size default MAX_IN_SIZE
+     *
+     * @param pkNameList pk column name list
+     * @param rowSize    the row size of records
+     * @param dbType     the type of database
+     * @return return where condition sql list.the sql can search all related 
records not just one.
+     */
+    public static List<WhereSql> buildWhereConditionListByPKs(List<String> 
pkNameList, int rowSize, String dbType) {
+        return buildWhereConditionListByPKs(pkNameList, rowSize, dbType, 
MAX_IN_SIZE);
+    }
+    /**
+     * each pk is a condition.the result will like :" [(id,userCode) in 
((?,?),(?,?)), (id,userCode) in ((?,?),(?,?)
+     * ), (id,userCode) in ((?,?))]"
      * Build where condition by pks string.
      *
      * @param pkNameList pk column name list
      * @param rowSize    the row size of records
      * @param dbType     the type of database
      * @param maxInSize  the max in size
-     * @return return where condition sql string.the sql can search all 
related records not just one.
-     * @throws SQLException the sql exception
+     * @return return where condition sql list.the sql can search all related 
records not just one.
      */
-    public static String buildWhereConditionByPKs(List<String> pkNameList, int 
rowSize, String dbType, int maxInSize)
-        throws SQLException {
-        StringBuilder whereStr = new StringBuilder();
+    public static List<WhereSql> buildWhereConditionListByPKs(List<String> 
pkNameList, int rowSize, String dbType, int maxInSize) {
+        List<WhereSql> whereSqls = new ArrayList<>();
         //we must consider the situation of composite primary key
         int batchSize = rowSize % maxInSize == 0 ? rowSize / maxInSize : 
(rowSize / maxInSize) + 1;
         for (int batch = 0; batch < batchSize; batch++) {
-            if (batch > 0) {
-                whereStr.append(" or ");
-            }
+            StringBuilder whereStr = new StringBuilder();
             whereStr.append("(");
             for (int i = 0; i < pkNameList.size(); i++) {
                 if (i > 0) {
@@ -88,9 +109,10 @@ public class SqlGenerateUtils {
                 whereStr.append(")");
             }
             whereStr.append(" )");
+            whereSqls.add(new WhereSql(whereStr.toString(), eachSize, 
pkNameList.size()));
         }
 
-        return whereStr.toString();
+        return whereSqls;
     }
 
     /**
@@ -135,4 +157,38 @@ public class SqlGenerateUtils {
         return whereStr.toString();
     }
 
+    public static class WhereSql {
+        /**
+         * sql
+         */
+        private final String sql;
+
+        /**
+         * row size
+         */
+        private final int rowSize;
+
+        /**
+         * pk size
+         */
+        private final int pkSize;
+
+        public WhereSql(String sql, int rowSize, int pkSize) {
+            this.sql = sql;
+            this.rowSize = rowSize;
+            this.pkSize = pkSize;
+        }
+
+        public String getSql() {
+            return sql;
+        }
+
+        public int getRowSize() {
+            return rowSize;
+        }
+
+        public int getPkSize() {
+            return pkSize;
+        }
+    }
 }
diff --git 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/BaseTransactionalExecutor.java
 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/BaseTransactionalExecutor.java
index 742f389410..de2ab8883c 100644
--- 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/BaseTransactionalExecutor.java
+++ 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/BaseTransactionalExecutor.java
@@ -520,16 +520,17 @@ public abstract class BaseTransactionalExecutor<T, S 
extends Statement> implemen
         // build check sql
         String firstKey = pkValuesMap.keySet().stream().findFirst().get();
         int rowSize = pkValuesMap.get(firstKey).size();
-        
suffix.append(WHERE).append(SqlGenerateUtils.buildWhereConditionByPKs(pkColumnNameList,
 rowSize, getDbType()));
+        suffix.append(WHERE);
         StringJoiner selectSQLJoin = new StringJoiner(", ", prefix, 
suffix.toString());
         List<String> insertColumnsUnEscape = 
recognizer.getInsertColumnsUnEscape();
         List<String> needColumns =
             getNeedColumns(tableMeta.getTableName(), 
sqlRecognizer.getTableAlias(), insertColumnsUnEscape);
         needColumns.forEach(selectSQLJoin::add);
         PreparedStatement ps = null;
+        String sqlStr = 
SqlGenerateUtils.buildSQLByPKs(selectSQLJoin.toString(), "", pkColumnNameList, 
rowSize, getDbType());
         ResultSet rs = null;
         try {
-            ps = 
statementProxy.getConnection().prepareStatement(selectSQLJoin.toString());
+            ps = statementProxy.getConnection().prepareStatement(sqlStr);
             int paramIndex = 1;
             for (int r = 0; r < rowSize; r++) {
                 for (int c = 0; c < pkColumnNameList.size(); c++) {
diff --git 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/MultiUpdateExecutor.java
 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/MultiUpdateExecutor.java
index 886e2d2d09..242be23b52 100644
--- 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/MultiUpdateExecutor.java
+++ 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/MultiUpdateExecutor.java
@@ -147,9 +147,8 @@ public class MultiUpdateExecutor<T, S extends Statement> 
extends AbstractDMLBase
             SQLUpdateRecognizer sqlUpdateRecognizer = (SQLUpdateRecognizer) 
sqlRecognizer;
             
updateColumnsSet.addAll(sqlUpdateRecognizer.getUpdateColumnsUnEscape());
         }
-        StringBuilder prefix = new StringBuilder("SELECT ");
-        String suffix = " FROM " + getFromTableInSQL() + " WHERE " + 
SqlGenerateUtils.buildWhereConditionByPKs(tableMeta.getPrimaryKeyOnlyName(), 
beforeImage.pkRows().size(), getDbType());
-        StringJoiner selectSQLJoiner = new StringJoiner(", ", 
prefix.toString(), suffix);
+        StringJoiner selectSQLJoiner = new StringJoiner(", ", "SELECT ",
+                " FROM " + getFromTableInSQL() + " WHERE ");
         if (ONLY_CARE_UPDATE_COLUMNS) {
             if (!containsPK(new ArrayList<>(updateColumnsSet))) {
                 
selectSQLJoiner.add(getColumnNamesInSQL(tableMeta.getEscapePkNameList(getDbType())));
@@ -162,7 +161,7 @@ public class MultiUpdateExecutor<T, S extends Statement> 
extends AbstractDMLBase
                 selectSQLJoiner.add(ColumnUtils.addEscape(columnName, 
getDbType()));
             }
         }
-        return selectSQLJoiner.toString();
+        return SqlGenerateUtils.buildSQLByPKs(selectSQLJoiner.toString(), "", 
tableMeta.getPrimaryKeyOnlyName(), beforeImage.pkRows().size(), getDbType());
     }
 
     protected String buildSuffixSql(String whereCondition) {
diff --git 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/UpdateExecutor.java
 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/UpdateExecutor.java
index 5459f13abb..2f75245463 100644
--- 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/UpdateExecutor.java
+++ 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/UpdateExecutor.java
@@ -113,14 +113,12 @@ public class UpdateExecutor<T, S extends Statement> 
extends AbstractDMLBaseExecu
     }
 
     private String buildAfterImageSQL(TableMeta tableMeta, TableRecords 
beforeImage) throws SQLException {
-        String prefix = "SELECT ";
-        String whereSql = 
SqlGenerateUtils.buildWhereConditionByPKs(tableMeta.getPrimaryKeyOnlyName(), 
beforeImage.pkRows().size(), getDbType());
-        String suffix = " FROM " + getFromTableInSQL() + " WHERE " + whereSql;
-        StringJoiner selectSQLJoiner = new StringJoiner(", ", prefix, suffix);
+        StringJoiner selectSQLJoiner = new StringJoiner(", ", "SELECT "
+                , " FROM " + getFromTableInSQL() + " WHERE ");
         SQLUpdateRecognizer recognizer = (SQLUpdateRecognizer) sqlRecognizer;
         List<String> needUpdateColumns = 
getNeedColumns(tableMeta.getTableName(), sqlRecognizer.getTableAlias(), 
recognizer.getUpdateColumnsUnEscape());
         needUpdateColumns.forEach(selectSQLJoiner::add);
-        return selectSQLJoiner.toString();
+        return SqlGenerateUtils.buildSQLByPKs(selectSQLJoiner.toString(), "", 
tableMeta.getPrimaryKeyOnlyName(), beforeImage.pkRows().size(), getDbType());
     }
 
 }
diff --git 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java
 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java
index bea122bcb4..95144967e2 100644
--- 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java
+++ 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java
@@ -199,18 +199,12 @@ public class MySQLUpdateJoinExecutor<T, S extends 
Statement> extends UpdateExecu
         TableRecords beforeImage) throws SQLException {
         SQLUpdateRecognizer recognizer = (SQLUpdateRecognizer) sqlRecognizer;
         TableMeta itemTableMeta = getTableMeta(itemTable);
-        StringBuilder prefix = new StringBuilder("SELECT ");
         List<String> pkColumns = getColumnNamesWithTablePrefixList(itemTable, 
recognizer.getTableAlias(itemTable), itemTableMeta.getPrimaryKeyOnlyName());
-        String whereSql = SqlGenerateUtils.buildWhereConditionByPKs(pkColumns, 
beforeImage.pkRows().size(), getDbType());
-        String suffix = " FROM " + joinTable + " WHERE " + whereSql;
-        //maybe duplicate row for select join sql.remove duplicate row by 
'group by' condition
-        suffix += GROUP_BY;
         List<String> itemTableUpdateColumns = 
getItemUpdateColumns(itemTableMeta, recognizer.getUpdateColumns());
         List<String> needUpdateColumns = getNeedColumns(itemTable, 
recognizer.getTableAlias(itemTable), itemTableUpdateColumns);
-        suffix += buildGroupBy(pkColumns, needUpdateColumns);
-        StringJoiner selectSQLJoiner = new StringJoiner(", ", 
prefix.toString(), suffix);
+        StringJoiner selectSQLJoiner = new StringJoiner(", ", "SELECT ", " 
FROM " + joinTable + " WHERE ");
         needUpdateColumns.forEach(selectSQLJoiner::add);
-        return selectSQLJoiner.toString();
+        return SqlGenerateUtils.buildSQLByPKs(selectSQLJoiner.toString(), 
GROUP_BY + buildGroupBy(pkColumns, needUpdateColumns), pkColumns, 
beforeImage.pkRows().size(), getDbType());
     }
 
     private List<String> getItemUpdateColumns(TableMeta itemTableMeta, 
List<String> updateColumns) {
diff --git 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/undo/AbstractUndoExecutor.java
 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/undo/AbstractUndoExecutor.java
index d964c5469c..538c811478 100644
--- 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/undo/AbstractUndoExecutor.java
+++ 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/undo/AbstractUndoExecutor.java
@@ -309,30 +309,32 @@ public abstract class AbstractUndoExecutor {
         // build check sql
         String firstKey = pkRowValues.keySet().stream().findFirst().get();
         int pkRowSize = pkRowValues.get(firstKey).size();
-        String checkSQL = buildCheckSql(sqlUndoLog.getTableName(),
-                SqlGenerateUtils.buildWhereConditionByPKs(pkNameList, 
pkRowSize, connectionProxy.getDbType()));
-
-        PreparedStatement statement = null;
-        ResultSet checkSet = null;
-        TableRecords currentRecords;
-        try {
-            statement = conn.prepareStatement(checkSQL);
-            int paramIndex = 1;
-            int rowSize = pkRowValues.get(pkNameList.get(0)).size();
-            for (int r = 0; r < rowSize; r++) {
-                for (int c = 0; c < pkNameList.size(); c++) {
-                    List<Field> pkColumnValueList = 
pkRowValues.get(pkNameList.get(c));
-                    Field field = pkColumnValueList.get(r);
-                    int dataType = 
tableMeta.getColumnMeta(field.getName()).getDataType();
-                    statement.setObject(paramIndex, field.getValue(), 
dataType);
-                    paramIndex++;
+        List<SqlGenerateUtils.WhereSql> sqlConditions = 
SqlGenerateUtils.buildWhereConditionListByPKs(pkNameList, pkRowSize, 
connectionProxy.getDbType());
+        TableRecords currentRecords = new TableRecords(tableMeta);
+        int totalRowIndex = 0;
+        for (SqlGenerateUtils.WhereSql sqlCondition : sqlConditions) {
+            String checkSQL = buildCheckSql(sqlUndoLog.getTableName(), 
sqlCondition.getSql());
+            PreparedStatement statement = null;
+            ResultSet checkSet = null;
+            try {
+                statement = conn.prepareStatement(checkSQL);
+                int paramIndex = 1;
+                for (int r = 0; r < sqlCondition.getRowSize(); r++) {
+                    for (int c = 0; c < sqlCondition.getPkSize(); c++) {
+                        List<Field> pkColumnValueList = 
pkRowValues.get(pkNameList.get(c));
+                        Field field = pkColumnValueList.get(totalRowIndex + r);
+                        int dataType = 
tableMeta.getColumnMeta(field.getName()).getDataType();
+                        statement.setObject(paramIndex, field.getValue(), 
dataType);
+                        paramIndex++;
+                    }
                 }
-            }
+                totalRowIndex += sqlCondition.getRowSize();
 
-            checkSet = statement.executeQuery();
-            currentRecords = TableRecords.buildRecords(tableMeta, checkSet);
-        } finally {
-            IOUtil.close(checkSet, statement);
+                checkSet = statement.executeQuery();
+                
currentRecords.getRows().addAll(TableRecords.buildRecords(tableMeta, 
checkSet).getRows());
+            } finally {
+                IOUtil.close(checkSet, statement);
+            }
         }
         return currentRecords;
     }
diff --git 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/SqlGenerateUtilsTest.java
 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/SqlGenerateUtilsTest.java
index 7ac5b0b467..45353c2bfc 100644
--- 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/SqlGenerateUtilsTest.java
+++ 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/SqlGenerateUtilsTest.java
@@ -16,28 +16,49 @@
  */
 package org.apache.seata.rm.datasource;
 
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.seata.rm.datasource.SqlGenerateUtils;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringJoiner;
+
 
 class SqlGenerateUtilsTest {
 
 
     @Test
-    void testBuildWhereConditionByPKs() throws SQLException {
-        List<String> pkNameList=new ArrayList<>();
+    void testBuildWhereConditionListByPKs() {
+        List<String> pkNameList = new ArrayList<>();
+        pkNameList.add("id");
+        pkNameList.add("name");
+        List<SqlGenerateUtils.WhereSql> results1 = 
SqlGenerateUtils.buildWhereConditionListByPKs(pkNameList, 4, "mysql", 2);
+        Assertions.assertEquals(2, results1.size());
+        results1.forEach(result -> {
+            Assertions.assertEquals("(id,name) in ( (?,?),(?,?) )", 
result.getSql());
+            Assertions.assertEquals(2, result.getRowSize());
+            Assertions.assertEquals(2, result.getPkSize());
+        });
+        List<SqlGenerateUtils.WhereSql> results2 = 
SqlGenerateUtils.buildWhereConditionListByPKs(pkNameList, 5, "mysql", 2);
+        Assertions.assertEquals(3, results2.size());
+        Assertions.assertEquals("(id,name) in ( (?,?),(?,?) )", 
results2.get(0).getSql());
+        Assertions.assertEquals(2, results2.get(0).getRowSize());
+        Assertions.assertEquals(2, results2.get(0).getPkSize());
+        Assertions.assertEquals("(id,name) in ( (?,?),(?,?) )", 
results2.get(1).getSql());
+        Assertions.assertEquals("(id,name) in ( (?,?) )", 
results2.get(2).getSql());
+        Assertions.assertEquals(1, results2.get(2).getRowSize());
+        Assertions.assertEquals(2, results2.get(2).getPkSize());
+    }
+
+    @Test
+    void testBuildSQLByPKs() {
+        String sqlPrefix = "select id,name from t_order where ";
+        List<String> pkNameList = new ArrayList<>();
         pkNameList.add("id");
         pkNameList.add("name");
-        String result = 
SqlGenerateUtils.buildWhereConditionByPKs(pkNameList,4,"mysql",2);
-        Assertions.assertEquals("(id,name) in ( (?,?),(?,?) ) or (id,name) in 
( (?,?),(?,?) )", result);
-        result = 
SqlGenerateUtils.buildWhereConditionByPKs(pkNameList,5,"mysql",2);
-        Assertions.assertEquals("(id,name) in ( (?,?),(?,?) ) or (id,name) in 
( (?,?),(?,?) ) or (id,name) in ( (?,?)"
-                + " )",
-            result);
+        List<SqlGenerateUtils.WhereSql> whereList = 
SqlGenerateUtils.buildWhereConditionListByPKs(pkNameList, 4, "mysql", 2);
+        StringJoiner sqlJoiner = new StringJoiner(" union ");
+        whereList.forEach(whereSql -> sqlJoiner.add(sqlPrefix + " " + 
whereSql.getSql()));
+        Assertions.assertEquals("select id,name from t_order where  (id,name) 
in ( (?,?),(?,?) ) union select id,name from t_order where  (id,name) in ( 
(?,?),(?,?) )", sqlJoiner.toString());
     }
 }
diff --git 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/exec/UpdateJoinExecutorTest.java
 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/exec/UpdateJoinExecutorTest.java
index c047decbd9..67404ec763 100644
--- 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/exec/UpdateJoinExecutorTest.java
+++ 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/exec/UpdateJoinExecutorTest.java
@@ -32,7 +32,6 @@ import org.apache.seata.rm.datasource.ConnectionProxy;
 import org.apache.seata.rm.datasource.DataSourceProxy;
 import org.apache.seata.rm.datasource.DataSourceProxyTest;
 import org.apache.seata.rm.datasource.StatementProxy;
-import org.apache.seata.rm.datasource.exec.UpdateExecutor;
 import org.apache.seata.rm.datasource.exec.mysql.MySQLUpdateJoinExecutor;
 import org.apache.seata.rm.datasource.mock.MockDriver;
 import org.apache.seata.rm.datasource.sql.struct.TableRecords;
@@ -58,6 +57,7 @@ public class UpdateJoinExecutorTest {
         };
         Object[][] beforeReturnValue = new Object[][]{
                 new Object[]{1, "Tom"},
+                new Object[]{2, "Tony"},
         };
         StatementProxy beforeMockStatementProxy = 
mockStatementProxy(returnValueColumnLabels, beforeReturnValue, columnMetas, 
indexMetas);
         String sql = "update t1 inner join t2 on t1.id = t2.id set t1.name = 
'WILL',t2.name = 'WILL'";
@@ -69,6 +69,7 @@ public class UpdateJoinExecutorTest {
         TableRecords beforeImage = mySQLUpdateJoinExecutor.beforeImage();
         Object[][] afterReturnValue = new Object[][]{
                 new Object[]{1, "WILL"},
+                new Object[]{2, "Tony"},
         };
         StatementProxy afterMockStatementProxy = 
mockStatementProxy(returnValueColumnLabels, afterReturnValue, columnMetas, 
indexMetas);
         mySQLUpdateJoinExecutor.statementProxy = afterMockStatementProxy;
diff --git 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/mock/MockExecuteHandlerImpl.java
 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/mock/MockExecuteHandlerImpl.java
index 17c0cf6607..22cb3fe8a4 100644
--- 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/mock/MockExecuteHandlerImpl.java
+++ 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/mock/MockExecuteHandlerImpl.java
@@ -70,7 +70,7 @@ public class MockExecuteHandlerImpl implements 
MockExecuteHandler {
         List<Object[]> metas = new ArrayList<>();
         if(asts.get(0) instanceof SQLSelectStatement) {
             SQLSelectStatement ast = (SQLSelectStatement) asts.get(0);
-            SQLSelectQueryBlock queryBlock = ast.getSelect().getQueryBlock();
+            SQLSelectQueryBlock queryBlock = 
ast.getSelect().getFirstQueryBlock();
             String tableName = "";
             if (queryBlock.getFrom() instanceof SQLExprTableSource) {
                 MySQLSelectForUpdateRecognizer recognizer = new 
MySQLSelectForUpdateRecognizer(sql, ast);
diff --git 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/undo/AbstractUndoExecutorTest.java
 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/undo/AbstractUndoExecutorTest.java
index 8f6522617a..b50eb6761b 100644
--- 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/undo/AbstractUndoExecutorTest.java
+++ 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/undo/AbstractUndoExecutorTest.java
@@ -209,12 +209,12 @@ public class AbstractUndoExecutorTest extends BaseH2Test {
         pkRowValues.put("id1", pkId1Values);
         pkRowValues.put("id2", pkId2Values);
 
-        String sql = SqlGenerateUtils.buildWhereConditionByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.MYSQL);
-        Assertions.assertEquals("(id1,id2) in ( (?,?),(?,?),(?,?) )", sql);
-        sql = SqlGenerateUtils.buildWhereConditionByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.MARIADB);
-        Assertions.assertEquals("(id1,id2) in ( (?,?),(?,?),(?,?) )", sql);
-        sql = SqlGenerateUtils.buildWhereConditionByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.POLARDBX);
-        Assertions.assertEquals("(id1,id2) in ( (?,?),(?,?),(?,?) )", sql);
+        List<SqlGenerateUtils.WhereSql> sql = 
SqlGenerateUtils.buildWhereConditionListByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.MYSQL, 1000);
+        Assertions.assertEquals("(id1,id2) in ( (?,?),(?,?),(?,?) )", 
sql.get(0).getSql());
+        sql = SqlGenerateUtils.buildWhereConditionListByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.MARIADB, 1000);
+        Assertions.assertEquals("(id1,id2) in ( (?,?),(?,?),(?,?) )", 
sql.get(0).getSql());
+        sql = SqlGenerateUtils.buildWhereConditionListByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.POLARDBX, 1000);
+        Assertions.assertEquals("(id1,id2) in ( (?,?),(?,?),(?,?) )", 
sql.get(0).getSql());
     }
 
     @Test
@@ -227,12 +227,12 @@ public class AbstractUndoExecutorTest extends BaseH2Test {
         pkId1Values.add(new Field());
         pkRowValues.put("id1", pkId1Values);
 
-        String sql = SqlGenerateUtils.buildWhereConditionByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.MYSQL);
-        Assertions.assertEquals("(id1) in ( (?) )", sql);
-        sql = SqlGenerateUtils.buildWhereConditionByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.MARIADB);
-        Assertions.assertEquals("(id1) in ( (?) )", sql);
-        sql = SqlGenerateUtils.buildWhereConditionByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.POLARDBX);
-        Assertions.assertEquals("(id1) in ( (?) )", sql);
+        List<SqlGenerateUtils.WhereSql> sql = 
SqlGenerateUtils.buildWhereConditionListByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.MYSQL);
+        Assertions.assertEquals("(id1) in ( (?) )", sql.get(0).getSql());
+        sql = SqlGenerateUtils.buildWhereConditionListByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.MARIADB);
+        Assertions.assertEquals("(id1) in ( (?) )", sql.get(0).getSql());
+        sql = SqlGenerateUtils.buildWhereConditionListByPKs(pkNameList, 
pkRowValues.get("id1").size(), JdbcConstants.POLARDBX);
+        Assertions.assertEquals("(id1) in ( (?) )", sql.get(0).getSql());
     }
 }
 
diff --git 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/dm/DmSelectForUpdateRecognizer.java
 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/dm/DmSelectForUpdateRecognizer.java
index 6b8b27be27..0a2ca76371 100644
--- 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/dm/DmSelectForUpdateRecognizer.java
+++ 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/dm/DmSelectForUpdateRecognizer.java
@@ -76,7 +76,7 @@ public class DmSelectForUpdateRecognizer extends 
BaseDmRecognizer implements SQL
         if (select == null) {
             throw new SQLParsingException("should never happen!");
         }
-        SQLSelectQueryBlock selectQueryBlock = select.getQueryBlock();
+        SQLSelectQueryBlock selectQueryBlock = select.getFirstQueryBlock();
         if (selectQueryBlock == null) {
             throw new SQLParsingException("should never happen!");
         }
diff --git 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/mysql/MySQLSelectForUpdateRecognizer.java
 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/mysql/MySQLSelectForUpdateRecognizer.java
index ff7ca61375..2d34a52927 100644
--- 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/mysql/MySQLSelectForUpdateRecognizer.java
+++ 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/mysql/MySQLSelectForUpdateRecognizer.java
@@ -102,7 +102,7 @@ public class MySQLSelectForUpdateRecognizer extends 
BaseMySQLRecognizer implemen
         if (select == null) {
             throw new SQLParsingException("should never happen!");
         }
-        SQLSelectQueryBlock selectQueryBlock = select.getQueryBlock();
+        SQLSelectQueryBlock selectQueryBlock = select.getFirstQueryBlock();
         if (selectQueryBlock == null) {
             throw new SQLParsingException("should never happen!");
         }
diff --git 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/oracle/OracleSelectForUpdateRecognizer.java
 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/oracle/OracleSelectForUpdateRecognizer.java
index 2e22524e14..91be41cf40 100644
--- 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/oracle/OracleSelectForUpdateRecognizer.java
+++ 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/oracle/OracleSelectForUpdateRecognizer.java
@@ -102,7 +102,7 @@ public class OracleSelectForUpdateRecognizer extends 
BaseOracleRecognizer implem
         if (select == null) {
             throw new SQLParsingException("should never happen!");
         }
-        SQLSelectQueryBlock selectQueryBlock = select.getQueryBlock();
+        SQLSelectQueryBlock selectQueryBlock = select.getFirstQueryBlock();
         if (selectQueryBlock == null) {
             throw new SQLParsingException("should never happen!");
         }
diff --git 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/postgresql/PostgresqlSelectForUpdateRecognizer.java
 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/postgresql/PostgresqlSelectForUpdateRecognizer.java
index 88a7f9af92..f7827a57f6 100644
--- 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/postgresql/PostgresqlSelectForUpdateRecognizer.java
+++ 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/postgresql/PostgresqlSelectForUpdateRecognizer.java
@@ -74,7 +74,7 @@ public class PostgresqlSelectForUpdateRecognizer extends 
BasePostgresqlRecognize
         if (select == null) {
             throw new SQLParsingException("should never happen!");
         }
-        SQLSelectQueryBlock selectQueryBlock = select.getQueryBlock();
+        SQLSelectQueryBlock selectQueryBlock = select.getFirstQueryBlock();
         if (selectQueryBlock == null) {
             throw new SQLParsingException("should never happen!");
         }
diff --git 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/sqlserver/SqlServerOperateRecognizerHolder.java
 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/sqlserver/SqlServerOperateRecognizerHolder.java
index d5711a2e15..3af2c98522 100644
--- 
a/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/sqlserver/SqlServerOperateRecognizerHolder.java
+++ 
b/sqlparser/seata-sqlparser-druid/src/main/java/org/apache/seata/sqlparser/druid/sqlserver/SqlServerOperateRecognizerHolder.java
@@ -55,7 +55,7 @@ public class SqlServerOperateRecognizerHolder implements 
SQLOperateRecognizerHol
 
     @Override
     public SQLRecognizer getSelectForUpdateRecognizer(String sql, SQLStatement 
ast) {
-        List<SQLHint> hints = ((SQLSelectStatement) 
ast).getSelect().getQueryBlock().getFrom().getHints();
+        List<SQLHint> hints = ((SQLSelectStatement) 
ast).getSelect().getFirstQueryBlock().getFrom().getHints();
         if (CollectionUtils.isNotEmpty(hints)) {
             List<String> hintsTexts = hints
                     .stream()


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to