This is an automated email from the ASF dual-hosted git repository. yiguolei pushed a commit to branch branch-2.1 in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.1 by this push: new 24702bfbf16 [BugFix](PreparedStatement) fix stmtId overflow (#47950) (#48271) 24702bfbf16 is described below commit 24702bfbf1636c5adb2f130432a13450f292b863 Author: lihangyu <lihan...@selectdb.com> AuthorDate: Tue Feb 25 20:33:50 2025 +0800 [BugFix](PreparedStatement) fix stmtId overflow (#47950) (#48271) cherry-pick from (#47950) --- .../main/java/org/apache/doris/common/Config.java | 5 +++ .../trees/plans/commands/PrepareCommand.java | 2 +- .../java/org/apache/doris/qe/ConnectContext.java | 13 +++++- .../org/apache/doris/qe/MysqlConnectProcessor.java | 4 +- .../java/org/apache/doris/qe/StmtExecutor.java | 5 ++- .../data/prepared_stmt_p0/prepared_stmt.out | Bin 5124 -> 5355 bytes .../suites/prepared_stmt_p0/prepared_stmt.groovy | 45 +++++++++++++++++++++ 7 files changed, 67 insertions(+), 7 deletions(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java index 5deaf8b51d5..6dbfd11da34 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java @@ -138,6 +138,11 @@ public class Config extends ConfigBase { description = {"是否检查table锁泄漏", "Whether to check table lock leaky"}) public static boolean check_table_lock_leaky = false; + @ConfField(mutable = true, masterOnly = false, + description = {"PreparedStatement stmtId 起始位置,仅用于测试", + "PreparedStatement stmtId starting position, used for testing onl"}) + public static long prepared_stmt_start_id = -1; + @ConfField(description = {"插件的安装目录", "The installation directory of the plugin"}) public static String plugin_dir = System.getenv("DORIS_HOME") + "/plugins"; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/PrepareCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/PrepareCommand.java index 43778a1e005..a844dcb9500 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/PrepareCommand.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/PrepareCommand.java @@ -110,7 +110,7 @@ public class PrepareCommand extends Command { ctx.addPreparedStatementContext(name, new PreparedStatementContext(this, ctx, ctx.getStatementContext(), name)); if (ctx.getCommand() == MysqlCommand.COM_STMT_PREPARE) { - executor.sendStmtPrepareOK((int) ctx.getStmtId(), labels); + executor.sendStmtPrepareOK(Integer.parseInt(name), labels); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java index 99a770a7efa..2d6911cc513 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java @@ -105,6 +105,8 @@ public class ConnectContext { // set for http_stream protected volatile TUniqueId loadId; protected volatile long backendId; + // range [Integer.MIN_VALUE, Integer.MAX_VALUE] + protected int preparedStmtId = Integer.MIN_VALUE; protected volatile LoadTaskInfo streamLoadInfo; protected volatile TUniqueId queryId = null; @@ -418,10 +420,11 @@ public class ConnectContext { } if (this.preparedStatementContextMap.size() > sessionVariable.maxPreparedStmtCount) { throw new UserException("Failed to create a server prepared statement" - + "possibly because there are too many active prepared statements on server already." + + " possibly because there are too many active prepared statements on server already." + "set max_prepared_stmt_count with larger number than " + sessionVariable.maxPreparedStmtCount); } this.preparedStatementContextMap.put(stmtName, ctx); + incPreparedStmtId(); } public void removePrepareStmt(String stmtName) { @@ -461,6 +464,14 @@ public class ConnectContext { return stmtId; } + public long getPreparedStmtId() { + return preparedStmtId; + } + + public void incPreparedStmtId() { + ++preparedStmtId; + } + public long getBackendId() { return backendId; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java index f86833451f8..f40bae578a4 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java @@ -261,9 +261,7 @@ public class MysqlConnectProcessor extends ConnectProcessor { // nererids PreparedStatementContext preparedStatementContext = ctx.getPreparedStementContext(String.valueOf(stmtId)); if (preparedStatementContext == null) { - if (LOG.isDebugEnabled()) { - LOG.debug("No such statement in context, stmtId:{}", stmtId); - } + LOG.warn("No such statement in context, stmtId:{}", stmtId); ctx.getState().setError(ErrorCode.ERR_UNKNOWN_COM_ERROR, "msg: Not supported such prepared statement"); return; diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java index ad2c48ed177..5af00a127e2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java @@ -679,9 +679,10 @@ public class StmtExecutor { if (isForwardToMaster()) { throw new UserException("Forward master command is not supported for prepare statement"); } - logicalPlan = new PrepareCommand(String.valueOf(context.getStmtId()), + long stmtId = Config.prepared_stmt_start_id > 0 + ? Config.prepared_stmt_start_id : context.getPreparedStmtId(); + logicalPlan = new PrepareCommand(String.valueOf(stmtId), logicalPlan, statementContext.getPlaceholders(), originStmt); - } // when we in transaction mode, we only support insert into command and transaction command if (context.isTxnModel()) { diff --git a/regression-test/data/prepared_stmt_p0/prepared_stmt.out b/regression-test/data/prepared_stmt_p0/prepared_stmt.out index 052094cd7d6..9cadb98813a 100644 Binary files a/regression-test/data/prepared_stmt_p0/prepared_stmt.out and b/regression-test/data/prepared_stmt_p0/prepared_stmt.out differ diff --git a/regression-test/suites/prepared_stmt_p0/prepared_stmt.groovy b/regression-test/suites/prepared_stmt_p0/prepared_stmt.groovy index fea781ff0b7..d8d1c943837 100644 --- a/regression-test/suites/prepared_stmt_p0/prepared_stmt.groovy +++ b/regression-test/suites/prepared_stmt_p0/prepared_stmt.groovy @@ -311,4 +311,49 @@ suite("test_prepared_stmt", "nonConcurrent") { def stmt_insert = prepareStatement "insert into mytable1 values(?, ?, ?, ?)" assertEquals(stmt_insert.class, com.mysql.cj.jdbc.ClientPreparedStatement); } + // test stmtId overflow + def result3 = connect(user, password, url) { + // def stmt_read1 = prepareStatement "select 1" + // assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt_read1.class) + // qe_overflow_1 stmt_read1 + // stmt_read1.close() + // int max + sql """admin set frontend config("prepared_stmt_start_id" = "2147483647");""" + def stmt_read2 = prepareStatement "select 2" + assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt_read2.class) + qe_overflow_2 stmt_read2 + qe_overflow_2 stmt_read2 + stmt_read2.close() + // int max + 1 + sql """admin set frontend config("prepared_stmt_start_id" = "2147483648");""" + def stmt_read3 = prepareStatement "select 3" + // overflow throw NumberFormatExceptio and fallback to ClientPreparedStatement + assertEquals(com.mysql.cj.jdbc.ClientPreparedStatement, stmt_read3.class) + qe_overflow_3 stmt_read3 + qe_overflow_3 stmt_read3 + stmt_read3.close() + // int min + sql """admin set frontend config("prepared_stmt_start_id" = "2147483646");""" + def stmt_read4 = prepareStatement "select 4" + assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt_read4.class) + qe_overflow_4 stmt_read4 + qe_overflow_4 stmt_read4 + stmt_read4.close() + + sql """admin set frontend config("prepared_stmt_start_id" = "123");""" + def stmt_read5 = prepareStatement "select 5" + assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt_read5.class) + qe_overflow_5 stmt_read5 + qe_overflow_5 stmt_read5 + stmt_read5.close() + + // set back + sql """admin set frontend config("prepared_stmt_start_id" = "-1");""" + def stmt_read6 = prepareStatement "select 6" + assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt_read6.class) + qe_overflow_6 stmt_read6 + qe_overflow_6 stmt_read6 + qe_overflow_6 stmt_read6 + stmt_read6.close() + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org