Bug #46788 | While using ON DUPLICATE KEY UPDATE on a batchRewriteStatements I get exception | ||
---|---|---|---|
Submitted: | 18 Aug 2009 14:58 | Modified: | 16 Sep 2009 13:42 |
Reporter: | Dan Dumitriu | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / J | Severity: | S2 (Serious) |
Version: | 5.1.8 | OS: | Linux (Fedora 10) |
Assigned to: | Mark Matthews | CPU Architecture: | Any |
Tags: | exception, ON DUPLICATE KEY UPDATE, Parameter index out of range |
[18 Aug 2009 14:58]
Dan Dumitriu
[18 Aug 2009 15:08]
Mark Matthews
Versions prior to 5.1.8 wouldn't attempt to re-write a query of this form as a multi-value INSERT. 5.1.8 will attempt to re-write this query as a multi-value INSERT. It seems we'll need a check that there are no parameters after the ON DUPLICATE KEY UPDATE clause, because it's not possible to re-write the query into a multi-value INSERT. Instead it should be sent as a multi-query (as it was prior to 5.1.8).
[18 Aug 2009 16:01]
Dan Dumitriu
Hi, Actually I was hopping I will get this fix and still aim for some performance improvement. As I found in a presentation (ConnectorJ Performance) by someone called Mark Matthews ;) A Rewritten INSERT INSERT INTO foo VALUES (...),(...),(...) up to max_allowed_packet Starting in 5.1.8, ON DUPLICATE KEY UPDATE rewritten into multi-value as well! except for case where you use LAST_INSERT_ID() I do not know if that is technically possible or not. Dan
[18 Aug 2009 19:01]
Mark Matthews
The issue is that the query can not be re-written to a form like: INSERT INTO foo VALUES (...), (...), (...) ON DUPLICATE KEY UPDATE ... because after the update the query has parameters. There is no form of multi-value INSERT that works for that case. The entire batch could be re-written to a form like: INSERT INTO foo VALUES (...) ON DUPLICATE KEY UPDATE bar=1; INSERT INTO foo VALUES (...) ON DUPLICATE KEY UPDATE bar=2; Which is what the fix will have to be. You might consider if the query can be re-written to not require a parameter in the UPDATE clause, i.e. using the VALUES function, see http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
[26 Aug 2009 14:50]
Mark Matthews
Fixed for 5.1.9.
[16 Sep 2009 13:42]
Tony Bedford
An entry was added to the 5.1.9 changelog: When using the ON DUPLICATE KEY UPDATE functionality together with the rewriteBatchedStatements option set to true, an exception was generated when trying to execute the prepared statement: INSERT INTO config_table (modified,id_) VALUES (?,?) ON DUPLICATE KEY UPDATE modified=? The exception generated was: java.sql.SQLException: Parameter index out of range (3 > number of parameters, which is 2). at com.sag.etl.job.processors.JdbcInsertProcessor.flush(JdbcInsertProcessor.java:135) ...... Caused by: java.sql.SQLException: Parameter index out of range (3 > number of parameters, which is 2). at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926) at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3657) at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3641) at com.mysql.jdbc.PreparedStatement.setBytesNoEscapeNoQuotes(PreparedStatement.java:3391) at com.mysql.jdbc.PreparedStatement.setOneBatchedParameterSet(PreparedStatement.java:4203) at com.mysql.jdbc.PreparedStatement.executeBatchedInserts(PreparedStatement.java:1759) at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1441) at com.sag.etl.job.processors.JdbcInsertProcessor.flush(JdbcInsertProcessor.java:131) ... 16 more