Bug #40439 Error using batched prepared statements

Submitted: 30 Oct 2008 17:07 Modified: 23 Jun 2009 14:34
Reporter: Stephane Varoqui Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:5.1.7 OS:Any
Assigned to: Jess Balint CPU Architecture:Any
Tags: Batch Insert Jdbc

[30 Oct 2008 17:07] Stephane Varoqui
Description:
When using rewriteBatchedStatements=true with:
insert into table_name_values (...) values (...) 

Query rewriting will fail because 'values' at the end of the table name is mistaken for the reserved keyword.

How to repeat:
            conn.setAutoCommit(false);

            final PreparedStatement ps = conn
                    .prepareStatement("INSERT INTO PRIMI_VALUES (ID, ELEMENT, ORDR) VALUES (?, ?, ?)");
            for (int k = 0; k < 10; k++) {
                ps.setInt(1, k);
                ps.setString(2, "toto");
                ps.setInt(3, k);
                ps.addBatch();
            }
            conn.commit();

Table name must be terminated by "VALUES" and followed by an empty space

Suggested fix:
        final static Pattern REGEXP = Pattern.compile("^.*?[ \\)]VALUES *\\(", Pattern.CASE_INSENSITIVE);
	private String extractValuesClause() throws SQLException {
		if (this.batchedValuesClause == null) {
			final Matcher matcher = REGEXP.matcher(this.originalSql);
	
			if (!matcher.find()) {
				return null;
			}
	
			int indexOfFirstParen = matcher.group().length()-1;
			assert indexOfFirstParen >= "INSERT INTO x VALUES(".length()-1;
			assert this.originalSql.charAt(indexOfFirstParen) == '(';
			
			if (indexOfFirstParen == -1) {
				return null;
			}
	
			int indexOfLastParen = this.originalSql.lastIndexOf(')');
	
			if (indexOfLastParen == -1) {
				return null;
			}
	
			this.batchedValuesClause = this.originalSql.substring(indexOfFirstParen,
					indexOfLastParen + 1);
		}
			
		return this.batchedValuesClause;
	}
[30 Oct 2008 20:34] Tonci Grgin
Test case

Attachment: TestBug40439.java (text/java), 1.87 KiB.

[30 Oct 2008 20:38] Tonci Grgin
Hello Stephane.

Verified as described using latest c/J sources and attached test case. If we do not use "rewriteBatchedStatements" everything is just fine. When "rewriteBatchedStatements=true" we have an error:

Connected to 5.0.68-pb10-log
java.vm.version         : 1.5.0_12-b04
java.vm.vendor          : Sun Microsystems Inc.
java.runtime.version    : 1.5.0_12-b04
os.name                 : Windows XP
os.version              : null
sun.management.compiler : HotSpot Client Compiler
E
Time: 0,407
There was 1 error:
1) testBug40439(testsuite.simple.TestBug40439)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 (2,'toto',2),(id,data, ordr) values (3,'toto',3),(id,data, ordr) values (' at line 1
	at com.mysql.jdbc.PreparedStatement.executeBatchedInserts(PreparedStatement.java:1495)
	at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1097)
	at testsuite.simple.TestBug40439.testBug40439(TestBug40439.java:42)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at testsuite.simple.TestBug40439.main(TestBug40439.java:57)

FAILURES!!!
Tests run: 1,  Failures: 0,  Errors: 1

And on server:
61 Query  INSERT INTO bug40439_values (id,data, ordr) values (1,'toto',1),(id,data, ordr) values (2,'toto',2),(id,data, ordr) values (3,'toto',3),(id,data, ordr) values (4,'toto',4),(id,data, ordr) values (5,'toto',5),(id,data, ordr) values (6,'toto',6),(id,data, ordr) values (7,'toto',7),(id,data, ordr) values (8,'toto',8),(id,data, ordr) values (9,'toto',9),(id,data, ordr) values (10,'toto',10)
[2 Mar 2009 21:45] Jess Balint
fix + test

Attachment: bug40439.diff (text/x-diff), 3.05 KiB.

[2 Jun 2009 5:59] Jess Balint
Pushed for release in 5.1.8
[23 Jun 2009 14:34] Tony Bedford
An entry was added to the 5.1.8 changelog:

When using rewriteBatchedStatements=true with:

INSERT INTO table_name_values (...) VALUES (...)

Query rewriting failed because “values” at the end of the table name was mistaken for the reserved keyword. The error generated was as follows:

testBug40439(testsuite.simple.TestBug40439)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 (2,'toto',2),(id,data, ordr) values
(3,'toto',3),(id,data, ordr) values (' at line 1
at com.mysql.jdbc.PreparedStatement.executeBatchedInserts(PreparedStatement.java:1495)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1097)
at testsuite.simple.TestBug40439.testBug40439(TestBug40439.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at testsuite.simple.TestBug40439.main(TestBug40439.java:57)

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.041 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.