pingcap / pingcap/tidb

Index out of bound when calling DEALLOCATE statement in JDBC

Open
#65,872 0 comments 0 reactions 1 assignee Claimed by @bb7133 View on GitHub
contribution may-affects-7.1 may-affects-7.5 may-affects-8.1 may-affects-8.5 severity/major sig/sql-infra type/bug
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. Minimal reproduce step (Required)

Hi,

I attach a script which can trigger an index out of bound error. I tried to reduce this script, but when I remove some statement from the script, the bug can not reproduce. And this issue can only be triggered with JDBC.

This is the java program to reproduce this:

```
import java.io.BufferedReader;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class TiDBRunner {
public static void main(String[] args) {
String url = "jdbc:mysql://127.0.0.1:4000/?user=root&password=&allowMultiQueries=true";
String filePath = "database92r-cur.sql";

try (Connection conn = DriverManager.getConnection(url);
BufferedReader reader = new BufferedReader(new FileReader(filePath))) {

StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
String trimmedLine = line.trim();
if (trimmedLine.isEmpty() || trimmedLine.startsWith("--")) {
continue;
}
sb.append(line).append("\n");
if (trimmedLine.endsWith(";")) {
String sql = sb.toString();
executeSql(conn, sql);
sb.setLength(0);
}
}

// Execute any remaining SQL (if file doesn't end with ;)
if (sb.length() > 0 && !sb.toString().trim().isEmpty()) {
executeSql(conn, sb.toString());
}

} catch (Exception e) {
e.printStackTrace();
}
}

private static void executeSql(Connection conn, String sql) {
try (Statement stmt = conn.createStatement()) {
System.out.println("Executing: " + sql.substring(0, Math.min(sql.length(), 100)) + (sql.length() > 100 ? "..." : ""));
stmt.execute(sql);
} catch (SQLException e) {
System.err.println("Failed to execute: " + sql);
e.printStackTrace();
}
}
}

```

This is the output:

```
Failed to execute: DEALLOCATE PREPARE prepare_query;

java.sql.SQLException: Index 4 out of bounds for length 4
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:763)
at com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:648)
at TiDBRunner.executeSql(TiDBRunner.java:44)
at TiDBRunner.main(TiDBRunner.java:26)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:484)
at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:208)
at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:135)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4
at com.mysql.cj.protocol.a.NativePacketPayload.readInteger(NativePacketPayload.java:398)
at com.mysql.cj.protocol.a.NativePacketPayload.readBytes(NativePacketPayload.java:523)
at com.mysql.cj.protocol.a.TextRowFactory.createFromMessage(TextRowFactory.java:66)
at com.mysql.cj.protocol.a.TextRowFactory.createFromMessage(TextRowFactory.java:42)
at com.mysql.cj.protocol.a.ResultsetRowReader.read(ResultsetRowReader.java:87)
at com.mysql.cj.protocol.a.ResultsetRowReader.read(ResultsetRowReader.java:42)
at com.mysql.cj.protocol.a.NativeProtocol.read(NativeProtocol.java:1648)
at com.mysql.cj.protocol.a.TextResultsetReader.read(TextResultsetReader.java:87)
at com.mysql.cj.protocol.a.TextResultsetReader.read(TextResultsetReader.java:48)
at com.mysql.cj.protocol.a.NativeProtocol.read(NativeProtocol.java:1661)
at com.mysql.cj.protocol.a.NativeProtocol.readAllResults(NativeProtocol.java:1715)
at com.mysql.cj.protocol.a.NativeProtocol.sendQueryPacket(NativeProtocol.java:1065)
at com.mysql.cj.protocol.a.NativeProtocol.sendQueryString(NativeProtocol.java:998)
at com.mysql.cj.NativeSession.execSQL(NativeSession.java:655)
at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:723)
... 8 more

```

This is the script file:

[database92r-cur.sql](https://github.com/user-attachments/files/24904446/database92r-cur.sql)

This is the command:

```
java -cp /root/.m2/repository/com/mysql/mysql-connector-j/8.0.33/mysql-connector-j-8.0.33.jar TiDBRunner.java
```

### 2. What did you expect to see? (Required)

No error

### 3. What did you see instead (Required)

Index 4 out of bounds for length 4

### 4. What is your TiDB version? (Required)

Release Version: v9.0.0-beta.2.pre-1118-gfc6f7b2e42\nEdition: Community\nGit Commit Hash: https://github.com/pingcap/tidb/commit/fc6f7b2e42be08957a9b80e5761bfa4793066353\nGit Branch: master\nUTC Build Time: 2026-01-26 12:27:51\nGoVersion: go1.25.6\nRace Enabled: false\nCheck Table Before Drop: false\nStore: unistore\nKernel Type: Classic

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.