=== modified file 'src/com/mysql/jdbc/ConnectionPropertiesImpl.java' --- src/com/mysql/jdbc/ConnectionPropertiesImpl.java 2013-12-11 09:34:24 +0000 +++ src/com/mysql/jdbc/ConnectionPropertiesImpl.java 2014-02-11 14:43:31 +0000 @@ -1699,6 +1699,12 @@ Messages.getString("ConnectionProperties.useReadAheadInput"), //$NON-NLS-1$ "3.1.5", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); //$NON-NLS-1$ + private BooleanConnectionProperty avoidCheckOnDuplicateKeyUpdateInSQL = new BooleanConnectionProperty( + "avoidCheckOnDuplicateKeyUpdateInSQL", //$NON-NLS-1$ + false, + Messages.getString("ConnectionProperties.avoidCheckOnDuplicateKeyUpdateInSQL"), //$NON-NLS-1$ + "5.1.30", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); //$NON-NLS-1$ + private BooleanConnectionProperty useSqlStateCodes = new BooleanConnectionProperty( "useSqlStateCodes", //$NON-NLS-1$ true, @@ -4796,6 +4802,15 @@ return this.getProceduresReturnsFunctions.getValueAsBoolean(); } + public boolean getAvoidCheckOnDuplicateKeyUpdateInSQL() { + return this.avoidCheckOnDuplicateKeyUpdateInSQL.getValueAsBoolean(); + } + + public void setAvoidCheckOnDuplicateKeyUpdateInSQL(boolean v) { + this.avoidCheckOnDuplicateKeyUpdateInSQL.setValue(v); + } + + public void setDetectCustomCollations(boolean detectCustomCollations) { this.detectCustomCollations.setValue(detectCustomCollations); } === modified file 'src/com/mysql/jdbc/LoadBalancedMySQLConnection.java' --- src/com/mysql/jdbc/LoadBalancedMySQLConnection.java 2013-12-11 09:34:24 +0000 +++ src/com/mysql/jdbc/LoadBalancedMySQLConnection.java 2014-02-11 13:58:11 +0000 @@ -2681,4 +2681,8 @@ public boolean getDetectCustomCollations() { return getActiveMySQLConnection().getDetectCustomCollations(); } + + public boolean getAvoidCheckOnDuplicateKeyUpdateInSQL() { + return getActiveMySQLConnection().getAvoidCheckOnDuplicateKeyUpdateInSQL(); + } } === modified file 'src/com/mysql/jdbc/LocalizedErrorMessages.properties' --- src/com/mysql/jdbc/LocalizedErrorMessages.properties 2013-12-11 09:34:24 +0000 +++ src/com/mysql/jdbc/LocalizedErrorMessages.properties 2014-02-11 14:44:12 +0000 @@ -651,7 +651,8 @@ ConnectionProperties.connectionAttributes=A comma-delimited list of user-defined key:value pairs (in addition to standard MySQL-defined key:value pairs) to be passed to MySQL Server for display as connection attributes in the PERFORMANCE_SCHEMA.SESSION_CONNECT_ATTRS table. Example usage: connectionAttributes=key1:value1,key2:value2 This functionality is available for use with MySQL Server version 5.6 or later only. Earlier versions of MySQL Server do not support connection attributes, causing this configuration option will be ignored. Setting connectionAttributes=none will cause connection attribute processing to be bypassed, for situations where Connection creation/initialization speed is critical. ConnectionProperties.getProceduresReturnsFunctions=Pre-JDBC4 DatabaseMetaData API has only the getProcedures() and getProcedureColumns() methods, so they return metadata info for both stored procedures and functions. JDBC4 was extended with the getFunctions() and getFunctionColumns() methods and the expected behaviours of previous methods are not well defined. For JDBC4 and higher, default 'true' value of the option means that calls of DatabaseMetaData.getProcedures() and DatabaseMetaData.getProcedureColumns() return metadata for both procedures and functions as before, keeping backward compatibility. Setting this property to 'false' decouples Connector/J from its pre-JDBC4 behaviours for DatabaseMetaData.getProcedures() and DatabaseMetaData.getProcedureColumns(), forcing them to return metadata for procedures only. ConnectionProperties.detectCustomCollations=Should the driver detect custom charsets/collations installed on server (true/false, defaults to 'false'). If this option set to 'true' driver gets actual charsets/collations from server each time connection establishes. This could slow down connection initialization significantly. -# +ConnectionProperties.avoidCheckOnDuplicateKeyUpdateInSQL=Avoids to check every INSERT statement if it contains "ON DUPLICATE KEY UPDATE" clause. +# # Error Messages for Connection Properties # === modified file 'src/com/mysql/jdbc/MySQLConnection.java' --- src/com/mysql/jdbc/MySQLConnection.java 2013-03-26 15:12:21 +0000 +++ src/com/mysql/jdbc/MySQLConnection.java 2014-02-11 13:58:11 +0000 @@ -206,4 +206,6 @@ MySQLConnection getLoadBalanceSafeProxy(); + boolean getAvoidCheckOnDuplicateKeyUpdateInSQL(); + } === modified file 'src/com/mysql/jdbc/ServerPreparedStatement.java' --- src/com/mysql/jdbc/ServerPreparedStatement.java 2013-11-19 14:37:08 +0000 +++ src/com/mysql/jdbc/ServerPreparedStatement.java 2014-02-11 13:58:06 +0000 @@ -372,12 +372,13 @@ checkNullOrEmptyQuery(sql); - this.hasOnDuplicateKeyUpdate = containsOnDuplicateKeyInString(sql); - int startOfStatement = findStartOfStatement(sql); this.firstCharOfStmt = StringUtils.firstAlphaCharUc(sql, startOfStatement); - + + this.hasOnDuplicateKeyUpdate = firstCharOfStmt == 'I' + && containsOnDuplicateKeyInString(sql); + if (this.connection.versionMeetsMinimum(5, 0, 0)) { this.serverNeedsResetBeforeEachExecution = !this.connection.versionMeetsMinimum(5, 0, 3); === modified file 'src/com/mysql/jdbc/StatementImpl.java' --- src/com/mysql/jdbc/StatementImpl.java 2013-11-17 19:53:19 +0000 +++ src/com/mysql/jdbc/StatementImpl.java 2014-02-11 14:53:39 +0000 @@ -799,10 +799,13 @@ MySQLConnection locallyScopedConn = checkClosed(); synchronized (locallyScopedConn.getConnectionMutex()) { + char firstNonWsChar = StringUtils.firstAlphaCharUc(sql, findStartOfStatement(sql)); + this.retrieveGeneratedKeys = returnGeneratedKeys; lastQueryIsOnDupKeyUpdate = false; if (returnGeneratedKeys) - lastQueryIsOnDupKeyUpdate = containsOnDuplicateKeyInString(sql); + lastQueryIsOnDupKeyUpdate = firstNonWsChar == 'I' + && containsOnDuplicateKeyInString(sql); resetCancelledState(); @@ -810,8 +813,6 @@ checkClosed(); - char firstNonWsChar = StringUtils.firstAlphaCharUc(sql, findStartOfStatement(sql)); - boolean isSelect = true; if (firstNonWsChar != 'S') { @@ -1208,7 +1209,8 @@ String sql = (String) this.batchedArgs.get(commandIndex); updateCounts[commandIndex] = executeUpdate(sql, true, true); // limit one generated key per OnDuplicateKey statement - getBatchedGeneratedKeys(containsOnDuplicateKeyInString(sql) ? 1 : 0); + char firstNonWsChar = StringUtils.firstAlphaCharUc(sql, findStartOfStatement(sql)); + getBatchedGeneratedKeys(firstNonWsChar == 'I' && containsOnDuplicateKeyInString(sql) ? 1 : 0); } catch (SQLException ex) { updateCounts[commandIndex] = EXECUTE_FAILED; @@ -3071,7 +3073,10 @@ } protected int getOnDuplicateKeyLocation(String sql) { - return StringUtils.indexOfIgnoreCaseRespectMarker(0, + if (this.connection.getAvoidCheckOnDuplicateKeyUpdateInSQL()) { + return -1; + } + return StringUtils.indexOfIgnoreCaseRespectMarker(0, sql, "ON DUPLICATE KEY UPDATE ", "\"'`", "\"'`", !this.connection.isNoBackslashEscapesSet()); }