diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/DeleteExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/DeleteExecutor.java index 4f67d1e40cc769ab2de9c21efa6927ce3ff9865a..e48e865893df38918b068fbff64c3e34dccc5588 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/DeleteExecutor.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/DeleteExecutor.java @@ -26,6 +26,7 @@ import io.seata.rm.datasource.ColumnUtils; import io.seata.rm.datasource.StatementProxy; import io.seata.rm.datasource.sql.struct.TableMeta; import io.seata.rm.datasource.sql.struct.TableRecords; +import io.seata.sqlparser.ParametersHolder; import io.seata.sqlparser.SQLDeleteRecognizer; import io.seata.sqlparser.SQLRecognizer; @@ -70,7 +71,8 @@ public class DeleteExecutor<T, S extends Statement> extends AbstractDMLBaseExecu if (StringUtils.isNotBlank(orderBy)) { suffix.append(orderBy); } - String limit = visitor.getLimit(); + ParametersHolder parametersHolder = statementProxy instanceof ParametersHolder ? (ParametersHolder)statementProxy : null; + String limit = visitor.getLimit(parametersHolder, paramAppenderList); if (StringUtils.isNotBlank(limit)) { suffix.append(limit); } diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/UpdateExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/UpdateExecutor.java index b899aa74e5de3f5b7b48d1ce82b8b5fe2d71bdf3..e2b39b3cf0220eb4e814bc1b33015db5375b01de 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/UpdateExecutor.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/UpdateExecutor.java @@ -34,6 +34,7 @@ import io.seata.rm.datasource.SqlGenerateUtils; import io.seata.rm.datasource.StatementProxy; import io.seata.rm.datasource.sql.struct.TableMeta; import io.seata.rm.datasource.sql.struct.TableRecords; +import io.seata.sqlparser.ParametersHolder; import io.seata.sqlparser.SQLRecognizer; import io.seata.sqlparser.SQLUpdateRecognizer; @@ -85,7 +86,8 @@ public class UpdateExecutor<T, S extends Statement> extends AbstractDMLBaseExecu if (StringUtils.isNotBlank(orderBy)) { suffix.append(orderBy); } - String limit = recognizer.getLimit(); + ParametersHolder parametersHolder = statementProxy instanceof ParametersHolder ? (ParametersHolder)statementProxy : null; + String limit = recognizer.getLimit(parametersHolder, paramAppenderList); if (StringUtils.isNotBlank(limit)) { suffix.append(limit); } diff --git a/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/WhereRecognizer.java b/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/WhereRecognizer.java index a010f644bc0f22957044ad3c87e02a5607145953..28f2b4db5c4f517179a6456d47e698f6771b42fc 100644 --- a/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/WhereRecognizer.java +++ b/sqlparser/seata-sqlparser-core/src/main/java/io/seata/sqlparser/WhereRecognizer.java @@ -46,7 +46,7 @@ public interface WhereRecognizer extends SQLRecognizer { * * @return The limit SQL. */ - default String getLimit() { + default String getLimit(ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) { return null; } diff --git a/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/BaseMySQLRecognizer.java b/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/BaseMySQLRecognizer.java index 58ebe6cfa2578d1baa043a4127ad8a5e60f56cd4..43c94b7e7d959ca7518f9c667f2b32b86528b443 100644 --- a/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/BaseMySQLRecognizer.java +++ b/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/BaseMySQLRecognizer.java @@ -17,6 +17,7 @@ package io.seata.sqlparser.druid.mysql; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; import com.alibaba.druid.sql.ast.SQLExpr; @@ -96,7 +97,7 @@ public abstract class BaseMySQLRecognizer extends BaseRecognizer { return sb.toString(); } - protected String getLimit(SQLStatement sqlStatement, SQLType sqlType) { + protected String getLimit(SQLStatement sqlStatement, SQLType sqlType, ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) { SQLLimit limit = null; if (SQLType.UPDATE == sqlType) { limit = ((MySqlUpdateStatement)sqlStatement).getLimit(); @@ -107,12 +108,24 @@ public abstract class BaseMySQLRecognizer extends BaseRecognizer { StringBuilder builder = new StringBuilder(" LIMIT "); SQLIntegerExpr expr; if (limit.getOffset() != null) { - expr = (SQLIntegerExpr)limit.getOffset(); - builder.append(expr.getNumber()).append(","); + if (limit.getOffset() instanceof SQLVariantRefExpr) { + builder.append("?,"); + Map<Integer, ArrayList<Object>> parameters = parametersHolder.getParameters(); + paramAppenderList.add(parameters.get(parameters.size() - 1)); + } else { + expr = (SQLIntegerExpr)limit.getOffset(); + builder.append(expr.getNumber()).append(","); + } } if (limit.getRowCount() != null) { - expr = (SQLIntegerExpr)limit.getRowCount(); - builder.append(expr.getNumber()); + if (limit.getRowCount() instanceof SQLVariantRefExpr) { + builder.append("?"); + Map<Integer, ArrayList<Object>> parameters = parametersHolder.getParameters(); + paramAppenderList.add(parameters.get(parameters.size())); + } else { + expr = (SQLIntegerExpr)limit.getRowCount(); + builder.append(expr.getNumber()); + } } return builder.toString(); } diff --git a/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/MySQLDeleteRecognizer.java b/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/MySQLDeleteRecognizer.java index 62c3a099f885207915cc4409d4852b07fd4f795d..6dcf19870e37867cd72b339bc4eb3df231723b3d 100644 --- a/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/MySQLDeleteRecognizer.java +++ b/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/MySQLDeleteRecognizer.java @@ -94,8 +94,8 @@ public class MySQLDeleteRecognizer extends BaseMySQLRecognizer implements SQLDel } @Override - public String getLimit() { - return super.getLimit(ast, getSQLType()); + public String getLimit(ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) { + return super.getLimit(ast, getSQLType(), parametersHolder, paramAppenderList); } @Override diff --git a/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/MySQLUpdateRecognizer.java b/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/MySQLUpdateRecognizer.java index 6eac619a74d7b6ae1ff1ea7a4d137a28cdaf409a..5f01571dad4c4bc70d4a4a8ea6552c56ebd33326 100644 --- a/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/MySQLUpdateRecognizer.java +++ b/sqlparser/seata-sqlparser-druid/src/main/java/io/seata/sqlparser/druid/mysql/MySQLUpdateRecognizer.java @@ -132,8 +132,8 @@ public class MySQLUpdateRecognizer extends BaseMySQLRecognizer implements SQLUpd } @Override - public String getLimit() { - return super.getLimit(ast, getSQLType()); + public String getLimit(ParametersHolder parametersHolder, ArrayList<List<Object>> paramAppenderList) { + return super.getLimit(ast, getSQLType(), parametersHolder, paramAppenderList); } @Override diff --git a/sqlparser/seata-sqlparser-druid/src/test/java/io/seata/sqlparser/druid/MySQLDeleteRecognizerTest.java b/sqlparser/seata-sqlparser-druid/src/test/java/io/seata/sqlparser/druid/MySQLDeleteRecognizerTest.java index f5bbb3783e50cee7972b1fa97bfed0bffe886e39..dc19801b9d45eb517187bad0e82e5c4814c5d278 100644 --- a/sqlparser/seata-sqlparser-druid/src/test/java/io/seata/sqlparser/druid/MySQLDeleteRecognizerTest.java +++ b/sqlparser/seata-sqlparser-druid/src/test/java/io/seata/sqlparser/druid/MySQLDeleteRecognizerTest.java @@ -49,10 +49,17 @@ public class MySQLDeleteRecognizerTest extends AbstractRecognizerTest { */ @Test public void deleteRecognizerTest_0() { + ParametersHolder parametersHolder = new ParametersHolder() { + @Override + public Map<Integer,ArrayList<Object>> getParameters() { + return Collections.EMPTY_MAP; + } + }; String sql = "DELETE FROM t1 WHERE id = 'id1' order by id asc,name desc limit 1,2"; SQLStatement statement = getSQLStatement(sql); + ArrayList<List<Object>> paramAppenderList = new ArrayList<>(); MySQLDeleteRecognizer mySQLDeleteRecognizer = new MySQLDeleteRecognizer(sql, statement); String orderBy = mySQLDeleteRecognizer.getOrderBy(); @@ -60,18 +67,18 @@ public class MySQLDeleteRecognizerTest extends AbstractRecognizerTest { Assertions.assertEquals(sql, mySQLDeleteRecognizer.getOriginalSQL()); Assertions.assertEquals("t1", mySQLDeleteRecognizer.getTableName()); Assertions.assertEquals("id = 'id1'", mySQLDeleteRecognizer.getWhereCondition()); - String limit = mySQLDeleteRecognizer.getLimit(); + String limit = mySQLDeleteRecognizer.getLimit(parametersHolder, paramAppenderList); Assertions.assertEquals(" LIMIT 1,2", limit); sql = "DELETE FROM t1 WHERE id > 1 order by id ,name desc limit 1"; statement = getSQLStatement(sql); mySQLDeleteRecognizer = new MySQLDeleteRecognizer(sql, statement); orderBy = mySQLDeleteRecognizer.getOrderBy(); Assertions.assertTrue(orderBy.equalsIgnoreCase(" order by id,name desc")); - Assertions.assertEquals(" LIMIT 1", mySQLDeleteRecognizer.getLimit()); + Assertions.assertEquals(" LIMIT 1", mySQLDeleteRecognizer.getLimit(parametersHolder, paramAppenderList)); sql = "DELETE FROM t1 WHERE id > 1"; statement = getSQLStatement(sql); mySQLDeleteRecognizer = new MySQLDeleteRecognizer(sql, statement); - Assertions.assertEquals(null, mySQLDeleteRecognizer.getLimit()); + Assertions.assertEquals(null, mySQLDeleteRecognizer.getLimit(parametersHolder, paramAppenderList)); orderBy = mySQLDeleteRecognizer.getOrderBy(); Assertions.assertEquals(null, mySQLDeleteRecognizer.getOrderBy());