Details
- 
    Bug 
- 
    Status: Closed (View Workflow)
- 
    Major 
- 
    Resolution: Fixed
- 
    2.7.2
- 
    None
Description
We found an issue when executing prepared queries using automatic key generation in parallel. It occurs when accessing a MySQL database (tested with 8.0.16, 5.7.26 and 5.6.50) via MariaDB Connector/J (2.7.2). When executing the following piece of code multiple times in parallel:
| try ( | 
| Connection connection = DriverManager.getConnection("jdbc:mysql://ensembldb.ensembl.org:3306?pool=true&minPoolSize=1&maxPoolSize=5&maxIdleTime=60", "anonymous", ""); | 
| PreparedStatement statement = connection.prepareStatement("SELECT * FROM acanthochromis_polyacanthus_core_100_1.analysis WHERE analysis_id = ?", Statement.RETURN_GENERATED_KEYS) | 
| ) { | 
| statement.setInt(1, 5); | 
| try (ResultSet result = statement.executeQuery()) { | 
| try (ResultSet keys = statement.getGeneratedKeys()) { | 
|             ResultSetMetaData metadata = keys.getMetaData(); | 
| int cols = metadata.getColumnCount(); | 
| for (int i = 1; i <= cols; i++) | 
|                 metadata.getColumnLabel(i); | 
|         } | 
|     } | 
| }
 | 
we see the following exceptions:
| java.lang.ArrayIndexOutOfBoundsException: 38 | 
| at org.mariadb.jdbc.internal.com.read.Buffer.skipLengthEncodedBytes(Buffer.java:228) | 
| at org.mariadb.jdbc.internal.com.read.resultset.ColumnDefinition.getString(ColumnDefinition.java:225) | 
| at org.mariadb.jdbc.internal.com.read.resultset.ColumnDefinition.getName(ColumnDefinition.java:243) | 
| at org.mariadb.jdbc.MariaDbResultSetMetaData.getColumnLabel(MariaDbResultSetMetaData.java:154) | 
| at MariaDBConnectionPool.executeQuery(MariaDBConnectionPool.java:30) | 
| 	[...]
 | 
| java.lang.StringIndexOutOfBoundsException: String index out of range: 121 | 
| at java.lang.String.checkBounds(String.java:385) | 
| at java.lang.String.<init>(String.java:462) | 
| at org.mariadb.jdbc.internal.com.read.Buffer.readStringLengthEncoded(Buffer.java:123) | 
| at org.mariadb.jdbc.internal.com.read.resultset.ColumnDefinition.getString(ColumnDefinition.java:227) | 
| at org.mariadb.jdbc.internal.com.read.resultset.ColumnDefinition.getName(ColumnDefinition.java:243) | 
| at org.mariadb.jdbc.MariaDbResultSetMetaData.getColumnLabel(MariaDbResultSetMetaData.java:154) | 
| at MariaDBConnectionPool.executeQuery(MariaDBConnectionPool.java:30) | 
| 	[...]
 | 
A reproducer can be found at https://github.com/riemenschneider/JDBCPoolUsingMariaDBDriverTest. It contains the relevant test:
- MariaDBConnectionPool: using the connection pooling provided by MariaDB Connector/J for running 1000 prepared queries in parallel.
Ignore the remaining tests. These were just used for tracking the issue down to MariaDB Connector/J.
Steps to reproduce:
- Clone the reproducer.
- Run gradlew clean test --tests MariaDBConnectionPool in the root folder of the cloned reproducer.