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

dataroaring pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new 3f15ddbf0a5 branch-3.0: [BugFix](PreparedStatement) fix stmtId 
overflow #47950 (#48116)
3f15ddbf0a5 is described below

commit 3f15ddbf0a5176b180d99c8796b4f4a5415d09d9
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sat Feb 22 13:42:58 2025 +0800

    branch-3.0: [BugFix](PreparedStatement) fix stmtId overflow #47950 (#48116)
    
    Cherry-picked from #47950
    
    Co-authored-by: lihangyu <lihan...@selectdb.com>
---
 .../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   |  46 +++++++++++++++++++++
 7 files changed, 68 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 ff8045b2da6..a541e9052e1 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
@@ -140,6 +140,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 f8788f0657f..40c0d8b567b 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
@@ -111,7 +111,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 0efe28e1ecf..6e0694689c9 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
@@ -116,6 +116,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;
@@ -415,10 +417,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) {
@@ -445,6 +448,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 da3baced5fa..9ded1f04cbc 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
@@ -186,9 +186,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 e7666f99b20..56bc302b93b 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
@@ -709,9 +709,10 @@ public class StmtExecutor {
             if (logicalPlan instanceof UnsupportedCommand || logicalPlan 
instanceof CreatePolicyCommand) {
                 throw new MustFallbackException("cannot prepare command " + 
logicalPlan.getClass().getSimpleName());
             }
-            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 7b4bf401bf0..ced7041e9fb 100644
--- a/regression-test/suites/prepared_stmt_p0/prepared_stmt.groovy
+++ b/regression-test/suites/prepared_stmt_p0/prepared_stmt.groovy
@@ -302,4 +302,50 @@ suite("test_prepared_stmt", "nonConcurrent") {
         assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, 
stmt_read.class)
         qe_select24 stmt_read
     }
+
+    // test stmtId overflow
+    def result2 = 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

Reply via email to