Skip to content

Commit 582d91f

Browse files
committed
Fix for Bug#81468 (23312764), MySQL server fails to rewrite batch insert when column name contains word select.
1 parent 9f14917 commit 582d91f

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
Version 8.0.29
55

6+
- Fix for Bug#81468 (23312764), MySQL server fails to rewrite batch insert when column name contains word select.
7+
68
- Fix for Bug#106435 (33850099), 8.0.28 Connector/J has regressive in setAutoCommit after Bug#104067 (33054827).
79

810
- Fix for Bug#106240 (33781440), StringIndexOutOfBoundsException when VALUE is at the end of the query.

src/test/java/testsuite/regression/StatementRegressionTest.java

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
package testsuite.regression;
3131

32+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
3233
import static org.junit.jupiter.api.Assertions.assertEquals;
3334
import static org.junit.jupiter.api.Assertions.assertFalse;
3435
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -12168,4 +12169,120 @@ public void testBug106240() throws Exception {
1216812169
() -> testConn.prepareStatement("INSERT INTO testBug106240 VALUES/* (?, ?) */ON DUPLICATE KEY UPDATE").execute());
1216912170
} while (useSPS = !useSPS);
1217012171
}
12172+
12173+
/**
12174+
* Tests for Bug#81468 (23312764), MySQL server fails to rewrite batch insert when column name contains word select.
12175+
* Resolved by fix for Bug#106240 (33781440), StringIndexOutOfBoundsException when VALUE is at the end of the query.
12176+
*
12177+
* @throws Exception
12178+
*/
12179+
@Test
12180+
public void testBug81468() throws Exception {
12181+
createTable("testBug81468", "(selection INT)"); // Column has to contain "select" in its name.
12182+
12183+
Properties props = new Properties();
12184+
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
12185+
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
12186+
props.setProperty(PropertyKey.queryInterceptors.getKeyName(), TestBug81468QueryInterceptor.class.getName());
12187+
props.setProperty(PropertyKey.rewriteBatchedStatements.getKeyName(), "true");
12188+
props.setProperty(PropertyKey.continueBatchOnError.getKeyName(), "false");
12189+
props.setProperty(PropertyKey.emulateUnsupportedPstmts.getKeyName(), "true");
12190+
12191+
boolean useSPS = false;
12192+
12193+
do {
12194+
props.setProperty(PropertyKey.useServerPrepStmts.getKeyName(), Boolean.toString(useSPS));
12195+
Connection testConn = getConnectionWithProps(props);
12196+
12197+
// Re-writes in a single query with three values.
12198+
TestBug81468QueryInterceptor.resetExpectedValues(1, 1, 3);
12199+
PreparedStatement testPStmt = testConn.prepareStatement("INSERT INTO testBug81468 (selection) VALUES (?)");
12200+
testPStmt.setInt(1, 11);
12201+
testPStmt.addBatch();
12202+
testPStmt.setInt(1, 12);
12203+
testPStmt.addBatch();
12204+
testPStmt.setInt(1, 13);
12205+
testPStmt.addBatch();
12206+
assertArrayEquals(new int[] { Statement.SUCCESS_NO_INFO, Statement.SUCCESS_NO_INFO, Statement.SUCCESS_NO_INFO }, testPStmt.executeBatch());
12207+
testPStmt.close();
12208+
12209+
// Re-writes in a single query with five values.
12210+
TestBug81468QueryInterceptor.resetExpectedValues(1, 1, 5);
12211+
testPStmt = testConn.prepareStatement("INSERT INTO testBug81468 (selection) VALUES (?)");
12212+
testPStmt.setInt(1, 21);
12213+
testPStmt.addBatch();
12214+
testPStmt.setInt(1, 22);
12215+
testPStmt.addBatch();
12216+
testPStmt.setInt(1, 23);
12217+
testPStmt.addBatch();
12218+
testPStmt.setInt(1, 24);
12219+
testPStmt.addBatch();
12220+
testPStmt.setInt(1, 25);
12221+
testPStmt.addBatch();
12222+
assertArrayEquals(new int[] { Statement.SUCCESS_NO_INFO, Statement.SUCCESS_NO_INFO, Statement.SUCCESS_NO_INFO, Statement.SUCCESS_NO_INFO,
12223+
Statement.SUCCESS_NO_INFO }, testPStmt.executeBatch());
12224+
testPStmt.close();
12225+
12226+
// Not enough queries to trigger the query re-write feature.
12227+
TestBug81468QueryInterceptor.resetExpectedValues(3, 1, 1);
12228+
Statement testStmt = testConn.createStatement();
12229+
testStmt.addBatch("INSERT INTO testBug81468 (selection) VALUES (31)");
12230+
testStmt.addBatch("INSERT INTO testBug81468 (selection) VALUES (32)");
12231+
testStmt.addBatch("INSERT INTO testBug81468 (selection) VALUES (33)");
12232+
assertArrayEquals(new int[] { 1, 1, 1 }, testStmt.executeBatch());
12233+
testStmt.close();
12234+
12235+
// Five or more queries triggers the query re-write feature.
12236+
TestBug81468QueryInterceptor.resetExpectedValues(1, 5, 5);
12237+
testStmt = testConn.createStatement();
12238+
testStmt.addBatch("INSERT INTO testBug81468 (selection) VALUES (41)");
12239+
testStmt.addBatch("INSERT INTO testBug81468 (selection) VALUES (42)");
12240+
testStmt.addBatch("INSERT INTO testBug81468 (selection) VALUES (43)");
12241+
testStmt.addBatch("INSERT INTO testBug81468 (selection) VALUES (44)");
12242+
testStmt.addBatch("INSERT INTO testBug81468 (selection) VALUES (45)");
12243+
assertArrayEquals(new int[] { 1, 1, 1, 1, 1 }, testStmt.executeBatch());
12244+
testStmt.close();
12245+
12246+
testConn.close();
12247+
} while (useSPS = !useSPS);
12248+
}
12249+
12250+
public static class TestBug81468QueryInterceptor extends BaseQueryInterceptor {
12251+
private static int expectedNumberOfExecutions = 0;
12252+
private static int expectedNumberOfQueries = 0;
12253+
private static int expectedNumberOfValues = 0;
12254+
private static int executionsCount = 0;
12255+
12256+
static void resetExpectedValues(int expExecs, int expQueries, int expVals) {
12257+
expectedNumberOfExecutions = expExecs;
12258+
expectedNumberOfQueries = expQueries;
12259+
expectedNumberOfValues = expVals;
12260+
executionsCount = 0;
12261+
}
12262+
12263+
@Override
12264+
public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery) {
12265+
String query = sql.get();
12266+
if (query.contains("testBug81468")) {
12267+
assertTrue(++executionsCount <= expectedNumberOfExecutions,
12268+
"Too many statement executions. The query [" + query + "] should have been re-written");
12269+
assertEquals(expectedNumberOfQueries, countQueries(query), "Wrong number of queries in [" + query + "]");
12270+
assertEquals(expectedNumberOfValues, countValues(query));
12271+
}
12272+
return super.preProcess(sql, interceptedQuery);
12273+
}
12274+
12275+
private int countQueries(String query) {
12276+
return query.split(";").length;
12277+
}
12278+
12279+
private int countValues(String query) {
12280+
query += "/* junk */"; // Add some junk to the end of the query so that the following split allows counting the values correctly.
12281+
if (query.contains("?")) {
12282+
return query.split("\\(\\?\\)").length - 1;
12283+
}
12284+
return query.split("\\(\\d{2}\\)").length - 1;
12285+
}
12286+
}
12287+
1217112288
}

0 commit comments

Comments
 (0)