Details
-
Bug
-
Status: Closed (View Workflow)
-
Minor
-
Resolution: Fixed
-
1.2.3
-
None
Description
A re-written batch insert statement can fail if the insert statement doesn't contain a space before the VALUES keyword. This is illustrated with the following test:
@Test
|
public void testWhitespaceInRewrittenBatchInsert() throws Exception {
|
Class.forName("org.mariadb.jdbc.Driver");
|
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true", "root", "password");
|
Statement stmt = null;
|
PreparedStatement insertStmt = null;
|
try {
|
stmt = conn.createStatement();
|
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS test_table(col1 VARCHAR(32), col2 VARCHAR(32))");
|
|
insertStmt = conn.prepareStatement("INSERT INTO test_table (col1, col2)VALUES (?, ?)");
|
insertStmt.setString(1, "a");
|
insertStmt.setString(2, "b");
|
insertStmt.addBatch();
|
insertStmt.setString(1, "c");
|
insertStmt.setString(2, "d");
|
insertStmt.addBatch();
|
insertStmt.executeBatch();
|
conn.commit();
|
}
|
finally {
|
if (insertStmt != null) {
|
insertStmt.close();
|
}
|
if (stmt != null) {
|
stmt.close();
|
}
|
conn.close();
|
}
|
}
|
The test will fail with the following exception:
java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES ('c', 'd')' at line 1
|
Query is:
|
sql : 'INSERT INTO test_table (col1, col2)VALUES (?, ?)', parameters : ['a','b']
|
at org.mariadb.jdbc.MySQLStatement.executeBatch(MySQLStatement.java:1274)
|
at TestMariaDBConnector.testWhitespaceInRewrittenBatchInsert(TestMariaDBConnector.java:30)
|
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
|
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
at java.lang.reflect.Method.invoke(Method.java:483)
|
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
|
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
|
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
|
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
|
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
|
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
|
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
|
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
|
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
|
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
|
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
|
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
|
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
|
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
|
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
|
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
|
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
|
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
|
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
|
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES ('c', 'd')' at line 1
|
Query is:
|
sql : 'INSERT INTO test_table (col1, col2)VALUES (?, ?)', parameters : ['a','b']
|
at org.mariadb.jdbc.internal.SQLExceptionMapper.get(SQLExceptionMapper.java:138)
|
at org.mariadb.jdbc.internal.SQLExceptionMapper.throwException(SQLExceptionMapper.java:106)
|
at org.mariadb.jdbc.MySQLStatement.executeQueryEpilog(MySQLStatement.java:252)
|
at org.mariadb.jdbc.MySQLStatement.execute(MySQLStatement.java:317)
|
at org.mariadb.jdbc.MySQLStatement.executeBatch(MySQLStatement.java:1254)
|
... 24 more
|
Caused by: org.mariadb.jdbc.internal.common.QueryException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES ('c', 'd')' at line 1
|
Query is:
|
sql : 'INSERT INTO test_table (col1, col2)VALUES (?, ?)', parameters : ['a','b']
|
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.getResult(MySQLProtocol.java:969)
|
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.executeQuery(MySQLProtocol.java:1021)
|
at org.mariadb.jdbc.MySQLStatement.execute(MySQLStatement.java:310)
|
... 25 more
|
This seems to because of the " VALUE" constant used to find the keyword in the MySQLStatement.getInsertIncipit() method.