Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/FabricConnection.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/FabricConnection.java (.../FabricConnection.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/FabricConnection.java (.../FabricConnection.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import com.mysql.fabric.proto.xmlrpc.XmlRpcClient; @@ -36,7 +37,9 @@ private Map shardMappingsByTableName = new HashMap(); private Map serverGroupsByName = new HashMap(); private long shardMappingsExpiration; + private int shardMappingsTtl; private long serverGroupsExpiration; + private int serverGroupsTtl; public FabricConnection(String url, String username, String password) throws FabricCommunicationException { this.client = new XmlRpcClient(url, username, password); @@ -67,13 +70,15 @@ public int refreshState() throws FabricCommunicationException { FabricStateResponse> serverGroups = this.client.getServerGroups(); FabricStateResponse> shardMappings = this.client.getShardMappings(); - this.serverGroupsExpiration = serverGroups.getExpireTimeMillis(); - this.shardMappingsExpiration = shardMappings.getExpireTimeMillis(); + this.serverGroupsExpiration = serverGroups.getExpireTimeMillis(); + this.serverGroupsTtl = serverGroups.getTtl(); for (ServerGroup g : serverGroups.getData()) { this.serverGroupsByName.put(g.getName(), g); } + this.shardMappingsExpiration = shardMappings.getExpireTimeMillis(); + this.shardMappingsTtl = shardMappings.getTtl(); for (ShardMapping m : shardMappings.getData()) { // a shard mapping may be associated with more than one table for (ShardTable t : m.getShardTables()) { @@ -84,16 +89,28 @@ return 0; } - public ServerGroup getServerGroup(String serverGroupName) throws FabricCommunicationException { + public int refreshStatePassive() { + try { + return refreshState(); + } catch (FabricCommunicationException e) { + // Fabric node is down but we can operate on previous setup. Just reset the TTL timers. + this.serverGroupsExpiration = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(this.serverGroupsTtl); + this.shardMappingsExpiration = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(this.shardMappingsTtl); + } + + return 0; + } + + public ServerGroup getServerGroup(String serverGroupName) { if (isStateExpired()) { - refreshState(); + refreshStatePassive(); } return this.serverGroupsByName.get(serverGroupName); } - public ShardMapping getShardMapping(String database, String table) throws FabricCommunicationException { + public ShardMapping getShardMapping(String database, String table) { if (isStateExpired()) { - refreshState(); + refreshStatePassive(); } return this.shardMappingsByTableName.get(database + "." + table); } Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/FabricStateResponse.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/FabricStateResponse.java (.../FabricStateResponse.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/FabricStateResponse.java (.../FabricStateResponse.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -23,24 +23,33 @@ package com.mysql.fabric; +import java.util.concurrent.TimeUnit; + public class FabricStateResponse { private T data; + private int secsTtl; private long expireTimeMillis; public FabricStateResponse(T data, int secsTtl) { this.data = data; - this.expireTimeMillis = System.currentTimeMillis() + (1000 * secsTtl); + this.secsTtl = secsTtl; + this.expireTimeMillis = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(secsTtl); } - public FabricStateResponse(T data, long expireTimeMillis) { + public FabricStateResponse(T data, int secsTtl, long presetExpireTimeMillis) { this.data = data; - this.expireTimeMillis = expireTimeMillis; + this.secsTtl = secsTtl; + this.expireTimeMillis = presetExpireTimeMillis; } public T getData() { return this.data; } + public int getTtl() { + return this.secsTtl; + } + /** * The expiration time of this data. Should be compared to {@link System.currentTimeMillis()}. */ Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/HashShardMapping.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/HashShardMapping.java (.../HashShardMapping.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/HashShardMapping.java (.../HashShardMapping.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -44,6 +44,7 @@ } private static final MessageDigest md5Hasher; + static { try { md5Hasher = MessageDigest.getInstance("MD5"); @@ -59,7 +60,10 @@ @Override protected ShardIndex getShardIndexForKey(String stringKey) { - String hashedKey = new BigInteger(/* unsigned/positive */1, md5Hasher.digest(stringKey.getBytes())).toString(16).toUpperCase(); + String hashedKey; + synchronized (md5Hasher) { + hashedKey = new BigInteger(/* unsigned/positive */1, md5Hasher.digest(stringKey.getBytes())).toString(16).toUpperCase(); + } // pad out to 32 digits for (int i = 0; i < (32 - hashedKey.length()); ++i) { Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/Response.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/Response.java (.../Response.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/Response.java (.../Response.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -36,9 +36,10 @@ private String fabricUuid; private int ttl; private String errorMessage; - private List resultSet; + private List> resultSet; - public Response(List responseData) throws FabricCommunicationException { + @SuppressWarnings("unchecked") + public Response(List responseData) throws FabricCommunicationException { // parser of protocol version 1 as defined by WL#7760 this.protocolVersion = (Integer) responseData.get(0); if (this.protocolVersion != 1) { @@ -50,10 +51,10 @@ if ("".equals(this.errorMessage)) { this.errorMessage = null; } - List resultSets = (List) responseData.get(4); + List> resultSets = (List>) responseData.get(4); if (resultSets.size() > 0) { - Map resultData = (Map) resultSets.get(0); - this.resultSet = new ResultSetParser().parse((Map) resultData.get("info"), (List) resultData.get("rows")); + Map resultData = resultSets.get(0); + this.resultSet = new ResultSetParser().parse((Map) resultData.get("info"), (List>) resultData.get("rows")); } } @@ -73,7 +74,7 @@ return this.errorMessage; } - public List getResultSet() { + public List> getResultSet() { return this.resultSet; } } Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/ServerGroup.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/ServerGroup.java (.../ServerGroup.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/ServerGroup.java (.../ServerGroup.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -47,6 +47,7 @@ /** * Find the master server for this group. + * * @return the master server, or null if there's no master for the current group state */ public Server getMaster() { @@ -60,6 +61,7 @@ /** * Lookup a server in this group for the matching host:port string. + * * @return the server, if found. null otherwise */ public Server getServer(String hostPortString) { Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/hibernate/FabricMultiTenantConnectionProvider.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/hibernate/FabricMultiTenantConnectionProvider.java (.../FabricMultiTenantConnectionProvider.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/hibernate/FabricMultiTenantConnectionProvider.java (.../FabricMultiTenantConnectionProvider.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -100,12 +100,8 @@ */ public Connection getConnection(String tenantIdentifier) throws SQLException { String serverGroupName = this.shardMapping.getGroupNameForKey(tenantIdentifier); - try { - ServerGroup serverGroup = this.fabricConnection.getServerGroup(serverGroupName); - return getReadWriteConnectionFromServerGroup(serverGroup); - } catch (FabricCommunicationException ex) { - throw new RuntimeException(ex); - } + ServerGroup serverGroup = this.fabricConnection.getServerGroup(serverGroupName); + return getReadWriteConnectionFromServerGroup(serverGroup); } /** @@ -135,6 +131,7 @@ return false; } + @SuppressWarnings("rawtypes") public boolean isUnwrappableAs(Class unwrapType) { return false; } Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLConnectionProxy.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLConnectionProxy.java (.../FabricMySQLConnectionProxy.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLConnectionProxy.java (.../FabricMySQLConnectionProxy.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -70,6 +70,8 @@ import com.mysql.jdbc.SingleByteCharsetConverter; import com.mysql.jdbc.StatementImpl; import com.mysql.jdbc.StatementInterceptorV2; +import com.mysql.jdbc.Util; +import com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException; import com.mysql.jdbc.log.Log; import com.mysql.jdbc.log.LogFactory; import com.mysql.jdbc.profiler.ProfilerEventHandler; @@ -84,7 +86,7 @@ */ public class FabricMySQLConnectionProxy extends ConnectionPropertiesImpl implements FabricMySQLConnection, FabricMySQLConnectionProperties { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 5845485979107347258L; private Log log; @@ -135,6 +137,20 @@ // These locks are used to prevent simultaneous syncing of the state of the current group's servers. private static final Set replConnGroupLocks = Collections.synchronizedSet(new HashSet()); + private static final Class JDBC4_NON_TRANSIENT_CONN_EXCEPTION; + + static { + Class clazz = null; + try { + if (Util.isJdbc4()) { + clazz = Class.forName("com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException"); + } + } catch (ClassNotFoundException e) { + // no-op + } + JDBC4_NON_TRANSIENT_CONN_EXCEPTION = clazz; + } + public FabricMySQLConnectionProxy(Properties props) throws SQLException { // first, handle and remove Fabric-specific properties. once fabricShardKey et al are ConnectionProperty instances this will be unnecessary this.fabricShardKey = props.getProperty(FabricMySQLDriver.FABRIC_SHARD_KEY_PROPERTY_KEY); @@ -190,16 +206,15 @@ getExceptionInterceptor(), this); } + // initialize log before any further calls that might actually use it + this.log = LogFactory.getLogger(getLogger(), "FabricMySQLConnectionProxy", null); + setShardTable(this.fabricShardTable); setShardKey(this.fabricShardKey); setServerGroupName(this.fabricServerGroup); - - this.log = LogFactory.getLogger(getLogger(), "FabricMySQLConnectionProxy", null); } - private boolean intercepting = false; // prevent recursion - /** * Deal with an exception thrown on an underlying connection. We only consider connection exceptions (SQL State 08xxx). We internally handle a possible * failover situation. @@ -208,19 +223,21 @@ * @param conn * @param group * @param hostname - * @param port + * @param portNumber * @throws FabricCommunicationException */ - synchronized SQLException interceptException(SQLException sqlEx, Connection conn, String groupName, String hostname, String port) + synchronized SQLException interceptException(SQLException sqlEx, Connection conn, String groupName, String hostname, String portNumber) throws FabricCommunicationException { - // we are only concerned with connection failures, skip anything else - if (sqlEx.getSQLState() != null && !(sqlEx.getSQLState().startsWith("08") - || com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException.class.isAssignableFrom(sqlEx.getClass()))) { + // we are only concerned with connection failures to MySQL servers, skip anything else including connection failures to Fabric + if ((sqlEx.getSQLState() == null || !sqlEx.getSQLState().startsWith("08")) + && !MySQLNonTransientConnectionException.class.isAssignableFrom(sqlEx.getClass()) + && (JDBC4_NON_TRANSIENT_CONN_EXCEPTION == null || !JDBC4_NON_TRANSIENT_CONN_EXCEPTION.isAssignableFrom(sqlEx.getClass())) + || sqlEx.getCause() != null && FabricCommunicationException.class.isAssignableFrom(sqlEx.getCause().getClass())) { return null; } // find the Server corresponding to this connection - Server currentServer = this.serverGroup.getServer(hostname + ":" + port); + Server currentServer = this.serverGroup.getServer(hostname + ":" + portNumber); // we have already failed over or dealt with this connection, let the exception propagate if (currentServer == null) { @@ -237,7 +254,7 @@ try { // refresh group status. (after reporting the error. error reporting may trigger a failover) try { - this.fabricConnection.refreshState(); + this.fabricConnection.refreshStatePassive(); setCurrentServerGroup(this.serverGroup.getName()); } catch (SQLException ex) { return SQLError.createSQLException("Unable to refresh Fabric state. Failover impossible", SQLError.SQL_STATE_CONNECTION_FAILURE, ex, null); @@ -264,12 +281,7 @@ */ private void refreshStateIfNecessary() throws SQLException { if (this.fabricConnection.isStateExpired()) { - try { - this.fabricConnection.refreshState(); - } catch (FabricCommunicationException ex) { - throw SQLError.createSQLException("Unable to establish connection to the Fabric server", SQLError.SQL_STATE_CONNECTION_REJECTED, ex, - getExceptionInterceptor(), this); - } + this.fabricConnection.refreshStatePassive(); if (this.serverGroup != null) { setCurrentServerGroup(this.serverGroup.getName()); } @@ -326,22 +338,16 @@ String db = this.database; if (shardTable.contains(".")) { String pair[] = shardTable.split("\\."); - table = pair[0]; - db = pair[1]; + db = pair[0]; + table = pair[1]; } - try { - this.shardMapping = this.fabricConnection.getShardMapping(db, table); - if (this.shardMapping == null) { - throw SQLError.createSQLException("Shard mapping not found for table `" + shardTable + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null, - getExceptionInterceptor(), this); - } - // default to global group - setCurrentServerGroup(this.shardMapping.getGlobalGroupName()); - - } catch (FabricCommunicationException ex) { - throw SQLError.createSQLException("Fabric communication failure.", SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE, ex, getExceptionInterceptor(), - this); + this.shardMapping = this.fabricConnection.getShardMapping(db, table); + if (this.shardMapping == null) { + throw SQLError.createSQLException("Shard mapping not found for table `" + shardTable + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null, + getExceptionInterceptor(), this); } + // default to global group + setCurrentServerGroup(this.shardMapping.getGlobalGroupName()); } } @@ -402,24 +408,18 @@ this.currentConnection = null; - try { - // choose shard mapping if necessary - if (this.shardMapping == null) { - if (this.fabricConnection.getShardMapping(this.database, tableName) != null) { - setShardTable(tableName); - } - } else { // make sure we aren't in conflict with the chosen shard mapping - ShardMapping mappingForTableName = this.fabricConnection.getShardMapping(this.database, tableName); - if (mappingForTableName != null && !mappingForTableName.equals(this.shardMapping)) { - throw SQLError.createSQLException("Cross-shard query not allowed", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null, getExceptionInterceptor(), - this); - } + // choose shard mapping if necessary + if (this.shardMapping == null) { + if (this.fabricConnection.getShardMapping(this.database, tableName) != null) { + setShardTable(tableName); } - this.queryTables.add(tableName); - } catch (FabricCommunicationException ex) { - throw SQLError.createSQLException("Fabric communication failure.", SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE, ex, getExceptionInterceptor(), - this); + } else { // make sure we aren't in conflict with the chosen shard mapping + ShardMapping mappingForTableName = this.fabricConnection.getShardMapping(this.database, tableName); + if (mappingForTableName != null && !mappingForTableName.equals(this.shardMapping)) { + throw SQLError.createSQLException("Cross-shard query not allowed", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null, getExceptionInterceptor(), this); + } } + this.queryTables.add(tableName); } /** @@ -433,15 +433,8 @@ * Change the server group to the given named group. */ protected void setCurrentServerGroup(String serverGroupName) throws SQLException { - this.serverGroup = null; + this.serverGroup = this.fabricConnection.getServerGroup(serverGroupName); - try { - this.serverGroup = this.fabricConnection.getServerGroup(serverGroupName); - } catch (FabricCommunicationException ex) { - throw SQLError.createSQLException("Fabric communication failure.", SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE, ex, getExceptionInterceptor(), - this); - } - if (this.serverGroup == null) { throw SQLError.createSQLException("Cannot find server group: `" + serverGroupName + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null, getExceptionInterceptor(), this); @@ -473,15 +466,15 @@ * instead the {@link LoadBalancedConnectionProxy} for either the * master or slaves. */ - protected MySQLConnection getActiveMySQLConnection() throws SQLException { + protected MySQLConnection getActiveMySQLConnectionChecked() throws SQLException { ReplicationConnection c = (ReplicationConnection) getActiveConnection(); MySQLConnection mc = (MySQLConnection) c.getCurrentConnection(); return mc; } - protected MySQLConnection getActiveMySQLConnectionPassive() { + public MySQLConnection getActiveMySQLConnection() { try { - return getActiveMySQLConnection(); + return getActiveMySQLConnectionChecked(); } catch (SQLException ex) { throw new IllegalStateException("Unable to determine active connection", ex); } @@ -508,8 +501,8 @@ currentMasterString = replConnGroup.getMasterHosts().iterator().next(); } // check if master has changed - if (currentMasterString != null && - (this.serverGroup.getMaster() == null || !currentMasterString.equals(this.serverGroup.getMaster().getHostPortString()))) { + if (currentMasterString != null + && (this.serverGroup.getMaster() == null || !currentMasterString.equals(this.serverGroup.getMaster().getHostPortString()))) { // old master is gone (there may be a new one) (closeGently=false) try { replConnGroup.removeMasterHost(currentMasterString, false); @@ -606,6 +599,7 @@ info.setProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY, getCatalog()); info.setProperty("connectionAttributes", "fabricHaGroup:" + this.serverGroup.getName()); info.setProperty("retriesAllDown", "1"); + info.setProperty("allowMasterDownConnections", "true"); info.setProperty("allowSlaveDownConnections", "true"); info.setProperty("readFromMasterWhenNoSlaves", "true"); this.currentConnection = ReplicationConnectionProxy.createProxyInstance(masterHost, info, slaveHosts, info); @@ -730,7 +724,7 @@ } public MySQLConnection getMultiHostSafeProxy() { - return getActiveMySQLConnectionPassive(); + return getActiveMySQLConnection(); } //////////////////////////////////////////////////////// @@ -897,30 +891,30 @@ public ResultSetInternalMethods execSQL(StatementImpl callingStatement, String sql, int maxRows, Buffer packet, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Field[] cachedMetadata) throws SQLException { - return getActiveMySQLConnection().execSQL(callingStatement, sql, maxRows, packet, resultSetType, resultSetConcurrency, streamResults, catalog, + return getActiveMySQLConnectionChecked().execSQL(callingStatement, sql, maxRows, packet, resultSetType, resultSetConcurrency, streamResults, catalog, cachedMetadata); } public ResultSetInternalMethods execSQL(StatementImpl callingStatement, String sql, int maxRows, Buffer packet, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Field[] cachedMetadata, boolean isBatch) throws SQLException { - return getActiveMySQLConnection().execSQL(callingStatement, sql, maxRows, packet, resultSetType, resultSetConcurrency, streamResults, catalog, + return getActiveMySQLConnectionChecked().execSQL(callingStatement, sql, maxRows, packet, resultSetType, resultSetConcurrency, streamResults, catalog, cachedMetadata, isBatch); } public String extractSqlFromPacket(String possibleSqlQuery, Buffer queryPacket, int endOfQueryPacketPosition) throws SQLException { - return getActiveMySQLConnection().extractSqlFromPacket(possibleSqlQuery, queryPacket, endOfQueryPacketPosition); + return getActiveMySQLConnectionChecked().extractSqlFromPacket(possibleSqlQuery, queryPacket, endOfQueryPacketPosition); } public StringBuilder generateConnectionCommentBlock(StringBuilder buf) { - return getActiveMySQLConnectionPassive().generateConnectionCommentBlock(buf); + return getActiveMySQLConnection().generateConnectionCommentBlock(buf); } public MysqlIO getIO() throws SQLException { - return getActiveMySQLConnection().getIO(); + return getActiveMySQLConnectionChecked().getIO(); } public Calendar getCalendarInstanceForSessionOrNew() { - return getActiveMySQLConnectionPassive().getCalendarInstanceForSessionOrNew(); + return getActiveMySQLConnection().getCalendarInstanceForSessionOrNew(); } /** @@ -932,11 +926,11 @@ } public String getServerCharset() { - return getActiveMySQLConnectionPassive().getServerCharset(); + return getActiveMySQLConnection().getServerCharset(); } public TimeZone getServerTimezoneTZ() { - return getActiveMySQLConnectionPassive().getServerTimezoneTZ(); + return getActiveMySQLConnection().getServerTimezoneTZ(); } /** @@ -966,11 +960,11 @@ } public String getCharacterSetMetadata() { - return getActiveMySQLConnectionPassive().getCharacterSetMetadata(); + return getActiveMySQLConnection().getCharacterSetMetadata(); } public java.sql.Statement getMetadataSafeStatement() throws SQLException { - return getActiveMySQLConnection().getMetadataSafeStatement(); + return getActiveMySQLConnectionChecked().getMetadataSafeStatement(); } /** @@ -1022,10 +1016,12 @@ throw SQLError.createSQLFeatureNotSupportedException(); } + @Deprecated public void clearHasTriedMaster() { // no-op } + @Deprecated public boolean hasTriedMaster() { return false; } @@ -2742,6 +2738,7 @@ public void setFailedOver(boolean flag) { } + @Deprecated public void setPreferSlaveDuringFailover(boolean flag) { } @@ -2851,13 +2848,17 @@ return null; } - return getActiveConnectionPassive().getExceptionInterceptor(); + return this.currentConnection.getExceptionInterceptor(); } public String getHost() { return null; } + public String getHostPortPair() { + return getActiveMySQLConnection().getHostPortPair(); + } + public long getId() { return -1; } @@ -2954,10 +2955,11 @@ } public boolean lowerCaseTableNames() { - return false; + return getActiveMySQLConnection().lowerCaseTableNames(); } /** + * * @param stmt */ public void maxRowsChanged(com.mysql.jdbc.Statement stmt) { @@ -2982,7 +2984,7 @@ } public boolean serverSupportsConvertFn() throws SQLException { - return false; + return getActiveMySQLConnectionChecked().serverSupportsConvertFn(); } public void setReadInfoMsgEnabled(boolean flag) { @@ -2992,7 +2994,7 @@ } public boolean storesLowerCaseTableName() { - return false; + return getActiveMySQLConnection().storesLowerCaseTableName(); } public void throwConnectionClosedException() throws SQLException { @@ -3002,6 +3004,7 @@ } /** + * * @param stmt * @throws SQLException */ @@ -3024,6 +3027,11 @@ return null; } + /** + * + * @param name + * @return + */ public String getClientInfo(String name) { return null; } @@ -3040,12 +3048,12 @@ return null; } - public SQLWarning getWarnings() { - return null; + public SQLWarning getWarnings() throws SQLException { + return getActiveMySQLConnectionChecked().getWarnings(); } - public String nativeSQL(String sql) { - return null; + public String nativeSQL(String sql) throws SQLException { + return getActiveMySQLConnectionChecked().nativeSQL(sql); } public ProfilerEventHandler getProfilerEventHandlerInstance() { Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLDriver.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLDriver.java (.../FabricMySQLDriver.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLDriver.java (.../FabricMySQLDriver.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -73,8 +73,8 @@ parsedProps.setProperty(FABRIC_PROTOCOL_PROPERTY_KEY, "http"); if (com.mysql.jdbc.Util.isJdbc4()) { try { - Constructor jdbc4proxy = Class.forName("com.mysql.fabric.jdbc.JDBC4FabricMySQLConnectionProxy").getConstructor( - new Class[] { Properties.class }); + Constructor jdbc4proxy = Class.forName("com.mysql.fabric.jdbc.JDBC4FabricMySQLConnectionProxy") + .getConstructor(new Class[] { Properties.class }); return (Connection) com.mysql.jdbc.Util.handleNewInstance(jdbc4proxy, new Object[] { parsedProps }, null); } catch (Exception e) { throw (SQLException) new SQLException(e.getMessage()).initCause(e); Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/JDBC4FabricMySQLConnectionProxy.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/JDBC4FabricMySQLConnectionProxy.java (.../JDBC4FabricMySQLConnectionProxy.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/JDBC4FabricMySQLConnectionProxy.java (.../JDBC4FabricMySQLConnectionProxy.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -85,6 +85,8 @@ */ public class JDBC4FabricMySQLConnectionProxy extends FabricMySQLConnectionProxy implements JDBC4FabricMySQLConnection, FabricMySQLConnectionProperties { + private static final long serialVersionUID = 5845485979107347258L; + private FabricConnection fabricConnection; public JDBC4FabricMySQLConnectionProxy(Properties props) throws SQLException { Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/DigestAuthentication.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/DigestAuthentication.java (.../DigestAuthentication.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/DigestAuthentication.java (.../DigestAuthentication.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -38,6 +38,8 @@ */ public class DigestAuthentication { + private static Random random = new Random(); + /** * Get the digest challenge header by connecting to the resource * with no credentials. @@ -59,8 +61,8 @@ } } else if (400 == conn.getResponseCode()) { // 400 usually means that auth is disabled on the Fabric node - throw new IOException("Fabric returns status 400. If authentication is disabled on the Fabric node, " + - "omit the `fabricUsername' and `fabricPassword' properties from your connection."); + throw new IOException("Fabric returns status 400. If authentication is disabled on the Fabric node, " + + "omit the `fabricUsername' and `fabricPassword' properties from your connection."); } else { throw ex; } @@ -163,10 +165,11 @@ * value used in the digest calculation. Same as Python. (no * motivation given for this algorithm) */ + @SuppressWarnings("deprecation") public static String generateCnonce(String nonce, String nc) { // Random string, keep it in basic printable ASCII range byte buf[] = new byte[8]; - new Random().nextBytes(buf); + random.nextBytes(buf); for (int i = 0; i < 8; ++i) { buf[i] = (byte) (0x20 + (buf[i] % 95)); } Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/InternalXmlRpcMethodCaller.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/InternalXmlRpcMethodCaller.java (.../InternalXmlRpcMethodCaller.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/InternalXmlRpcMethodCaller.java (.../InternalXmlRpcMethodCaller.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -72,8 +72,8 @@ return v.getValue(); } - private List methodResponseArrayToList(Array array) { - List result = new ArrayList(); + private List methodResponseArrayToList(Array array) { + List result = new ArrayList(); for (Value v : array.getData().getValue()) { result.add(unwrapValue(v)); } @@ -88,7 +88,7 @@ this.xmlRpcClient.clearHeader(name); } - public List call(String methodName, Object args[]) throws FabricCommunicationException { + public List call(String methodName, Object args[]) throws FabricCommunicationException { MethodCall methodCall = new MethodCall(); Params p = new Params(); if (args == null) { Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/ResultSetParser.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/ResultSetParser.java (.../ResultSetParser.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/ResultSetParser.java (.../ResultSetParser.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -39,15 +39,16 @@ * Transform the Fabric formatted result into a list of * hashes/rows. */ - public List parse(Map info, List rows) { + public List> parse(Map info, List> rows) { + @SuppressWarnings("unchecked") List fieldNames = (List) info.get("names"); Map fieldNameIndexes = new HashMap(); for (int i = 0; i < fieldNames.size(); ++i) { fieldNameIndexes.put(fieldNames.get(i), i); } - List result = new ArrayList(rows.size()); - for (List r : rows) { + List> result = new ArrayList>(rows.size()); + for (List r : rows) { Map resultRow = new HashMap(); for (Map.Entry f : fieldNameIndexes.entrySet()) { resultRow.put(f.getKey(), r.get(f.getValue())); Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/XmlRpcClient.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/XmlRpcClient.java (.../XmlRpcClient.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/XmlRpcClient.java (.../XmlRpcClient.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import com.mysql.fabric.FabricCommunicationException; import com.mysql.fabric.FabricStateResponse; @@ -62,6 +63,7 @@ private static final String METHOD_GROUP_LOOKUP_GROUPS = "group.lookup_groups"; private static final String METHOD_GROUP_CREATE = "group.create"; private static final String METHOD_GROUP_ADD = "group.add"; + private static final String METHOD_GROUP_REMOVE = "group.remove"; private static final String METHOD_GROUP_PROMOTE = "group.promote"; private static final String METHOD_GROUP_DESTROY = "group.destroy"; private static final String METHOD_THREAT_REPORT_ERROR = "threat.report_error"; @@ -98,7 +100,7 @@ /** * Unmarshall a response representing a server. */ - private static Server unmarshallServer(Map serverData) throws FabricCommunicationException { + private static Server unmarshallServer(Map serverData) throws FabricCommunicationException { ServerMode mode; ServerRole role; @@ -131,9 +133,9 @@ /** * Convert a list of string/string/bool to Server objects. */ - private static Set toServerSet(List l) throws FabricCommunicationException { + private static Set toServerSet(List> l) throws FabricCommunicationException { Set servers = new HashSet(); - for (Map serverData : l) { + for (Map serverData : l) { servers.add(unmarshallServer(serverData)); } return servers; @@ -160,7 +162,7 @@ public Set getFabricNames() throws FabricCommunicationException { Response resp = errorSafeCallMethod(METHOD_DUMP_FABRIC_NODES, new Object[] {}); Set names = new HashSet(); - for (Map node : resp.getResultSet()) { + for (Map node : resp.getResultSet()) { names.add(node.get(FIELD_HOST) + ":" + node.get(FIELD_PORT)); } return names; @@ -171,7 +173,7 @@ */ public Set getGroupNames() throws FabricCommunicationException { Set groupNames = new HashSet(); - for (Map row : errorSafeCallMethod(METHOD_GROUP_LOOKUP_GROUPS, null).getResultSet()) { + for (Map row : errorSafeCallMethod(METHOD_GROUP_LOOKUP_GROUPS, null).getResultSet()) { groupNames.add((String) row.get(FIELD_GROUP_ID)); } return groupNames; @@ -198,7 +200,7 @@ Response response = errorSafeCallMethod(METHOD_DUMP_SERVERS, new Object[] { version, groupPattern }); // collect all servers by group name Map> serversByGroupName = new HashMap>(); - for (Map server : response.getResultSet()) { + for (Map server : response.getResultSet()) { Server s = unmarshallServer(server); if (serversByGroupName.get(s.getGroupName()) == null) { serversByGroupName.put(s.getGroupName(), new HashSet()); @@ -224,7 +226,7 @@ Response tablesResponse = errorSafeCallMethod(METHOD_DUMP_SHARD_TABLES, args); Set tables = new HashSet(); // construct the tables - for (Map rawTable : tablesResponse.getResultSet()) { + for (Map rawTable : tablesResponse.getResultSet()) { String database = (String) rawTable.get(FIELD_SCHEMA_NAME); String table = (String) rawTable.get(FIELD_TABLE_NAME); String column = (String) rawTable.get(FIELD_COLUMN_NAME); @@ -241,7 +243,7 @@ Set indices = new HashSet(); // construct the index - for (Map rawIndexEntry : indexResponse.getResultSet()) { + for (Map rawIndexEntry : indexResponse.getResultSet()) { String bound = (String) rawIndexEntry.get(FIELD_LOWER_BOUND); int shardId = (Integer) rawIndexEntry.get(FIELD_SHARD_ID); String groupName = (String) rawIndexEntry.get(FIELD_GROUP_ID); @@ -263,11 +265,12 @@ Object args[] = new Object[] { version, shardMappingIdPattern }; // common to all calls Response mapsResponse = errorSafeCallMethod(METHOD_DUMP_SHARD_MAPS, args); // use the lowest ttl of all the calls - long minExpireTimeMillis = System.currentTimeMillis() + (1000 * mapsResponse.getTtl()); + long minExpireTimeMillis = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(mapsResponse.getTtl()); + int baseTtl = mapsResponse.getTtl(); // construct the maps Set mappings = new HashSet(); - for (Map rawMapping : mapsResponse.getResultSet()) { + for (Map rawMapping : mapsResponse.getResultSet()) { int mappingId = (Integer) rawMapping.get(FIELD_MAPPING_ID); ShardingType shardingType = ShardingType.valueOf((String) rawMapping.get(FIELD_TYPE_NAME)); String globalGroupName = (String) rawMapping.get(FIELD_GLOBAL_GROUP_ID); @@ -286,7 +289,7 @@ mappings.add(m); } - return new FabricStateResponse>(mappings, minExpireTimeMillis); + return new FabricStateResponse>(mappings, baseTtl, minExpireTimeMillis); } public FabricStateResponse> getShardMappings() throws FabricCommunicationException { @@ -341,6 +344,10 @@ errorSafeCallMethod(METHOD_GROUP_ADD, new Object[] { groupName, hostname + ":" + port }); } + public void removeServerFromGroup(String groupName, String hostname, int port) throws FabricCommunicationException { + errorSafeCallMethod(METHOD_GROUP_REMOVE, new Object[] { groupName, hostname + ":" + port }); + } + public void promoteServerInGroup(String groupName, String hostname, int port) throws FabricCommunicationException { ServerGroup serverGroup = getServerGroup(groupName); for (Server s : serverGroup.getServers()) { Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Value.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Value.java (.../Value.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Value.java (.../Value.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -23,6 +23,7 @@ package com.mysql.fabric.xmlrpc.base; +import java.util.Arrays; import java.util.GregorianCalendar; import javax.xml.datatype.DatatypeConfigurationException; @@ -187,7 +188,7 @@ break; case Value.TYPE_base64: - sb.append("" + ((byte[]) this.objValue).toString() + ""); + sb.append("" + Arrays.toString((byte[]) this.objValue) + ""); // TODO it's wrong but no harm because it isn't used in fabric protocol break; case Value.TYPE_struct: Index: 3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/exceptions/MySQLFabricException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/exceptions/MySQLFabricException.java (.../MySQLFabricException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/exceptions/MySQLFabricException.java (.../MySQLFabricException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -37,8 +37,8 @@ } public MySQLFabricException(Fault fault) { - super((String) ((Struct) fault.getValue().getValue()).getMember().get(1).getValue().getValue(), "", (Integer) ((Struct) fault.getValue().getValue()) - .getMember().get(0).getValue().getValue()); + super((String) ((Struct) fault.getValue().getValue()).getMember().get(1).getValue().getValue(), "", + (Integer) ((Struct) fault.getValue().getValue()).getMember().get(0).getValue().getValue()); } public MySQLFabricException(String reason, String SQLState, int vendorCode) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/AbandonedConnectionCleanupThread.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/AbandonedConnectionCleanupThread.java (.../AbandonedConnectionCleanupThread.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/AbandonedConnectionCleanupThread.java (.../AbandonedConnectionCleanupThread.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -24,23 +24,44 @@ package com.mysql.jdbc; import java.lang.ref.Reference; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; import com.mysql.jdbc.NonRegisteringDriver.ConnectionPhantomReference; -public class AbandonedConnectionCleanupThread extends Thread { - private static boolean running = true; - private static Thread threadRef = null; +/** + * This class implements a thread that is responsible for closing abandoned MySQL connections, i.e., connections that are not explicitly closed. + * There is only one instance of this class and there is a single thread to do this task. This thread's executor is statically referenced in this same class. + */ +public class AbandonedConnectionCleanupThread implements Runnable { + private static final ExecutorService cleanupThreadExcecutorService; + static Thread threadRef = null; - public AbandonedConnectionCleanupThread() { - super("Abandoned connection cleanup thread"); + static { + cleanupThreadExcecutorService = Executors.newSingleThreadExecutor(new ThreadFactory() { + public Thread newThread(Runnable r) { + Thread t = new Thread(r, "Abandoned connection cleanup thread"); + t.setDaemon(true); + // Tie the thread's context ClassLoader to the ClassLoader that loaded the class instead of inheriting the context ClassLoader from the current + // thread, which would happen by default. + // Application servers may use this information if they attempt to shutdown this thread. By leaving the default context ClassLoader this thread + // could end up being shut down even when it is shared by other applications and, being it statically initialized, thus, never restarted again. + t.setContextClassLoader(AbandonedConnectionCleanupThread.class.getClassLoader()); + return threadRef = t; + } + }); + cleanupThreadExcecutorService.execute(new AbandonedConnectionCleanupThread()); } - @Override + private AbandonedConnectionCleanupThread() { + } + public void run() { - threadRef = this; - while (running) { + for (;;) { try { - Reference ref = NonRegisteringDriver.refQueue.remove(100); + checkContextClassLoaders(); + Reference ref = NonRegisteringDriver.refQueue.remove(5000); if (ref != null) { try { ((ConnectionPhantomReference) ref).cleanup(); @@ -49,19 +70,78 @@ } } + } catch (InterruptedException e) { + threadRef = null; + return; + } catch (Exception ex) { - // no where to really log this if we're static + // Nowhere to really log this. } } } - public static void shutdown() throws InterruptedException { - running = false; - if (threadRef != null) { - threadRef.interrupt(); - threadRef.join(); - threadRef = null; + /** + * Checks if the thread's context ClassLoader is active. This is usually true but some application managers implement a life-cycle mechanism in their + * ClassLoaders that is linked to the corresponding application's life-cycle. As such, a stopped/ended application will have a ClassLoader unable to load + * anything and, eventually, they throw an exception when trying to do so. When this happens, this thread has no point in being alive anymore. + */ + private void checkContextClassLoaders() { + try { + threadRef.getContextClassLoader().getResource(""); + } catch (Throwable e) { + // Shutdown no matter what. + uncheckedShutdown(); } } + /** + * Checks if the context ClassLoaders from this and the caller thread are the same. + * + * @return true if both threads share the same context ClassLoader, false otherwise + */ + private static boolean consistentClassLoaders() { + ClassLoader callerCtxClassLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader threadCtxClassLoader = threadRef.getContextClassLoader(); + return callerCtxClassLoader != null && threadCtxClassLoader != null && callerCtxClassLoader == threadCtxClassLoader; + } + + /** + * Performs a checked shutdown, i.e., the context ClassLoaders from this and the caller thread are checked for consistency prior to performing the shutdown + * operation. + */ + public static void checkedShutdown() { + shutdown(true); + } + + /** + * Performs an unchecked shutdown, i.e., the shutdown is performed independently of the context ClassLoaders from the involved threads. + */ + public static void uncheckedShutdown() { + shutdown(false); + } + + /** + * Shuts down this thread either checking or not the context ClassLoaders from the involved threads. + * + * @param checked + * does a checked shutdown if true, unchecked otherwise + */ + private static void shutdown(boolean checked) { + if (checked && !consistentClassLoaders()) { + // This thread can't be shutdown from the current thread's context ClassLoader. Doing so would most probably prevent from restarting this thread + // later on. An unchecked shutdown can still be done if needed by calling shutdown(false). + return; + } + cleanupThreadExcecutorService.shutdownNow(); + } + + /** + * Shuts down this thread. + * + * @deprecated use {@link #checkedShutdown()} instead. + */ + @Deprecated + public static void shutdown() { + checkedShutdown(); + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Buffer.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Buffer.java (.../Buffer.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Buffer.java (.../Buffer.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -45,6 +45,14 @@ protected boolean wasMultiPacket = false; + /* Type ids of response packets. */ + public static final short TYPE_ID_ERROR = 0xFF; + public static final short TYPE_ID_EOF = 0xFE; + /** It has the same signature as EOF, but may be issued by server only during handshake phase **/ + public static final short TYPE_ID_AUTH_SWITCH = 0xFE; + public static final short TYPE_ID_LOCAL_INFILE = 0xFB; + public static final short TYPE_ID_OK = 0; + public Buffer(byte[] buf) { this.byteBuffer = buf; setBufLength(buf.length); @@ -224,18 +232,22 @@ return this.position; } - final boolean isLastDataPacket() { - return ((getBufLength() < 9) && ((this.byteBuffer[0] & 0xff) == 254)); + final boolean isEOFPacket() { + return (this.byteBuffer[0] & 0xff) == TYPE_ID_EOF && (getBufLength() <= 5); } final boolean isAuthMethodSwitchRequestPacket() { - return ((this.byteBuffer[0] & 0xff) == 254); + return (this.byteBuffer[0] & 0xff) == TYPE_ID_AUTH_SWITCH; } final boolean isOKPacket() { - return ((this.byteBuffer[0] & 0xff) == 0); + return (this.byteBuffer[0] & 0xff) == TYPE_ID_OK; } + final boolean isResultSetOKPacket() { + return (this.byteBuffer[0] & 0xff) == TYPE_ID_EOF && (getBufLength() < 16777215); + } + final boolean isRawPacket() { return ((this.byteBuffer[0] & 0xff) == 1); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/BufferRow.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/BufferRow.java (.../BufferRow.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/BufferRow.java (.../BufferRow.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -267,8 +267,9 @@ break; default: - throw SQLError.createSQLException(Messages.getString("MysqlIO.97") + this.metadata[i].getMysqlType() + Messages.getString("MysqlIO.98") - + (i + 1) + Messages.getString("MysqlIO.99") + this.metadata.length + Messages.getString("MysqlIO.100"), + throw SQLError.createSQLException( + Messages.getString("MysqlIO.97") + this.metadata[i].getMysqlType() + Messages.getString("MysqlIO.98") + (i + 1) + + Messages.getString("MysqlIO.99") + this.metadata.length + Messages.getString("MysqlIO.100"), SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } @@ -361,8 +362,9 @@ return this.rowFromServer.readLenByteArray(0); default: - throw SQLError.createSQLException(Messages.getString("MysqlIO.97") + this.metadata[index].getMysqlType() + Messages.getString("MysqlIO.98") - + (index + 1) + Messages.getString("MysqlIO.99") + this.metadata.length + Messages.getString("MysqlIO.100"), + throw SQLError.createSQLException( + Messages.getString("MysqlIO.97") + this.metadata[index].getMysqlType() + Messages.getString("MysqlIO.98") + (index + 1) + + Messages.getString("MysqlIO.99") + this.metadata.length + Messages.getString("MysqlIO.100"), SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/CallableStatement.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/CallableStatement.java (.../CallableStatement.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/CallableStatement.java (.../CallableStatement.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -219,7 +219,21 @@ while (paramTypesRs.next()) { String paramName = paramTypesRs.getString(4); - int inOutModifier = paramTypesRs.getInt(5); + int inOutModifier; + switch (paramTypesRs.getInt(5)) { + case DatabaseMetaData.procedureColumnIn: + inOutModifier = ParameterMetaData.parameterModeIn; + break; + case DatabaseMetaData.procedureColumnInOut: + inOutModifier = ParameterMetaData.parameterModeInOut; + break; + case DatabaseMetaData.procedureColumnOut: + case DatabaseMetaData.procedureColumnReturn: + inOutModifier = ParameterMetaData.parameterModeOut; + break; + default: + inOutModifier = ParameterMetaData.parameterModeUnknown; + } boolean isOutParameter = false; boolean isInParameter = false; @@ -1365,13 +1379,12 @@ throw SQLError.createSQLException(Messages.getString("CallableStatement.2"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } - if (this.paramInfo == null) { + CallableStatementParam namedParamInfo; + if (this.paramInfo == null || (namedParamInfo = this.paramInfo.getParameter(paramName)) == null) { throw SQLError.createSQLException(Messages.getString("CallableStatement.3") + paramName + Messages.getString("CallableStatement.4"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } - CallableStatementParam namedParamInfo = this.paramInfo.getParameter(paramName); - if (forOut && !namedParamInfo.isOut) { throw SQLError.createSQLException(Messages.getString("CallableStatement.5") + paramName + Messages.getString("CallableStatement.6"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); @@ -2137,7 +2150,9 @@ } if (!found) { - throw SQLError.createSQLException("boo!", "S1000", this.connection.getExceptionInterceptor()); + throw SQLError.createSQLException( + Messages.getString("CallableStatement.21") + outParamInfo.paramName + Messages.getString("CallableStatement.22"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/CharsetMapping.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/CharsetMapping.java (.../CharsetMapping.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/CharsetMapping.java (.../CharsetMapping.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -42,7 +42,7 @@ */ public class CharsetMapping { - public static final int MAP_SIZE = 255; // Size of static maps + public static final int MAP_SIZE = 2048; // Size of static maps public static final String[] COLLATION_INDEX_TO_COLLATION_NAME; public static final MysqlCharset[] COLLATION_INDEX_TO_CHARSET; @@ -120,7 +120,8 @@ private static final String MYSQL_4_0_CHARSET_NAME_win1251 = "win1251"; // 4.1 => 17 (removed) private static final String MYSQL_4_0_CHARSET_NAME_win1251ukr = "win1251ukr"; // 4.1 => 23 cp1251 cp1251_ukrainian_ci - private static final String NOT_USED = MYSQL_CHARSET_NAME_latin1; // punting for not-used character sets + public static final String NOT_USED = MYSQL_CHARSET_NAME_latin1; // punting for not-used character sets + public static final String COLLATION_NOT_DEFINED = "none"; public static final int MYSQL_COLLATION_INDEX_utf8 = 33; public static final int MYSQL_COLLATION_INDEX_binary = 63; @@ -129,8 +130,7 @@ static { // complete list of mysql character sets and their corresponding java encoding names - MysqlCharset[] charset = new MysqlCharset[] { - new MysqlCharset(MYSQL_4_0_CHARSET_NAME_usa7, 1, 0, new String[] { "US-ASCII" }, 4, 0), + MysqlCharset[] charset = new MysqlCharset[] { new MysqlCharset(MYSQL_4_0_CHARSET_NAME_usa7, 1, 0, new String[] { "US-ASCII" }, 4, 0), new MysqlCharset(MYSQL_CHARSET_NAME_ascii, 1, 0, new String[] { "US-ASCII", "ASCII" }), new MysqlCharset(MYSQL_CHARSET_NAME_big5, 2, 0, new String[] { "Big5" }), @@ -257,94 +257,37 @@ // complete list of mysql collations and their corresponding character sets each element of collation[1]..collation[MAP_SIZE-1] must not be null Collation[] collation = new Collation[MAP_SIZE]; collation[1] = new Collation(1, "big5_chinese_ci", 1, MYSQL_CHARSET_NAME_big5); - collation[84] = new Collation(84, "big5_bin", 0, MYSQL_CHARSET_NAME_big5); - collation[2] = new Collation(2, "latin2_czech_cs", 0, MYSQL_CHARSET_NAME_latin2); - collation[9] = new Collation(9, "latin2_general_ci", 1, MYSQL_CHARSET_NAME_latin2); - collation[21] = new Collation(21, "latin2_hungarian_ci", 0, MYSQL_CHARSET_NAME_latin2); - collation[27] = new Collation(27, "latin2_croatian_ci", 0, MYSQL_CHARSET_NAME_latin2); - collation[77] = new Collation(77, "latin2_bin", 0, MYSQL_CHARSET_NAME_latin2); - + collation[3] = new Collation(3, "dec8_swedish_ci", 0, MYSQL_CHARSET_NAME_dec8); collation[4] = new Collation(4, "cp850_general_ci", 1, MYSQL_CHARSET_NAME_cp850); - collation[80] = new Collation(80, "cp850_bin", 0, MYSQL_CHARSET_NAME_cp850); - collation[5] = new Collation(5, "latin1_german1_ci", 1, MYSQL_CHARSET_NAME_latin1); - collation[8] = new Collation(8, "latin1_swedish_ci", 0, MYSQL_CHARSET_NAME_latin1); - collation[15] = new Collation(15, "latin1_danish_ci", 0, MYSQL_CHARSET_NAME_latin1); - collation[31] = new Collation(31, "latin1_german2_ci", 0, MYSQL_CHARSET_NAME_latin1); - collation[47] = new Collation(47, "latin1_bin", 0, MYSQL_CHARSET_NAME_latin1); - collation[48] = new Collation(48, "latin1_general_ci", 0, MYSQL_CHARSET_NAME_latin1); - collation[49] = new Collation(49, "latin1_general_cs", 0, MYSQL_CHARSET_NAME_latin1); - collation[76] = new Collation(76, "not_implemented", 0, NOT_USED); - collation[94] = new Collation(94, "latin1_spanish_ci", 0, MYSQL_CHARSET_NAME_latin1); - collation[100] = new Collation(100, "not_implemented", 0, NOT_USED); - collation[125] = new Collation(125, "not_implemented", 0, NOT_USED); - collation[126] = new Collation(126, "not_implemented", 0, NOT_USED); - collation[127] = new Collation(127, "not_implemented", 0, NOT_USED); - collation[152] = new Collation(152, "not_implemented", 0, NOT_USED); - collation[153] = new Collation(153, "not_implemented", 0, NOT_USED); - collation[154] = new Collation(154, "not_implemented", 0, NOT_USED); - collation[155] = new Collation(155, "not_implemented", 0, NOT_USED); - collation[156] = new Collation(156, "not_implemented", 0, NOT_USED); - collation[157] = new Collation(157, "not_implemented", 0, NOT_USED); - collation[158] = new Collation(158, "not_implemented", 0, NOT_USED); - collation[184] = new Collation(184, "not_implemented", 0, NOT_USED); - collation[185] = new Collation(185, "not_implemented", 0, NOT_USED); - collation[186] = new Collation(186, "not_implemented", 0, NOT_USED); - collation[187] = new Collation(187, "not_implemented", 0, NOT_USED); - collation[188] = new Collation(188, "not_implemented", 0, NOT_USED); - collation[189] = new Collation(189, "not_implemented", 0, NOT_USED); - collation[190] = new Collation(190, "not_implemented", 0, NOT_USED); - collation[191] = new Collation(191, "not_implemented", 0, NOT_USED); - collation[216] = new Collation(216, "not_implemented", 0, NOT_USED); - collation[217] = new Collation(217, "not_implemented", 0, NOT_USED); - collation[218] = new Collation(218, "not_implemented", 0, NOT_USED); - collation[219] = new Collation(219, "not_implemented", 0, NOT_USED); - collation[220] = new Collation(220, "not_implemented", 0, NOT_USED); - collation[221] = new Collation(221, "not_implemented", 0, NOT_USED); - collation[222] = new Collation(222, "not_implemented", 0, NOT_USED); - collation[248] = new Collation(248, "gb18030_chinese_ci", 1, MYSQL_CHARSET_NAME_gb18030); - collation[249] = new Collation(249, "gb18030_bin", 0, MYSQL_CHARSET_NAME_gb18030); - collation[250] = new Collation(250, "gb18030_unicode_520_ci", 0, MYSQL_CHARSET_NAME_gb18030); - collation[251] = new Collation(251, "not_implemented", 0, NOT_USED); - collation[252] = new Collation(252, "not_implemented", 0, NOT_USED); - collation[253] = new Collation(253, "not_implemented", 0, NOT_USED); - collation[254] = new Collation(254, "not_implemented", 0, NOT_USED); - collation[10] = new Collation(10, "swe7_swedish_ci", 0, MYSQL_CHARSET_NAME_swe7); - collation[82] = new Collation(82, "swe7_bin", 0, MYSQL_CHARSET_NAME_swe7); collation[6] = new Collation(6, "hp8_english_ci", 0, MYSQL_CHARSET_NAME_hp8); - collation[72] = new Collation(72, "hp8_bin", 0, MYSQL_CHARSET_NAME_hp8); - collation[3] = new Collation(3, "dec8_swedish_ci", 0, MYSQL_CHARSET_NAME_dec8); - collation[69] = new Collation(69, "dec8_bin", 0, MYSQL_CHARSET_NAME_dec8); - collation[32] = new Collation(32, "armscii8_general_ci", 0, MYSQL_CHARSET_NAME_armscii8); - collation[64] = new Collation(64, "armscii8_bin", 0, MYSQL_CHARSET_NAME_armscii8); - collation[92] = new Collation(92, "geostd8_general_ci", 0, MYSQL_CHARSET_NAME_geostd8); - collation[93] = new Collation(93, "geostd8_bin", 0, MYSQL_CHARSET_NAME_geostd8); - collation[7] = new Collation(7, "koi8r_general_ci", 0, MYSQL_CHARSET_NAME_koi8r); - collation[74] = new Collation(74, "koi8r_bin", 0, MYSQL_CHARSET_NAME_koi8r); - + collation[8] = new Collation(8, "latin1_swedish_ci", 0, MYSQL_CHARSET_NAME_latin1); + collation[9] = new Collation(9, "latin2_general_ci", 1, MYSQL_CHARSET_NAME_latin2); + collation[10] = new Collation(10, "swe7_swedish_ci", 0, MYSQL_CHARSET_NAME_swe7); collation[11] = new Collation(11, "ascii_general_ci", 0, MYSQL_CHARSET_NAME_ascii); - collation[65] = new Collation(65, "ascii_bin", 0, MYSQL_CHARSET_NAME_ascii); - collation[12] = new Collation(12, "ujis_japanese_ci", 0, MYSQL_CHARSET_NAME_ujis); - collation[91] = new Collation(91, "ujis_bin", 0, MYSQL_CHARSET_NAME_ujis); - collation[13] = new Collation(13, "sjis_japanese_ci", 0, MYSQL_CHARSET_NAME_sjis); collation[14] = new Collation(14, "cp1251_bulgarian_ci", 0, MYSQL_CHARSET_NAME_cp1251); + collation[15] = new Collation(15, "latin1_danish_ci", 0, MYSQL_CHARSET_NAME_latin1); collation[16] = new Collation(16, "hebrew_general_ci", 0, MYSQL_CHARSET_NAME_hebrew); collation[17] = new Collation(17, "latin1_german1_ci", 0, MYSQL_4_0_CHARSET_NAME_win1251); // removed since 4.1 collation[18] = new Collation(18, "tis620_thai_ci", 0, MYSQL_CHARSET_NAME_tis620); collation[19] = new Collation(19, "euckr_korean_ci", 0, MYSQL_CHARSET_NAME_euckr); collation[20] = new Collation(20, "latin7_estonian_cs", 0, MYSQL_CHARSET_NAME_latin7); + collation[21] = new Collation(21, "latin2_hungarian_ci", 0, MYSQL_CHARSET_NAME_latin2); collation[22] = new Collation(22, "koi8u_general_ci", 0, MYSQL_CHARSET_NAME_koi8u); collation[23] = new Collation(23, "cp1251_ukrainian_ci", 0, MYSQL_CHARSET_NAME_cp1251); collation[24] = new Collation(24, "gb2312_chinese_ci", 0, MYSQL_CHARSET_NAME_gb2312); collation[25] = new Collation(25, "greek_general_ci", 0, MYSQL_CHARSET_NAME_greek); collation[26] = new Collation(26, "cp1250_general_ci", 1, MYSQL_CHARSET_NAME_cp1250); + collation[27] = new Collation(27, "latin2_croatian_ci", 0, MYSQL_CHARSET_NAME_latin2); collation[28] = new Collation(28, "gbk_chinese_ci", 1, MYSQL_CHARSET_NAME_gbk); collation[29] = new Collation(29, "cp1257_lithuanian_ci", 0, MYSQL_CHARSET_NAME_cp1257); collation[30] = new Collation(30, "latin5_turkish_ci", 1, MYSQL_CHARSET_NAME_latin5); + collation[31] = new Collation(31, "latin1_german2_ci", 0, MYSQL_CHARSET_NAME_latin1); + collation[32] = new Collation(32, "armscii8_general_ci", 0, MYSQL_CHARSET_NAME_armscii8); collation[33] = new Collation(33, "utf8_general_ci", 1, MYSQL_CHARSET_NAME_utf8); collation[34] = new Collation(34, "cp1250_czech_cs", 0, MYSQL_CHARSET_NAME_cp1250); collation[35] = new Collation(35, "ucs2_general_ci", 1, MYSQL_CHARSET_NAME_ucs2); @@ -359,6 +302,9 @@ collation[44] = new Collation(44, "cp1250_croatian_ci", 0, MYSQL_CHARSET_NAME_cp1250); collation[45] = new Collation(45, "utf8mb4_general_ci", 1, MYSQL_CHARSET_NAME_utf8mb4); collation[46] = new Collation(46, "utf8mb4_bin", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[47] = new Collation(47, "latin1_bin", 0, MYSQL_CHARSET_NAME_latin1); + collation[48] = new Collation(48, "latin1_general_ci", 0, MYSQL_CHARSET_NAME_latin1); + collation[49] = new Collation(49, "latin1_general_cs", 0, MYSQL_CHARSET_NAME_latin1); collation[50] = new Collation(50, "cp1251_bin", 0, MYSQL_CHARSET_NAME_cp1251); collation[51] = new Collation(51, "cp1251_general_ci", 1, MYSQL_CHARSET_NAME_cp1251); collation[52] = new Collation(52, "cp1251_general_cs", 0, MYSQL_CHARSET_NAME_cp1251); @@ -373,28 +319,43 @@ collation[61] = new Collation(61, "utf32_bin", 0, MYSQL_CHARSET_NAME_utf32); collation[62] = new Collation(62, "utf16le_bin", 0, MYSQL_CHARSET_NAME_utf16le); collation[63] = new Collation(63, "binary", 1, MYSQL_CHARSET_NAME_binary); + collation[64] = new Collation(64, "armscii8_bin", 0, MYSQL_CHARSET_NAME_armscii8); + collation[65] = new Collation(65, "ascii_bin", 0, MYSQL_CHARSET_NAME_ascii); collation[66] = new Collation(66, "cp1250_bin", 0, MYSQL_CHARSET_NAME_cp1250); collation[67] = new Collation(67, "cp1256_bin", 0, MYSQL_CHARSET_NAME_cp1256); collation[68] = new Collation(68, "cp866_bin", 0, MYSQL_CHARSET_NAME_cp866); + collation[69] = new Collation(69, "dec8_bin", 0, MYSQL_CHARSET_NAME_dec8); collation[70] = new Collation(70, "greek_bin", 0, MYSQL_CHARSET_NAME_greek); collation[71] = new Collation(71, "hebrew_bin", 0, MYSQL_CHARSET_NAME_hebrew); + collation[72] = new Collation(72, "hp8_bin", 0, MYSQL_CHARSET_NAME_hp8); collation[73] = new Collation(73, "keybcs2_bin", 0, MYSQL_CHARSET_NAME_keybcs2); + collation[74] = new Collation(74, "koi8r_bin", 0, MYSQL_CHARSET_NAME_koi8r); collation[75] = new Collation(75, "koi8u_bin", 0, MYSQL_CHARSET_NAME_koi8u); + collation[76] = new Collation(76, "utf8_tolower_ci", 0, MYSQL_CHARSET_NAME_utf8); + collation[77] = new Collation(77, "latin2_bin", 0, MYSQL_CHARSET_NAME_latin2); collation[78] = new Collation(78, "latin5_bin", 0, MYSQL_CHARSET_NAME_latin5); collation[79] = new Collation(79, "latin7_bin", 0, MYSQL_CHARSET_NAME_latin7); + collation[80] = new Collation(80, "cp850_bin", 0, MYSQL_CHARSET_NAME_cp850); collation[81] = new Collation(81, "cp852_bin", 0, MYSQL_CHARSET_NAME_cp852); + collation[82] = new Collation(82, "swe7_bin", 0, MYSQL_CHARSET_NAME_swe7); collation[83] = new Collation(83, "utf8_bin", 0, MYSQL_CHARSET_NAME_utf8); + collation[84] = new Collation(84, "big5_bin", 0, MYSQL_CHARSET_NAME_big5); collation[85] = new Collation(85, "euckr_bin", 0, MYSQL_CHARSET_NAME_euckr); collation[86] = new Collation(86, "gb2312_bin", 0, MYSQL_CHARSET_NAME_gb2312); collation[87] = new Collation(87, "gbk_bin", 0, MYSQL_CHARSET_NAME_gbk); collation[88] = new Collation(88, "sjis_bin", 0, MYSQL_CHARSET_NAME_sjis); collation[89] = new Collation(89, "tis620_bin", 0, MYSQL_CHARSET_NAME_tis620); collation[90] = new Collation(90, "ucs2_bin", 0, MYSQL_CHARSET_NAME_ucs2); + collation[91] = new Collation(91, "ujis_bin", 0, MYSQL_CHARSET_NAME_ujis); + collation[92] = new Collation(92, "geostd8_general_ci", 0, MYSQL_CHARSET_NAME_geostd8); + collation[93] = new Collation(93, "geostd8_bin", 0, MYSQL_CHARSET_NAME_geostd8); + collation[94] = new Collation(94, "latin1_spanish_ci", 0, MYSQL_CHARSET_NAME_latin1); collation[95] = new Collation(95, "cp932_japanese_ci", 1, MYSQL_CHARSET_NAME_cp932); collation[96] = new Collation(96, "cp932_bin", 0, MYSQL_CHARSET_NAME_cp932); collation[97] = new Collation(97, "eucjpms_japanese_ci", 1, MYSQL_CHARSET_NAME_eucjpms); collation[98] = new Collation(98, "eucjpms_bin", 0, MYSQL_CHARSET_NAME_eucjpms); collation[99] = new Collation(99, "cp1250_polish_ci", 0, MYSQL_CHARSET_NAME_cp1250); + collation[101] = new Collation(101, "utf16_unicode_ci", 0, MYSQL_CHARSET_NAME_utf16); collation[102] = new Collation(102, "utf16_icelandic_ci", 0, MYSQL_CHARSET_NAME_utf16); collation[103] = new Collation(103, "utf16_latvian_ci", 0, MYSQL_CHARSET_NAME_utf16); @@ -419,6 +380,7 @@ collation[122] = new Collation(122, "utf16_croatian_ci", 0, MYSQL_CHARSET_NAME_utf16); collation[123] = new Collation(123, "utf16_unicode_520_ci", 0, MYSQL_CHARSET_NAME_utf16); collation[124] = new Collation(124, "utf16_vietnamese_ci", 0, MYSQL_CHARSET_NAME_utf16); + collation[128] = new Collation(128, "ucs2_unicode_ci", 0, MYSQL_CHARSET_NAME_ucs2); collation[129] = new Collation(129, "ucs2_icelandic_ci", 0, MYSQL_CHARSET_NAME_ucs2); collation[130] = new Collation(130, "ucs2_latvian_ci", 0, MYSQL_CHARSET_NAME_ucs2); @@ -443,6 +405,7 @@ collation[149] = new Collation(149, "ucs2_croatian_ci", 0, MYSQL_CHARSET_NAME_ucs2); collation[150] = new Collation(150, "ucs2_unicode_520_ci", 0, MYSQL_CHARSET_NAME_ucs2); collation[151] = new Collation(151, "ucs2_vietnamese_ci", 0, MYSQL_CHARSET_NAME_ucs2); + collation[159] = new Collation(159, "ucs2_general_mysql500_ci", 0, MYSQL_CHARSET_NAME_ucs2); collation[160] = new Collation(160, "utf32_unicode_ci", 0, MYSQL_CHARSET_NAME_utf32); collation[161] = new Collation(161, "utf32_icelandic_ci", 0, MYSQL_CHARSET_NAME_utf32); @@ -468,6 +431,7 @@ collation[181] = new Collation(181, "utf32_croatian_ci", 0, MYSQL_CHARSET_NAME_utf32); collation[182] = new Collation(182, "utf32_unicode_520_ci", 0, MYSQL_CHARSET_NAME_utf32); collation[183] = new Collation(183, "utf32_vietnamese_ci", 0, MYSQL_CHARSET_NAME_utf32); + collation[192] = new Collation(192, "utf8_unicode_ci", 0, MYSQL_CHARSET_NAME_utf8); collation[193] = new Collation(193, "utf8_icelandic_ci", 0, MYSQL_CHARSET_NAME_utf8); collation[194] = new Collation(194, "utf8_latvian_ci", 0, MYSQL_CHARSET_NAME_utf8); @@ -492,6 +456,7 @@ collation[213] = new Collation(213, "utf8_croatian_ci", 0, MYSQL_CHARSET_NAME_utf8); collation[214] = new Collation(214, "utf8_unicode_520_ci", 0, MYSQL_CHARSET_NAME_utf8); collation[215] = new Collation(215, "utf8_vietnamese_ci", 0, MYSQL_CHARSET_NAME_utf8); + collation[223] = new Collation(223, "utf8_general_mysql500_ci", 0, MYSQL_CHARSET_NAME_utf8); collation[224] = new Collation(224, "utf8mb4_unicode_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); collation[225] = new Collation(225, "utf8mb4_icelandic_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); @@ -517,21 +482,97 @@ collation[245] = new Collation(245, "utf8mb4_croatian_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); collation[246] = new Collation(246, "utf8mb4_unicode_520_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); collation[247] = new Collation(247, "utf8mb4_vietnamese_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[248] = new Collation(248, "gb18030_chinese_ci", 1, MYSQL_CHARSET_NAME_gb18030); + collation[249] = new Collation(249, "gb18030_bin", 0, MYSQL_CHARSET_NAME_gb18030); + collation[250] = new Collation(250, "gb18030_unicode_520_ci", 0, MYSQL_CHARSET_NAME_gb18030); + collation[255] = new Collation(255, "utf8mb4_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[256] = new Collation(256, "utf8mb4_de_pb_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[257] = new Collation(257, "utf8mb4_is_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[258] = new Collation(258, "utf8mb4_lv_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[259] = new Collation(259, "utf8mb4_ro_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[260] = new Collation(260, "utf8mb4_sl_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[261] = new Collation(261, "utf8mb4_pl_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[262] = new Collation(262, "utf8mb4_et_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[263] = new Collation(263, "utf8mb4_es_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[264] = new Collation(264, "utf8mb4_sv_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[265] = new Collation(265, "utf8mb4_tr_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[266] = new Collation(266, "utf8mb4_cs_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[267] = new Collation(267, "utf8mb4_da_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[268] = new Collation(268, "utf8mb4_lt_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[269] = new Collation(269, "utf8mb4_sk_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[270] = new Collation(270, "utf8mb4_es_trad_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[271] = new Collation(271, "utf8mb4_la_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + + collation[273] = new Collation(273, "utf8mb4_eo_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[274] = new Collation(274, "utf8mb4_hu_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[275] = new Collation(275, "utf8mb4_hr_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + + collation[277] = new Collation(277, "utf8mb4_vi_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + + collation[278] = new Collation(278, "utf8mb4_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[279] = new Collation(279, "utf8mb4_de_pb_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[280] = new Collation(280, "utf8mb4_is_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[281] = new Collation(281, "utf8mb4_lv_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[282] = new Collation(282, "utf8mb4_ro_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[283] = new Collation(283, "utf8mb4_sl_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[284] = new Collation(284, "utf8mb4_pl_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[285] = new Collation(285, "utf8mb4_et_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[286] = new Collation(286, "utf8mb4_es_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[287] = new Collation(287, "utf8mb4_sv_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[288] = new Collation(288, "utf8mb4_tr_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[289] = new Collation(289, "utf8mb4_cs_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[290] = new Collation(290, "utf8mb4_da_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[291] = new Collation(291, "utf8mb4_lt_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[292] = new Collation(292, "utf8mb4_sk_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[293] = new Collation(293, "utf8mb4_es_trad_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[294] = new Collation(294, "utf8mb4_la_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + + collation[296] = new Collation(296, "utf8mb4_eo_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[297] = new Collation(297, "utf8mb4_hu_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[298] = new Collation(298, "utf8mb4_hr_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + + collation[300] = new Collation(300, "utf8mb4_vi_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + + collation[303] = new Collation(303, "utf8mb4_ja_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + + collation[326] = new Collation(326, "utf8mb4_test_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[327] = new Collation(327, "utf16_test_ci", 0, MYSQL_CHARSET_NAME_utf16); + collation[328] = new Collation(328, "utf8mb4_test_400_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + + collation[336] = new Collation(336, "utf8_bengali_standard_ci", 0, MYSQL_CHARSET_NAME_utf8); + collation[337] = new Collation(337, "utf8_bengali_traditional_ci", 0, MYSQL_CHARSET_NAME_utf8); + + collation[352] = new Collation(352, "utf8_phone_ci", 0, MYSQL_CHARSET_NAME_utf8); + collation[353] = new Collation(353, "utf8_test_ci", 0, MYSQL_CHARSET_NAME_utf8); + collation[354] = new Collation(354, "utf8_5624_1", 0, MYSQL_CHARSET_NAME_utf8); + collation[355] = new Collation(355, "utf8_5624_2", 0, MYSQL_CHARSET_NAME_utf8); + collation[356] = new Collation(356, "utf8_5624_3", 0, MYSQL_CHARSET_NAME_utf8); + collation[357] = new Collation(357, "utf8_5624_4", 0, MYSQL_CHARSET_NAME_utf8); + collation[358] = new Collation(358, "ucs2_test_ci", 0, MYSQL_CHARSET_NAME_ucs2); + collation[359] = new Collation(359, "ucs2_vn_ci", 0, MYSQL_CHARSET_NAME_ucs2); + collation[360] = new Collation(360, "ucs2_5624_1", 0, MYSQL_CHARSET_NAME_ucs2); + + collation[368] = new Collation(368, "utf8_5624_5", 0, MYSQL_CHARSET_NAME_utf8); + collation[391] = new Collation(391, "utf32_test_ci", 0, MYSQL_CHARSET_NAME_utf32); + collation[2047] = new Collation(2047, "utf8_maxuserid_ci", 0, MYSQL_CHARSET_NAME_utf8); + COLLATION_INDEX_TO_COLLATION_NAME = new String[MAP_SIZE]; COLLATION_INDEX_TO_CHARSET = new MysqlCharset[MAP_SIZE]; Map charsetNameToCollationIndexMap = new TreeMap(); Map charsetNameToCollationPriorityMap = new TreeMap(); Set tempUTF8MB4Indexes = new HashSet(); + Collation notUsedCollation = new Collation(0, COLLATION_NOT_DEFINED, 0, NOT_USED); for (int i = 1; i < MAP_SIZE; i++) { - COLLATION_INDEX_TO_COLLATION_NAME[i] = collation[i].collationName; - COLLATION_INDEX_TO_CHARSET[i] = collation[i].mysqlCharset; - String charsetName = collation[i].mysqlCharset.charsetName; + Collation coll = collation[i] != null ? collation[i] : notUsedCollation; + COLLATION_INDEX_TO_COLLATION_NAME[i] = coll.collationName; + COLLATION_INDEX_TO_CHARSET[i] = coll.mysqlCharset; + String charsetName = coll.mysqlCharset.charsetName; - if (!charsetNameToCollationIndexMap.containsKey(charsetName) || charsetNameToCollationPriorityMap.get(charsetName) < collation[i].priority) { + if (!charsetNameToCollationIndexMap.containsKey(charsetName) || charsetNameToCollationPriorityMap.get(charsetName) < coll.priority) { charsetNameToCollationIndexMap.put(charsetName, i); - charsetNameToCollationPriorityMap.put(charsetName, collation[i].priority); + charsetNameToCollationPriorityMap.put(charsetName, coll.priority); } // Filling indexes of utf8mb4 collations @@ -540,16 +581,6 @@ } } - // Sanity check - for (int i = 1; i < MAP_SIZE; i++) { - if (COLLATION_INDEX_TO_COLLATION_NAME[i] == null) { - throw new RuntimeException("Assertion failure: No mapping from charset index " + i + " to a mysql collation"); - } - if (COLLATION_INDEX_TO_COLLATION_NAME[i] == null) { - throw new RuntimeException("Assertion failure: No mapping from charset index " + i + " to a Java character set"); - } - } - CHARSET_NAME_TO_COLLATION_INDEX = Collections.unmodifiableMap(charsetNameToCollationIndexMap); UTF8MB4_INDEXES = Collections.unmodifiableSet(tempUTF8MB4Indexes); @@ -582,6 +613,8 @@ tempMap.put("swedish", "latin1"); tempMap.put("ukrainian", "koi8u"); ERROR_MESSAGE_FILE_TO_MYSQL_CHARSET = Collections.unmodifiableMap(tempMap); + + collation = null; } public final static String getMysqlCharsetForJavaEncoding(String javaEncoding, Connection conn) throws SQLException { @@ -604,7 +637,8 @@ } if (versionedProp == null || versionedProp.major < charset.major || versionedProp.minor < charset.minor - || versionedProp.subminor < charset.subminor || versionedProp.priority < charset.priority) { + || versionedProp.subminor < charset.subminor || (versionedProp.priority < charset.priority && versionedProp.major == charset.major + && versionedProp.minor == charset.minor && versionedProp.subminor == charset.subminor)) { if (charset.isOkayForVersion(conn)) { versionedProp = charset; } @@ -647,10 +681,13 @@ /** * MySQL charset could map to several Java encodings. - * So here we choose the one according to next rules:
  • if there is no static mapping for this charset then return javaEncoding value as is because this - * could be a custom charset for example
  • if static mapping exists and javaEncoding equals to one of Java encoding canonical names or aliases available + * So here we choose the one according to next rules: + *
  • if there is no static mapping for this charset then return javaEncoding value as is because this + * could be a custom charset for example + *
  • if static mapping exists and javaEncoding equals to one of Java encoding canonical names or aliases available * for this mapping then javaEncoding value as is; this is required when result should match to connection encoding, for example if connection encoding is - * Cp943 we must avoid getting SHIFT_JIS for sjis mysql charset
  • if static mapping exists and javaEncoding doesn't match any Java encoding canonical + * Cp943 we must avoid getting SHIFT_JIS for sjis mysql charset + *
  • if static mapping exists and javaEncoding doesn't match any Java encoding canonical * names or aliases available for this mapping then return default Java encoding (the first in mapping list) * * @param mysqlCharsetName Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Clob.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Clob.java (.../Clob.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Clob.java (.../Clob.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -233,8 +233,8 @@ if (streamSize < this.charData.length()) { try { - out.write(StringUtils.getBytes(this.charData, null, null, false, null, this.exceptionInterceptor), streamSize, this.charData.length() - - streamSize); + out.write(StringUtils.getBytes(this.charData, null, null, false, null, this.exceptionInterceptor), streamSize, + this.charData.length() - streamSize); } catch (SQLException ex) { // } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/CompressedInputStream.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/CompressedInputStream.java (.../CompressedInputStream.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/CompressedInputStream.java (.../CompressedInputStream.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -157,12 +157,21 @@ // // Read data, note this this code is reached when using compressed packets that have not been compressed, as well // - uncompressedData = new byte[compressedPacketLength]; - readFully(uncompressedData, 0, compressedPacketLength); + uncompressedLength = compressedPacketLength; + uncompressedData = new byte[uncompressedLength]; + readFully(uncompressedData, 0, uncompressedLength); } if (doTrace) { - this.log.logTrace("Uncompressed packet: \n" + StringUtils.dumpAsHex(uncompressedData, compressedPacketLength)); + if (uncompressedLength > 1024) { + this.log.logTrace("Uncompressed packet: \n" + StringUtils.dumpAsHex(uncompressedData, 256)); + byte[] tempData = new byte[256]; + System.arraycopy(uncompressedData, uncompressedLength - 256, tempData, 0, 256); + this.log.logTrace("Uncompressed packet: \n" + StringUtils.dumpAsHex(tempData, 256)); + this.log.logTrace("Large packet dump truncated. Showing first and last 256 bytes."); + } else { + this.log.logTrace("Uncompressed packet: \n" + StringUtils.dumpAsHex(uncompressedData, uncompressedLength)); + } } if ((this.buffer != null) && (this.pos < this.buffer.length)) { @@ -173,14 +182,9 @@ int remaining = this.buffer.length - this.pos; byte[] newBuffer = new byte[remaining + uncompressedData.length]; - int newIndex = 0; + System.arraycopy(this.buffer, this.pos, newBuffer, 0, remaining); + System.arraycopy(uncompressedData, 0, newBuffer, remaining, uncompressedData.length); - for (int i = this.pos; i < this.buffer.length; i++) { - newBuffer[newIndex++] = this.buffer[i]; - } - - System.arraycopy(uncompressedData, 0, newBuffer, newIndex, uncompressedData.length); - uncompressedData = newBuffer; } @@ -249,10 +253,13 @@ return -1; } - System.arraycopy(this.buffer, this.pos, b, off, len); - this.pos += len; + int remainingBufferLength = this.buffer.length - this.pos; + int consummedBytesLength = Math.min(remainingBufferLength, len); - return len; + System.arraycopy(this.buffer, this.pos, b, off, consummedBytesLength); + this.pos += consummedBytesLength; + + return consummedBytesLength; } private final int readFully(byte[] b, int off, int len) throws IOException { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionGroup.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionGroup.java (.../ConnectionGroup.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionGroup.java (.../ConnectionGroup.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -27,7 +27,6 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -63,32 +62,16 @@ this.activeConnections++; return currentConnectionId; - } - /* - * (non-Javadoc) - * - * @see com.mysql.jdbc.ConnectionGroupMBean#getGroupName() - */ public String getGroupName() { return this.groupName; } - /* - * (non-Javadoc) - * - * @see com.mysql.jdbc.ConnectionGroupMBean#getInitialHostList() - */ public Collection getInitialHosts() { return this.hostList; } - /* - * (non-Javadoc) - * - * @see com.mysql.jdbc.ConnectionGroupMBean#getActiveHostCount() - */ public int getActiveHostCount() { return this.activeHosts; } @@ -97,81 +80,47 @@ return this.closedHosts; } - /* - * (non-Javadoc) - * - * @see com.mysql.jdbc.ConnectionGroupMBean#getTotalLogicalConnectionCount() - */ public long getTotalLogicalConnectionCount() { return this.connections; } - /* - * (non-Javadoc) - * - * @see com.mysql.jdbc.ConnectionGroupMBean#getActiveLogicalConnectionCount() - */ public long getActiveLogicalConnectionCount() { return this.activeConnections; } - /* - * (non-Javadoc) - * - * @see com.mysql.jdbc.ConnectionGroupMBean#getActivePhysicalConnectionCount() - */ public long getActivePhysicalConnectionCount() { long result = 0; Map proxyMap = new HashMap(); synchronized (this.connectionProxies) { proxyMap.putAll(this.connectionProxies); } - Iterator> i = proxyMap.entrySet().iterator(); - while (i.hasNext()) { - LoadBalancedConnectionProxy proxy = i.next().getValue(); + for (LoadBalancedConnectionProxy proxy : proxyMap.values()) { result += proxy.getActivePhysicalConnectionCount(); - } return result; } - /* - * (non-Javadoc) - * - * @see com.mysql.jdbc.ConnectionGroupMBean#getTotalPhysicalConnectionCount() - */ public long getTotalPhysicalConnectionCount() { long allConnections = this.closedProxyTotalPhysicalConnections; Map proxyMap = new HashMap(); synchronized (this.connectionProxies) { proxyMap.putAll(this.connectionProxies); } - Iterator> i = proxyMap.entrySet().iterator(); - while (i.hasNext()) { - LoadBalancedConnectionProxy proxy = i.next().getValue(); + for (LoadBalancedConnectionProxy proxy : proxyMap.values()) { allConnections += proxy.getTotalPhysicalConnectionCount(); - } return allConnections; } - /* - * (non-Javadoc) - * - * @see com.mysql.jdbc.ConnectionGroupMBean#getTotalTransactionCount() - */ public long getTotalTransactionCount() { // need to account for closed connection proxies long transactions = this.closedProxyTotalTransactions; Map proxyMap = new HashMap(); synchronized (this.connectionProxies) { proxyMap.putAll(this.connectionProxies); } - Iterator> i = proxyMap.entrySet().iterator(); - while (i.hasNext()) { - LoadBalancedConnectionProxy proxy = i.next().getValue(); + for (LoadBalancedConnectionProxy proxy : proxyMap.values()) { transactions += proxy.getTransactionCount(); - } return transactions; } @@ -181,67 +130,95 @@ this.connectionProxies.remove(Long.valueOf(proxy.getConnectionGroupProxyID())); this.closedProxyTotalPhysicalConnections += proxy.getTotalPhysicalConnectionCount(); this.closedProxyTotalTransactions += proxy.getTransactionCount(); - } - public void removeHost(String host) throws SQLException { - removeHost(host, false); + /** + * Remove the given host (host:port pair) from this Connection Group. + * + * @param hostPortPair + * The host:port pair to remove. + * @throws SQLException + */ + public void removeHost(String hostPortPair) throws SQLException { + removeHost(hostPortPair, false); } - public void removeHost(String host, boolean killExistingConnections) throws SQLException { - this.removeHost(host, killExistingConnections, true); - + /** + * Remove the given host (host:port pair) from this Connection Group. + * + * @param hostPortPair + * The host:port pair to remove. + * @param removeExisting + * Whether affects existing load-balanced connections or only new ones. + * @throws SQLException + */ + public void removeHost(String hostPortPair, boolean removeExisting) throws SQLException { + this.removeHost(hostPortPair, removeExisting, true); } - /* - * (non-Javadoc) + /** + * Remove the given host (host:port pair) from this Connection Group and, consequently, from all the load-balanced connections it holds. * - * @see com.mysql.jdbc.ConnectionGroupMBean#removeHost(java.lang.String, boolean, boolean) + * @param hostPortPair + * The host:port pair to remove. + * @param removeExisting + * Whether affects existing load-balanced connections or only new ones. + * @param waitForGracefulFailover + * If true instructs the load-balanced connections to fail-over the underlying active connection before removing this host, otherwise remove + * immediately. + * @throws SQLException */ - public synchronized void removeHost(String host, boolean killExistingConnections, boolean waitForGracefulFailover) throws SQLException { + public synchronized void removeHost(String hostPortPair, boolean removeExisting, boolean waitForGracefulFailover) throws SQLException { if (this.activeHosts == 1) { throw SQLError.createSQLException("Cannot remove host, only one configured host active.", null); } - if (this.hostList.remove(host)) { + if (this.hostList.remove(hostPortPair)) { this.activeHosts--; } else { - throw SQLError.createSQLException("Host is not configured: " + host, null); + throw SQLError.createSQLException("Host is not configured: " + hostPortPair, null); } - if (killExistingConnections) { + if (removeExisting) { // make a local copy to keep synchronization overhead to minimum Map proxyMap = new HashMap(); synchronized (this.connectionProxies) { proxyMap.putAll(this.connectionProxies); } - Iterator> i = proxyMap.entrySet().iterator(); - while (i.hasNext()) { - LoadBalancedConnectionProxy proxy = i.next().getValue(); + for (LoadBalancedConnectionProxy proxy : proxyMap.values()) { if (waitForGracefulFailover) { - proxy.removeHostWhenNotInUse(host); + proxy.removeHostWhenNotInUse(hostPortPair); } else { - proxy.removeHost(host); + proxy.removeHost(hostPortPair); } } } - this.closedHosts.add(host); + this.closedHosts.add(hostPortPair); } - public void addHost(String host) { - addHost(host, false); + /** + * Add the given host (host:port pair) to this Connection Group. + * + * @param hostPortPair + * The host:port pair to add. + * @throws SQLException + */ + public void addHost(String hostPortPair) { + addHost(hostPortPair, false); } - /* - * (non-Javadoc) + /** + * Add the given host (host:port pair) to this Connection Group and, consequently, to all the load-balanced connections it holds. * - * @see com.mysql.jdbc.ConnectionGroupMBean#addHost(java.lang.String, boolean) + * @param hostPortPair + * The host:port pair to add. + * @param forExisting + * Whether affects existing load-balanced connections or only new ones. */ - public void addHost(String host, boolean forExisting) { - + public void addHost(String hostPortPair, boolean forExisting) { synchronized (this) { - if (this.hostList.add(host)) { + if (this.hostList.add(hostPortPair)) { this.activeHosts++; } } @@ -256,12 +233,8 @@ proxyMap.putAll(this.connectionProxies); } - Iterator> i = proxyMap.entrySet().iterator(); - while (i.hasNext()) { - LoadBalancedConnectionProxy proxy = i.next().getValue(); - proxy.addHost(host); + for (LoadBalancedConnectionProxy proxy : proxyMap.values()) { + proxy.addHost(hostPortPair); } - } - } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionGroupManager.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionGroupManager.java (.../ConnectionGroupManager.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionGroupManager.java (.../ConnectionGroupManager.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -78,15 +78,14 @@ } - public static void addHost(String group, String host, boolean forExisting) { + public static void addHost(String group, String hostPortPair, boolean forExisting) { Collection s = getGroupsMatching(group); for (ConnectionGroup cg : s) { - cg.addHost(host, forExisting); + cg.addHost(hostPortPair, forExisting); } } public static int getActiveHostCount(String group) { - Set active = new HashSet(); Collection s = getGroupsMatching(group); for (ConnectionGroup cg : s) { @@ -150,8 +149,8 @@ return count; } - public static void removeHost(String group, String host) throws SQLException { - removeHost(group, host, false); + public static void removeHost(String group, String hostPortPair) throws SQLException { + removeHost(group, hostPortPair, false); } public static void removeHost(String group, String host, boolean removeExisting) throws SQLException { @@ -203,7 +202,5 @@ sep = ","; } return sb.toString(); - } - } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionImpl.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionImpl.java (.../ConnectionImpl.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionImpl.java (.../ConnectionImpl.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.lang.ref.WeakReference; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; @@ -56,7 +57,7 @@ import java.util.Stack; import java.util.TimeZone; import java.util.Timer; -import java.util.TreeMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import com.mysql.jdbc.PreparedStatement.ParseInfo; @@ -90,6 +91,10 @@ return this.host; } + public String getHostPortPair() { + return this.hostPortPair != null ? this.hostPortPair : this.host + ":" + this.port; + } + private MySQLConnection proxy = null; private InvocationHandler realProxy = null; @@ -120,12 +125,16 @@ return this.getProxy(); } + public MySQLConnection getActiveMySQLConnection() { + return this; + } + public Object getConnectionMutex() { return (this.realProxy != null) ? this.realProxy : getProxy(); } - class ExceptionInterceptorChain implements ExceptionInterceptor { - List interceptors; + public class ExceptionInterceptorChain implements ExceptionInterceptor { + private List interceptors; ExceptionInterceptorChain(String interceptorClasses) throws SQLException { this.interceptors = Util.loadExtensions(ConnectionImpl.this, ConnectionImpl.this.props, interceptorClasses, "Connection.BadExceptionInterceptor", @@ -168,6 +177,11 @@ } } } + + public List getInterceptors() { + return this.interceptors; + } + } /** @@ -257,16 +271,6 @@ protected static Map roundRobinStatsMap; /** - * Actual collation index to collation name map for given server URLs. - */ - private static final Map> dynamicIndexToCollationMapByUrl = new HashMap>(); - - /** - * Actual collation index to mysql charset name map for given server URLs. - */ - private static final Map> dynamicIndexToCharsetMapByUrl = new HashMap>(); - - /** * Actual collation index to mysql charset name map of user defined charsets for given server URLs. */ private static final Map> customIndexToCharsetMapByUrl = new HashMap>(); @@ -363,23 +367,8 @@ public Timer getCancelTimer() { synchronized (getConnectionMutex()) { if (this.cancelTimer == null) { - boolean createdNamedTimer = false; - - // Use reflection magic to try this on JDK's 1.5 and newer, fallback to non-named timer on older VMs. - try { - Constructor ctr = Timer.class.getConstructor(new Class[] { String.class, Boolean.TYPE }); - - this.cancelTimer = ctr.newInstance(new Object[] { "MySQL Statement Cancellation Timer", Boolean.TRUE }); - createdNamedTimer = true; - } catch (Throwable t) { - createdNamedTimer = false; - } - - if (!createdNamedTimer) { - this.cancelTimer = new Timer(true); - } + this.cancelTimer = new Timer("MySQL Statement Cancellation Timer", true); } - return this.cancelTimer; } } @@ -482,16 +471,10 @@ /** The hostname we're connected to */ private String host = null; - /** - * We need this 'bootstrapped', because 4.1 and newer will send fields back - * with this even before we fill this dynamically from the server. - */ - public Map indexToMysqlCharset = new HashMap(); + public Map indexToCustomMysqlCharset = null; - public Map indexToCustomMysqlCharset = null; //new HashMap(); + private Map mysqlCharsetToCustomMblen = null; - private Map mysqlCharsetToCustomMblen = null; //new HashMap(); - /** The I/O abstraction interface (network conn to MySQL server */ private transient MysqlIO io = null; @@ -565,8 +548,11 @@ private int[] oldHistCounts = null; - /** A map of currently open statements */ - private Map openStatements; + /** + * An array of currently open statements. + * Copy-on-write used here to avoid ConcurrentModificationException when statements unregister themselves while we iterate over the list. + */ + private final CopyOnWriteArrayList openStatements = new CopyOnWriteArrayList(); private LRUCache parsedCallableStatementCache; @@ -730,8 +716,6 @@ // this.log = LogFactory.getLogger(getLogger(), LOGGER_INSTANCE_NAME, getExceptionInterceptor()); - this.openStatements = new HashMap(); - if (NonRegisteringDriver.isHostPropertiesList(hostToConnectTo)) { Properties hostSpecificProps = NonRegisteringDriver.expandHostKeyValues(hostToConnectTo); @@ -913,58 +897,33 @@ */ private void buildCollationMapping() throws SQLException { - Map indexToCharset = null; - Map sortedCollationMap = null; Map customCharset = null; Map customMblen = null; if (getCacheServerConfiguration()) { - synchronized (dynamicIndexToCharsetMapByUrl) { - indexToCharset = dynamicIndexToCharsetMapByUrl.get(getURL()); - sortedCollationMap = dynamicIndexToCollationMapByUrl.get(getURL()); + synchronized (customIndexToCharsetMapByUrl) { customCharset = customIndexToCharsetMapByUrl.get(getURL()); customMblen = customCharsetToMblenMapByUrl.get(getURL()); } } - if (indexToCharset == null) { - indexToCharset = new HashMap(); + if (customCharset == null && getDetectCustomCollations() && versionMeetsMinimum(4, 1, 0)) { - if (versionMeetsMinimum(4, 1, 0) && getDetectCustomCollations()) { + java.sql.Statement stmt = null; + java.sql.ResultSet results = null; - java.sql.Statement stmt = null; - java.sql.ResultSet results = null; + try { + customCharset = new HashMap(); + customMblen = new HashMap(); + stmt = getMetadataSafeStatement(); + try { - sortedCollationMap = new TreeMap(); - customCharset = new HashMap(); - customMblen = new HashMap(); + results = stmt.executeQuery("SHOW COLLATION"); + while (results.next()) { + int collationIndex = ((Number) results.getObject(3)).intValue(); + String charsetName = results.getString(2); - stmt = getMetadataSafeStatement(); - - try { - results = stmt.executeQuery("SHOW COLLATION"); - if (versionMeetsMinimum(5, 0, 0)) { - Util.resultSetToMap(sortedCollationMap, results, 3, 2); - } else { - while (results.next()) { - sortedCollationMap.put(results.getLong(3), results.getString(2)); - } - } - } catch (SQLException ex) { - if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) { - throw ex; - } - } - - for (Iterator> indexIter = sortedCollationMap.entrySet().iterator(); indexIter.hasNext();) { - Map.Entry indexEntry = indexIter.next(); - - int collationIndex = indexEntry.getKey().intValue(); - String charsetName = indexEntry.getValue(); - - indexToCharset.put(collationIndex, charsetName); - // if no static map for charsetIndex or server has a different mapping then our static map, adding it to custom map if (collationIndex >= CharsetMapping.MAP_SIZE || !charsetName.equals(CharsetMapping.getMysqlCharsetNameForCollationIndex(collationIndex))) { @@ -976,70 +935,61 @@ customMblen.put(charsetName, null); } } + } catch (SQLException ex) { + if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) { + throw ex; + } + } - // if there is a number of custom charsets we should execute SHOW CHARACTER SET to know theirs mblen - if (customMblen.size() > 0) { - try { - results = stmt.executeQuery("SHOW CHARACTER SET"); - while (results.next()) { - String charsetName = results.getString("Charset"); - if (customMblen.containsKey(charsetName)) { - customMblen.put(charsetName, results.getInt("Maxlen")); - } + // if there is a number of custom charsets we should execute SHOW CHARACTER SET to know their mblen + if (customMblen.size() > 0) { + try { + results = stmt.executeQuery("SHOW CHARACTER SET"); + while (results.next()) { + String charsetName = results.getString("Charset"); + if (customMblen.containsKey(charsetName)) { + customMblen.put(charsetName, results.getInt("Maxlen")); } - } catch (SQLException ex) { - if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) { - throw ex; - } } - } - - if (getCacheServerConfiguration()) { - synchronized (dynamicIndexToCharsetMapByUrl) { - dynamicIndexToCharsetMapByUrl.put(getURL(), indexToCharset); - dynamicIndexToCollationMapByUrl.put(getURL(), sortedCollationMap); - customIndexToCharsetMapByUrl.put(getURL(), customCharset); - customCharsetToMblenMapByUrl.put(getURL(), customMblen); + } catch (SQLException ex) { + if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) { + throw ex; } } + } - } catch (SQLException ex) { - throw ex; - } catch (RuntimeException ex) { - SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); - sqlEx.initCause(ex); - throw sqlEx; - } finally { - if (results != null) { - try { - results.close(); - } catch (java.sql.SQLException sqlE) { - // ignore - } + if (getCacheServerConfiguration()) { + synchronized (customIndexToCharsetMapByUrl) { + customIndexToCharsetMapByUrl.put(getURL(), customCharset); + customCharsetToMblenMapByUrl.put(getURL(), customMblen); } + } - if (stmt != null) { - try { - stmt.close(); - } catch (java.sql.SQLException sqlE) { - // ignore - } + } catch (SQLException ex) { + throw ex; + } catch (RuntimeException ex) { + SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + sqlEx.initCause(ex); + throw sqlEx; + } finally { + if (results != null) { + try { + results.close(); + } catch (java.sql.SQLException sqlE) { + // ignore } } - } else { - for (int i = 1; i < CharsetMapping.MAP_SIZE; i++) { - indexToCharset.put(i, CharsetMapping.getMysqlCharsetNameForCollationIndex(i)); - } - if (getCacheServerConfiguration()) { - synchronized (dynamicIndexToCharsetMapByUrl) { - dynamicIndexToCharsetMapByUrl.put(getURL(), indexToCharset); + + if (stmt != null) { + try { + stmt.close(); + } catch (java.sql.SQLException sqlE) { + // ignore } } } - } - this.indexToMysqlCharset = Collections.unmodifiableMap(indexToCharset); if (customCharset != null) { this.indexToCustomMysqlCharset = Collections.unmodifiableMap(customCharset); } @@ -1145,6 +1095,8 @@ canHandleAsStatement = false; } else if (StringUtils.startsWithIgnoreCaseAndWs(sql, "SHOW WARNINGS") && versionMeetsMinimum(5, 7, 2)) { canHandleAsStatement = false; + } else if (sql.startsWith(StatementImpl.PING_MARKER)) { + canHandleAsStatement = false; } return canHandleAsStatement; @@ -1393,6 +1345,7 @@ this.isClosed = true; } + @Deprecated public void clearHasTriedMaster() { this.hasTriedMasterFlag = false; } @@ -1453,7 +1406,7 @@ this.cachedPreparedStatementParams.put(nativeSql, pStmt.getParseInfo()); } else { - pStmt = new com.mysql.jdbc.PreparedStatement(getMultiHostSafeProxy(), nativeSql, this.database, pStmtInfo); + pStmt = com.mysql.jdbc.PreparedStatement.getInstance(getMultiHostSafeProxy(), nativeSql, this.database, pStmtInfo); } } else { pStmt = com.mysql.jdbc.PreparedStatement.getInstance(getMultiHostSafeProxy(), nativeSql, this.database); @@ -1528,30 +1481,16 @@ private void closeAllOpenStatements() throws SQLException { SQLException postponedException = null; - if (this.openStatements != null) { - List currentlyOpenStatements = new ArrayList(); // we need this to - // avoid ConcurrentModificationEx - - for (Iterator iter = this.openStatements.keySet().iterator(); iter.hasNext();) { - currentlyOpenStatements.add(iter.next()); + for (Statement stmt : this.openStatements) { + try { + ((StatementImpl) stmt).realClose(false, true); + } catch (SQLException sqlEx) { + postponedException = sqlEx; // throw it later, cleanup all statements first } + } - int numStmts = currentlyOpenStatements.size(); - - for (int i = 0; i < numStmts; i++) { - StatementImpl stmt = (StatementImpl) currentlyOpenStatements.get(i); - - try { - stmt.realClose(false, true); - } catch (SQLException sqlEx) { - postponedException = sqlEx; // throw it later, cleanup all - // statements first - } - } - - if (postponedException != null) { - throw postponedException; - } + if (postponedException != null) { + throw postponedException; } } @@ -2179,7 +2118,7 @@ // // Retrieve any 'lost' prepared statements if re-connecting // - Iterator statementIter = this.openStatements.values().iterator(); + Iterator statementIter = this.openStatements.iterator(); // // We build a list of these outside the map of open statements, because in the process of re-preparing, we might end up having to close a prepared @@ -2250,6 +2189,10 @@ // reset max-rows to default value this.sessionMaxRows = -1; + // preconfigure some server variables which are consulted before their initialization from server + this.serverVariables = new HashMap(); + this.serverVariables.put("character_set_server", "utf8"); + this.io = new MysqlIO(newHost, newPort, mergedProps, getSocketFactoryClassName(), getProxy(), getSocketTimeout(), this.largeRowSizeThreshold.getValueAsInt()); this.io.doHandshake(this.user, this.password, this.database); @@ -2648,14 +2591,7 @@ } public int getActiveStatementCount() { - // Might not have one of these if not tracking open resources - if (this.openStatements != null) { - synchronized (this.openStatements) { - return this.openStatements.size(); - } - } - - return 0; + return this.openStatements.size(); } /** @@ -2785,8 +2721,13 @@ if (charsetIndex != MysqlDefs.NO_CHARSET_INFO) { try { - if (this.indexToMysqlCharset.size() > 0) { - javaEncoding = CharsetMapping.getJavaEncodingForMysqlCharset(this.indexToMysqlCharset.get(charsetIndex), getEncoding()); + // getting charset name from dynamic maps in connection; we do it before checking against static maps because custom charset on server can be mapped + // to index from our static map key's diapason + if (this.indexToCustomMysqlCharset != null) { + String cs = this.indexToCustomMysqlCharset.get(charsetIndex); + if (cs != null) { + javaEncoding = CharsetMapping.getJavaEncodingForMysqlCharset(cs, getEncoding()); + } } // checking against static maps if no custom charset found if (javaEncoding == null) { @@ -2891,6 +2832,7 @@ public int getMaxBytesPerChar(Integer charsetIndex, String javaCharsetName) throws SQLException { String charset = null; + int res = 1; try { // if we can get it by charsetIndex just doing it @@ -2922,7 +2864,7 @@ } if (mblen != null) { - return mblen.intValue(); + res = mblen.intValue(); } } catch (SQLException ex) { throw ex; @@ -2932,7 +2874,7 @@ throw sqlEx; } - return 1; // we don't know + return res; } /** @@ -3167,6 +3109,7 @@ return this.props; } + @Deprecated public boolean hasTriedMaster() { return this.hasTriedMasterFlag; } @@ -3297,6 +3240,22 @@ buildCollationMapping(); + // Trying to workaround server collations with index > 255. Such index doesn't fit into server greeting packet, 0 is sent instead. + // Now we could set io.serverCharsetIndex according to "collation_server" value. + if (this.io.serverCharsetIndex == 0) { + String collationServer = this.serverVariables.get("collation_server"); + if (collationServer != null) { + for (int i = 1; i < CharsetMapping.COLLATION_INDEX_TO_COLLATION_NAME.length; i++) { + if (CharsetMapping.COLLATION_INDEX_TO_COLLATION_NAME[i].equals(collationServer)) { + this.io.serverCharsetIndex = i; + } + } + } else { + // We can't do more, just trying to use utf8mb4_general_ci because the most of collations in that range are utf8mb4. + this.io.serverCharsetIndex = 45; + } + } + LicenseConfiguration.checkLicenseType(this.serverVariables); String lowerCaseTables = this.serverVariables.get("lower_case_table_names"); @@ -3348,36 +3307,17 @@ this.io.checkForCharsetMismatch(); if (this.serverVariables.containsKey("sql_mode")) { - int sqlMode = 0; - String sqlModeAsString = this.serverVariables.get("sql_mode"); - try { - sqlMode = Integer.parseInt(sqlModeAsString); - } catch (NumberFormatException nfe) { - // newer versions of the server has this as a string-y list... - sqlMode = 0; - - if (sqlModeAsString != null) { - if (sqlModeAsString.indexOf("ANSI_QUOTES") != -1) { - sqlMode |= 4; - } - - if (sqlModeAsString.indexOf("NO_BACKSLASH_ESCAPES") != -1) { - this.noBackslashEscapes = true; - } - } + if (StringUtils.isStrictlyNumeric(sqlModeAsString)) { + // Old MySQL servers used to have sql_mode as a numeric value. + this.useAnsiQuotes = (Integer.parseInt(sqlModeAsString) & 4) > 0; + } else if (sqlModeAsString != null) { + this.useAnsiQuotes = sqlModeAsString.indexOf("ANSI_QUOTES") != -1; + this.noBackslashEscapes = sqlModeAsString.indexOf("NO_BACKSLASH_ESCAPES") != -1; } - - if ((sqlMode & 4) > 0) { - this.useAnsiQuotes = true; - } else { - this.useAnsiQuotes = false; - } } } - boolean overrideDefaultAutocommit = isAutoCommitNonDefaultOnServer(); - configureClientCharacterSet(false); try { @@ -3392,16 +3332,7 @@ if (versionMeetsMinimum(3, 23, 15)) { this.transactionsSupported = true; - - if (!overrideDefaultAutocommit) { - try { - setAutoCommit(true); // to override anything the server is set to...reqd by JDBC spec. - } catch (SQLException ex) { - if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) { - throw ex; - } - } - } + handleAutoCommitDefaults(); } else { this.transactionsSupported = false; } @@ -3454,7 +3385,7 @@ } if (versionMeetsMinimum(5, 0, 0) && (getUseLocalTransactionState() || getElideSetAutoCommits()) && isQueryCacheEnabled() - && !versionMeetsMinimum(6, 0, 10)) { + && !versionMeetsMinimum(5, 1, 32)) { // Can't trust the server status flag on the wire if query cache is enabled, due to Bug#36326 setUseLocalTransactionState(false); setElideSetAutoCommits(false); @@ -3467,8 +3398,9 @@ setupServerForTruncationChecks(); } - private boolean isQueryCacheEnabled() { - return "ON".equalsIgnoreCase(this.serverVariables.get("query_cache_type")) && !"0".equalsIgnoreCase(this.serverVariables.get("query_cache_size")); + public boolean isQueryCacheEnabled() { + return "YES".equalsIgnoreCase(this.serverVariables.get("have_query_cache")) && "ON".equalsIgnoreCase(this.serverVariables.get("query_cache_type")) + && !"0".equalsIgnoreCase(this.serverVariables.get("query_cache_size")); } private int getServerVariableAsInt(String variableName, int fallbackValue) throws SQLException { @@ -3483,36 +3415,26 @@ } /** - * Has the default autocommit value of 0 been changed on the server - * via init_connect? - * - * @return true if autocommit is not the default of '0' on the server. - * - * @throws SQLException + * Resets a default auto-commit value of 0 to 1, as required by JDBC specification. + * Takes into account that the default auto-commit value of 0 may have been changed on the server via init_connect. */ - private boolean isAutoCommitNonDefaultOnServer() throws SQLException { - boolean overrideDefaultAutocommit = false; + private void handleAutoCommitDefaults() throws SQLException { + boolean resetAutoCommitDefault = false; - String initConnectValue = this.serverVariables.get("init_connect"); - - if (versionMeetsMinimum(4, 1, 2) && initConnectValue != null && initConnectValue.length() > 0) { - if (!getElideSetAutoCommits()) { + if (!getElideSetAutoCommits()) { + String initConnectValue = this.serverVariables.get("init_connect"); + if (versionMeetsMinimum(4, 1, 2) && initConnectValue != null && initConnectValue.length() > 0) { // auto-commit might have changed java.sql.ResultSet rs = null; java.sql.Statement stmt = null; try { stmt = getMetadataSafeStatement(); - rs = stmt.executeQuery("SELECT @@session.autocommit"); - if (rs.next()) { this.autoCommit = rs.getBoolean(1); - if (this.autoCommit != true) { - overrideDefaultAutocommit = true; - } + resetAutoCommitDefault = !this.autoCommit; } - } finally { if (rs != null) { try { @@ -3521,7 +3443,6 @@ // do nothing } } - if (stmt != null) { try { stmt.close(); @@ -3531,15 +3452,24 @@ } } } else { - if (this.getIO().isSetNeededForAutoCommitMode(true)) { - // we're not in standard autocommit=true mode - this.autoCommit = false; - overrideDefaultAutocommit = true; - } + // reset it anyway, the server may have been initialized with --autocommit=0 + resetAutoCommitDefault = true; } + } else if (this.getIO().isSetNeededForAutoCommitMode(true)) { + // we're not in standard autocommit=true mode + this.autoCommit = false; + resetAutoCommitDefault = true; } - return overrideDefaultAutocommit; + if (resetAutoCommitDefault) { + try { + setAutoCommit(true); // required by JDBC spec + } catch (SQLException ex) { + if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) { + throw ex; + } + } + } } public boolean isClientTzUTC() { @@ -3566,9 +3496,7 @@ * the list. */ public boolean isMasterConnection() { - synchronized (getConnectionMutex()) { - return false; // handled higher up - } + return false; // handled higher up } /** @@ -3626,7 +3554,7 @@ } } catch (SQLException ex1) { if (ex1.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) { - throw SQLError.createSQLException("Could not retrieve transation read-only status server", SQLError.SQL_STATE_GENERAL_ERROR, ex1, + throw SQLError.createSQLException("Could not retrieve transaction read-only status from server", SQLError.SQL_STATE_GENERAL_ERROR, ex1, getExceptionInterceptor()); } } @@ -3710,8 +3638,6 @@ return this.isServerTzUTC; } - private boolean usingCachedConfig = false; - private void createConfigCacheIfNeeded() throws SQLException { synchronized (getConnectionMutex()) { if (this.serverConfigCache != null) { @@ -3796,7 +3722,6 @@ if (cachedServerVersion != null && this.io.getServerVersion() != null && cachedServerVersion.equals(this.io.getServerVersion())) { this.serverVariables = cachedVariableMap; - this.usingCachedConfig = true; return; } @@ -3841,6 +3766,7 @@ queryBuf.append(", @@character_set_connection AS character_set_connection"); queryBuf.append(", @@character_set_results AS character_set_results"); queryBuf.append(", @@character_set_server AS character_set_server"); + queryBuf.append(", @@collation_server AS collation_server"); queryBuf.append(", @@init_connect AS init_connect"); queryBuf.append(", @@interactive_timeout AS interactive_timeout"); if (!versionMeetsMinimum(5, 5, 0)) { @@ -3851,8 +3777,7 @@ queryBuf.append(", @@max_allowed_packet AS max_allowed_packet"); queryBuf.append(", @@net_buffer_length AS net_buffer_length"); queryBuf.append(", @@net_write_timeout AS net_write_timeout"); - queryBuf.append(", @@query_cache_size AS query_cache_size"); - queryBuf.append(", @@query_cache_type AS query_cache_type"); + queryBuf.append(", @@have_query_cache AS have_query_cache"); queryBuf.append(", @@sql_mode AS sql_mode"); queryBuf.append(", @@system_time_zone AS system_time_zone"); queryBuf.append(", @@time_zone AS time_zone"); @@ -3866,6 +3791,18 @@ this.serverVariables.put(rsmd.getColumnLabel(i), results.getString(i)); } } + + if ("YES".equalsIgnoreCase(this.serverVariables.get("have_query_cache"))) { + results.close(); + results = stmt.executeQuery("SELECT @@query_cache_size AS query_cache_size, @@query_cache_type AS query_cache_type"); + if (results.next()) { + ResultSetMetaData rsmd = results.getMetaData(); + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + this.serverVariables.put(rsmd.getColumnLabel(i), results.getString(i)); + } + } + } + } else { results = stmt.executeQuery(versionComment + "SHOW VARIABLES"); while (results.next()) { @@ -3886,7 +3823,6 @@ this.serverConfigCache.put(getURL(), this.serverVariables); - this.usingCachedConfig = true; } } catch (SQLException e) { throw e; @@ -4147,7 +4083,8 @@ if (this.useServerPreparedStmts && canServerPrepare) { if (this.getCachePreparedStatements()) { synchronized (this.serverSideStatementCache) { - pStmt = (com.mysql.jdbc.ServerPreparedStatement) this.serverSideStatementCache.remove(sql); + pStmt = (com.mysql.jdbc.ServerPreparedStatement) this.serverSideStatementCache + .remove(makePreparedStatementCacheKey(this.database, sql)); if (pStmt != null) { ((com.mysql.jdbc.ServerPreparedStatement) pStmt).setClosed(false); @@ -4313,7 +4250,7 @@ this.exceptionInterceptor.destroy(); } } finally { - this.openStatements = null; + this.openStatements.clear(); if (this.io != null) { this.io.releaseResources(); this.io = null; @@ -4337,21 +4274,32 @@ } + private String makePreparedStatementCacheKey(String catalog, String query) { + StringBuilder key = new StringBuilder(); + key.append("/*").append(catalog).append("*/"); + key.append(query); + return key.toString(); + } + public void recachePreparedStatement(ServerPreparedStatement pstmt) throws SQLException { synchronized (getConnectionMutex()) { - if (pstmt.isPoolable()) { + if (getCachePreparedStatements() && pstmt.isPoolable()) { synchronized (this.serverSideStatementCache) { - this.serverSideStatementCache.put(pstmt.originalSql, pstmt); + Object oldServerPrepStmt = this.serverSideStatementCache.put(makePreparedStatementCacheKey(pstmt.currentCatalog, pstmt.originalSql), pstmt); + if (oldServerPrepStmt != null) { + ((ServerPreparedStatement) oldServerPrepStmt).isCached = false; + ((ServerPreparedStatement) oldServerPrepStmt).realClose(true, true); + } } } } } public void decachePreparedStatement(ServerPreparedStatement pstmt) throws SQLException { synchronized (getConnectionMutex()) { - if (pstmt.isPoolable()) { + if (getCachePreparedStatements() && pstmt.isPoolable()) { synchronized (this.serverSideStatementCache) { - this.serverSideStatementCache.remove(pstmt.originalSql); + this.serverSideStatementCache.remove(makePreparedStatementCacheKey(pstmt.currentCatalog, pstmt.originalSql)); } } } @@ -4385,9 +4333,7 @@ * the Statement instance to remove */ public void registerStatement(Statement stmt) { - synchronized (this.openStatements) { - this.openStatements.put(stmt, stmt); - } + this.openStatements.addIfAbsent(stmt); } /** @@ -4734,7 +4680,6 @@ * @see java.sql.Connection#prepareStatement(String) */ public java.sql.PreparedStatement serverPrepareStatement(String sql) throws SQLException { - String nativeSql = getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql) : sql; return ServerPreparedStatement.getInstance(getMultiHostSafeProxy(), nativeSql, this.getCatalog(), DEFAULT_RESULT_SET_TYPE, @@ -4810,20 +4755,16 @@ * If a connection is in auto-commit mode, than all its SQL statements will * be executed and committed as individual transactions. Otherwise, its SQL * statements are grouped into transactions that are terminated by either - * commit() or rollback(). By default, new connections are in auto- commit + * commit() or rollback(). By default, new connections are in auto-commit * mode. The commit occurs when the statement completes or the next execute * occurs, whichever comes first. In the case of statements returning a * ResultSet, the statement completes when the last row of the ResultSet has * been retrieved or the ResultSet has been closed. In advanced cases, a * single statement may return multiple results as well as output parameter * values. Here the commit occurs when all results and output param values * have been retrieved. - *

    - * Note: MySQL does not support transactions, so this method is a no-op. - *

    * * @param autoCommitFlag - * - * true enables auto-commit; false disables it * @exception SQLException * if a database access error occurs @@ -4964,9 +4905,7 @@ * The failedOver to set. */ public void setFailedOver(boolean flag) { - synchronized (getConnectionMutex()) { - // handled higher up - } + // handled higher up } /** @@ -4985,6 +4924,7 @@ * @param preferSlaveDuringFailover * The preferSlaveDuringFailover to set. */ + @Deprecated public void setPreferSlaveDuringFailover(boolean flag) { // no-op, handled further up in the wrapper } @@ -5074,31 +5014,35 @@ private void setSessionVariables() throws SQLException { if (this.versionMeetsMinimum(4, 0, 0) && getSessionVariables() != null) { - List variablesToSet = StringUtils.split(getSessionVariables(), ",", "\"'", "\"'", false); + List variablesToSet = new ArrayList(); + for (String part : StringUtils.split(getSessionVariables(), ",", "\"'(", "\"')", "\"'", true)) { + variablesToSet.addAll(StringUtils.split(part, ";", "\"'(", "\"')", "\"'", true)); + } - int numVariablesToSet = variablesToSet.size(); - - java.sql.Statement stmt = null; - - try { - stmt = getMetadataSafeStatement(); - - for (int i = 0; i < numVariablesToSet; i++) { - String variableValuePair = variablesToSet.get(i); - - if (variableValuePair.startsWith("@")) { - stmt.executeUpdate("SET " + variableValuePair); - } else { - stmt.executeUpdate("SET SESSION " + variableValuePair); + if (!variablesToSet.isEmpty()) { + java.sql.Statement stmt = null; + try { + stmt = getMetadataSafeStatement(); + StringBuilder query = new StringBuilder("SET "); + String separator = ""; + for (String variableToSet : variablesToSet) { + if (variableToSet.length() > 0) { + query.append(separator); + if (!variableToSet.startsWith("@")) { + query.append("SESSION "); + } + query.append(variableToSet); + separator = ","; + } } + stmt.executeUpdate(query.toString()); + } finally { + if (stmt != null) { + stmt.close(); + } } - } finally { - if (stmt != null) { - stmt.close(); - } } } - } /** @@ -5219,7 +5163,11 @@ */ public void shutdownServer() throws SQLException { try { - this.io.sendCommand(MysqlDefs.SHUTDOWN, null, null, false, null, 0); + if (versionMeetsMinimum(5, 7, 9)) { + execSQL(null, "SHUTDOWN", -1, null, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY, false, this.database, null, false); + } else { + this.io.sendCommand(MysqlDefs.SHUTDOWN, null, null, false, null, 0); + } } catch (Exception ex) { SQLException sqlEx = SQLError.createSQLException(Messages.getString("Connection.UnhandledExceptionDuringShutdown"), SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); @@ -5249,11 +5197,7 @@ * the Statement instance to remove */ public void unregisterStatement(Statement stmt) { - if (this.openStatements != null) { - synchronized (this.openStatements) { - this.openStatements.remove(stmt); - } - } + this.openStatements.remove(stmt); } public boolean useAnsiQuotedIdentifiers() { @@ -5556,19 +5500,7 @@ } checkClosed(); - final MysqlIO mysqlIo = this.io; - - executor.execute(new Runnable() { - - public void run() { - try { - setSocketTimeout(milliseconds); // for re-connects - mysqlIo.setSocketTimeout(milliseconds); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - }); + executor.execute(new NetworkTimeoutSetter(this, this.io, milliseconds)); } } @@ -5587,4 +5519,33 @@ public void setProfilerEventHandlerInstance(ProfilerEventHandler h) { this.eventSink = h; } + + private static class NetworkTimeoutSetter implements Runnable { + private final WeakReference connImplRef; + private final WeakReference mysqlIoRef; + private final int milliseconds; + + public NetworkTimeoutSetter(ConnectionImpl conn, MysqlIO io, int milliseconds) { + this.connImplRef = new WeakReference(conn); + this.mysqlIoRef = new WeakReference(io); + this.milliseconds = milliseconds; + } + + public void run() { + try { + ConnectionImpl conn = this.connImplRef.get(); + if (conn != null) { + synchronized (conn.getConnectionMutex()) { + conn.setSocketTimeout(this.milliseconds); // for re-connects + MysqlIO io = this.mysqlIoRef.get(); + if (io != null) { + io.setSocketTimeout(this.milliseconds); + } + } + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionProperties.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionProperties.java (.../ConnectionProperties.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionProperties.java (.../ConnectionProperties.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -1158,6 +1158,10 @@ public void setLoadBalanceStrategy(String strategy); + public String getServerAffinityOrder(); + + public void setServerAffinityOrder(String hostsList); + public boolean getTcpNoDelay(); public void setTcpNoDelay(boolean flag); @@ -1332,6 +1336,10 @@ public void setLoadBalanceEnableJMX(boolean loadBalanceEnableJMX); + public void setLoadBalanceHostRemovalGracePeriod(int loadBalanceHostRemovalGracePeriod) throws SQLException; + + public int getLoadBalanceHostRemovalGracePeriod(); + public void setLoadBalanceAutoCommitStatementThreshold(int loadBalanceAutoCommitStatementThreshold) throws SQLException; public int getLoadBalanceAutoCommitStatementThreshold(); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesImpl.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesImpl.java (.../ConnectionPropertiesImpl.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesImpl.java (.../ConnectionPropertiesImpl.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -417,9 +417,10 @@ void setValue(int intValue, String valueAsString, ExceptionInterceptor exceptionInterceptor) throws SQLException { if (isRangeBased()) { if ((intValue < getLowerBound()) || (intValue > getUpperBound())) { - throw SQLError.createSQLException("The connection property '" + getPropertyName() + "' only accepts integer values in the range of " - + getLowerBound() + " - " + getUpperBound() + ", the value '" + (valueAsString == null ? intValue : valueAsString) - + "' exceeds this range.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + throw SQLError.createSQLException( + "The connection property '" + getPropertyName() + "' only accepts integer values in the range of " + getLowerBound() + " - " + + getUpperBound() + ", the value '" + (valueAsString == null ? intValue : valueAsString) + "' exceeds this range.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } } @@ -451,9 +452,10 @@ void setValue(long longValue, String valueAsString, ExceptionInterceptor exceptionInterceptor) throws SQLException { if (isRangeBased()) { if ((longValue < getLowerBound()) || (longValue > getUpperBound())) { - throw SQLError.createSQLException("The connection property '" + getPropertyName() + "' only accepts long integer values in the range of " - + getLowerBound() + " - " + getUpperBound() + ", the value '" + (valueAsString == null ? longValue : valueAsString) - + "' exceeds this range.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + throw SQLError.createSQLException( + "The connection property '" + getPropertyName() + "' only accepts long integer values in the range of " + getLowerBound() + " - " + + getUpperBound() + ", the value '" + (valueAsString == null ? longValue : valueAsString) + "' exceeds this range.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } } this.valueAsObject = Long.valueOf(longValue); @@ -684,6 +686,9 @@ private BooleanConnectionProperty autoClosePStmtStreams = new BooleanConnectionProperty("autoClosePStmtStreams", false, Messages.getString("ConnectionProperties.autoClosePstmtStreams"), "3.1.12", MISC_CATEGORY, Integer.MIN_VALUE); + private StringConnectionProperty replicationConnectionGroup = new StringConnectionProperty("replicationConnectionGroup", null, + Messages.getString("ConnectionProperties.replicationConnectionGroup"), "5.1.27", HA_CATEGORY, Integer.MIN_VALUE); + private BooleanConnectionProperty allowMasterDownConnections = new BooleanConnectionProperty("allowMasterDownConnections", false, Messages.getString("ConnectionProperties.allowMasterDownConnections"), "5.1.27", HA_CATEGORY, Integer.MAX_VALUE); @@ -721,7 +726,8 @@ private BooleanConnectionProperty functionsNeverReturnBlobs = new BooleanConnectionProperty("functionsNeverReturnBlobs", false, "Should the driver always treat data from functions returning BLOBs as Strings - specifically to work around dubious metadata " - + "returned by the server for GROUP BY clauses?", "5.0.8", MISC_CATEGORY, Integer.MIN_VALUE); + + "returned by the server for GROUP BY clauses?", + "5.0.8", MISC_CATEGORY, Integer.MIN_VALUE); private BooleanConnectionProperty cacheCallableStatements = new BooleanConnectionProperty("cacheCallableStmts", false, Messages.getString("ConnectionProperties.cacheCallableStatements"), "3.1.2", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); @@ -871,6 +877,9 @@ private StringConnectionProperty loadBalanceStrategy = new StringConnectionProperty("loadBalanceStrategy", "random", null, Messages.getString("ConnectionProperties.loadBalanceStrategy"), "5.0.6", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); + private StringConnectionProperty serverAffinityOrder = new StringConnectionProperty("serverAffinityOrder", "", null, + Messages.getString("ConnectionProperties.serverAffinityOrder"), "5.1.4.", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); + private IntegerConnectionProperty loadBalanceBlacklistTimeout = new IntegerConnectionProperty("loadBalanceBlacklistTimeout", 0, 0, Integer.MAX_VALUE, Messages.getString("ConnectionProperties.loadBalanceBlacklistTimeout"), "5.1.0", MISC_CATEGORY, Integer.MIN_VALUE); @@ -896,6 +905,9 @@ private BooleanConnectionProperty loadBalanceEnableJMX = new BooleanConnectionProperty("loadBalanceEnableJMX", false, Messages.getString("ConnectionProperties.loadBalanceEnableJMX"), "5.1.13", MISC_CATEGORY, Integer.MAX_VALUE); + private IntegerConnectionProperty loadBalanceHostRemovalGracePeriod = new IntegerConnectionProperty("loadBalanceHostRemovalGracePeriod", 15000, 0, + Integer.MAX_VALUE, Messages.getString("ConnectionProperties.loadBalanceHostRemovalGracePeriod"), "5.1.39", MISC_CATEGORY, Integer.MAX_VALUE); + private StringConnectionProperty loadBalanceAutoCommitStatementRegex = new StringConnectionProperty("loadBalanceAutoCommitStatementRegex", null, Messages.getString("ConnectionProperties.loadBalanceAutoCommitStatementRegex"), "5.1.15", MISC_CATEGORY, Integer.MIN_VALUE); @@ -908,8 +920,9 @@ private MemorySizeConnectionProperty locatorFetchBufferSize = new MemorySizeConnectionProperty("locatorFetchBufferSize", 1024 * 1024, 0, Integer.MAX_VALUE, Messages.getString("ConnectionProperties.locatorFetchBufferSize"), "3.2.1", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - private StringConnectionProperty loggerClassName = new StringConnectionProperty("logger", STANDARD_LOGGER_NAME, Messages.getString( - "ConnectionProperties.logger", new Object[] { Log.class.getName(), STANDARD_LOGGER_NAME }), "3.1.1", DEBUGING_PROFILING_CATEGORY, 0); + private StringConnectionProperty loggerClassName = new StringConnectionProperty("logger", STANDARD_LOGGER_NAME, + Messages.getString("ConnectionProperties.logger", new Object[] { Log.class.getName(), STANDARD_LOGGER_NAME }), "3.1.1", DEBUGING_PROFILING_CATEGORY, + 0); private BooleanConnectionProperty logSlowQueries = new BooleanConnectionProperty("logSlowQueries", false, Messages.getString("ConnectionProperties.logSlowQueries"), "3.1.2", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); @@ -946,8 +959,8 @@ "When determining procedure parameter types for CallableStatements, and the connected user " + " can't access procedure bodies through \"SHOW CREATE PROCEDURE\" or select on mysql.proc " + " should the driver instead create basic metadata (all parameters reported as IN VARCHARs," - + " but allowing registerOutParameter() to be called on them anyway) instead of throwing an exception?", "5.0.3", MISC_CATEGORY, - Integer.MIN_VALUE); + + " but allowing registerOutParameter() to be called on them anyway) instead of throwing an exception?", + "5.0.3", MISC_CATEGORY, Integer.MIN_VALUE); private BooleanConnectionProperty noDatetimeStringSync = new BooleanConnectionProperty("noDatetimeStringSync", false, Messages.getString("ConnectionProperties.noDatetimeStringSync"), "3.1.7", MISC_CATEGORY, Integer.MIN_VALUE); @@ -1102,14 +1115,14 @@ "overrideSupportsIntegrityEnhancementFacility", false, Messages.getString("ConnectionProperties.overrideSupportsIEF"), "3.1.12", MISC_CATEGORY, Integer.MIN_VALUE); - private BooleanConnectionProperty tcpNoDelay = new BooleanConnectionProperty(StandardSocketFactory.TCP_NO_DELAY_PROPERTY_NAME, Boolean.valueOf( - StandardSocketFactory.TCP_NO_DELAY_DEFAULT_VALUE).booleanValue(), Messages.getString("ConnectionProperties.tcpNoDelay"), "5.0.7", NETWORK_CATEGORY, - Integer.MIN_VALUE); - - private BooleanConnectionProperty tcpKeepAlive = new BooleanConnectionProperty(StandardSocketFactory.TCP_KEEP_ALIVE_PROPERTY_NAME, Boolean.valueOf( - StandardSocketFactory.TCP_KEEP_ALIVE_DEFAULT_VALUE).booleanValue(), Messages.getString("ConnectionProperties.tcpKeepAlive"), "5.0.7", + private BooleanConnectionProperty tcpNoDelay = new BooleanConnectionProperty(StandardSocketFactory.TCP_NO_DELAY_PROPERTY_NAME, + Boolean.valueOf(StandardSocketFactory.TCP_NO_DELAY_DEFAULT_VALUE).booleanValue(), Messages.getString("ConnectionProperties.tcpNoDelay"), "5.0.7", NETWORK_CATEGORY, Integer.MIN_VALUE); + private BooleanConnectionProperty tcpKeepAlive = new BooleanConnectionProperty(StandardSocketFactory.TCP_KEEP_ALIVE_PROPERTY_NAME, + Boolean.valueOf(StandardSocketFactory.TCP_KEEP_ALIVE_DEFAULT_VALUE).booleanValue(), Messages.getString("ConnectionProperties.tcpKeepAlive"), + "5.0.7", NETWORK_CATEGORY, Integer.MIN_VALUE); + private IntegerConnectionProperty tcpRcvBuf = new IntegerConnectionProperty(StandardSocketFactory.TCP_RCV_BUF_PROPERTY_NAME, Integer.parseInt(StandardSocketFactory.TCP_RCV_BUF_DEFAULT_VALUE), 0, Integer.MAX_VALUE, Messages.getString("ConnectionProperties.tcpSoRcvBuf"), "5.0.7", NETWORK_CATEGORY, Integer.MIN_VALUE); @@ -1160,8 +1173,8 @@ private BooleanConnectionProperty useDirectRowUnpack = new BooleanConnectionProperty("useDirectRowUnpack", true, "Use newer result set row unpacking code that skips a copy from network buffers " - + " to a MySQL packet instance and instead reads directly into the result set row data buffers.", "5.1.1", PERFORMANCE_CATEGORY, - Integer.MIN_VALUE); + + " to a MySQL packet instance and instead reads directly into the result set row data buffers.", + "5.1.1", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); private BooleanConnectionProperty useFastIntParsing = new BooleanConnectionProperty("useFastIntParsing", true, Messages.getString("ConnectionProperties.useFastIntParsing"), "3.1.4", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); @@ -1241,9 +1254,10 @@ Messages.getString("ConnectionProperties.yearIsDateType"), "3.1.9", MISC_CATEGORY, Integer.MIN_VALUE); private StringConnectionProperty zeroDateTimeBehavior = new StringConnectionProperty("zeroDateTimeBehavior", ZERO_DATETIME_BEHAVIOR_EXCEPTION, - new String[] { ZERO_DATETIME_BEHAVIOR_EXCEPTION, ZERO_DATETIME_BEHAVIOR_ROUND, ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL }, Messages.getString( - "ConnectionProperties.zeroDateTimeBehavior", new Object[] { ZERO_DATETIME_BEHAVIOR_EXCEPTION, ZERO_DATETIME_BEHAVIOR_ROUND, - ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL }), "3.1.4", MISC_CATEGORY, Integer.MIN_VALUE); + new String[] { ZERO_DATETIME_BEHAVIOR_EXCEPTION, ZERO_DATETIME_BEHAVIOR_ROUND, ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL }, + Messages.getString("ConnectionProperties.zeroDateTimeBehavior", + new Object[] { ZERO_DATETIME_BEHAVIOR_EXCEPTION, ZERO_DATETIME_BEHAVIOR_ROUND, ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL }), + "3.1.4", MISC_CATEGORY, Integer.MIN_VALUE); private BooleanConnectionProperty useJvmCharsetConverters = new BooleanConnectionProperty("useJvmCharsetConverters", false, Messages.getString("ConnectionProperties.useJvmCharsetConverters"), "5.0.1", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); @@ -1759,7 +1773,10 @@ * @see com.mysql.jdbc.IConnectionProperties#getElideSetAutoCommits() */ public boolean getElideSetAutoCommits() { - return this.elideSetAutoCommits.getValueAsBoolean(); + // Server Bug#66884 (SERVER_STATUS is always initiated with SERVER_STATUS_AUTOCOMMIT=1) invalidates this feature. + return false; + // TODO Turn this feature back on as soon as the server bug is fixed. Consider making it version specific. + // return this.elideSetAutoCommits.getValueAsBoolean(); } /* @@ -4379,6 +4396,14 @@ this.loadBalanceStrategy.setValue(strategy); } + public String getServerAffinityOrder() { + return this.serverAffinityOrder.getValueAsString(); + } + + public void setServerAffinityOrder(String hostsList) { + this.serverAffinityOrder.setValue(hostsList); + } + public boolean getTcpNoDelay() { return this.tcpNoDelay.getValueAsBoolean(); } @@ -4672,7 +4697,6 @@ public void setLoadBalanceValidateConnectionOnSwapServer(boolean loadBalanceValidateConnectionOnSwapServer) { this.loadBalanceValidateConnectionOnSwapServer.setValue(loadBalanceValidateConnectionOnSwapServer); - } public String getLoadBalanceConnectionGroup() { @@ -4715,6 +4739,14 @@ this.loadBalanceEnableJMX.setValue(loadBalanceEnableJMX); } + public void setLoadBalanceHostRemovalGracePeriod(int loadBalanceHostRemovalGracePeriod) throws SQLException { + this.loadBalanceHostRemovalGracePeriod.setValue(loadBalanceHostRemovalGracePeriod, getExceptionInterceptor()); + } + + public int getLoadBalanceHostRemovalGracePeriod() { + return this.loadBalanceHostRemovalGracePeriod.getValueAsInt(); + } + public void setLoadBalanceAutoCommitStatementThreshold(int loadBalanceAutoCommitStatementThreshold) throws SQLException { this.loadBalanceAutoCommitStatementThreshold.setValue(loadBalanceAutoCommitStatementThreshold, getExceptionInterceptor()); } @@ -4765,7 +4797,6 @@ public void setDefaultAuthenticationPlugin(String defaultAuthenticationPlugin) { this.defaultAuthenticationPlugin.setValue(defaultAuthenticationPlugin); - } public String getDefaultAuthenticationPlugin() { @@ -4796,6 +4827,14 @@ return this.disconnectOnExpiredPasswords.getValueAsBoolean(); } + public String getReplicationConnectionGroup() { + return this.replicationConnectionGroup.getValueAsString(); + } + + public void setReplicationConnectionGroup(String replicationConnectionGroup) { + this.replicationConnectionGroup.setValue(replicationConnectionGroup); + } + public boolean getAllowMasterDownConnections() { return this.allowMasterDownConnections.getValueAsBoolean(); } @@ -4826,7 +4865,6 @@ public void setReplicationEnableJMX(boolean replicationEnableJMX) { this.replicationEnableJMX.setValue(replicationEnableJMX); - } public void setGetProceduresReturnsFunctions(boolean getProcedureReturnsFunctions) { @@ -4851,8 +4889,7 @@ public void setServerRSAPublicKeyFile(String serverRSAPublicKeyFile) throws SQLException { if (this.serverRSAPublicKeyFile.getUpdateCount() > 0) { - throw SQLError.createSQLException( - Messages.getString("ConnectionProperties.dynamicChangeIsNotAllowed", new Object[] { "'serverRSAPublicKeyFile'" }), + throw SQLError.createSQLException(Messages.getString("ConnectionProperties.dynamicChangeIsNotAllowed", new Object[] { "'serverRSAPublicKeyFile'" }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); } this.serverRSAPublicKeyFile.setValue(serverRSAPublicKeyFile); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaData.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaData.java (.../DatabaseMetaData.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaData.java (.../DatabaseMetaData.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -253,8 +253,8 @@ /* If the size is specified with the DDL, use that */ if ((StringUtils.indexOfIgnoreCase(typeInfo, "char") != -1 || StringUtils.indexOfIgnoreCase(typeInfo, "text") != -1 - || StringUtils.indexOfIgnoreCase(typeInfo, "blob") != -1 || StringUtils.indexOfIgnoreCase(typeInfo, "binary") != -1 || StringUtils - .indexOfIgnoreCase(typeInfo, "bit") != -1) && typeInfo.indexOf("(") != -1) { + || StringUtils.indexOfIgnoreCase(typeInfo, "blob") != -1 || StringUtils.indexOfIgnoreCase(typeInfo, "binary") != -1 + || StringUtils.indexOfIgnoreCase(typeInfo, "bit") != -1) && typeInfo.indexOf("(") != -1) { int endParenIndex = typeInfo.indexOf(")"); if (endParenIndex == -1) { @@ -426,6 +426,12 @@ } return compareTo((IndexMetaDataKey) obj) == 0; } + + @Override + public int hashCode() { + assert false : "hashCode not designed"; + return 0; + } } /** @@ -474,6 +480,12 @@ } return compareTo((TableMetaDataKey) obj) == 0; } + + @Override + public int hashCode() { + assert false : "hashCode not designed"; + return 0; + } } /** @@ -519,6 +531,12 @@ } @Override + public int hashCode() { + assert false : "hashCode not designed"; + return 0; + } + + @Override public String toString() { return "{KEY:" + this.key + "; VALUE:" + this.value + "}"; } @@ -528,8 +546,8 @@ * Enumeration for Table Types */ protected enum TableType { - LOCAL_TEMPORARY("LOCAL TEMPORARY"), SYSTEM_TABLE("SYSTEM TABLE"), SYSTEM_VIEW("SYSTEM VIEW"), TABLE("TABLE", new String[] { "BASE TABLE" }), VIEW( - "VIEW"), UNKNOWN("UNKNOWN"); + LOCAL_TEMPORARY("LOCAL TEMPORARY"), SYSTEM_TABLE("SYSTEM TABLE"), SYSTEM_VIEW("SYSTEM VIEW"), TABLE("TABLE", new String[] { "BASE TABLE" }), + VIEW("VIEW"), UNKNOWN("UNKNOWN"); private String name; private byte[] nameAsBytes; @@ -646,10 +664,10 @@ static { if (Util.isJdbc4()) { try { - JDBC_4_DBMD_SHOW_CTOR = Class.forName("com.mysql.jdbc.JDBC4DatabaseMetaData").getConstructor( - new Class[] { com.mysql.jdbc.MySQLConnection.class, String.class }); - JDBC_4_DBMD_IS_CTOR = Class.forName("com.mysql.jdbc.JDBC4DatabaseMetaDataUsingInfoSchema").getConstructor( - new Class[] { com.mysql.jdbc.MySQLConnection.class, String.class }); + JDBC_4_DBMD_SHOW_CTOR = Class.forName("com.mysql.jdbc.JDBC4DatabaseMetaData") + .getConstructor(new Class[] { com.mysql.jdbc.MySQLConnection.class, String.class }); + JDBC_4_DBMD_IS_CTOR = Class.forName("com.mysql.jdbc.JDBC4DatabaseMetaDataUsingInfoSchema") + .getConstructor(new Class[] { com.mysql.jdbc.MySQLConnection.class, String.class }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { @@ -671,18 +689,18 @@ "DESC", "DESCRIBE", "DETERMINISTIC", "DISTINCT", "DISTINCTROW", "DIV", "DOUBLE", "DROP", "DUAL", "EACH", "ELSE", "ELSEIF", "ENCLOSED", "ESCAPED", "EXISTS", "EXIT", "EXPLAIN", "FALSE", "FETCH", "FLOAT", "FLOAT4", "FLOAT8", "FOR", "FORCE", "FOREIGN", "FROM", "FULLTEXT", "GENERATED", "GET", "GRANT", "GROUP", "HAVING", "HIGH_PRIORITY", "HOUR_MICROSECOND", "HOUR_MINUTE", "HOUR_SECOND", "IF", "IGNORE", "IN", "INDEX", "INFILE", "INNER", - "INOUT", "INSENSITIVE", "INSERT", "INT", "INT1", "INT2", "INT3", "INT4", "INT8", "INTEGER", "INTERVAL", "INTO", "IO_AFTER_GTIDS", - "IO_BEFORE_GTIDS", "IS", "ITERATE", "JOIN", "KEY", "KEYS", "KILL", "LEADING", "LEAVE", "LEFT", "LIKE", "LIMIT", "LINEAR", "LINES", "LOAD", - "LOCALTIME", "LOCALTIMESTAMP", "LOCK", "LONG", "LONGBLOB", "LONGTEXT", "LOOP", "LOW_PRIORITY", "MASTER_BIND", "MASTER_SSL_VERIFY_SERVER_CERT", - "MATCH", "MAXVALUE", "MEDIUMBLOB", "MEDIUMINT", "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND", "MINUTE_SECOND", "MOD", "MODIFIES", "NATURAL", - "NOT", "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON", "OPTIMIZE", "OPTIMIZER_COSTS", "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT", "OUTER", - "OUTFILE", "PARTITION", "PRECISION", "PRIMARY", "PROCEDURE", "PURGE", "RANGE", "READ", "READS", "READ_WRITE", "REAL", "REFERENCES", "REGEXP", - "RELEASE", "RENAME", "REPEAT", "REPLACE", "REQUIRE", "RESIGNAL", "RESTRICT", "RETURN", "REVOKE", "RIGHT", "RLIKE", "SCHEMA", "SCHEMAS", - "SECOND_MICROSECOND", "SELECT", "SENSITIVE", "SEPARATOR", "SET", "SHOW", "SIGNAL", "SMALLINT", "SPATIAL", "SPECIFIC", "SQL", "SQLEXCEPTION", - "SQLSTATE", "SQLWARNING", "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", "SSL", "STARTING", "STORED", "STRAIGHT_JOIN", "TABLE", - "TERMINATED", "THEN", "TINYBLOB", "TINYINT", "TINYTEXT", "TO", "TRAILING", "TRIGGER", "TRUE", "UNDO", "UNION", "UNIQUE", "UNLOCK", "UNSIGNED", - "UPDATE", "USAGE", "USE", "USING", "UTC_DATE", "UTC_TIME", "UTC_TIMESTAMP", "VALUES", "VARBINARY", "VARCHAR", "VARCHARACTER", "VARYING", "VIRTUAL", - "WHEN", "WHERE", "WHILE", "WITH", "WRITE", "XOR", "YEAR_MONTH", "ZEROFILL" }; + "INOUT", "INSENSITIVE", "INSERT", "INT", "INT1", "INT2", "INT3", "INT4", "INT8", "INTEGER", "INTERVAL", "INTO", "IO_AFTER_GTIDS", "IO_BEFORE_GTIDS", + "IS", "ITERATE", "JOIN", "KEY", "KEYS", "KILL", "LEADING", "LEAVE", "LEFT", "LIKE", "LIMIT", "LINEAR", "LINES", "LOAD", "LOCALTIME", + "LOCALTIMESTAMP", "LOCK", "LONG", "LONGBLOB", "LONGTEXT", "LOOP", "LOW_PRIORITY", "MASTER_BIND", "MASTER_SSL_VERIFY_SERVER_CERT", "MATCH", + "MAXVALUE", "MEDIUMBLOB", "MEDIUMINT", "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND", "MINUTE_SECOND", "MOD", "MODIFIES", "NATURAL", "NOT", + "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON", "OPTIMIZE", "OPTIMIZER_COSTS", "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT", "OUTER", "OUTFILE", + "PARTITION", "PRECISION", "PRIMARY", "PROCEDURE", "PURGE", "RANGE", "READ", "READS", "READ_WRITE", "REAL", "REFERENCES", "REGEXP", "RELEASE", + "RENAME", "REPEAT", "REPLACE", "REQUIRE", "RESIGNAL", "RESTRICT", "RETURN", "REVOKE", "RIGHT", "RLIKE", "SCHEMA", "SCHEMAS", "SECOND_MICROSECOND", + "SELECT", "SENSITIVE", "SEPARATOR", "SET", "SHOW", "SIGNAL", "SMALLINT", "SPATIAL", "SPECIFIC", "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", + "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", "SSL", "STARTING", "STORED", "STRAIGHT_JOIN", "TABLE", "TERMINATED", "THEN", + "TINYBLOB", "TINYINT", "TINYTEXT", "TO", "TRAILING", "TRIGGER", "TRUE", "UNDO", "UNION", "UNIQUE", "UNLOCK", "UNSIGNED", "UPDATE", "USAGE", "USE", + "USING", "UTC_DATE", "UTC_TIME", "UTC_TIMESTAMP", "VALUES", "VARBINARY", "VARCHAR", "VARCHARACTER", "VARYING", "VIRTUAL", "WHEN", "WHERE", "WHILE", + "WITH", "WRITE", "XOR", "YEAR_MONTH", "ZEROFILL" }; // SQL:92 reserved words from 'ANSI X3.135-1992, January 4, 1993' private static final String[] SQL92_KEYWORDS = new String[] { "ABSOLUTE", "ACTION", "ADD", "ALL", "ALLOCATE", "ALTER", "AND", "ANY", "ARE", "AS", "ASC", @@ -720,13 +738,13 @@ "OLD", "ON", "ONLY", "OPEN", "OR", "ORDER", "OUT", "OUTER", "OVER", "OVERLAPS", "OVERLAY", "PARAMETER", "PARTITION", "PERCENTILE_CONT", "PERCENTILE_DISC", "PERCENT_RANK", "POSITION", "POWER", "PRECISION", "PREPARE", "PRIMARY", "PROCEDURE", "RANGE", "RANK", "READS", "REAL", "RECURSIVE", "REF", "REFERENCES", "REFERENCING", "REGR_AVGX", "REGR_AVGY", "REGR_COUNT", "REGR_INTERCEPT", "REGR_R2", "REGR_SLOPE", "REGR_SXX", - "REGR_SXY", "REGR_SYY", "RELEASE", "RESULT", "RETURN", "RETURNS", "REVOKE", "RIGHT", "ROLLBACK", "ROLLUP", "ROW", "ROWS", "ROW_NUMBER", - "SAVEPOINT", "SCOPE", "SCROLL", "SEARCH", "SECOND", "SELECT", "SENSITIVE", "SESSION_USER", "SET", "SIMILAR", "SMALLINT", "SOME", "SPECIFIC", - "SPECIFICTYPE", "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", "SQRT", "START", "STATIC", "STDDEV_POP", "STDDEV_SAMP", "SUBMULTISET", - "SUBSTRING", "SUM", "SYMMETRIC", "SYSTEM", "SYSTEM_USER", "TABLE", "TABLESAMPLE", "THEN", "TIME", "TIMESTAMP", "TIMEZONE_HOUR", "TIMEZONE_MINUTE", - "TO", "TRAILING", "TRANSLATE", "TRANSLATION", "TREAT", "TRIGGER", "TRIM", "TRUE", "UESCAPE", "UNION", "UNIQUE", "UNKNOWN", "UNNEST", "UPDATE", - "UPPER", "USER", "USING", "VALUE", "VALUES", "VARCHAR", "VARYING", "VAR_POP", "VAR_SAMP", "WHEN", "WHENEVER", "WHERE", "WIDTH_BUCKET", "WINDOW", - "WITH", "WITHIN", "WITHOUT", "YEAR" }; + "REGR_SXY", "REGR_SYY", "RELEASE", "RESULT", "RETURN", "RETURNS", "REVOKE", "RIGHT", "ROLLBACK", "ROLLUP", "ROW", "ROWS", "ROW_NUMBER", "SAVEPOINT", + "SCOPE", "SCROLL", "SEARCH", "SECOND", "SELECT", "SENSITIVE", "SESSION_USER", "SET", "SIMILAR", "SMALLINT", "SOME", "SPECIFIC", "SPECIFICTYPE", + "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", "SQRT", "START", "STATIC", "STDDEV_POP", "STDDEV_SAMP", "SUBMULTISET", "SUBSTRING", "SUM", + "SYMMETRIC", "SYSTEM", "SYSTEM_USER", "TABLE", "TABLESAMPLE", "THEN", "TIME", "TIMESTAMP", "TIMEZONE_HOUR", "TIMEZONE_MINUTE", "TO", "TRAILING", + "TRANSLATE", "TRANSLATION", "TREAT", "TRIGGER", "TRIM", "TRUE", "UESCAPE", "UNION", "UNIQUE", "UNKNOWN", "UNNEST", "UPDATE", "UPPER", "USER", + "USING", "VALUE", "VALUES", "VARCHAR", "VARYING", "VAR_POP", "VAR_SAMP", "WHEN", "WHENEVER", "WHERE", "WIDTH_BUCKET", "WINDOW", "WITH", "WITHIN", + "WITHOUT", "YEAR" }; private static volatile String mysqlKeywords = null; @@ -741,16 +759,25 @@ // We need to provide factory-style methods so we can support both JDBC3 (and older) and JDBC4 runtimes, otherwise the class verifier complains... + /** + * + * @param connToSet + * must not be null + * @param databaseToSet + * @param checkForInfoSchema + * @return + * @throws SQLException + */ protected static DatabaseMetaData getInstance(MySQLConnection connToSet, String databaseToSet, boolean checkForInfoSchema) throws SQLException { if (!Util.isJdbc4()) { - if (checkForInfoSchema && connToSet != null && connToSet.getUseInformationSchema() && connToSet.versionMeetsMinimum(5, 0, 7)) { + if (checkForInfoSchema && connToSet.getUseInformationSchema() && connToSet.versionMeetsMinimum(5, 0, 7)) { return new DatabaseMetaDataUsingInfoSchema(connToSet, databaseToSet); } return new DatabaseMetaData(connToSet, databaseToSet); } - if (checkForInfoSchema && connToSet != null && connToSet.getUseInformationSchema() && connToSet.versionMeetsMinimum(5, 0, 7)) { + if (checkForInfoSchema && connToSet.getUseInformationSchema() && connToSet.versionMeetsMinimum(5, 0, 7)) { return (DatabaseMetaData) Util.handleNewInstance(JDBC_4_DBMD_IS_CTOR, new Object[] { connToSet, databaseToSet }, connToSet.getExceptionInterceptor()); @@ -875,8 +902,8 @@ rowData[5] = s2b(functionName); // SPECFIC NAME } - procedureRows.add(new ComparableWrapper(getFullyQualifiedName(catalog, functionName), new ByteArrayRow(rowData, - getExceptionInterceptor()))); + procedureRows.add(new ComparableWrapper(getFullyQualifiedName(catalog, functionName), + new ByteArrayRow(rowData, getExceptionInterceptor()))); } } } @@ -935,8 +962,8 @@ rowData[8] = s2b(procedureName); - procedureRows.add(new ComparableWrapper(getFullyQualifiedName(catalog, procedureName), new ByteArrayRow(rowData, - getExceptionInterceptor()))); + procedureRows.add(new ComparableWrapper(getFullyQualifiedName(catalog, procedureName), + new ByteArrayRow(rowData, getExceptionInterceptor()))); } } } @@ -1630,9 +1657,10 @@ String procedureDef = paramRetrievalRs.getString(fieldName); if (!this.conn.getNoAccessToProcedureBodies() && (procedureDef == null || procedureDef.length() == 0)) { - throw SQLError.createSQLException("User does not have access to metadata required to determine " - + "stored procedure parameter types. If rights can not be granted, configure connection with \"noAccessToProcedureBodies=true\" " - + "to have driver generate parameters that represent INOUT strings irregardless of actual parameter types.", + throw SQLError.createSQLException( + "User does not have access to metadata required to determine " + + "stored procedure parameter types. If rights can not be granted, configure connection with \"noAccessToProcedureBodies=true\" " + + "to have driver generate parameters that represent INOUT strings irregardless of actual parameter types.", SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } @@ -1811,9 +1839,7 @@ paramName = paramName.substring(1, paramName.length() - 1); } - int wildCompareRes = StringUtils.wildCompare(paramName, parameterNamePattern); - - if (wildCompareRes != StringUtils.WILD_COMPARE_NO_MATCH) { + if (StringUtils.wildCompareIgnoreCase(paramName, parameterNamePattern)) { ResultSetRow row = convertTypeDescriptorToProcedureRow(procNameAsBytes, procCatAsBytes, paramName, isOutParam, isInParam, false, typeDesc, forGetFunctionColumns, ordinal++); @@ -2393,11 +2419,11 @@ } fullColumnQueryBuf.append("COLUMNS FROM "); - fullColumnQueryBuf.append(StringUtils.quoteIdentifier(tableName, DatabaseMetaData.this.quotedId, - DatabaseMetaData.this.conn.getPedantic())); + fullColumnQueryBuf.append( + StringUtils.quoteIdentifier(tableName, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.conn.getPedantic())); fullColumnQueryBuf.append(" FROM "); - fullColumnQueryBuf.append(StringUtils.quoteIdentifier(catalogStr, DatabaseMetaData.this.quotedId, - DatabaseMetaData.this.conn.getPedantic())); + fullColumnQueryBuf.append( + StringUtils.quoteIdentifier(catalogStr, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.conn.getPedantic())); results = stmt.executeQuery(fullColumnQueryBuf.toString()); @@ -2437,17 +2463,16 @@ } else { String collation = results.getString("Collation"); int mbminlen = 1; - if (collation != null - && ("TEXT".equals(typeDesc.typeName) || "TINYTEXT".equals(typeDesc.typeName) || "MEDIUMTEXT" - .equals(typeDesc.typeName))) { + if (collation != null && ("TEXT".equals(typeDesc.typeName) || "TINYTEXT".equals(typeDesc.typeName) + || "MEDIUMTEXT".equals(typeDesc.typeName))) { if (collation.indexOf("ucs2") > -1 || collation.indexOf("utf16") > -1) { mbminlen = 2; } else if (collation.indexOf("utf32") > -1) { mbminlen = 4; } } - rowVal[6] = mbminlen == 1 ? s2b(typeDesc.columnSize.toString()) : s2b(((Integer) (typeDesc.columnSize / mbminlen)) - .toString()); + rowVal[6] = mbminlen == 1 ? s2b(typeDesc.columnSize.toString()) + : s2b(((Integer) (typeDesc.columnSize / mbminlen)).toString()); } rowVal[7] = s2b(Integer.toString(typeDesc.bufferLength)); rowVal[8] = typeDesc.decimalDigits == null ? null : s2b(typeDesc.decimalDigits.toString()); @@ -2637,8 +2662,8 @@ * @throws SQLException * if a database access error occurs */ - public java.sql.ResultSet getCrossReference(final String primaryCatalog, final String primarySchema, final String primaryTable, - final String foreignCatalog, final String foreignSchema, final String foreignTable) throws SQLException { + public java.sql.ResultSet getCrossReference(final String primaryCatalog, final String primarySchema, final String primaryTable, final String foreignCatalog, + final String foreignSchema, final String foreignTable) throws SQLException { if (primaryTable == null) { throw SQLError.createSQLException("Table not specified.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } @@ -2668,8 +2693,8 @@ fkresults = extractForeignKeyFromCreateTable(catalogStr, null); } else { StringBuilder queryBuf = new StringBuilder("SHOW TABLE STATUS FROM "); - queryBuf.append(StringUtils.quoteIdentifier(catalogStr, DatabaseMetaData.this.quotedId, - DatabaseMetaData.this.conn.getPedantic())); + queryBuf.append( + StringUtils.quoteIdentifier(catalogStr, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.conn.getPedantic())); fkresults = stmt.executeQuery(queryBuf.toString()); } @@ -2961,8 +2986,8 @@ fkresults = extractForeignKeyFromCreateTable(catalogStr, null); } else { StringBuilder queryBuf = new StringBuilder("SHOW TABLE STATUS FROM "); - queryBuf.append(StringUtils.quoteIdentifier(catalogStr, DatabaseMetaData.this.quotedId, - DatabaseMetaData.this.conn.getPedantic())); + queryBuf.append( + StringUtils.quoteIdentifier(catalogStr, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.conn.getPedantic())); fkresults = stmt.executeQuery(queryBuf.toString()); } @@ -3175,8 +3200,8 @@ } else { StringBuilder queryBuf = new StringBuilder("SHOW TABLE STATUS "); queryBuf.append(" FROM "); - queryBuf.append(StringUtils.quoteIdentifier(catalogStr, DatabaseMetaData.this.quotedId, - DatabaseMetaData.this.conn.getPedantic())); + queryBuf.append( + StringUtils.quoteIdentifier(catalogStr, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.conn.getPedantic())); queryBuf.append(" LIKE "); queryBuf.append(StringUtils.quoteIdentifier(table, "'", true)); @@ -3804,7 +3829,8 @@ *
  • SQL_DATA_TYPE int => reserved for future use
  • *
  • SQL_DATETIME_SUB int => reserved for future use
  • *
  • CHAR_OCTET_LENGTH int => the maximum length of binary and character based columns. For any other datatype the returned value is a NULL
  • - *
  • ORDINAL_POSITION int => the ordinal position, starting from 1. A value of 0 is returned if this row describes the procedure's return value.
  • + *
  • ORDINAL_POSITION int => the ordinal position, starting from 1. A value of 0 is returned if this row describes the procedure's return value. + *
  • *
  • IS_NULLABLE String => ISO rules are used to determine the nullability for a column. *
      *
    • YES --- if the parameter can include NULLs
    • @@ -3906,8 +3932,9 @@ boolean hasResults = false; while (procsAndOrFuncsRs.next()) { - procsOrFuncsToExtractList.add(new ComparableWrapper(getFullyQualifiedName(procsAndOrFuncsRs.getString(1), - procsAndOrFuncsRs.getString(3)), procsAndOrFuncsRs.getShort(8) == procedureNoResult ? PROCEDURE : FUNCTION)); + procsOrFuncsToExtractList.add( + new ComparableWrapper(getFullyQualifiedName(procsAndOrFuncsRs.getString(1), procsAndOrFuncsRs.getString(3)), + procsAndOrFuncsRs.getShort(8) == procedureNoResult ? PROCEDURE : FUNCTION)); hasResults = true; } @@ -4060,29 +4087,25 @@ void forEach(String catalogStr) throws SQLException { String db = catalogStr; - boolean fromSelect = false; ResultSet proceduresRs = null; boolean needsClientFiltering = true; StringBuilder selectFromMySQLProcSQL = new StringBuilder(); selectFromMySQLProcSQL.append("SELECT name, type, comment FROM mysql.proc WHERE "); if (returnProcedures && !returnFunctions) { - selectFromMySQLProcSQL.append("type = 'PROCEDURE' and "); + selectFromMySQLProcSQL.append("type = 'PROCEDURE' AND "); } else if (!returnProcedures && returnFunctions) { - selectFromMySQLProcSQL.append("type = 'FUNCTION' and "); + selectFromMySQLProcSQL.append("type = 'FUNCTION' AND "); } - selectFromMySQLProcSQL.append("name like ? and db <=> ? ORDER BY name, type"); + selectFromMySQLProcSQL.append("name LIKE ? AND db <=> ? ORDER BY name, type"); java.sql.PreparedStatement proceduresStmt = prepareMetaDataSafeStatement(selectFromMySQLProcSQL.toString()); try { // // Try using system tables first, as this is a little bit more efficient.... // - - boolean hasTypeColumn = false; - if (db != null) { if (DatabaseMetaData.this.conn.lowerCaseTableNames()) { db = db.toLowerCase(); @@ -4098,52 +4121,42 @@ try { proceduresRs = proceduresStmt.executeQuery(); - fromSelect = true; needsClientFiltering = false; - hasTypeColumn = true; - } catch (SQLException sqlEx) { - // - // Okay, system tables aren't accessible, so use 'SHOW ....'.... - // - proceduresStmt.close(); + if (returnProcedures) { + convertToJdbcProcedureList(true, db, proceduresRs, needsClientFiltering, db, procedureRowsToSort, nameIndex); + } - fromSelect = false; - - if (DatabaseMetaData.this.conn.versionMeetsMinimum(5, 0, 1)) { - nameIndex = 2; - } else { - nameIndex = 1; + if (returnFunctions) { + convertToJdbcFunctionList(db, proceduresRs, needsClientFiltering, db, procedureRowsToSort, nameIndex, fields); } - proceduresStmt = prepareMetaDataSafeStatement("SHOW PROCEDURE STATUS LIKE ?"); + } catch (SQLException sqlEx) { + nameIndex = DatabaseMetaData.this.conn.versionMeetsMinimum(5, 0, 1) ? 2 : 1; - proceduresStmt.setString(1, procNamePattern); + // System tables aren't accessible, so use 'SHOW [FUNCTION|PROCEDURE] STATUS instead. + // Functions first: + if (returnFunctions) { + proceduresStmt.close(); - proceduresRs = proceduresStmt.executeQuery(); - } + proceduresStmt = prepareMetaDataSafeStatement("SHOW FUNCTION STATUS LIKE ?"); + proceduresStmt.setString(1, procNamePattern); + proceduresRs = proceduresStmt.executeQuery(); - if (returnProcedures) { - convertToJdbcProcedureList(fromSelect, db, proceduresRs, needsClientFiltering, db, procedureRowsToSort, nameIndex); - } + convertToJdbcFunctionList(db, proceduresRs, needsClientFiltering, db, procedureRowsToSort, nameIndex, fields); + } - if (!hasTypeColumn) { - // need to go after functions too... - if (proceduresStmt != null) { + // Procedures next: + if (returnProcedures) { proceduresStmt.close(); - } - proceduresStmt = prepareMetaDataSafeStatement("SHOW FUNCTION STATUS LIKE ?"); + proceduresStmt = prepareMetaDataSafeStatement("SHOW PROCEDURE STATUS LIKE ?"); + proceduresStmt.setString(1, procNamePattern); + proceduresRs = proceduresStmt.executeQuery(); - proceduresStmt.setString(1, procNamePattern); - - proceduresRs = proceduresStmt.executeQuery(); - + convertToJdbcProcedureList(false, db, proceduresRs, needsClientFiltering, db, procedureRowsToSort, nameIndex); + } } - //Should be here, not in IF block! - if (returnFunctions) { - convertToJdbcFunctionList(db, proceduresRs, needsClientFiltering, db, procedureRowsToSort, nameIndex, fields); - } } finally { SQLException rethrowSqlEx = null; @@ -4628,10 +4641,10 @@ try { try { - results = stmt.executeQuery((!DatabaseMetaData.this.conn.versionMeetsMinimum(5, 0, 2) ? "SHOW TABLES FROM " - : "SHOW FULL TABLES FROM ") - + StringUtils.quoteIdentifier(catalogStr, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.conn.getPedantic()) - + " LIKE " + StringUtils.quoteIdentifier(tableNamePat, "'", true)); + results = stmt + .executeQuery((!DatabaseMetaData.this.conn.versionMeetsMinimum(5, 0, 2) ? "SHOW TABLES FROM " : "SHOW FULL TABLES FROM ") + + StringUtils.quoteIdentifier(catalogStr, DatabaseMetaData.this.quotedId, DatabaseMetaData.this.conn.getPedantic()) + + " LIKE " + StringUtils.quoteIdentifier(tableNamePat, "'", true)); } catch (SQLException sqlEx) { if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE.equals(sqlEx.getSQLState())) { throw sqlEx; @@ -4672,7 +4685,7 @@ } } - int typeColumnIndex = 0; + int typeColumnIndex = 1; // MySQL 4.x returns the result set containing the single field with table names, so we always refer to first column boolean hasTableTypes = false; if (DatabaseMetaData.this.conn.versionMeetsMinimum(5, 0, 2)) { @@ -4772,8 +4785,8 @@ if (shouldReportTables) { // Pre-MySQL-5.0.1, tables only row[3] = TableType.TABLE.asBytes(); - sortedRows.put(new TableMetaDataKey(TableType.TABLE.getName(), catalogStr, null, results.getString(1)), new ByteArrayRow( - row, getExceptionInterceptor())); + sortedRows.put(new TableMetaDataKey(TableType.TABLE.getName(), catalogStr, null, results.getString(1)), + new ByteArrayRow(row, getExceptionInterceptor())); } } } @@ -6935,9 +6948,9 @@ */ public boolean supportsConvert(int fromType, int toType) throws SQLException { switch (fromType) { - /* - * The char/binary types can be converted to pretty much anything. - */ + /* + * The char/binary types can be converted to pretty much anything. + */ case java.sql.Types.CHAR: case java.sql.Types.VARCHAR: case java.sql.Types.LONGVARCHAR: @@ -6977,9 +6990,9 @@ case java.sql.Types.BIT: return false; - /* - * The numeric types. Basically they can convert among themselves, and with char/binary types. - */ + /* + * The numeric types. Basically they can convert among themselves, and with char/binary types. + */ case java.sql.Types.DECIMAL: case java.sql.Types.NUMERIC: case java.sql.Types.REAL: @@ -7016,9 +7029,9 @@ case java.sql.Types.NULL: return false; - /* - * With this driver, this will always be a serialized object, so the char/binary types will work. - */ + /* + * With this driver, this will always be a serialized object, so the char/binary types will work. + */ case java.sql.Types.OTHER: switch (toType) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaDataUsingInfoSchema.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaDataUsingInfoSchema.java (.../DatabaseMetaDataUsingInfoSchema.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaDataUsingInfoSchema.java (.../DatabaseMetaDataUsingInfoSchema.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -219,36 +219,13 @@ sqlBuf.append("CASE WHEN LCASE(DATA_TYPE)='date' THEN 10 WHEN LCASE(DATA_TYPE)='time' THEN 8 WHEN LCASE(DATA_TYPE)='datetime' THEN 19 " + "WHEN LCASE(DATA_TYPE)='timestamp' THEN 19 WHEN CHARACTER_MAXIMUM_LENGTH IS NULL THEN NUMERIC_PRECISION WHEN CHARACTER_MAXIMUM_LENGTH > " - + Integer.MAX_VALUE - + " THEN " - + Integer.MAX_VALUE - + " ELSE CHARACTER_MAXIMUM_LENGTH END AS COLUMN_SIZE, " - + MysqlIO.getMaxBuf() - + " AS BUFFER_LENGTH," - + "NUMERIC_SCALE AS DECIMAL_DIGITS," - + "10 AS NUM_PREC_RADIX," - + "CASE WHEN IS_NULLABLE='NO' THEN " - + columnNoNulls - + " ELSE CASE WHEN IS_NULLABLE='YES' THEN " - + columnNullable - + " ELSE " - + columnNullableUnknown - + " END END AS NULLABLE," - + "COLUMN_COMMENT AS REMARKS," - + "COLUMN_DEFAULT AS COLUMN_DEF," - + "0 AS SQL_DATA_TYPE," - + "0 AS SQL_DATETIME_SUB," - + "CASE WHEN CHARACTER_OCTET_LENGTH > " - + Integer.MAX_VALUE - + " THEN " - + Integer.MAX_VALUE - + " ELSE CHARACTER_OCTET_LENGTH END AS CHAR_OCTET_LENGTH," - + "ORDINAL_POSITION," - + "IS_NULLABLE," - + "NULL AS SCOPE_CATALOG," - + "NULL AS SCOPE_SCHEMA," - + "NULL AS SCOPE_TABLE," - + "NULL AS SOURCE_DATA_TYPE," + + Integer.MAX_VALUE + " THEN " + Integer.MAX_VALUE + " ELSE CHARACTER_MAXIMUM_LENGTH END AS COLUMN_SIZE, " + MysqlIO.getMaxBuf() + + " AS BUFFER_LENGTH," + "NUMERIC_SCALE AS DECIMAL_DIGITS," + "10 AS NUM_PREC_RADIX," + "CASE WHEN IS_NULLABLE='NO' THEN " + columnNoNulls + + " ELSE CASE WHEN IS_NULLABLE='YES' THEN " + columnNullable + " ELSE " + columnNullableUnknown + " END END AS NULLABLE," + + "COLUMN_COMMENT AS REMARKS," + "COLUMN_DEFAULT AS COLUMN_DEF," + "0 AS SQL_DATA_TYPE," + "0 AS SQL_DATETIME_SUB," + + "CASE WHEN CHARACTER_OCTET_LENGTH > " + Integer.MAX_VALUE + " THEN " + Integer.MAX_VALUE + + " ELSE CHARACTER_OCTET_LENGTH END AS CHAR_OCTET_LENGTH," + "ORDINAL_POSITION," + "IS_NULLABLE," + "NULL AS SCOPE_CATALOG," + + "NULL AS SCOPE_SCHEMA," + "NULL AS SCOPE_TABLE," + "NULL AS SOURCE_DATA_TYPE," + "IF (EXTRA LIKE '%auto_increment%','YES','NO') AS IS_AUTOINCREMENT, " + "IF (EXTRA LIKE '%GENERATED%','YES','NO') AS IS_GENERATEDCOLUMN FROM INFORMATION_SCHEMA.COLUMNS WHERE "); @@ -384,27 +361,12 @@ String sql = "SELECT A.REFERENCED_TABLE_SCHEMA AS PKTABLE_CAT,NULL AS PKTABLE_SCHEM, A.REFERENCED_TABLE_NAME AS PKTABLE_NAME," + "A.REFERENCED_COLUMN_NAME AS PKCOLUMN_NAME, A.TABLE_SCHEMA AS FKTABLE_CAT, NULL AS FKTABLE_SCHEM, A.TABLE_NAME AS FKTABLE_NAME, " - + "A.COLUMN_NAME AS FKCOLUMN_NAME, A.ORDINAL_POSITION AS KEY_SEQ," - + generateUpdateRuleClause() - + " AS UPDATE_RULE," - + generateDeleteRuleClause() - + " AS DELETE_RULE," - + "A.CONSTRAINT_NAME AS FK_NAME," - + "(SELECT CONSTRAINT_NAME FROM" - + " INFORMATION_SCHEMA.TABLE_CONSTRAINTS" - + " WHERE TABLE_SCHEMA = A.REFERENCED_TABLE_SCHEMA AND" - + " TABLE_NAME = A.REFERENCED_TABLE_NAME AND" - + " CONSTRAINT_TYPE IN ('UNIQUE','PRIMARY KEY') LIMIT 1)" - + " AS PK_NAME," - + importedKeyNotDeferrable - + " AS DEFERRABILITY " - + "FROM " - + "INFORMATION_SCHEMA.KEY_COLUMN_USAGE A JOIN " - + "INFORMATION_SCHEMA.TABLE_CONSTRAINTS B " - + "USING (TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME) " - + generateOptionalRefContraintsJoin() - + "WHERE " - + "B.CONSTRAINT_TYPE = 'FOREIGN KEY' " + + "A.COLUMN_NAME AS FKCOLUMN_NAME, A.ORDINAL_POSITION AS KEY_SEQ," + generateUpdateRuleClause() + " AS UPDATE_RULE," + + generateDeleteRuleClause() + " AS DELETE_RULE," + "A.CONSTRAINT_NAME AS FK_NAME," + "(SELECT CONSTRAINT_NAME FROM" + + " INFORMATION_SCHEMA.TABLE_CONSTRAINTS" + " WHERE TABLE_SCHEMA = A.REFERENCED_TABLE_SCHEMA AND" + " TABLE_NAME = A.REFERENCED_TABLE_NAME AND" + + " CONSTRAINT_TYPE IN ('UNIQUE','PRIMARY KEY') LIMIT 1)" + " AS PK_NAME," + importedKeyNotDeferrable + " AS DEFERRABILITY " + "FROM " + + "INFORMATION_SCHEMA.KEY_COLUMN_USAGE A JOIN " + "INFORMATION_SCHEMA.TABLE_CONSTRAINTS B " + + "USING (TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME) " + generateOptionalRefContraintsJoin() + "WHERE " + "B.CONSTRAINT_TYPE = 'FOREIGN KEY' " + "AND A.REFERENCED_TABLE_SCHEMA LIKE ? AND A.REFERENCED_TABLE_NAME=? " + "AND A.TABLE_SCHEMA LIKE ? AND A.TABLE_NAME=? ORDER BY A.TABLE_SCHEMA, A.TABLE_NAME, A.ORDINAL_POSITION"; @@ -503,29 +465,13 @@ String sql = "SELECT A.REFERENCED_TABLE_SCHEMA AS PKTABLE_CAT, NULL AS PKTABLE_SCHEM, A.REFERENCED_TABLE_NAME AS PKTABLE_NAME, " + "A.REFERENCED_COLUMN_NAME AS PKCOLUMN_NAME, A.TABLE_SCHEMA AS FKTABLE_CAT, NULL AS FKTABLE_SCHEM, A.TABLE_NAME AS FKTABLE_NAME," - + "A.COLUMN_NAME AS FKCOLUMN_NAME, A.ORDINAL_POSITION AS KEY_SEQ," - + generateUpdateRuleClause() - + " AS UPDATE_RULE," - + generateDeleteRuleClause() - + " AS DELETE_RULE," - + "A.CONSTRAINT_NAME AS FK_NAME," - + "(SELECT CONSTRAINT_NAME FROM" - + " INFORMATION_SCHEMA.TABLE_CONSTRAINTS" - + " WHERE TABLE_SCHEMA = A.REFERENCED_TABLE_SCHEMA AND" - + " TABLE_NAME = A.REFERENCED_TABLE_NAME AND" - + " CONSTRAINT_TYPE IN ('UNIQUE','PRIMARY KEY') LIMIT 1)" - + " AS PK_NAME," - + importedKeyNotDeferrable - + " AS DEFERRABILITY " - + "FROM " - + "INFORMATION_SCHEMA.KEY_COLUMN_USAGE A JOIN " - + "INFORMATION_SCHEMA.TABLE_CONSTRAINTS B " - + "USING (TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME) " - + generateOptionalRefContraintsJoin() - + "WHERE " - + "B.CONSTRAINT_TYPE = 'FOREIGN KEY' " - + "AND A.REFERENCED_TABLE_SCHEMA LIKE ? AND A.REFERENCED_TABLE_NAME=? " - + "ORDER BY A.TABLE_SCHEMA, A.TABLE_NAME, A.ORDINAL_POSITION"; + + "A.COLUMN_NAME AS FKCOLUMN_NAME, A.ORDINAL_POSITION AS KEY_SEQ," + generateUpdateRuleClause() + " AS UPDATE_RULE," + + generateDeleteRuleClause() + " AS DELETE_RULE," + "A.CONSTRAINT_NAME AS FK_NAME," + "(SELECT CONSTRAINT_NAME FROM" + + " INFORMATION_SCHEMA.TABLE_CONSTRAINTS" + " WHERE TABLE_SCHEMA = A.REFERENCED_TABLE_SCHEMA AND" + " TABLE_NAME = A.REFERENCED_TABLE_NAME AND" + + " CONSTRAINT_TYPE IN ('UNIQUE','PRIMARY KEY') LIMIT 1)" + " AS PK_NAME," + importedKeyNotDeferrable + " AS DEFERRABILITY " + "FROM " + + "INFORMATION_SCHEMA.KEY_COLUMN_USAGE A JOIN " + "INFORMATION_SCHEMA.TABLE_CONSTRAINTS B " + + "USING (TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME) " + generateOptionalRefContraintsJoin() + "WHERE " + "B.CONSTRAINT_TYPE = 'FOREIGN KEY' " + + "AND A.REFERENCED_TABLE_SCHEMA LIKE ? AND A.REFERENCED_TABLE_NAME=? " + "ORDER BY A.TABLE_SCHEMA, A.TABLE_NAME, A.ORDINAL_POSITION"; java.sql.PreparedStatement pStmt = null; @@ -634,31 +580,13 @@ String sql = "SELECT A.REFERENCED_TABLE_SCHEMA AS PKTABLE_CAT, NULL AS PKTABLE_SCHEM, A.REFERENCED_TABLE_NAME AS PKTABLE_NAME," + "A.REFERENCED_COLUMN_NAME AS PKCOLUMN_NAME, A.TABLE_SCHEMA AS FKTABLE_CAT, NULL AS FKTABLE_SCHEM, A.TABLE_NAME AS FKTABLE_NAME, " - + "A.COLUMN_NAME AS FKCOLUMN_NAME, A.ORDINAL_POSITION AS KEY_SEQ," - + generateUpdateRuleClause() - + " AS UPDATE_RULE," - + generateDeleteRuleClause() - + " AS DELETE_RULE," - + "A.CONSTRAINT_NAME AS FK_NAME," - + "(SELECT CONSTRAINT_NAME FROM" - + " INFORMATION_SCHEMA.TABLE_CONSTRAINTS" - + " WHERE TABLE_SCHEMA = A.REFERENCED_TABLE_SCHEMA AND" - + " TABLE_NAME = A.REFERENCED_TABLE_NAME AND" - + " CONSTRAINT_TYPE IN ('UNIQUE','PRIMARY KEY') LIMIT 1)" - + " AS PK_NAME," - + importedKeyNotDeferrable - + " AS DEFERRABILITY " - + "FROM " - + "INFORMATION_SCHEMA.KEY_COLUMN_USAGE A " - + "JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS B USING " - + "(CONSTRAINT_NAME, TABLE_NAME) " - + generateOptionalRefContraintsJoin() - + "WHERE " - + "B.CONSTRAINT_TYPE = 'FOREIGN KEY' " - + "AND A.TABLE_SCHEMA LIKE ? " - + "AND A.TABLE_NAME=? " - + "AND A.REFERENCED_TABLE_SCHEMA IS NOT NULL " - + "ORDER BY A.REFERENCED_TABLE_SCHEMA, A.REFERENCED_TABLE_NAME, A.ORDINAL_POSITION"; + + "A.COLUMN_NAME AS FKCOLUMN_NAME, A.ORDINAL_POSITION AS KEY_SEQ," + generateUpdateRuleClause() + " AS UPDATE_RULE," + + generateDeleteRuleClause() + " AS DELETE_RULE," + "A.CONSTRAINT_NAME AS FK_NAME," + "(SELECT CONSTRAINT_NAME FROM" + + " INFORMATION_SCHEMA.TABLE_CONSTRAINTS" + " WHERE TABLE_SCHEMA = A.REFERENCED_TABLE_SCHEMA AND" + " TABLE_NAME = A.REFERENCED_TABLE_NAME AND" + + " CONSTRAINT_TYPE IN ('UNIQUE','PRIMARY KEY') LIMIT 1)" + " AS PK_NAME," + importedKeyNotDeferrable + " AS DEFERRABILITY " + "FROM " + + "INFORMATION_SCHEMA.KEY_COLUMN_USAGE A " + "JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS B USING " + "(CONSTRAINT_NAME, TABLE_NAME) " + + generateOptionalRefContraintsJoin() + "WHERE " + "B.CONSTRAINT_TYPE = 'FOREIGN KEY' " + "AND A.TABLE_SCHEMA LIKE ? " + "AND A.TABLE_NAME=? " + + "AND A.REFERENCED_TABLE_SCHEMA IS NOT NULL " + "ORDER BY A.REFERENCED_TABLE_SCHEMA, A.REFERENCED_TABLE_NAME, A.ORDINAL_POSITION"; java.sql.PreparedStatement pStmt = null; @@ -1612,10 +1540,10 @@ pStmt.setString(2, functionNamePattern); ResultSet rs = executeMetadataQuery(pStmt); - ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(new Field[] { new Field("", "FUNCTION_CAT", Types.CHAR, 255), - new Field("", "FUNCTION_SCHEM", Types.CHAR, 255), new Field("", "FUNCTION_NAME", Types.CHAR, 255), - new Field("", "REMARKS", Types.CHAR, 255), new Field("", "FUNCTION_TYPE", Types.SMALLINT, 6), - new Field("", "SPECIFIC_NAME", Types.CHAR, 255) }); + ((com.mysql.jdbc.ResultSetInternalMethods) rs) + .redefineFieldsForDBMD(new Field[] { new Field("", "FUNCTION_CAT", Types.CHAR, 255), new Field("", "FUNCTION_SCHEM", Types.CHAR, 255), + new Field("", "FUNCTION_NAME", Types.CHAR, 255), new Field("", "REMARKS", Types.CHAR, 255), + new Field("", "FUNCTION_TYPE", Types.SMALLINT, 6), new Field("", "SPECIFIC_NAME", Types.CHAR, 255) }); return rs; } finally { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessor.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessor.java (.../EscapeProcessor.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessor.java (.../EscapeProcessor.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -29,7 +29,6 @@ import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Collections; -import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -319,7 +318,7 @@ } } - if (conn != null && (!conn.getUseTimezone() || !conn.getUseLegacyDatetimeCode())) { + if (!conn.getUseTimezone() || !conn.getUseLegacyDatetimeCode()) { newSql.append("'"); newSql.append(hour); newSql.append(":"); @@ -329,14 +328,8 @@ newSql.append(fractionalSecond); newSql.append("'"); } else { - Calendar sessionCalendar = null; + Calendar sessionCalendar = conn.getCalendarInstanceForSessionOrNew(); - if (conn != null) { - sessionCalendar = conn.getCalendarInstanceForSessionOrNew(); - } else { - sessionCalendar = new GregorianCalendar(); - } - try { int hourInt = Integer.parseInt(hour); int minuteInt = Integer.parseInt(minute); @@ -378,7 +371,7 @@ String argument = token.substring(startPos, endPos); try { - if (conn != null && !conn.getUseLegacyDatetimeCode()) { + if (!conn.getUseLegacyDatetimeCode()) { Timestamp ts = Timestamp.valueOf(argument); SimpleDateFormat tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US); @@ -424,19 +417,12 @@ * Thanks to Craig Longman for pointing out this bug */ - if (conn != null && !conn.getUseTimezone() && !conn.getUseJDBCCompliantTimezoneShift()) { + if (!conn.getUseTimezone() && !conn.getUseJDBCCompliantTimezoneShift()) { newSql.append("'").append(year4).append("-").append(month2).append("-").append(day2).append(" ").append(hour).append(":") .append(minute).append(":").append(second).append(fractionalSecond).append("'"); } else { - Calendar sessionCalendar; + Calendar sessionCalendar = conn.getCalendarInstanceForSessionOrNew(); - if (conn != null) { - sessionCalendar = conn.getCalendarInstanceForSessionOrNew(); - } else { - sessionCalendar = new GregorianCalendar(); - sessionCalendar.setTimeZone(TimeZone.getTimeZone("GMT")); - } - try { int year4Int = Integer.parseInt(year4); int month2Int = Integer.parseInt(month2); @@ -532,8 +518,9 @@ int firstIndexOfParen = functionToken.indexOf("("); if (firstIndexOfParen == -1) { - throw SQLError.createSQLException("Syntax error while processing {fn convert (... , ...)} token, missing opening parenthesis in token '" - + functionToken + "'.", SQLError.SQL_STATE_SYNTAX_ERROR, conn.getExceptionInterceptor()); + throw SQLError.createSQLException( + "Syntax error while processing {fn convert (... , ...)} token, missing opening parenthesis in token '" + functionToken + "'.", + SQLError.SQL_STATE_SYNTAX_ERROR, conn.getExceptionInterceptor()); } int indexOfComma = functionToken.lastIndexOf(","); @@ -546,8 +533,9 @@ int indexOfCloseParen = functionToken.indexOf(')', indexOfComma); if (indexOfCloseParen == -1) { - throw SQLError.createSQLException("Syntax error while processing {fn convert (... , ...)} token, missing closing parenthesis in token '" - + functionToken + "'.", SQLError.SQL_STATE_SYNTAX_ERROR, conn.getExceptionInterceptor()); + throw SQLError.createSQLException( + "Syntax error while processing {fn convert (... , ...)} token, missing closing parenthesis in token '" + functionToken + "'.", + SQLError.SQL_STATE_SYNTAX_ERROR, conn.getExceptionInterceptor()); } @@ -571,9 +559,9 @@ // CAST/CONVERT, so we can't re-write some data type conversions (date,time,timestamp, datetime) if (newType == null) { - throw SQLError.createSQLException("Can't find conversion re-write for type '" + type - + "' that is applicable for this server version while processing escape tokens.", SQLError.SQL_STATE_GENERAL_ERROR, - conn.getExceptionInterceptor()); + throw SQLError.createSQLException( + "Can't find conversion re-write for type '" + type + "' that is applicable for this server version while processing escape tokens.", + SQLError.SQL_STATE_GENERAL_ERROR, conn.getExceptionInterceptor()); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ExportControlled.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ExportControlled.java (.../ExportControlled.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ExportControlled.java (.../ExportControlled.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -31,27 +31,41 @@ import java.net.Socket; import java.net.SocketException; import java.net.URL; +import java.security.InvalidAlgorithmParameterException; import java.security.KeyFactory; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; +import java.security.cert.CertPath; +import java.security.cert.CertPathValidator; +import java.security.cert.CertPathValidatorException; +import java.security.cert.CertPathValidatorResult; import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.PKIXCertPathValidatorResult; +import java.security.cert.PKIXParameters; +import java.security.cert.TrustAnchor; +import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.security.spec.X509EncodedKeySpec; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Properties; +import java.util.Set; import javax.crypto.Cipher; +import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; @@ -89,8 +103,8 @@ List allowedProtocols = new ArrayList(); List supportedProtocols = Arrays.asList(((SSLSocket) mysqlIO.mysqlConnection).getSupportedProtocols()); - for (String protocol : (mysqlIO.versionMeetsMinimum(5, 6, 0) && Util.isEnterpriseEdition(mysqlIO.getServerVersion()) ? new String[] { "TLSv1.2", - "TLSv1.1", "TLSv1" } : new String[] { "TLSv1.1", "TLSv1" })) { + for (String protocol : (mysqlIO.versionMeetsMinimum(5, 6, 0) && Util.isEnterpriseEdition(mysqlIO.getServerVersion()) + ? new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" } : new String[] { "TLSv1.1", "TLSv1" })) { if (supportedProtocols.contains(protocol)) { allowedProtocols.add(protocol); } @@ -116,8 +130,8 @@ } else { // If we don't override ciphers, then we check for known restrictions boolean disableDHAlgorithm = false; - if (mysqlIO.versionMeetsMinimum(5, 5, 45) && !mysqlIO.versionMeetsMinimum(5, 6, 0) || mysqlIO.versionMeetsMinimum(5, 6, 26) - && !mysqlIO.versionMeetsMinimum(5, 7, 0) || mysqlIO.versionMeetsMinimum(5, 7, 6)) { + if (mysqlIO.versionMeetsMinimum(5, 5, 45) && !mysqlIO.versionMeetsMinimum(5, 6, 0) + || mysqlIO.versionMeetsMinimum(5, 6, 26) && !mysqlIO.versionMeetsMinimum(5, 7, 0) || mysqlIO.versionMeetsMinimum(5, 7, 6)) { // Workaround for JVM bug http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6521495 // Starting from 5.5.45, 5.6.26 and 5.7.6 server the key length used for creating Diffie-Hellman keys has been // increased from 512 to 2048 bits, while JVMs affected by this bug allow only range from 512 to 1024 (inclusive). @@ -204,23 +218,126 @@ private ExportControlled() { /* prevent instantiation */ } + /** + * Implementation of X509TrustManager wrapping JVM X509TrustManagers to add expiration check + */ + public static class X509TrustManagerWrapper implements X509TrustManager { + + private X509TrustManager origTm = null; + private boolean verifyServerCert = false; + private CertificateFactory certFactory = null; + private PKIXParameters validatorParams = null; + private CertPathValidator validator = null; + + public X509TrustManagerWrapper(X509TrustManager tm, boolean verifyServerCertificate) throws CertificateException { + this.origTm = tm; + this.verifyServerCert = verifyServerCertificate; + + if (verifyServerCertificate) { + try { + Set anch = new HashSet(); + for (X509Certificate cert : tm.getAcceptedIssuers()) { + anch.add(new TrustAnchor(cert, null)); + } + this.validatorParams = new PKIXParameters(anch); + this.validatorParams.setRevocationEnabled(false); + this.validator = CertPathValidator.getInstance("PKIX"); + this.certFactory = CertificateFactory.getInstance("X.509"); + } catch (Exception e) { + throw new CertificateException(e); + } + } + } + + public X509TrustManagerWrapper() { + } + + public X509Certificate[] getAcceptedIssuers() { + return this.origTm != null ? this.origTm.getAcceptedIssuers() : new X509Certificate[0]; + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + for (int i = 0; i < chain.length; i++) { + chain[i].checkValidity(); + } + + if (this.validatorParams != null) { + + X509CertSelector certSelect = new X509CertSelector(); + certSelect.setSerialNumber(chain[0].getSerialNumber()); + + try { + CertPath certPath = this.certFactory.generateCertPath(Arrays.asList(chain)); + // Validate against truststore + CertPathValidatorResult result = this.validator.validate(certPath, this.validatorParams); + // Check expiration for the CA used to validate this path + ((PKIXCertPathValidatorResult) result).getTrustAnchor().getTrustedCert().checkValidity(); + + } catch (InvalidAlgorithmParameterException e) { + throw new CertificateException(e); + } catch (CertPathValidatorException e) { + throw new CertificateException(e); + } + } + + if (this.verifyServerCert) { + this.origTm.checkServerTrusted(chain, authType); + } + } + + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + this.origTm.checkClientTrusted(chain, authType); + } + }; + private static SSLSocketFactory getSSLSocketFactoryDefaultOrConfigured(MysqlIO mysqlIO) throws SQLException { String clientCertificateKeyStoreUrl = mysqlIO.connection.getClientCertificateKeyStoreUrl(); - String trustCertificateKeyStoreUrl = mysqlIO.connection.getTrustCertificateKeyStoreUrl(); - String clientCertificateKeyStoreType = mysqlIO.connection.getClientCertificateKeyStoreType(); String clientCertificateKeyStorePassword = mysqlIO.connection.getClientCertificateKeyStorePassword(); - String trustCertificateKeyStoreType = mysqlIO.connection.getTrustCertificateKeyStoreType(); + String clientCertificateKeyStoreType = mysqlIO.connection.getClientCertificateKeyStoreType(); + String trustCertificateKeyStoreUrl = mysqlIO.connection.getTrustCertificateKeyStoreUrl(); String trustCertificateKeyStorePassword = mysqlIO.connection.getTrustCertificateKeyStorePassword(); + String trustCertificateKeyStoreType = mysqlIO.connection.getTrustCertificateKeyStoreType(); - if (StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl) && StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl)) { - if (mysqlIO.connection.getVerifyServerCertificate()) { - return (SSLSocketFactory) SSLSocketFactory.getDefault(); + if (StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl)) { + clientCertificateKeyStoreUrl = System.getProperty("javax.net.ssl.keyStore"); + clientCertificateKeyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword"); + clientCertificateKeyStoreType = System.getProperty("javax.net.ssl.keyStoreType"); + if (StringUtils.isNullOrEmpty(clientCertificateKeyStoreType)) { + clientCertificateKeyStoreType = "JKS"; } + // check URL + if (!StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl)) { + try { + new URL(clientCertificateKeyStoreUrl); + } catch (MalformedURLException e) { + clientCertificateKeyStoreUrl = "file:" + clientCertificateKeyStoreUrl; + } + } } + if (StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl)) { + trustCertificateKeyStoreUrl = System.getProperty("javax.net.ssl.trustStore"); + trustCertificateKeyStorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); + trustCertificateKeyStoreType = System.getProperty("javax.net.ssl.trustStoreType"); + if (StringUtils.isNullOrEmpty(trustCertificateKeyStoreType)) { + trustCertificateKeyStoreType = "JKS"; + } + // check URL + if (!StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl)) { + try { + new URL(trustCertificateKeyStoreUrl); + } catch (MalformedURLException e) { + trustCertificateKeyStoreUrl = "file:" + trustCertificateKeyStoreUrl; + } + } + } + TrustManagerFactory tmf = null; KeyManagerFactory kmf = null; + KeyManager[] kms = null; + List tms = new ArrayList(); + try { tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); @@ -240,6 +357,7 @@ ksIS = ksURL.openStream(); clientKeyStore.load(ksIS, password); kmf.init(clientKeyStore, password); + kms = kmf.getKeyManagers(); } } catch (UnrecoverableKeyException uke) { throw SQLError.createSQLException("Could not recover keys from client keystore. Check password?", SQL_STATE_BAD_SSL_PARAMS, 0, false, @@ -273,69 +391,66 @@ } } - if (!StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl)) { + InputStream trustStoreIS = null; + try { + KeyStore trustKeyStore = null; - InputStream ksIS = null; - try { - if (!StringUtils.isNullOrEmpty(trustCertificateKeyStoreType)) { - KeyStore trustKeyStore = KeyStore.getInstance(trustCertificateKeyStoreType); - URL ksURL = new URL(trustCertificateKeyStoreUrl); + if (!StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl) && !StringUtils.isNullOrEmpty(trustCertificateKeyStoreType)) { + trustStoreIS = new URL(trustCertificateKeyStoreUrl).openStream(); + char[] trustStorePassword = (trustCertificateKeyStorePassword == null) ? new char[0] : trustCertificateKeyStorePassword.toCharArray(); - char[] password = (trustCertificateKeyStorePassword == null) ? new char[0] : trustCertificateKeyStorePassword.toCharArray(); - ksIS = ksURL.openStream(); - trustKeyStore.load(ksIS, password); - tmf.init(trustKeyStore); - } - } catch (NoSuchAlgorithmException nsae) { - throw SQLError.createSQLException("Unsupported keystore algorithm [" + nsae.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, - mysqlIO.getExceptionInterceptor()); - } catch (KeyStoreException kse) { - throw SQLError.createSQLException("Could not create KeyStore instance [" + kse.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, - mysqlIO.getExceptionInterceptor()); - } catch (CertificateException nsae) { - throw SQLError.createSQLException("Could not load trust" + trustCertificateKeyStoreType + " keystore from " + trustCertificateKeyStoreUrl, - SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor()); - } catch (MalformedURLException mue) { - throw SQLError.createSQLException(trustCertificateKeyStoreUrl + " does not appear to be a valid URL.", SQL_STATE_BAD_SSL_PARAMS, 0, false, - mysqlIO.getExceptionInterceptor()); - } catch (IOException ioe) { - SQLException sqlEx = SQLError.createSQLException("Cannot open " + trustCertificateKeyStoreUrl + " [" + ioe.getMessage() + "]", - SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor()); + trustKeyStore = KeyStore.getInstance(trustCertificateKeyStoreType); + trustKeyStore.load(trustStoreIS, trustStorePassword); + } - sqlEx.initCause(ioe); + tmf.init(trustKeyStore); // (trustKeyStore == null) initializes the TrustManagerFactory with the default truststore. - throw sqlEx; - } finally { - if (ksIS != null) { - try { - ksIS.close(); - } catch (IOException e) { - // can't close input stream, but keystore can be properly initialized so we shouldn't throw this exception - } + // building the customized list of TrustManagers from original one if it's available + TrustManager[] origTms = tmf.getTrustManagers(); + final boolean verifyServerCert = mysqlIO.connection.getVerifyServerCertificate(); + + for (TrustManager tm : origTms) { + // wrap X509TrustManager or put original if non-X509 TrustManager + tms.add(tm instanceof X509TrustManager ? new X509TrustManagerWrapper((X509TrustManager) tm, verifyServerCert) : tm); + } + + } catch (MalformedURLException e) { + throw SQLError.createSQLException(trustCertificateKeyStoreUrl + " does not appear to be a valid URL.", SQL_STATE_BAD_SSL_PARAMS, 0, false, + mysqlIO.getExceptionInterceptor()); + } catch (KeyStoreException e) { + throw SQLError.createSQLException("Could not create KeyStore instance [" + e.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, + mysqlIO.getExceptionInterceptor()); + } catch (NoSuchAlgorithmException e) { + throw SQLError.createSQLException("Unsupported keystore algorithm [" + e.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, + mysqlIO.getExceptionInterceptor()); + } catch (CertificateException e) { + throw SQLError.createSQLException("Could not load trust" + trustCertificateKeyStoreType + " keystore from " + trustCertificateKeyStoreUrl, + SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor()); + } catch (IOException e) { + SQLException sqlEx = SQLError.createSQLException("Cannot open " + trustCertificateKeyStoreType + " [" + e.getMessage() + "]", + SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor()); + sqlEx.initCause(e); + throw sqlEx; + } finally { + if (trustStoreIS != null) { + try { + trustStoreIS.close(); + } catch (IOException e) { + // can't close input stream, but keystore can be properly initialized so we shouldn't throw this exception } } } - SSLContext sslContext = null; + // if original TrustManagers are not available then putting one X509TrustManagerWrapper which take care only about expiration check + if (tms.size() == 0) { + tms.add(new X509TrustManagerWrapper()); + } try { - sslContext = SSLContext.getInstance("TLS"); - sslContext.init(StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl) ? null : kmf.getKeyManagers(), - mysqlIO.connection.getVerifyServerCertificate() ? tmf.getTrustManagers() : new X509TrustManager[] { new X509TrustManager() { - public void checkClientTrusted(X509Certificate[] chain, String authType) { - // return without complaint - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - // return without complaint - } - - public X509Certificate[] getAcceptedIssuers() { - return null; - } - } }, null); - + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(kms, tms.toArray(new TrustManager[tms.size()]), null); return sslContext.getSocketFactory(); + } catch (NoSuchAlgorithmException nsae) { throw SQLError.createSQLException("TLS is not a valid SSL protocol.", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor()); } catch (KeyManagementException kme) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Field.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Field.java (.../Field.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Field.java (.../Field.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -152,7 +152,7 @@ boolean isFromFunction = this.originalTableNameLength == 0; if (this.mysqlType == MysqlDefs.FIELD_TYPE_BLOB) { - if (this.connection != null && this.connection.getBlobsAreStrings() || (this.connection.getFunctionsNeverReturnBlobs() && isFromFunction)) { + if (this.connection.getBlobsAreStrings() || (this.connection.getFunctionsNeverReturnBlobs() && isFromFunction)) { this.sqlType = Types.VARCHAR; this.mysqlType = MysqlDefs.FIELD_TYPE_VARCHAR; } else if (this.collationIndex == CharsetMapping.MYSQL_COLLATION_INDEX_binary || !this.connection.versionMeetsMinimum(4, 1, 0)) { @@ -190,13 +190,18 @@ this.encoding = "UTF-16"; } + // MySQL encodes JSON data with utf8mb4. + if (this.mysqlType == MysqlDefs.FIELD_TYPE_JSON) { + this.encoding = "UTF-8"; + } + // Handle VARBINARY/BINARY (server doesn't have a different type for this boolean isBinary = isBinary(); if (this.connection.versionMeetsMinimum(4, 1, 0) && this.mysqlType == MysqlDefs.FIELD_TYPE_VAR_STRING && isBinary && this.collationIndex == CharsetMapping.MYSQL_COLLATION_INDEX_binary) { - if (this.connection != null && (this.connection.getFunctionsNeverReturnBlobs() && isFromFunction)) { + if (this.connection.getFunctionsNeverReturnBlobs() && isFromFunction) { this.sqlType = Types.VARCHAR; this.mysqlType = MysqlDefs.FIELD_TYPE_VARCHAR; } else if (this.isOpaqueBinary()) { @@ -217,19 +222,12 @@ } if (this.mysqlType == MysqlDefs.FIELD_TYPE_BIT) { - this.isSingleBit = (this.length == 0); + this.isSingleBit = this.length == 0 + || this.length == 1 && (this.connection.versionMeetsMinimum(5, 0, 21) || this.connection.versionMeetsMinimum(5, 1, 10)); - if (this.connection != null && (this.connection.versionMeetsMinimum(5, 0, 21) || this.connection.versionMeetsMinimum(5, 1, 10)) - && this.length == 1) { - this.isSingleBit = true; - } - - if (this.isSingleBit) { - this.sqlType = Types.BIT; - } else { - this.sqlType = Types.VARBINARY; - this.colFlag |= 128; // we need to pretend this is a full - this.colFlag |= 16; // binary blob + if (!this.isSingleBit) { + this.colFlag |= 128; // Pretend this is a full binary(128) and blob(16) so that this field is de-serializable. + this.colFlag |= 16; isBinary = true; } } @@ -330,8 +328,8 @@ /** * Constructor used when communicating with pre 4.1 servers */ - Field(MySQLConnection conn, byte[] buffer, int nameStart, int nameLength, int tableNameStart, int tableNameLength, int length, int mysqlType, - short colFlag, int colDecimals) throws SQLException { + Field(MySQLConnection conn, byte[] buffer, int nameStart, int nameLength, int tableNameStart, int tableNameLength, int length, int mysqlType, short colFlag, + int colDecimals) throws SQLException { this(conn, buffer, -1, -1, tableNameStart, tableNameLength, -1, -1, nameStart, nameLength, -1, -1, length, mysqlType, colFlag, colDecimals, -1, -1, NO_CHARSET_INFO); } @@ -610,6 +608,10 @@ return null; } + if (stringLength == 0) { + return ""; + } + String stringVal = null; if (this.connection != null) { @@ -781,8 +783,8 @@ } private boolean isNativeDateTimeType() { - return (this.mysqlType == MysqlDefs.FIELD_TYPE_DATE || this.mysqlType == MysqlDefs.FIELD_TYPE_NEWDATE - || this.mysqlType == MysqlDefs.FIELD_TYPE_DATETIME || this.mysqlType == MysqlDefs.FIELD_TYPE_TIME || this.mysqlType == MysqlDefs.FIELD_TYPE_TIMESTAMP); + return (this.mysqlType == MysqlDefs.FIELD_TYPE_DATE || this.mysqlType == MysqlDefs.FIELD_TYPE_NEWDATE || this.mysqlType == MysqlDefs.FIELD_TYPE_DATETIME + || this.mysqlType == MysqlDefs.FIELD_TYPE_TIME || this.mysqlType == MysqlDefs.FIELD_TYPE_TIMESTAMP); } public void setConnection(MySQLConnection conn) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC42ResultSet.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC42ResultSet.java (.../JDBC42ResultSet.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC42ResultSet.java (.../JDBC42ResultSet.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -27,6 +27,8 @@ import java.sql.SQLException; import java.sql.SQLType; import java.sql.Struct; +import java.sql.Time; +import java.sql.Timestamp; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -62,20 +64,25 @@ } if (type.equals(LocalDate.class)) { - return type.cast(getDate(columnIndex).toLocalDate()); + final Date date = getDate(columnIndex); + return date == null ? null : type.cast(date.toLocalDate()); } else if (type.equals(LocalDateTime.class)) { - return type.cast(getTimestamp(columnIndex).toLocalDateTime()); + final Timestamp timestamp = getTimestamp(columnIndex); + return timestamp == null ? null : type.cast(timestamp.toLocalDateTime()); } else if (type.equals(LocalTime.class)) { - return type.cast(getTime(columnIndex).toLocalTime()); + final Time time = getTime(columnIndex); + return time == null ? null : type.cast(time.toLocalTime()); } else if (type.equals(OffsetDateTime.class)) { try { - return type.cast(OffsetDateTime.parse(getString(columnIndex))); + final String string = getString(columnIndex); + return string == null ? null : type.cast(OffsetDateTime.parse(string)); } catch (DateTimeParseException e) { // Let it continue and try by object deserialization. } } else if (type.equals(OffsetTime.class)) { try { - return type.cast(OffsetTime.parse(getString(columnIndex))); + final String string = getString(columnIndex); + return string == null? null : type.cast(OffsetTime.parse(string)); } catch (DateTimeParseException e) { // Let it continue and try by object deserialization. } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC42UpdatableResultSet.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC42UpdatableResultSet.java (.../JDBC42UpdatableResultSet.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC42UpdatableResultSet.java (.../JDBC42UpdatableResultSet.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -61,31 +61,33 @@ * @throws SQLException */ public T getObject(int columnIndex, Class type) throws SQLException { - if (type == null) { - throw SQLError.createSQLException("Type parameter can not be null", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); - } + synchronized (checkClosed().getConnectionMutex()) { + if (type == null) { + throw SQLError.createSQLException("Type parameter can not be null", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } - if (type.equals(LocalDate.class)) { - return type.cast(getDate(columnIndex).toLocalDate()); - } else if (type.equals(LocalDateTime.class)) { - return type.cast(getTimestamp(columnIndex).toLocalDateTime()); - } else if (type.equals(LocalTime.class)) { - return type.cast(getTime(columnIndex).toLocalTime()); - } else if (type.equals(OffsetDateTime.class)) { - try { - return type.cast(OffsetDateTime.parse(getString(columnIndex))); - } catch (DateTimeParseException e) { - // Let it continue and try by object deserialization. + if (type.equals(LocalDate.class)) { + return type.cast(getDate(columnIndex).toLocalDate()); + } else if (type.equals(LocalDateTime.class)) { + return type.cast(getTimestamp(columnIndex).toLocalDateTime()); + } else if (type.equals(LocalTime.class)) { + return type.cast(getTime(columnIndex).toLocalTime()); + } else if (type.equals(OffsetDateTime.class)) { + try { + return type.cast(OffsetDateTime.parse(getString(columnIndex))); + } catch (DateTimeParseException e) { + // Let it continue and try by object deserialization. + } + } else if (type.equals(OffsetTime.class)) { + try { + return type.cast(OffsetTime.parse(getString(columnIndex))); + } catch (DateTimeParseException e) { + // Let it continue and try by object deserialization. + } } - } else if (type.equals(OffsetTime.class)) { - try { - return type.cast(OffsetTime.parse(getString(columnIndex))); - } catch (DateTimeParseException e) { - // Let it continue and try by object deserialization. - } - } - return super.getObject(columnIndex, type); + return super.getObject(columnIndex, type); + } } /** @@ -96,7 +98,7 @@ * @throws SQLException */ @Override - public synchronized void updateObject(int columnIndex, Object x) throws SQLException { + public void updateObject(int columnIndex, Object x) throws SQLException { super.updateObject(columnIndex, JDBC42Helper.convertJavaTimeToJavaSql(x)); } @@ -109,7 +111,7 @@ * @throws SQLException */ @Override - public synchronized void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException { + public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException { super.updateObject(columnIndex, JDBC42Helper.convertJavaTimeToJavaSql(x), scaleOrLength); } @@ -121,7 +123,7 @@ * @throws SQLException */ @Override - public synchronized void updateObject(String columnLabel, Object x) throws SQLException { + public void updateObject(String columnLabel, Object x) throws SQLException { super.updateObject(columnLabel, JDBC42Helper.convertJavaTimeToJavaSql(x)); } @@ -134,7 +136,7 @@ * @throws SQLException */ @Override - public synchronized void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException { + public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException { super.updateObject(columnLabel, JDBC42Helper.convertJavaTimeToJavaSql(x), scaleOrLength); } @@ -147,7 +149,7 @@ * @param targetSqlType * @throws SQLException */ - public synchronized void updateObject(int columnIndex, Object x, SQLType targetSqlType) throws SQLException { + public void updateObject(int columnIndex, Object x, SQLType targetSqlType) throws SQLException { super.updateObjectInternal(columnIndex, JDBC42Helper.convertJavaTimeToJavaSql(x), translateAndCheckSqlType(targetSqlType), 0); } @@ -161,7 +163,7 @@ * @param scaleOrLength * @throws SQLException */ - public synchronized void updateObject(int columnIndex, Object x, SQLType targetSqlType, int scaleOrLength) throws SQLException { + public void updateObject(int columnIndex, Object x, SQLType targetSqlType, int scaleOrLength) throws SQLException { super.updateObjectInternal(columnIndex, JDBC42Helper.convertJavaTimeToJavaSql(x), translateAndCheckSqlType(targetSqlType), scaleOrLength); } @@ -174,7 +176,7 @@ * @param targetSqlType * @throws SQLException */ - public synchronized void updateObject(String columnLabel, Object x, SQLType targetSqlType) throws SQLException { + public void updateObject(String columnLabel, Object x, SQLType targetSqlType) throws SQLException { super.updateObjectInternal(findColumn(columnLabel), JDBC42Helper.convertJavaTimeToJavaSql(x), translateAndCheckSqlType(targetSqlType), 0); } @@ -188,7 +190,7 @@ * @param scaleOrLength * @throws SQLException */ - public synchronized void updateObject(String columnLabel, Object x, SQLType targetSqlType, int scaleOrLength) throws SQLException { + public void updateObject(String columnLabel, Object x, SQLType targetSqlType, int scaleOrLength) throws SQLException { super.updateObjectInternal(findColumn(columnLabel), JDBC42Helper.convertJavaTimeToJavaSql(x), translateAndCheckSqlType(targetSqlType), scaleOrLength); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4ClientInfoProviderSP.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4ClientInfoProviderSP.java (.../JDBC4ClientInfoProviderSP.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4ClientInfoProviderSP.java (.../JDBC4ClientInfoProviderSP.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -43,18 +43,18 @@ String getClientInfoSpName = configurationProps.getProperty("clientInfoGetSPName", "getClientInfo"); String getClientInfoBulkSpName = configurationProps.getProperty("clientInfoGetBulkSPName", "getClientInfoBulk"); String clientInfoCatalog = configurationProps.getProperty("clientInfoCatalog", ""); // "" means use current from - // connection + // connection String catalog = "".equals(clientInfoCatalog) ? conn.getCatalog() : clientInfoCatalog; - this.setClientInfoSp = ((com.mysql.jdbc.Connection) conn).clientPrepareStatement("CALL " + identifierQuote + catalog + identifierQuote + "." - + identifierQuote + setClientInfoSpName + identifierQuote + "(?, ?)"); + this.setClientInfoSp = ((com.mysql.jdbc.Connection) conn).clientPrepareStatement( + "CALL " + identifierQuote + catalog + identifierQuote + "." + identifierQuote + setClientInfoSpName + identifierQuote + "(?, ?)"); - this.getClientInfoSp = ((com.mysql.jdbc.Connection) conn).clientPrepareStatement("CALL" + identifierQuote + catalog + identifierQuote + "." - + identifierQuote + getClientInfoSpName + identifierQuote + "(?)"); + this.getClientInfoSp = ((com.mysql.jdbc.Connection) conn).clientPrepareStatement( + "CALL" + identifierQuote + catalog + identifierQuote + "." + identifierQuote + getClientInfoSpName + identifierQuote + "(?)"); - this.getClientInfoBulkSp = ((com.mysql.jdbc.Connection) conn).clientPrepareStatement("CALL " + identifierQuote + catalog + identifierQuote + "." - + identifierQuote + getClientInfoBulkSpName + identifierQuote + "()"); + this.getClientInfoBulkSp = ((com.mysql.jdbc.Connection) conn).clientPrepareStatement( + "CALL " + identifierQuote + catalog + identifierQuote + "." + identifierQuote + getClientInfoBulkSpName + identifierQuote + "()"); } public synchronized void destroy() throws SQLException { @@ -121,7 +121,7 @@ public synchronized void setClientInfo(java.sql.Connection conn, Properties properties) throws SQLClientInfoException { try { - Enumeration propNames = properties.propertyNames(); + Enumeration propNames = properties.propertyNames(); while (propNames.hasMoreElements()) { String name = (String) propNames.nextElement(); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4CommentClientInfoProvider.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4CommentClientInfoProvider.java (.../JDBC4CommentClientInfoProvider.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4CommentClientInfoProvider.java (.../JDBC4CommentClientInfoProvider.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -60,7 +60,7 @@ public synchronized void setClientInfo(java.sql.Connection conn, Properties properties) throws SQLClientInfoException { this.clientInfo = new Properties(); - Enumeration propNames = properties.propertyNames(); + Enumeration propNames = properties.propertyNames(); while (propNames.hasMoreElements()) { String name = (String) propNames.nextElement(); @@ -78,14 +78,14 @@ private synchronized void setComment(java.sql.Connection conn) { StringBuilder commentBuf = new StringBuilder(); - Iterator elements = this.clientInfo.entrySet().iterator(); + Iterator> elements = this.clientInfo.entrySet().iterator(); while (elements.hasNext()) { if (commentBuf.length() > 0) { commentBuf.append(", "); } - Map.Entry entry = (Map.Entry) elements.next(); + Map.Entry entry = elements.next(); commentBuf.append("" + entry.getKey()); commentBuf.append("="); commentBuf.append("" + entry.getValue()); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4Connection.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4Connection.java (.../JDBC4Connection.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4Connection.java (.../JDBC4Connection.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -38,6 +38,9 @@ import com.mysql.jdbc.SQLError; public class JDBC4Connection extends ConnectionImpl implements JDBC4MySQLConnection { + + private static final long serialVersionUID = 2877471301981509475L; + private JDBC4ClientInfoProvider infoProvider; public JDBC4Connection(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url) throws SQLException { @@ -213,12 +216,12 @@ if (this.infoProvider == null) { try { try { - this.infoProvider = (JDBC4ClientInfoProvider) Util.getInstance(getClientInfoProvider(), new Class[0], new Object[0], + this.infoProvider = (JDBC4ClientInfoProvider) Util.getInstance(getClientInfoProvider(), new Class[0], new Object[0], getExceptionInterceptor()); } catch (SQLException sqlEx) { if (sqlEx.getCause() instanceof ClassCastException) { // try with package name prepended - this.infoProvider = (JDBC4ClientInfoProvider) Util.getInstance("com.mysql.jdbc." + getClientInfoProvider(), new Class[0], + this.infoProvider = (JDBC4ClientInfoProvider) Util.getInstance("com.mysql.jdbc." + getClientInfoProvider(), new Class[0], new Object[0], getExceptionInterceptor()); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4MySQLConnection.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4MySQLConnection.java (.../JDBC4MySQLConnection.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4MySQLConnection.java (.../JDBC4MySQLConnection.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -64,7 +64,7 @@ public Clob createClob(); public NClob createNClob(); - + /* * Non standard methods: */ Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4MysqlSQLXML.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4MysqlSQLXML.java (.../JDBC4MysqlSQLXML.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4MysqlSQLXML.java (.../JDBC4MysqlSQLXML.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -258,7 +258,7 @@ * javax.xml.transform.sax.SAXSource - returns a SAXSource * javax.xml.transform.stax.StAXSource - returns a StAXSource * javax.xml.transform.stream.StreamSource - returns a StreamSource - * + * * * @return a Source for reading the XML value. * @throws SQLException @@ -271,7 +271,8 @@ * if the JDBC driver does not support this method * @since 1.6 */ - public synchronized Source getSource(Class clazz) throws SQLException { + @SuppressWarnings("unchecked") + public synchronized T getSource(Class clazz) throws SQLException { checkClosed(); checkWorkingWithResult(); @@ -288,7 +289,7 @@ inputSource = new InputSource(new StringReader(this.stringRep)); } - return new SAXSource(inputSource); + return (T) new SAXSource(inputSource); } else if (clazz.equals(DOMSource.class)) { try { DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); @@ -303,7 +304,7 @@ inputSource = new InputSource(new StringReader(this.stringRep)); } - return new DOMSource(builder.parse(inputSource)); + return (T) new DOMSource(builder.parse(inputSource)); } catch (Throwable t) { SQLException sqlEx = SQLError.createSQLException(t.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); sqlEx.initCause(t); @@ -320,7 +321,7 @@ reader = new StringReader(this.stringRep); } - return new StreamSource(reader); + return (T) new StreamSource(reader); } else if (clazz.equals(StAXSource.class)) { try { Reader reader = null; @@ -331,7 +332,7 @@ reader = new StringReader(this.stringRep); } - return new StAXSource(this.inputFactory.createXMLStreamReader(reader)); + return (T) new StAXSource(this.inputFactory.createXMLStreamReader(reader)); } catch (XMLStreamException ex) { SQLException sqlEx = SQLError.createSQLException(ex.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); sqlEx.initCause(ex); @@ -445,7 +446,7 @@ * javax.xml.transform.sax.SAXResult - returns a SAXResult * javax.xml.transform.stax.StAXResult - returns a StAXResult * javax.xml.transform.stream.StreamResult - returns a StreamResult - * + * * * @return Returns a Result for setting the XML value. * @throws SQLException @@ -458,7 +459,8 @@ * if the JDBC driver does not support this method * @since 1.6 */ - public synchronized Result setResult(Class clazz) throws SQLException { + @SuppressWarnings("unchecked") + public synchronized T setResult(Class clazz) throws SQLException { checkClosed(); checkWorkingWithResult(); @@ -475,21 +477,21 @@ this.asSAXResult = new SAXResult(this.saxToReaderConverter); - return this.asSAXResult; + return (T) this.asSAXResult; } else if (clazz.equals(DOMResult.class)) { this.asDOMResult = new DOMResult(); - return this.asDOMResult; + return (T) this.asDOMResult; } else if (clazz.equals(StreamResult.class)) { - return new StreamResult(setCharacterStreamInternal()); + return (T) new StreamResult(setCharacterStreamInternal()); } else if (clazz.equals(StAXResult.class)) { try { if (this.outputFactory == null) { this.outputFactory = XMLOutputFactory.newInstance(); } - return new StAXResult(this.outputFactory.createXMLEventWriter(setCharacterStreamInternal())); + return (T) new StAXResult(this.outputFactory.createXMLEventWriter(setCharacterStreamInternal())); } catch (XMLStreamException ex) { SQLException sqlEx = SQLError.createSQLException(ex.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); sqlEx.initCause(ex); @@ -771,8 +773,8 @@ default: - if (((c >= 0x01 && c <= 0x1F && c != 0x09 && c != 0x0A) || (c >= 0x7F && c <= 0x9F) || c == 0x2028) || isAttributeData - && (c == 0x09 || c == 0x0A)) { + if (((c >= 0x01 && c <= 0x1F && c != 0x09 && c != 0x0A) || (c >= 0x7F && c <= 0x9F) || c == 0x2028) + || isAttributeData && (c == 0x09 || c == 0x0A)) { this.buf.append("&#x"); this.buf.append(Integer.toHexString(c).toUpperCase()); this.buf.append(";"); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4ServerPreparedStatement.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4ServerPreparedStatement.java (.../JDBC4ServerPreparedStatement.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4ServerPreparedStatement.java (.../JDBC4ServerPreparedStatement.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -56,10 +56,9 @@ setNull(parameterIndex, java.sql.Types.BINARY); } else { BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + resetToType(binding, MysqlDefs.FIELD_TYPE_BLOB); binding.value = reader; - binding.isNull = false; binding.isLongData = true; if (this.connection.getUseStreamLengthsInPrepStmts()) { @@ -102,10 +101,9 @@ setNull(parameterIndex, java.sql.Types.NCLOB); } else { BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + resetToType(binding, MysqlDefs.FIELD_TYPE_BLOB); binding.value = reader; - binding.isNull = false; binding.isLongData = true; if (this.connection.getUseStreamLengthsInPrepStmts()) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4UpdatableResultSet.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4UpdatableResultSet.java (.../JDBC4UpdatableResultSet.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4UpdatableResultSet.java (.../JDBC4UpdatableResultSet.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -201,26 +201,28 @@ * @exception SQLException * if a database-access error occurs */ - public synchronized void updateNCharacterStream(int columnIndex, java.io.Reader x, int length) throws SQLException { - String fieldEncoding = this.fields[columnIndex - 1].getEncoding(); - if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { - throw new SQLException("Can not call updateNCharacterStream() when field's character set isn't UTF-8"); - } - - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); + public void updateNCharacterStream(int columnIndex, java.io.Reader x, int length) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + String fieldEncoding = this.fields[columnIndex - 1].getEncoding(); + if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { + throw new SQLException("Can not call updateNCharacterStream() when field's character set isn't UTF-8"); } - ((com.mysql.jdbc.JDBC4PreparedStatement) this.updater).setNCharacterStream(columnIndex, x, length); - } else { - ((com.mysql.jdbc.JDBC4PreparedStatement) this.inserter).setNCharacterStream(columnIndex, x, length); + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - if (x == null) { - this.thisRow.setColumnValue(columnIndex - 1, null); + ((com.mysql.jdbc.JDBC4PreparedStatement) this.updater).setNCharacterStream(columnIndex, x, length); } else { - this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); + ((com.mysql.jdbc.JDBC4PreparedStatement) this.inserter).setNCharacterStream(columnIndex, x, length); + + if (x == null) { + this.thisRow.setColumnValue(columnIndex - 1, null); + } else { + this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); + } } } } @@ -242,23 +244,25 @@ * @exception SQLException * if a database-access error occurs */ - public synchronized void updateNCharacterStream(String columnName, java.io.Reader reader, int length) throws SQLException { + public void updateNCharacterStream(String columnName, java.io.Reader reader, int length) throws SQLException { updateNCharacterStream(findColumn(columnName), reader, length); } /** * @see ResultSet#updateNClob(int, NClob) */ public void updateNClob(int columnIndex, java.sql.NClob nClob) throws SQLException { - String fieldEncoding = this.fields[columnIndex - 1].getEncoding(); - if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { - throw new SQLException("Can not call updateNClob() when field's character set isn't UTF-8"); - } + synchronized (checkClosed().getConnectionMutex()) { + String fieldEncoding = this.fields[columnIndex - 1].getEncoding(); + if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { + throw new SQLException("Can not call updateNClob() when field's character set isn't UTF-8"); + } - if (nClob == null) { - updateNull(columnIndex); - } else { - updateNCharacterStream(columnIndex, nClob.getCharacterStream(), (int) nClob.length()); + if (nClob == null) { + updateNull(columnIndex); + } else { + updateNCharacterStream(columnIndex, nClob.getCharacterStream(), (int) nClob.length()); + } } } @@ -283,27 +287,29 @@ * @exception SQLException * if a database-access error occurs */ - public synchronized void updateNString(int columnIndex, String x) throws SQLException { - String fieldEncoding = this.fields[columnIndex - 1].getEncoding(); - if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { - throw new SQLException("Can not call updateNString() when field's character set isn't UTF-8"); - } - - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); + public void updateNString(int columnIndex, String x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + String fieldEncoding = this.fields[columnIndex - 1].getEncoding(); + if (fieldEncoding == null || !fieldEncoding.equals("UTF-8")) { + throw new SQLException("Can not call updateNString() when field's character set isn't UTF-8"); } - ((com.mysql.jdbc.JDBC4PreparedStatement) this.updater).setNString(columnIndex, x); - } else { - ((com.mysql.jdbc.JDBC4PreparedStatement) this.inserter).setNString(columnIndex, x); + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - if (x == null) { - this.thisRow.setColumnValue(columnIndex - 1, null); + ((com.mysql.jdbc.JDBC4PreparedStatement) this.updater).setNString(columnIndex, x); } else { - this.thisRow.setColumnValue(columnIndex - 1, StringUtils.getBytes(x, this.charConverter, fieldEncoding, this.connection.getServerCharset(), - this.connection.parserKnowsUnicode(), getExceptionInterceptor())); + ((com.mysql.jdbc.JDBC4PreparedStatement) this.inserter).setNString(columnIndex, x); + + if (x == null) { + this.thisRow.setColumnValue(columnIndex - 1, null); + } else { + this.thisRow.setColumnValue(columnIndex - 1, StringUtils.getBytes(x, this.charConverter, fieldEncoding, this.connection.getServerCharset(), + this.connection.parserKnowsUnicode(), getExceptionInterceptor())); + } } } } @@ -322,7 +328,7 @@ * @exception SQLException * if a database-access error occurs */ - public synchronized void updateNString(String columnName, String x) throws SQLException { + public void updateNString(String columnName, String x) throws SQLException { updateNString(findColumn(columnName), x); } @@ -526,7 +532,7 @@ return asString; } - public synchronized boolean isClosed() throws SQLException { + public boolean isClosed() throws SQLException { return this.isClosed; } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedConnectionProxy.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedConnectionProxy.java (.../LoadBalancedConnectionProxy.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedConnectionProxy.java (.../LoadBalancedConnectionProxy.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -24,12 +24,14 @@ package com.mysql.jdbc; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -57,7 +59,6 @@ protected Map liveConnections; private Map hostsToListIndexMap; private Map connectionsToHostsMap; - private long activePhysicalConnections = 0; private long totalPhysicalConnections = 0; private long[] responseTimes; @@ -68,7 +69,10 @@ public static final String BLACKLIST_TIMEOUT_PROPERTY_KEY = "loadBalanceBlacklistTimeout"; private int globalBlacklistTimeout = 0; private static Map globalBlacklist = new HashMap(); - private String hostToRemove = null; + public static final String HOST_REMOVAL_GRACE_PERIOD_PROPERTY_KEY = "loadBalanceHostRemovalGracePeriod"; + private int hostRemovalGracePeriod = 0; + // host:port pairs to be considered as removed (definitely blacklisted) from the original hosts list. + private Set hostsToRemove = new HashSet(); private boolean inTransaction = false; private long transactionStartTime = 0; @@ -160,17 +164,28 @@ this.globalBlacklistTimeout = Integer.parseInt(blacklistTimeoutAsString); } catch (NumberFormatException nfe) { throw SQLError.createSQLException( - Messages.getString("LoadBalancedConnectionProxy.badValueForLoadBalanceBlacklistTimeout", new Object[] { retriesAllDownAsString }), + Messages.getString("LoadBalancedConnectionProxy.badValueForLoadBalanceBlacklistTimeout", new Object[] { blacklistTimeoutAsString }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); } + String hostRemovalGracePeriodAsString = this.localProps.getProperty(HOST_REMOVAL_GRACE_PERIOD_PROPERTY_KEY, "15000"); + try { + this.hostRemovalGracePeriod = Integer.parseInt(hostRemovalGracePeriodAsString); + } catch (NumberFormatException nfe) { + throw SQLError.createSQLException(Messages.getString("LoadBalancedConnectionProxy.badValueForLoadBalanceHostRemovalGracePeriod", + new Object[] { hostRemovalGracePeriodAsString }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + } + String strategy = this.localProps.getProperty("loadBalanceStrategy", "random"); if ("random".equals(strategy)) { - this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, "com.mysql.jdbc.RandomBalanceStrategy", "InvalidLoadBalanceStrategy", null) + this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, RandomBalanceStrategy.class.getName(), "InvalidLoadBalanceStrategy", null) .get(0); } else if ("bestResponseTime".equals(strategy)) { this.balancer = (BalanceStrategy) Util - .loadExtensions(null, props, "com.mysql.jdbc.BestResponseTimeBalanceStrategy", "InvalidLoadBalanceStrategy", null).get(0); + .loadExtensions(null, props, BestResponseTimeBalanceStrategy.class.getName(), "InvalidLoadBalanceStrategy", null).get(0); + } else if ("serverAffinity".equals(strategy)) { + this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, ServerAffinityStrategy.class.getName(), "InvalidLoadBalanceStrategy", null) + .get(0); } else { this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, strategy, "InvalidLoadBalanceStrategy", null).get(0); } @@ -359,7 +374,6 @@ this.liveConnections.put(hostPortSpec, conn); this.connectionsToHostsMap.put(conn, hostPortSpec); - this.activePhysicalConnections++; this.totalPhysicalConnections++; return conn; @@ -372,7 +386,6 @@ // close all underlying connections for (MySQLConnection c : this.liveConnections.values()) { try { - this.activePhysicalConnections--; c.close(); } catch (SQLException e) { } @@ -405,7 +418,6 @@ // abort all underlying connections for (MySQLConnection c : this.liveConnections.values()) { try { - this.activePhysicalConnections--; c.abortInternal(); } catch (SQLException e) { } @@ -430,7 +442,6 @@ // close all underlying connections for (MySQLConnection c : this.liveConnections.values()) { try { - this.activePhysicalConnections--; c.abort(executor); } catch (SQLException e) { } @@ -466,7 +477,7 @@ } else { String reason = "No operations allowed after connection closed."; if (this.closedReason != null) { - reason += (" " + this.closedReason); + reason += " " + this.closedReason; } throw SQLError.createSQLException(reason, SQLError.SQL_STATE_CONNECTION_NOT_OPEN, null /* no access to a interceptor here... */); } @@ -538,7 +549,6 @@ } foundHost = true; } catch (SQLException e) { - this.activePhysicalConnections--; // give up if it is the current connection, otherwise NPE faking resultset later. if (host.equals(this.connectionsToHostsMap.get(this.currentConnection))) { // clean up underlying connections, since connection pool won't do it @@ -604,7 +614,6 @@ */ public void addToGlobalBlacklist(String host) { addToGlobalBlacklist(host, System.currentTimeMillis() + this.globalBlacklistTimeout); - } /** @@ -615,22 +624,21 @@ } /** - * Returns a local hosts blacklist, or a blacklist with a single host to be removed, while cleaning up expired records from the global blacklist. + * Returns a local hosts blacklist, while cleaning up expired records from the global blacklist, or a blacklist with the hosts to be removed. * * @return * A local hosts blacklist. */ public synchronized Map getGlobalBlacklist() { if (!isGlobalBlacklistEnabled()) { - String localHostToRemove = this.hostToRemove; - - if (this.hostToRemove != null) { - HashMap fakedBlacklist = new HashMap(); - fakedBlacklist.put(localHostToRemove, System.currentTimeMillis() + 5000); - return fakedBlacklist; + if (this.hostsToRemove.isEmpty()) { + return new HashMap(1); } - - return new HashMap(1); + HashMap fakedBlacklist = new HashMap(); + for (String h : this.hostsToRemove) { + fakedBlacklist.put(h, System.currentTimeMillis() + 5000); + } + return fakedBlacklist; } // Make a local copy of the blacklist @@ -670,24 +678,28 @@ /** * Removes a host from the host list, allowing it some time to be released gracefully if needed. * - * @param host + * @param hostPortPair * The host to be removed. * @throws SQLException */ - public void removeHostWhenNotInUse(String host) throws SQLException { - int timeBetweenChecks = 1000; - long timeBeforeHardFail = 15000; + public void removeHostWhenNotInUse(String hostPortPair) throws SQLException { + if (this.hostRemovalGracePeriod <= 0) { + removeHost(hostPortPair); + return; + } + int timeBetweenChecks = this.hostRemovalGracePeriod > 1000 ? 1000 : this.hostRemovalGracePeriod; + synchronized (this) { - addToGlobalBlacklist(host, System.currentTimeMillis() + timeBeforeHardFail + 1000); + addToGlobalBlacklist(hostPortPair, System.currentTimeMillis() + this.hostRemovalGracePeriod + timeBetweenChecks); long cur = System.currentTimeMillis(); - while (System.currentTimeMillis() < cur + timeBeforeHardFail) { - this.hostToRemove = host; + while (System.currentTimeMillis() < cur + this.hostRemovalGracePeriod) { + this.hostsToRemove.add(hostPortPair); - if (!host.equals(this.currentConnection.getHost())) { - removeHost(host); + if (!hostPortPair.equals(this.currentConnection.getHostPortPair())) { + removeHost(hostPortPair); return; } @@ -699,60 +711,67 @@ } } - removeHost(host); + removeHost(hostPortPair); } /** * Removes a host from the host list. * - * @param host + * @param hostPortPair * The host to be removed. * @throws SQLException */ - public synchronized void removeHost(String host) throws SQLException { + public synchronized void removeHost(String hostPortPair) throws SQLException { if (this.connectionGroup != null) { - if (this.connectionGroup.getInitialHosts().size() == 1 && this.connectionGroup.getInitialHosts().contains(host)) { + if (this.connectionGroup.getInitialHosts().size() == 1 && this.connectionGroup.getInitialHosts().contains(hostPortPair)) { throw SQLError.createSQLException("Cannot remove only configured host.", null); } + } - this.hostToRemove = host; + this.hostsToRemove.add(hostPortPair); - if (host.equals(this.currentConnection.getHost())) { - closeAllConnections(); - } else { - this.connectionsToHostsMap.remove(this.liveConnections.remove(host)); - Integer idx = this.hostsToListIndexMap.remove(host); - long[] newResponseTimes = new long[this.responseTimes.length - 1]; - int newIdx = 0; - for (Iterator i = this.hostList.iterator(); i.hasNext(); newIdx++) { - String copyHost = i.next(); + this.connectionsToHostsMap.remove(this.liveConnections.remove(hostPortPair)); + if (this.hostsToListIndexMap.remove(hostPortPair) != null) { + long[] newResponseTimes = new long[this.responseTimes.length - 1]; + int newIdx = 0; + for (String h : this.hostList) { + if (!this.hostsToRemove.contains(h)) { + Integer idx = this.hostsToListIndexMap.get(h); if (idx != null && idx < this.responseTimes.length) { newResponseTimes[newIdx] = this.responseTimes[idx]; - this.hostsToListIndexMap.put(copyHost, newIdx); } + this.hostsToListIndexMap.put(h, newIdx++); } - this.responseTimes = newResponseTimes; } + this.responseTimes = newResponseTimes; } + + if (hostPortPair.equals(this.currentConnection.getHostPortPair())) { + invalidateConnection(this.currentConnection); + pickNewConnection(); + } } /** * Adds a host to the hosts list. * - * @param host + * @param hostPortPair * The host to be added. */ - public synchronized boolean addHost(String host) { - if (this.hostsToListIndexMap.containsKey(host)) { + public synchronized boolean addHost(String hostPortPair) { + if (this.hostsToListIndexMap.containsKey(hostPortPair)) { return false; } long[] newResponseTimes = new long[this.responseTimes.length + 1]; System.arraycopy(this.responseTimes, 0, newResponseTimes, 0, this.responseTimes.length); this.responseTimes = newResponseTimes; - this.hostList.add(host); - this.hostsToListIndexMap.put(host, this.responseTimes.length - 1); + if (!this.hostList.contains(hostPortPair)) { + this.hostList.add(hostPortPair); + } + this.hostsToListIndexMap.put(hostPortPair, this.responseTimes.length - 1); + this.hostsToRemove.remove(hostPortPair); return true; } @@ -766,7 +785,7 @@ } public synchronized long getActivePhysicalConnectionCount() { - return this.activePhysicalConnections; + return this.liveConnections.size(); } public synchronized long getTotalPhysicalConnectionCount() { @@ -794,4 +813,35 @@ } return 0; } + + /** + * A LoadBalancedConnection proxy that provides null-functionality. It can be used as a replacement of the null keyword in the places where a + * LoadBalancedConnection object cannot be effectively null because that would be a potential source of NPEs. + */ + private static class NullLoadBalancedConnectionProxy implements InvocationHandler { + public NullLoadBalancedConnectionProxy() { + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + SQLException exceptionToThrow = SQLError.createSQLException(Messages.getString("LoadBalancedConnectionProxy.unusableConnection"), + SQLError.SQL_STATE_INVALID_TRANSACTION_STATE, MysqlErrorNumbers.ERROR_CODE_NULL_LOAD_BALANCED_CONNECTION, true, null); + Class[] declaredException = method.getExceptionTypes(); + for (Class declEx : declaredException) { + if (declEx.isAssignableFrom(exceptionToThrow.getClass())) { + throw exceptionToThrow; + } + } + throw new IllegalStateException(exceptionToThrow.getMessage(), exceptionToThrow); + } + } + + private static LoadBalancedConnection nullLBConnectionInstance = null; + + static synchronized LoadBalancedConnection getNullLoadBalancedConnectionInstance() { + if (nullLBConnectionInstance == null) { + nullLBConnectionInstance = (LoadBalancedConnection) java.lang.reflect.Proxy.newProxyInstance(LoadBalancedConnection.class.getClassLoader(), + INTERFACES_TO_PROXY, new NullLoadBalancedConnectionProxy()); + } + return nullLBConnectionInstance; + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/LocalizedErrorMessages.properties =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/LocalizedErrorMessages.properties (.../LocalizedErrorMessages.properties) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/LocalizedErrorMessages.properties (.../LocalizedErrorMessages.properties) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -180,6 +180,7 @@ NonRegisteringDriver.17=Cannot load connection class because of underlying exception: ' NonRegisteringDriver.18='. NonRegisteringDriver.37=Must specify port after ':' in connection string +MysqlDataSource.BadUrl=Failed to get a connection using the URL ''{0}''. SQLError.35=Disconnect error SQLError.36=Data truncated SQLError.37=Privilege not revoked @@ -233,6 +234,7 @@ StringUtils.10=Unsupported character encoding ' StringUtils.11='. StringUtils.15=Illegal argument value {0} for openingMarkers and/or {1} for closingMarkers. These cannot be null and must have the same length. +StringUtils.16=Illegal argument value {0} for overridingMarkers. These cannot be null and must be a sub-set of openingMarkers {1}. RowDataDynamic.2=WARN: Possible incomplete traversal of result set. Streaming result set had RowDataDynamic.3=\ rows left to read when it was closed. RowDataDynamic.4=\n\nYou should consider re-formulating your query to @@ -457,6 +459,8 @@ # ConnectionProperties.loadDataLocal=Should the driver allow use of 'LOAD DATA LOCAL INFILE...' (defaults to 'true'). +ConnectionProperties.replicationEnableJMX=Enables JMX-based management of replication connection groups, including live slave promotion, addition of new slaves and removal of master or slave hosts from load-balanced master and slave connection pools. +ConnectionProperties.replicationConnectionGroup=Logical group of replication connections within a classloader, used to manage different groups independently. If not specified, live management of replication connections is disabled. ConnectionProperties.allowMasterDownConnections=By default, a replication-aware connection will fail to connect when configured master hosts are all unavailable at initial connection. Setting this property to 'true' allows to establish the initial connection, by failing over to the slave servers, in read-only state. It won't prevent subsequent failures when switching back to the master hosts i.e. by setting the replication connection to read/write state. ConnectionProperties.allowSlaveDownConnections=By default, a replication-aware connection will fail to connect when configured slave hosts are all unavailable at initial connection. Setting this property to 'true' allows to establish the initial connection. It won't prevent failures when switching to slaves i.e. by setting the replication connection to read-only state. The property 'readFromMasterWhenNoSlaves' should be used for this purpose. ConnectionProperties.readFromMasterWhenNoSlaves=Replication-aware connections distribute load by using the master hosts when in read/write state and by using the slave hosts when in read-only state. If, when setting the connection to read-only state, none of the slave hosts are available, an SQLExeception is thrown back. Setting this property to 'true' allows to fail over to the master hosts, while setting the connection state to read-only, when no slave hosts are available at switch instant. @@ -514,16 +518,17 @@ ConnectionProperties.interactiveClient=Set the CLIENT_INTERACTIVE flag, which tells MySQL to timeout connections based on INTERACTIVE_TIMEOUT instead of WAIT_TIMEOUT ConnectionProperties.jdbcCompliantTruncation=Should the driver throw java.sql.DataTruncation exceptions when data is truncated as is required by the JDBC specification when connected to a server that supports warnings (MySQL 4.1.0 and newer)? This property has no effect if the server sql-mode includes STRICT_TRANS_TABLES. ConnectionProperties.largeRowSizeThreshold=What size result set row should the JDBC driver consider "large", and thus use a more memory-efficient way of representing the row internally? -ConnectionProperties.loadBalanceStrategy=If using a load-balanced connection to connect to SQL nodes in a MySQL Cluster/NDB configuration (by using the URL prefix "jdbc:mysql:loadbalance://"), which load balancing algorithm should the driver use: (1) "random" - the driver will pick a random host for each request. This tends to work better than round-robin, as the randomness will somewhat account for spreading loads where requests vary in response time, while round-robin can sometimes lead to overloaded nodes if there are variations in response times across the workload. (2) "bestResponseTime" - the driver will route the request to the host that had the best response time for the previous transaction. +ConnectionProperties.loadBalanceStrategy=If using a load-balanced connection to connect to SQL nodes in a MySQL Cluster/NDB configuration (by using the URL prefix "jdbc:mysql:loadbalance://"), which load balancing algorithm should the driver use: (1) "random" - the driver will pick a random host for each request. This tends to work better than round-robin, as the randomness will somewhat account for spreading loads where requests vary in response time, while round-robin can sometimes lead to overloaded nodes if there are variations in response times across the workload. (2) "bestResponseTime" - the driver will route the request to the host that had the best response time for the previous transaction. (3) "serverAffinity" - the driver initially attempts to enforce server affinity while still respecting and benefiting from the fault tolerance aspects of the load-balancing implementation. The server affinity ordered list is provided using the property 'serverAffinityOrder'. If none of the servers listed in the affinity list is responsive, the driver then refers to the "random" strategy to proceed with choosing the next server. +ConnectionProperties.serverAffinityOrder=A comma separated list containing the host/port pairs that are to be used in load-balancing "serverAffinity" strategy. Only the sub-set of the hosts enumerated in the main hosts section in this URL will be used and they must be identical in case and type, i.e., can't use an IP address in one place and the corresponding host name in the other. ConnectionProperties.loadBalanceBlacklistTimeout=Time in milliseconds between checks of servers which are unavailable, by controlling how long a server lives in the global blacklist. ConnectionProperties.loadBalancePingTimeout=Time in milliseconds to wait for ping response from each of load-balanced physical connections when using load-balanced Connection. ConnectionProperties.loadBalanceValidateConnectionOnSwapServer=Should the load-balanced Connection explicitly check whether the connection is live when swapping to a new physical connection at commit/rollback? -ConnectionProperties.loadBalanceConnectionGroup=Logical group of load-balanced connections within a classloader, used to manage different groups independently. If not specified, live management of load-balanced connections is disabled. +ConnectionProperties.loadBalanceConnectionGroup=Logical group of load-balanced connections within a classloader, used to manage different groups independently. If not specified, live management of load-balanced connections is disabled. ConnectionProperties.loadBalanceExceptionChecker=Fully-qualified class name of custom exception checker. The class must implement com.mysql.jdbc.LoadBalanceExceptionChecker interface, and is used to inspect SQLExceptions and determine whether they should trigger fail-over to another host in a load-balanced deployment. ConnectionProperties.loadBalanceSQLStateFailover=Comma-delimited list of SQLState codes used by default load-balanced exception checker to determine whether a given SQLException should trigger failover. The SQLState of a given SQLException is evaluated to determine whether it begins with any value in the comma-delimited list. ConnectionProperties.loadBalanceSQLExceptionSubclassFailover=Comma-delimited list of classes/interfaces used by default load-balanced exception checker to determine whether a given SQLException should trigger failover. The comparison is done using Class.isInstance(SQLException) using the thrown SQLException. ConnectionProperties.loadBalanceEnableJMX=Enables JMX-based management of load-balanced connection groups, including live addition/removal of hosts from load-balancing pool. -ConnectionProperties.replicationEnableJMX=Enables JMX-based management of replication connection groups, including live slave promotion, addition of new slaves and removal of master or slave hosts from load-balanced master and slave connection pools. +ConnectionProperties.loadBalanceHostRemovalGracePeriod=Sets the grace period to wait for a host being removed from a load-balanced connection, to be released when it is currently the active host. ConnectionProperties.loadBalanceAutoCommitStatementThreshold=When auto-commit is enabled, the number of statements which should be executed before triggering load-balancing to rebalance. Default value of 0 causes load-balanced connections to only rebalance when exceptions are encountered, or auto-commit is disabled and transactions are explicitly committed or rolled back. ConnectionProperties.loadBalanceAutoCommitStatementRegex=When load-balancing is enabled for auto-commit statements (via loadBalanceAutoCommitStatementThreshold), the statement counter will only increment when the SQL matches the regular expression. By default, every statement issued matches. ConnectionProperties.localSocketAddress=Hostname or IP address given to explicitly configure the interface that the driver will bind the client side of the TCP/IP connection to when connecting. @@ -575,7 +580,7 @@ ConnectionProperties.selfDestructOnPingSecondsLifetime=If set to a non-zero value, the driver will report close the connection and report failure when Connection.ping() or Connection.isValid(int) is called if the connection's lifetime exceeds this value. ConnectionProperties.selfDestructOnPingMaxOperations==If set to a non-zero value, the driver will report close the connection and report failure when Connection.ping() or Connection.isValid(int) is called if the connection's count of commands sent to the server exceeds this value. ConnectionProperties.serverTimezone=Override detection/mapping of time zone. Used when time zone from server doesn't map to Java time zone -ConnectionProperties.sessionVariables=A comma-separated list of name/value pairs to be sent as SET SESSION ... to the server when the driver connects. +ConnectionProperties.sessionVariables=A comma or semicolon separated list of name=value pairs to be sent as SET [SESSION] ... to the server when the driver connects. ConnectionProperties.slowQueryThresholdMillis=If 'logSlowQueries' is enabled, how long should a query (in ms) before it is logged as 'slow'? ConnectionProperties.slowQueryThresholdNanos=If 'useNanosForElapsedTime' is set to true, and this property is set to a non-zero value, the driver will use this threshold (in nanosecond units) to determine if a query was slow. ConnectionProperties.socketFactory=The name of the class that the driver should use for creating socket connections to the server. This class must implement the interface 'com.mysql.jdbc.SocketFactory' and have public no-args constructor. @@ -694,12 +699,14 @@ LoadBalancedConnectionProxy.badValueForRetriesAllDown=Bad value ''{0}'' for property "retriesAllDown". LoadBalancedConnectionProxy.badValueForLoadBalanceBlacklistTimeout=Bad value ''{0}'' for property "loadBalanceBlacklistTimeout". +LoadBalancedConnectionProxy.badValueForLoadBalanceHostRemovalGracePeriod=Bad value ''{0}'' for property "loadBalanceHostRemovalGracePeriod". LoadBalancedConnectionProxy.badValueForLoadBalanceEnableJMX=Bad value ''{0}'' for property "loadBalanceEnableJMX". LoadBalancedConnectionProxy.badValueForLoadBalanceAutoCommitStatementThreshold=Invalid numeric value ''{0}'' for property "loadBalanceAutoCommitStatementThreshold". LoadBalancedConnectionProxy.badValueForLoadBalanceAutoCommitStatementRegex=Bad value ''{0}'' for property "loadBalanceAutoCommitStatementRegex". +LoadBalancedConnectionProxy.unusableConnection=The connection is unusable at the current state. There may be no hosts to connect to or all hosts this connection knows may be down at the moment. ReplicationConnectionProxy.badValueForAllowMasterDownConnections=Bad value ''{0}'' for property "allowMasterDownConnections". ReplicationConnectionProxy.badValueForReadFromMasterWhenNoSlaves=Bad value ''{0}'' for property "readFromMasterWhenNoSlaves". ReplicationConnectionProxy.badValueForReplicationEnableJMX=Bad value ''{0}'' for property "replicationEnableJMX". - - +ReplicationConnectionProxy.initializationWithEmptyHostsLists=A replication connection cannot be initialized without master hosts and slave hosts, simultaneously. +ReplicationConnectionProxy.noHostsInconsistentState=The replication connection is an inconsistent state due to non existing hosts in both its internal hosts lists. Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostConnectionProxy.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostConnectionProxy.java (.../MultiHostConnectionProxy.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostConnectionProxy.java (.../MultiHostConnectionProxy.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -96,6 +96,11 @@ } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (METHOD_EQUALS.equals(method.getName())) { + // Let args[0] "unwrap" to its InvocationHandler if it is a proxy. + return args[0].equals(this); + } + synchronized (MultiHostConnectionProxy.this) { Object result = null; @@ -452,6 +457,15 @@ return invokeMore(proxy, method, args); } catch (InvocationTargetException e) { throw e.getCause() != null ? e.getCause() : e; + } catch (Exception e) { + // Check if the captured exception must be wrapped by an unchecked exception. + Class[] declaredException = method.getExceptionTypes(); + for (Class declEx : declaredException) { + if (declEx.isAssignableFrom(e.getClass())) { + throw e; + } + } + throw new IllegalStateException(e.getMessage(), e); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostMySQLConnection.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostMySQLConnection.java (.../MultiHostMySQLConnection.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostMySQLConnection.java (.../MultiHostMySQLConnection.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -70,7 +70,7 @@ return this.thisAsProxy; } - protected MySQLConnection getActiveMySQLConnection() { + public MySQLConnection getActiveMySQLConnection() { synchronized (this.thisAsProxy) { return this.thisAsProxy.currentConnection; } @@ -88,6 +88,7 @@ getActiveMySQLConnection().checkClosed(); } + @Deprecated public void clearHasTriedMaster() { getActiveMySQLConnection().clearHasTriedMaster(); } @@ -428,6 +429,10 @@ return getActiveMySQLConnection().getLoadBalanceStrategy(); } + public String getServerAffinityOrder() { + return getActiveMySQLConnection().getServerAffinityOrder(); + } + public boolean getLoadBalanceValidateConnectionOnSwapServer() { return getActiveMySQLConnection().getLoadBalanceValidateConnectionOnSwapServer(); } @@ -1180,6 +1185,10 @@ getActiveMySQLConnection().setLoadBalanceStrategy(strategy); } + public void setServerAffinityOrder(String hostsList) { + getActiveMySQLConnection().setServerAffinityOrder(hostsList); + } + public void setLoadBalanceValidateConnectionOnSwapServer(boolean loadBalanceValidateConnectionOnSwapServer) { getActiveMySQLConnection().setLoadBalanceValidateConnectionOnSwapServer(loadBalanceValidateConnectionOnSwapServer); } @@ -1724,6 +1733,10 @@ return getActiveMySQLConnection().getHost(); } + public String getHostPortPair() { + return getActiveMySQLConnection().getHostPortPair(); + } + public long getId() { return getActiveMySQLConnection().getId(); } @@ -1856,6 +1869,7 @@ return getActiveMySQLConnection().hasSameProperties(c); } + @Deprecated public boolean hasTriedMaster() { return getActiveMySQLConnection().hasTriedMaster(); } @@ -2080,6 +2094,7 @@ getActiveMySQLConnection().setInGlobalTx(flag); } + @Deprecated public void setPreferSlaveDuringFailover(boolean flag) { getActiveMySQLConnection().setPreferSlaveDuringFailover(flag); } @@ -2216,6 +2231,14 @@ getActiveMySQLConnection().setLoadBalanceSQLStateFailover(loadBalanceSQLStateFailover); } + public void setLoadBalanceHostRemovalGracePeriod(int loadBalanceHostRemovalGracePeriod) throws SQLException { + getActiveMySQLConnection().setLoadBalanceHostRemovalGracePeriod(loadBalanceHostRemovalGracePeriod); + } + + public int getLoadBalanceHostRemovalGracePeriod() { + return getActiveMySQLConnection().getLoadBalanceHostRemovalGracePeriod(); + } + public boolean isProxySet() { return this.getActiveMySQLConnection().isProxySet(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MySQLConnection.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MySQLConnection.java (.../MySQLConnection.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MySQLConnection.java (.../MySQLConnection.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -83,6 +83,8 @@ String getHost(); + String getHostPortPair(); + long getId(); long getIdleFor(); @@ -205,6 +207,8 @@ MySQLConnection getMultiHostSafeProxy(); + MySQLConnection getActiveMySQLConnection(); + ProfilerEventHandler getProfilerEventHandlerInstance(); void setProfilerEventHandlerInstance(ProfilerEventHandler h); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDefs.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDefs.java (.../MysqlDefs.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDefs.java (.../MysqlDefs.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -60,15 +60,15 @@ static final int CONNECT = 11; - static final int CREATE_DB = 5; + static final int CREATE_DB = 5; // Not used; deprecated? static final int DEBUG = 13; static final int DELAYED_INSERT = 16; - static final int DROP_DB = 6; + static final int DROP_DB = 6; // Not used; deprecated? - static final int FIELD_LIST = 4; + static final int FIELD_LIST = 4; // Not used; deprecated in MySQL 5.7.11 and MySQL 8.0.0. static final int FIELD_TYPE_BIT = 16; @@ -151,17 +151,17 @@ static final int PING = 14; - static final int PROCESS_INFO = 10; + static final int PROCESS_INFO = 10; // Not used; deprecated in MySQL 5.7.11 and MySQL 8.0.0. - static final int PROCESS_KILL = 12; + static final int PROCESS_KILL = 12; // Not used; deprecated in MySQL 5.7.11 and MySQL 8.0.0. static final int QUERY = 3; static final int QUIT = 1; - static final int RELOAD = 7; + static final int RELOAD = 7; // Not used; deprecated in MySQL 5.7.11 and MySQL 8.0.0. - static final int SHUTDOWN = 8; + static final int SHUTDOWN = 8; // Deprecated in MySQL 5.7.9 and MySQL 8.0.0. // // Constants defined from mysql @@ -425,6 +425,9 @@ case MysqlDefs.FIELD_TYPE_INT24: return "FIELD_TYPE_INT24"; + case MysqlDefs.FIELD_TYPE_BIT: + return "FIELD_TYPE_BIT"; + case MysqlDefs.FIELD_TYPE_DATE: return "FIELD_TYPE_DATE"; @@ -528,9 +531,9 @@ while (mysqlTypes.hasNext()) { String mysqlTypeName = mysqlTypes.next(); - buf.append(" WHEN "); + buf.append(" WHEN UPPER("); buf.append(mysqlTypeColumnName); - buf.append("='"); + buf.append(")='"); buf.append(mysqlTypeName); buf.append("' THEN "); buf.append(typesMap.get(mysqlTypeName)); @@ -541,7 +544,7 @@ buf.append(mysqlTypeColumnName); buf.append("='"); buf.append(mysqlTypeName); - buf.append(" unsigned' THEN "); + buf.append(" UNSIGNED' THEN "); buf.append(typesMap.get(mysqlTypeName)); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlErrorNumbers.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlErrorNumbers.java (.../MysqlErrorNumbers.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlErrorNumbers.java (.../MysqlErrorNumbers.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -943,6 +943,10 @@ public final static int ER_DUP_LIST_ENTRY = 1909; //SQLSTATE: HY000 Message: Duplicate entry '%s'.; was introduced in 5.7.4. public final static int ER_SQL_MODE_NO_EFFECT = 1910; //SQLSTATE: HY000 Message: '%s' mode no longer has any effect. Use STRICT_ALL_TABLES or STRICT_TRANS_TABLES instead.; was introduced in 5.7.4. + // Connector/J-specific errors outside the space of server errors. + public static final int ERROR_CODE_NULL_LOAD_BALANCED_CONNECTION = 1000001; + public static final int ERROR_CODE_REPLICATION_CONNECTION_WITH_NO_HOSTS = 1000002; + private MysqlErrorNumbers() { // prevent instantiation } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlIO.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlIO.java (.../MysqlIO.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlIO.java (.../MysqlIO.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -99,6 +99,8 @@ private static final int CLIENT_CONNECT_ATTRS = 0x00100000; private static final int CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA = 0x00200000; private static final int CLIENT_CAN_HANDLE_EXPIRED_PASSWORD = 0x00400000; + private static final int CLIENT_SESSION_TRACK = 0x00800000; + private static final int CLIENT_DEPRECATE_EOF = 0x01000000; private static final int SERVER_STATUS_IN_TRANS = 1; private static final int SERVER_STATUS_AUTOCOMMIT = 2; // Server in auto_commit mode @@ -421,9 +423,14 @@ } } - packet = reuseAndReadPacket(this.reusablePacket); + // There is no EOF packet after fields when CLIENT_DEPRECATE_EOF is set + if (!isEOFDeprecated() || + // if we asked to use cursor then there should be an OK packet here + (this.connection.versionMeetsMinimum(5, 0, 2) && callingStatement != null && isBinaryEncoded && callingStatement.isCursorRequired())) { - readServerStatusForResultSets(packet); + packet = reuseAndReadPacket(this.reusablePacket); + readServerStatusForResultSets(packet); + } // // Handle cursor-based fetch first @@ -594,17 +601,14 @@ this.readPacketSequence = multiPacketSeq; // Read data - byte[] buffer = new byte[packetLength + 1]; + byte[] buffer = new byte[packetLength]; int numBytesRead = readFully(this.mysqlInput, buffer, 0, packetLength); if (numBytesRead != packetLength) { throw new IOException("Short read, expected " + packetLength + " bytes, only read " + numBytesRead); } - buffer[packetLength] = 0; - Buffer packet = new Buffer(buffer); - packet.setBufLength(packetLength + 1); if (this.traceProtocol) { StringBuilder traceMessageBuf = new StringBuilder(); @@ -779,9 +783,7 @@ // Just to be safe, check if a transaction is in progress on the server.... // if so, then we must be in autoCommit == false // therefore return the opposite of transaction status - boolean inTransactionOnServer = ((this.serverStatus & SERVER_STATUS_IN_TRANS) != 0); - - return !inTransactionOnServer; + return !inTransactionOnServer(); } return autoCommitModeOnServer != autoCommitFlag; @@ -1208,6 +1210,15 @@ this.clientParam |= CLIENT_INTERACTIVE; } + if ((this.serverCapabilities & CLIENT_SESSION_TRACK) != 0) { + // TODO MYSQLCONNJ-437 + // this.clientParam |= CLIENT_SESSION_TRACK; + } + + if ((this.serverCapabilities & CLIENT_DEPRECATE_EOF) != 0) { + this.clientParam |= CLIENT_DEPRECATE_EOF; + } + // // switch to pluggable authentication if available // @@ -1345,8 +1356,7 @@ } // Check for errors, not for 4.1.1 or newer, as the new auth protocol doesn't work that way (see secureAuth411() for more details...) - //if (!versionMeetsMinimum(4, 1, 1)) { - if (!(versionMeetsMinimum(4, 1, 1) || !((this.protocolVersion > 9) && (this.serverCapabilities & CLIENT_PROTOCOL_41) != 0))) { + if (!(versionMeetsMinimum(4, 1, 1)) || !((this.protocolVersion > 9) && (this.serverCapabilities & CLIENT_PROTOCOL_41) != 0)) { checkErrorPacket(); } @@ -1558,8 +1568,7 @@ */ private void checkConfidentiality(AuthenticationPlugin plugin) throws SQLException { if (plugin.requiresConfidentiality() && !isSSLEstablished()) { - throw SQLError.createSQLException( - Messages.getString("Connection.AuthenticationPluginRequiresSSL", new Object[] { plugin.getProtocolPluginName() }), + throw SQLError.createSQLException(Messages.getString("Connection.AuthenticationPluginRequiresSSL", new Object[] { plugin.getProtocolPluginName() }), getExceptionInterceptor()); } } @@ -1615,6 +1624,13 @@ if (!done) { if (challenge != null) { + + if (challenge.isOKPacket()) { + throw SQLError.createSQLException( + Messages.getString("Connection.UnexpectedAuthenticationApproval", new Object[] { plugin.getProtocolPluginName() }), + getExceptionInterceptor()); + } + // read Auth Challenge Packet this.clientParam |= CLIENT_PLUGIN_AUTH | CLIENT_LONG_PASSWORD | CLIENT_PROTOCOL_41 | CLIENT_TRANSACTIONS // Need this to get server status values @@ -1659,8 +1675,8 @@ * Use default if there is no plugin for pluginName. */ plugin = getAuthenticationPlugin(this.clientDefaultAuthenticationPluginName); - } else if (pluginName.equals(Sha256PasswordPlugin.PLUGIN_NAME) && !isSSLEstablished() - && this.connection.getServerRSAPublicKeyFile() == null && !this.connection.getAllowPublicKeyRetrieval()) { + } else if (pluginName.equals(Sha256PasswordPlugin.PLUGIN_NAME) && !isSSLEstablished() && this.connection.getServerRSAPublicKeyFile() == null + && !this.connection.getAllowPublicKeyRetrieval()) { /* * Fall back to default if plugin is 'sha256_password' but required conditions for this to work aren't met. If default is other than * 'sha256_password' this will result in an immediate authentication switch request, allowing for other plugins to authenticate @@ -1696,13 +1712,22 @@ this.packetSequence++; this.compressedPacketSequence++; + if (plugin == null) { + // this shouldn't happen in normal handshake packets exchange, + // we do it just to ensure that we don't get NPE in other case + plugin = getAuthenticationPlugin(this.serverDefaultAuthenticationPluginName != null ? this.serverDefaultAuthenticationPluginName + : this.clientDefaultAuthenticationPluginName); + } + if (challenge.isOKPacket()) { + // get the server status from the challenge packet. + challenge.newReadLength(); // affected_rows + challenge.newReadLength(); // last_insert_id + + this.oldServerStatus = this.serverStatus; + this.serverStatus = challenge.readInt(); + // if OK packet then finish handshake - if (!done) { - throw SQLError.createSQLException( - Messages.getString("Connection.UnexpectedAuthenticationApproval", new Object[] { plugin.getProtocolPluginName() }), - getExceptionInterceptor()); - } plugin.destroy(); break; @@ -1713,7 +1738,7 @@ String pluginName = challenge.readString("ASCII", getExceptionInterceptor()); // get new plugin - if (plugin != null && !plugin.getProtocolPluginName().equals(pluginName)) { + if (!plugin.getProtocolPluginName().equals(pluginName)) { plugin.destroy(); plugin = getAuthenticationPlugin(pluginName); // if plugin is not found for pluginName throw exception @@ -1987,7 +2012,7 @@ // rowPacket.setPosition(rowPacket.getPosition() - 1); - if (!rowPacket.isLastDataPacket()) { + if (!(!isEOFDeprecated() && rowPacket.isEOFPacket() || isEOFDeprecated() && rowPacket.isResultSetOKPacket())) { if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE || (!useBufferRowIfPossible && !useBufferRowExplicit)) { byte[][] rowData = new byte[columnCount][]; @@ -2015,7 +2040,7 @@ // // Handle binary-encoded data for server-side PreparedStatements... // - if (!rowPacket.isLastDataPacket()) { + if (!(!isEOFDeprecated() && rowPacket.isEOFPacket() || isEOFDeprecated() && rowPacket.isResultSetOKPacket())) { if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE || (!useBufferRowIfPossible && !useBufferRowExplicit)) { return unpackBinaryResultSetRow(fields, rowPacket, resultSetConcurrency); } @@ -2075,7 +2100,7 @@ remaining--; if (firstTime) { - if (sw == 255) { + if (sw == Buffer.TYPE_ID_ERROR) { // error packet - we assemble it whole for "fidelity" in case we ever need an entire packet in checkErrorPacket() but we could've gotten // away with just writing the error code and message in it (for now). Buffer errorPacket = new Buffer(packetLength + HEADER_LENGTH); @@ -2090,22 +2115,50 @@ checkErrorPacket(errorPacket); } - if (sw == 254 && packetLength < 9) { + if (sw == Buffer.TYPE_ID_EOF && packetLength < 16777215) { + // Both EOF and OK packets have the same 0xfe signature in result sets. + + // OK packet length limit restricted to MAX_PACKET_LENGTH value (256L*256L*256L-1) as any length greater + // than this value will have first byte of OK packet to be 254 thus does not provide a means to identify + // if this is OK or EOF packet. + // Thus we need to check the packet length to distinguish between OK packet and ResultsetRow packet starting with 0xfe if (this.use41Extensions) { - this.warningCount = (this.mysqlInput.read() & 0xff) | ((this.mysqlInput.read() & 0xff) << 8); - remaining -= 2; + if (isEOFDeprecated()) { + // read OK packet + remaining -= skipLengthEncodedInteger(this.mysqlInput); // affected_rows + remaining -= skipLengthEncodedInteger(this.mysqlInput); // last_insert_id - if (this.warningCount > 0) { - this.hadWarnings = true; // this is a 'latch', it's reset by sendCommand() - } + this.oldServerStatus = this.serverStatus; + this.serverStatus = (this.mysqlInput.read() & 0xff) | ((this.mysqlInput.read() & 0xff) << 8); + checkTransactionState(this.oldServerStatus); + remaining -= 2; - this.oldServerStatus = this.serverStatus; + this.warningCount = (this.mysqlInput.read() & 0xff) | ((this.mysqlInput.read() & 0xff) << 8); + remaining -= 2; - this.serverStatus = (this.mysqlInput.read() & 0xff) | ((this.mysqlInput.read() & 0xff) << 8); - checkTransactionState(this.oldServerStatus); + if (this.warningCount > 0) { + this.hadWarnings = true; // this is a 'latch', it's reset by sendCommand() + } - remaining -= 2; + } else { + // read EOF packet + this.warningCount = (this.mysqlInput.read() & 0xff) | ((this.mysqlInput.read() & 0xff) << 8); + remaining -= 2; + if (this.warningCount > 0) { + this.hadWarnings = true; // this is a 'latch', it's reset by sendCommand() + } + + this.oldServerStatus = this.serverStatus; + + this.serverStatus = (this.mysqlInput.read() & 0xff) | ((this.mysqlInput.read() & 0xff) << 8); + checkTransactionState(this.oldServerStatus); + + remaining -= 2; + } + + setServerSlowQueryFlags(); + if (remaining > 0) { skipFully(this.mysqlInput, remaining); } @@ -2440,17 +2493,13 @@ this.sendPacket.writeByte((byte) command); - if ((command == MysqlDefs.INIT_DB) || (command == MysqlDefs.CREATE_DB) || (command == MysqlDefs.DROP_DB) || (command == MysqlDefs.QUERY) - || (command == MysqlDefs.COM_PREPARE)) { + if ((command == MysqlDefs.INIT_DB) || (command == MysqlDefs.QUERY) || (command == MysqlDefs.COM_PREPARE)) { if (extraDataCharEncoding == null) { this.sendPacket.writeStringNoNull(extraData); } else { this.sendPacket.writeStringNoNull(extraData, extraDataCharEncoding, this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), this.connection); } - } else if (command == MysqlDefs.PROCESS_KILL) { - long id = Long.parseLong(extraData); - this.sendPacket.writeLong(id); } send(this.sendPacket, this.sendPacket.getPosition()); @@ -2480,8 +2529,14 @@ return returnPacket; } catch (IOException ioEx) { + preserveOldTransactionState(); throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); + + } catch (SQLException e) { + preserveOldTransactionState(); + throw e; + } finally { if (timeoutMillis != 0) { try { @@ -2684,8 +2739,7 @@ if (queryWasSlow && !this.serverQueryWasSlow /* don't log slow queries twice */) { StringBuilder mesgBuf = new StringBuilder(48 + profileQueryToLog.length()); - mesgBuf.append(Messages.getString( - "MysqlIO.SlowQuery", + mesgBuf.append(Messages.getString("MysqlIO.SlowQuery", new Object[] { String.valueOf(this.useAutoSlowLog ? " 95% of all queries " : this.slowQueryThreshold), this.queryTimingUnits, Long.valueOf(queryEndTime - queryStartTime) })); mesgBuf.append(profileQueryToLog); @@ -2694,8 +2748,8 @@ eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_SLOW_QUERY, "", catalog, this.connection.getId(), (callingStatement != null) ? callingStatement.getId() : 999, ((ResultSetImpl) rs).resultId, System.currentTimeMillis(), - (int) (queryEndTime - queryStartTime), this.queryTimingUnits, null, LogUtils.findCallingClassAndMethod(new Throwable()), mesgBuf - .toString())); + (int) (queryEndTime - queryStartTime), this.queryTimingUnits, null, LogUtils.findCallingClassAndMethod(new Throwable()), + mesgBuf.toString())); if (this.connection.getExplainSlowQueries()) { if (oldPacketPosition < MAX_QUERY_SIZE_TO_EXPLAIN) { @@ -2713,22 +2767,22 @@ if (this.queryBadIndexUsed && this.profileSql) { eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_SLOW_QUERY, "", catalog, this.connection.getId(), (callingStatement != null) ? callingStatement.getId() : 999, ((ResultSetImpl) rs).resultId, System.currentTimeMillis(), - (queryEndTime - queryStartTime), this.queryTimingUnits, null, LogUtils.findCallingClassAndMethod(new Throwable()), Messages - .getString("MysqlIO.33") + profileQueryToLog)); + (queryEndTime - queryStartTime), this.queryTimingUnits, null, LogUtils.findCallingClassAndMethod(new Throwable()), + Messages.getString("MysqlIO.33") + profileQueryToLog)); } if (this.queryNoIndexUsed && this.profileSql) { eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_SLOW_QUERY, "", catalog, this.connection.getId(), (callingStatement != null) ? callingStatement.getId() : 999, ((ResultSetImpl) rs).resultId, System.currentTimeMillis(), - (queryEndTime - queryStartTime), this.queryTimingUnits, null, LogUtils.findCallingClassAndMethod(new Throwable()), Messages - .getString("MysqlIO.35") + profileQueryToLog)); + (queryEndTime - queryStartTime), this.queryTimingUnits, null, LogUtils.findCallingClassAndMethod(new Throwable()), + Messages.getString("MysqlIO.35") + profileQueryToLog)); } if (this.serverQueryWasSlow && this.profileSql) { eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_SLOW_QUERY, "", catalog, this.connection.getId(), (callingStatement != null) ? callingStatement.getId() : 999, ((ResultSetImpl) rs).resultId, System.currentTimeMillis(), - (queryEndTime - queryStartTime), this.queryTimingUnits, null, LogUtils.findCallingClassAndMethod(new Throwable()), Messages - .getString("MysqlIO.ServerSlowQuery") + profileQueryToLog)); + (queryEndTime - queryStartTime), this.queryTimingUnits, null, LogUtils.findCallingClassAndMethod(new Throwable()), + Messages.getString("MysqlIO.ServerSlowQuery") + profileQueryToLog)); } } @@ -2983,6 +3037,24 @@ return n; } + private final int skipLengthEncodedInteger(InputStream in) throws IOException { + int sw = in.read() & 0xff; + + switch (sw) { + case 252: + return (int) skipFully(in, 2) + 1; + + case 253: + return (int) skipFully(in, 3) + 1; + + case 254: + return (int) skipFully(in, 8) + 1; + + default: + return 1; + } + } + /** * Reads one result set off of the wire, if the result is actually an * update count, creates an update-count only result set. @@ -3139,9 +3211,8 @@ boolean shouldClobber = this.connection.getClobberStreamingResults(); if (!shouldClobber) { - throw SQLError.createSQLException( - Messages.getString("MysqlIO.39") + this.streamingData + Messages.getString("MysqlIO.40") + Messages.getString("MysqlIO.41") - + Messages.getString("MysqlIO.42"), getExceptionInterceptor()); + throw SQLError.createSQLException(Messages.getString("MysqlIO.39") + this.streamingData + Messages.getString("MysqlIO.40") + + Messages.getString("MysqlIO.41") + Messages.getString("MysqlIO.42"), getExceptionInterceptor()); } // Close the result set @@ -3211,16 +3282,38 @@ if (this.use41Extensions) { rowPacket.readByte(); // skips the 'last packet' flag - this.warningCount = rowPacket.readInt(); + if (isEOFDeprecated()) { + // read OK packet + rowPacket.newReadLength(); // affected_rows + rowPacket.newReadLength(); // last_insert_id - if (this.warningCount > 0) { - this.hadWarnings = true; // this is a 'latch', it's reset by sendCommand() - } + this.oldServerStatus = this.serverStatus; + this.serverStatus = rowPacket.readInt(); + checkTransactionState(this.oldServerStatus); - this.oldServerStatus = this.serverStatus; - this.serverStatus = rowPacket.readInt(); - checkTransactionState(this.oldServerStatus); + this.warningCount = rowPacket.readInt(); + if (this.warningCount > 0) { + this.hadWarnings = true; // this is a 'latch', it's reset by sendCommand() + } + rowPacket.readByte(); // advance pointer + + if (this.connection.isReadInfoMsgEnabled()) { + rowPacket.readString(this.connection.getErrorMessageEncoding(), getExceptionInterceptor()); // info + } + + } else { + // read EOF packet + this.warningCount = rowPacket.readInt(); + if (this.warningCount > 0) { + this.hadWarnings = true; // this is a 'latch', it's reset by sendCommand() + } + + this.oldServerStatus = this.serverStatus; + this.serverStatus = rowPacket.readInt(); + checkTransactionState(this.oldServerStatus); + + } setServerSlowQueryFlags(); } } @@ -3243,7 +3336,8 @@ } } - private void enqueuePacketForDebugging(boolean isPacketBeingSent, boolean isPacketReused, int sendLength, byte[] header, Buffer packet) throws SQLException { + private void enqueuePacketForDebugging(boolean isPacketBeingSent, boolean isPacketReused, int sendLength, byte[] header, Buffer packet) + throws SQLException { if ((this.packetDebugRingBuffer.size() + 1) > this.connection.getPacketDebugBufferSize()) { this.packetDebugRingBuffer.removeFirst(); } @@ -3518,9 +3612,10 @@ int bytesRead = readFully(this.mysqlInput, byteBuf, 0, packetLength); if (bytesRead != lengthToWrite) { - throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, SQLError - .createSQLException(Messages.getString("MysqlIO.50") + lengthToWrite + Messages.getString("MysqlIO.51") + bytesRead + ".", - getExceptionInterceptor()), getExceptionInterceptor()); + throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, + SQLError.createSQLException(Messages.getString("MysqlIO.50") + lengthToWrite + Messages.getString("MysqlIO.51") + bytesRead + ".", + getExceptionInterceptor()), + getExceptionInterceptor()); } reuse.writeBytesNoNull(byteBuf, 0, lengthToWrite); @@ -3537,18 +3632,18 @@ */ private void checkPacketSequencing(byte multiPacketSeq) throws SQLException { if ((multiPacketSeq == -128) && (this.readPacketSequence != 127)) { - throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, new IOException( - "Packets out of order, expected packet # -128, but received packet # " + multiPacketSeq), getExceptionInterceptor()); + throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, + new IOException("Packets out of order, expected packet # -128, but received packet # " + multiPacketSeq), getExceptionInterceptor()); } if ((this.readPacketSequence == -1) && (multiPacketSeq != 0)) { - throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, new IOException( - "Packets out of order, expected packet # -1, but received packet # " + multiPacketSeq), getExceptionInterceptor()); + throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, + new IOException("Packets out of order, expected packet # -1, but received packet # " + multiPacketSeq), getExceptionInterceptor()); } if ((multiPacketSeq != -128) && (this.readPacketSequence != -1) && (multiPacketSeq != (this.readPacketSequence + 1))) { - throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, new IOException( - "Packets out of order, expected packet # " + (this.readPacketSequence + 1) + ", but received packet # " + multiPacketSeq), + throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, + new IOException("Packets out of order, expected packet # " + (this.readPacketSequence + 1) + ", but received packet # " + multiPacketSeq), getExceptionInterceptor()); } } @@ -3583,9 +3678,8 @@ throw new PacketTooBigException(packetLen, this.maxAllowedPacket); } - if ((this.serverMajorVersion >= 4) - && (packetLen - HEADER_LENGTH >= this.maxThreeBytes || (this.useCompression && packetLen - HEADER_LENGTH >= this.maxThreeBytes - - COMP_HEADER_LENGTH))) { + if ((this.serverMajorVersion >= 4) && (packetLen - HEADER_LENGTH >= this.maxThreeBytes + || (this.useCompression && packetLen - HEADER_LENGTH >= this.maxThreeBytes - COMP_HEADER_LENGTH))) { sendSplitPackets(packet, packetLen); } else { @@ -3685,8 +3779,9 @@ filePacket = new Buffer((packetLength + HEADER_LENGTH)); this.loadFileBufRef = new SoftReference(filePacket); } catch (OutOfMemoryError oom) { - throw SQLError.createSQLException("Could not allocate packet of " + packetLength + " bytes required for LOAD DATA LOCAL INFILE operation." - + " Try increasing max heap allocation for JVM or decreasing server variable 'max_allowed_packet'", + throw SQLError.createSQLException( + "Could not allocate packet of " + packetLength + " bytes required for LOAD DATA LOCAL INFILE operation." + + " Try increasing max heap allocation for JVM or decreasing server variable 'max_allowed_packet'", SQLError.SQL_STATE_MEMORY_ALLOCATION_FAILURE, getExceptionInterceptor()); } @@ -3876,7 +3971,6 @@ throw new MysqlDataTruncation(errorBuf.toString(), 0, true, false, 0, 0, errno); } throw SQLError.createSQLException(errorBuf.toString(), xOpen, errno, false, getExceptionInterceptor(), this.connection); - } serverErrorMessage = resultPacket.readString(this.connection.getErrorMessageEncoding(), getExceptionInterceptor()); @@ -3891,8 +3985,8 @@ errorBuf.append(serverErrorMessage); errorBuf.append("\""); - throw SQLError.createSQLException(SQLError.get(SQLError.SQL_STATE_GENERAL_ERROR) + ", " + errorBuf.toString(), SQLError.SQL_STATE_GENERAL_ERROR, - -1, false, getExceptionInterceptor(), this.connection); + throw SQLError.createSQLException(SQLError.get(SQLError.SQL_STATE_GENERAL_ERROR) + ", " + errorBuf.toString(), SQLError.SQL_STATE_GENERAL_ERROR, -1, + false, getExceptionInterceptor(), this.connection); } } @@ -4010,6 +4104,7 @@ int cbuflen = packetLen + ((packetLen / this.maxThreeBytes) + 1) * HEADER_LENGTH; if (toCompress == null) { toCompress = new Buffer(cbuflen); + this.compressBufRef = new SoftReference(toCompress); } else if (toCompress.getBufLength() < cbuflen) { toCompress.setPosition(toCompress.getBufLength()); toCompress.ensureCapacity(cbuflen - toCompress.getBufLength()); @@ -4160,7 +4255,7 @@ byte[] replyAsBytes = b.getByteBuffer(); - if ((replyAsBytes.length == 25) && (replyAsBytes[0] != 0)) { + if ((replyAsBytes.length == 24) && (replyAsBytes[0] != 0)) { // Old passwords will have '*' at the first byte of hash */ if (replyAsBytes[0] != '*') { try { @@ -4174,9 +4269,9 @@ /* Finally hash complete password using hash we got from server */ passwordHash = Security.passwordHashStage2(passwordHash, replyAsBytes); - byte[] packetDataAfterSalt = new byte[replyAsBytes.length - 5]; + byte[] packetDataAfterSalt = new byte[replyAsBytes.length - 4]; - System.arraycopy(replyAsBytes, 4, packetDataAfterSalt, 0, replyAsBytes.length - 5); + System.arraycopy(replyAsBytes, 4, packetDataAfterSalt, 0, replyAsBytes.length - 4); byte[] mysqlScrambleBuff = new byte[SEED_LENGTH]; @@ -4193,18 +4288,18 @@ send(packet2, 24); } catch (NoSuchAlgorithmException nse) { - throw SQLError.createSQLException(Messages.getString("MysqlIO.91") + Messages.getString("MysqlIO.92"), - SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + throw SQLError.createSQLException(Messages.getString("MysqlIO.91") + Messages.getString("MysqlIO.92"), SQLError.SQL_STATE_GENERAL_ERROR, + getExceptionInterceptor()); } } else { try { /* Create password to decode scramble */ byte[] passwordHash = Security.createKeyFromOldPassword(password); /* Decypt and store scramble 4 = hash for stage2 */ - byte[] netReadPos4 = new byte[replyAsBytes.length - 5]; + byte[] netReadPos4 = new byte[replyAsBytes.length - 4]; - System.arraycopy(replyAsBytes, 4, netReadPos4, 0, replyAsBytes.length - 5); + System.arraycopy(replyAsBytes, 4, netReadPos4, 0, replyAsBytes.length - 4); byte[] mysqlScrambleBuff = new byte[SEED_LENGTH]; @@ -4220,8 +4315,8 @@ send(packet2, 24); } catch (NoSuchAlgorithmException nse) { - throw SQLError.createSQLException(Messages.getString("MysqlIO.91") + Messages.getString("MysqlIO.92"), - SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + throw SQLError.createSQLException(Messages.getString("MysqlIO.91") + Messages.getString("MysqlIO.92"), SQLError.SQL_STATE_GENERAL_ERROR, + getExceptionInterceptor()); } } } @@ -4285,7 +4380,9 @@ } // User/Password data - packet.writeString(user, enc, this.connection); + if (user != null) { + packet.writeString(user, enc, this.connection); + } if (password.length() != 0) { packet.writeByte((byte) 0x14); @@ -4322,7 +4419,7 @@ Buffer reply = checkErrorPacket(); - if (reply.isLastDataPacket()) { + if (reply.isAuthMethodSwitchRequestPacket()) { /* * By sending this very specific reply server asks us to send scrambled password in old format. The reply contains scramble_323. */ @@ -4458,9 +4555,10 @@ break; default: - throw SQLError.createSQLException(Messages.getString("MysqlIO.97") + curField.getMysqlType() + Messages.getString("MysqlIO.98") + columnIndex - + Messages.getString("MysqlIO.99") + fields.length + Messages.getString("MysqlIO.100"), SQLError.SQL_STATE_GENERAL_ERROR, - getExceptionInterceptor()); + throw SQLError.createSQLException( + Messages.getString("MysqlIO.97") + curField.getMysqlType() + Messages.getString("MysqlIO.98") + columnIndex + + Messages.getString("MysqlIO.99") + fields.length + Messages.getString("MysqlIO.100"), + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } @@ -4752,14 +4850,16 @@ case MysqlDefs.FIELD_TYPE_DECIMAL: case MysqlDefs.FIELD_TYPE_NEW_DECIMAL: case MysqlDefs.FIELD_TYPE_BIT: + case MysqlDefs.FIELD_TYPE_JSON: unpackedRowData[columnIndex] = binaryData.readLenByteArray(0); break; default: - throw SQLError.createSQLException(Messages.getString("MysqlIO.97") + curField.getMysqlType() + Messages.getString("MysqlIO.98") + columnIndex - + Messages.getString("MysqlIO.99") + fields.length + Messages.getString("MysqlIO.100"), SQLError.SQL_STATE_GENERAL_ERROR, - getExceptionInterceptor()); + throw SQLError.createSQLException( + Messages.getString("MysqlIO.97") + curField.getMysqlType() + Messages.getString("MysqlIO.98") + columnIndex + + Messages.getString("MysqlIO.99") + fields.length + Messages.getString("MysqlIO.100"), + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } @@ -4856,8 +4956,8 @@ } private void checkTransactionState(int oldStatus) throws SQLException { - boolean previouslyInTrans = ((oldStatus & SERVER_STATUS_IN_TRANS) != 0); - boolean currentlyInTrans = ((this.serverStatus & SERVER_STATUS_IN_TRANS) != 0); + boolean previouslyInTrans = (oldStatus & SERVER_STATUS_IN_TRANS) != 0; + boolean currentlyInTrans = inTransactionOnServer(); if (previouslyInTrans && !currentlyInTrans) { this.connection.transactionCompleted(); @@ -4866,6 +4966,10 @@ } } + private void preserveOldTransactionState() { + this.serverStatus |= (this.oldServerStatus & SERVER_STATUS_IN_TRANS); + } + protected void setStatementInterceptors(List statementInterceptors) { this.statementInterceptors = statementInterceptors.isEmpty() ? null : statementInterceptors; } @@ -4876,7 +4980,9 @@ protected void setSocketTimeout(int milliseconds) throws SQLException { try { - this.mysqlConnection.setSoTimeout(milliseconds); + if (this.mysqlConnection != null) { + this.mysqlConnection.setSoTimeout(milliseconds); + } } catch (SocketException e) { SQLException sqlEx = SQLError.createSQLException("Invalid socket timeout value or state", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); @@ -4935,4 +5041,8 @@ } packet.writeByte((byte) charsetIndex); } + + public boolean isEOFDeprecated() { + return (this.clientParam & CLIENT_DEPRECATE_EOF) != 0; + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlParameterMetadata.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlParameterMetadata.java (.../MysqlParameterMetadata.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlParameterMetadata.java (.../MysqlParameterMetadata.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -154,8 +154,9 @@ } if (paramNumber > this.parameterCount) { - throw SQLError.createSQLException("Parameter index of '" + paramNumber + "' is greater than number of parameters, which is '" + this.parameterCount - + "'.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + throw SQLError.createSQLException( + "Parameter index of '" + paramNumber + "' is greater than number of parameters, which is '" + this.parameterCount + "'.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/NdbLoadBalanceExceptionChecker.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/NdbLoadBalanceExceptionChecker.java (.../NdbLoadBalanceExceptionChecker.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/NdbLoadBalanceExceptionChecker.java (.../NdbLoadBalanceExceptionChecker.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -34,7 +34,7 @@ private boolean checkNdbException(SQLException ex) { // Have to parse the message since most NDB errors are mapped to the same DEMC, sadly. - return (ex.getMessage().startsWith("Lock wait timeout exceeded") || (ex.getMessage().startsWith("Got temporary error") && ex.getMessage().endsWith( - "from NDB"))); + return (ex.getMessage().startsWith("Lock wait timeout exceeded") + || (ex.getMessage().startsWith("Got temporary error") && ex.getMessage().endsWith("from NDB"))); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringDriver.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringDriver.java (.../NonRegisteringDriver.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringDriver.java (.../NonRegisteringDriver.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -101,10 +101,13 @@ } static { - AbandonedConnectionCleanupThread referenceThread = new AbandonedConnectionCleanupThread(); - referenceThread.setDaemon(true); - referenceThread.start(); + try { + Class.forName(AbandonedConnectionCleanupThread.class.getName()); + } catch (ClassNotFoundException e) { + // ignore + } } + /** * Key used to retreive the database value from the properties instance * passed to the driver. @@ -193,7 +196,7 @@ String[] splitValues = new String[2]; - if (StringUtils.startsWithIgnoreCaseAndWs(hostPortPair, "address")) { + if (StringUtils.startsWithIgnoreCaseAndWs(hostPortPair, "address=")) { splitValues[HOST_NAME_INDEX] = hostPortPair.trim(); splitValues[PORT_NUMBER_INDEX] = null; @@ -594,6 +597,7 @@ return false; } + @SuppressWarnings("deprecation") public Properties parseURL(String url, Properties defaults) throws java.sql.SQLException { Properties urlProps = (defaults != null) ? new Properties(defaults) : new Properties(); @@ -712,14 +716,17 @@ urlProps = propTransformer.transformProperties(urlProps); } catch (InstantiationException e) { - throw SQLError.createSQLException("Unable to create properties transform instance '" + propertiesTransformClassName - + "' due to underlying exception: " + e.toString(), SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); + throw SQLError.createSQLException( + "Unable to create properties transform instance '" + propertiesTransformClassName + "' due to underlying exception: " + e.toString(), + SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); } catch (IllegalAccessException e) { - throw SQLError.createSQLException("Unable to create properties transform instance '" + propertiesTransformClassName - + "' due to underlying exception: " + e.toString(), SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); + throw SQLError.createSQLException( + "Unable to create properties transform instance '" + propertiesTransformClassName + "' due to underlying exception: " + e.toString(), + SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); } catch (ClassNotFoundException e) { - throw SQLError.createSQLException("Unable to create properties transform instance '" + propertiesTransformClassName - + "' due to underlying exception: " + e.toString(), SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); + throw SQLError.createSQLException( + "Unable to create properties transform instance '" + propertiesTransformClassName + "' due to underlying exception: " + e.toString(), + SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); } } @@ -769,8 +776,9 @@ } configProps.load(configAsStream); } catch (IOException ioEx) { - SQLException sqlEx = SQLError.createSQLException("Unable to load configuration template '" + configName - + "' due to underlying IOException: " + ioEx, SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); + SQLException sqlEx = SQLError.createSQLException( + "Unable to load configuration template '" + configName + "' due to underlying IOException: " + ioEx, + SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); sqlEx.initCause(ioEx); throw sqlEx; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/PacketTooBigException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/PacketTooBigException.java (.../PacketTooBigException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/PacketTooBigException.java (.../PacketTooBigException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -41,9 +41,8 @@ * the maximum size the server will accept */ public PacketTooBigException(long packetSize, long maximumPacketSize) { - super( - Messages.getString("PacketTooBigException.0") + packetSize + Messages.getString("PacketTooBigException.1") + maximumPacketSize - + Messages.getString("PacketTooBigException.2") + Messages.getString("PacketTooBigException.3") - + Messages.getString("PacketTooBigException.4"), SQLError.SQL_STATE_GENERAL_ERROR); + super(Messages.getString("PacketTooBigException.0") + packetSize + Messages.getString("PacketTooBigException.1") + maximumPacketSize + + Messages.getString("PacketTooBigException.2") + Messages.getString("PacketTooBigException.3") + Messages.getString("PacketTooBigException.4"), + SQLError.SQL_STATE_GENERAL_ERROR); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/PreparedStatement.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/PreparedStatement.java (.../PreparedStatement.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/PreparedStatement.java (.../PreparedStatement.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -86,8 +86,8 @@ String jdbc4ClassName = Util.isJdbc42() ? "com.mysql.jdbc.JDBC42PreparedStatement" : "com.mysql.jdbc.JDBC4PreparedStatement"; JDBC_4_PSTMT_2_ARG_CTOR = Class.forName(jdbc4ClassName).getConstructor(new Class[] { MySQLConnection.class, String.class }); JDBC_4_PSTMT_3_ARG_CTOR = Class.forName(jdbc4ClassName).getConstructor(new Class[] { MySQLConnection.class, String.class, String.class }); - JDBC_4_PSTMT_4_ARG_CTOR = Class.forName(jdbc4ClassName).getConstructor( - new Class[] { MySQLConnection.class, String.class, String.class, ParseInfo.class }); + JDBC_4_PSTMT_4_ARG_CTOR = Class.forName(jdbc4ClassName) + .getConstructor(new Class[] { MySQLConnection.class, String.class, String.class, ParseInfo.class }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { @@ -822,11 +822,7 @@ detectFractionalSecondsSupport(); this.originalSql = sql; - if (this.originalSql.startsWith(PING_MARKER)) { - this.doPingInstead = true; - } else { - this.doPingInstead = false; - } + this.doPingInstead = this.originalSql.startsWith(PING_MARKER); this.dbmd = this.connection.getMetaData(); @@ -1134,27 +1130,35 @@ MySQLConnection locallyScopedConn = this.connection; - if (!checkReadOnlySafeStatement()) { + if (!this.doPingInstead && !checkReadOnlySafeStatement()) { throw SQLError.createSQLException(Messages.getString("PreparedStatement.20") + Messages.getString("PreparedStatement.21"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } ResultSetInternalMethods rs = null; - CachedResultSetMetaData cachedMetadata = null; - this.lastQueryIsOnDupKeyUpdate = false; if (this.retrieveGeneratedKeys) { this.lastQueryIsOnDupKeyUpdate = containsOnDuplicateKeyUpdateInSQL(); } + this.batchedGeneratedKeys = null; + + resetCancelledState(); + + implicitlyCloseAllOpenResults(); + clearWarnings(); - setupStreamingTimeout(locallyScopedConn); + if (this.doPingInstead) { + doPingInstead(); - this.batchedGeneratedKeys = null; + return true; + } + setupStreamingTimeout(locallyScopedConn); + Buffer sendPacket = fillSendPacket(); String oldCatalog = null; @@ -1167,6 +1171,7 @@ // // Check if we have cached metadata for this query... // + CachedResultSetMetaData cachedMetadata = null; if (locallyScopedConn.getCacheResultSetMetadata()) { cachedMetadata = locallyScopedConn.getCachedMetaData(this.originalSql); } @@ -1507,7 +1512,7 @@ try { try { batchedStatement = /* FIXME -if we ever care about folks proxying our MySQLConnection */ - prepareBatchedInsertSQL(locallyScopedConn, numValuesPerBatch); + prepareBatchedInsertSQL(locallyScopedConn, numValuesPerBatch); if (locallyScopedConn.getEnableQueryTimeouts() && batchTimeout != 0 && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) { timeoutTask = new CancelTask(batchedStatement); @@ -1832,18 +1837,10 @@ synchronized (checkClosed().getConnectionMutex()) { try { - resetCancelledState(); - MySQLConnection locallyScopedConnection = this.connection; this.numberOfExecutions++; - if (this.doPingInstead) { - doPingInstead(); - - return this.results; - } - ResultSetInternalMethods rs; CancelTask timeoutTask = null; @@ -1902,7 +1899,7 @@ return rs; } catch (NullPointerException npe) { checkClosed(); // we can't synchronize ourselves against async connection-close due to deadlock issues, so this is the next best thing for - // this particular corner case. + // this particular corner case. throw npe; } @@ -1925,18 +1922,24 @@ checkForDml(this.originalSql, this.firstCharOfStmt); - CachedResultSetMetaData cachedMetadata = null; + this.batchedGeneratedKeys = null; + resetCancelledState(); + + implicitlyCloseAllOpenResults(); + clearWarnings(); - this.batchedGeneratedKeys = null; + if (this.doPingInstead) { + doPingInstead(); + return this.results; + } + setupStreamingTimeout(locallyScopedConn); Buffer sendPacket = fillSendPacket(); - implicitlyCloseAllOpenResults(); - String oldCatalog = null; if (!locallyScopedConn.getCatalog().equals(this.currentCatalog)) { @@ -1947,6 +1950,7 @@ // // Check if we have cached metadata for this query... // + CachedResultSetMetaData cachedMetadata = null; if (locallyScopedConn.getCacheResultSetMetadata()) { cachedMetadata = locallyScopedConn.getCachedMetaData(this.originalSql); } @@ -2045,6 +2049,8 @@ throw SQLError.createSQLException(Messages.getString("PreparedStatement.37"), "01S03", getExceptionInterceptor()); } + resetCancelledState(); + implicitlyCloseAllOpenResults(); ResultSetInternalMethods rs = null; @@ -2586,9 +2592,11 @@ } private final char getSuccessor(char c, int n) { - return ((c == 'y') && (n == 2)) ? 'X' : (((c == 'y') && (n < 4)) ? 'y' : ((c == 'y') ? 'M' : (((c == 'M') && (n == 2)) ? 'Y' - : (((c == 'M') && (n < 3)) ? 'M' : ((c == 'M') ? 'd' : (((c == 'd') && (n < 2)) ? 'd' : ((c == 'd') ? 'H' : (((c == 'H') && (n < 2)) ? 'H' - : ((c == 'H') ? 'm' : (((c == 'm') && (n < 2)) ? 'm' : ((c == 'm') ? 's' : (((c == 's') && (n < 2)) ? 's' : 'W')))))))))))); + return ((c == 'y') && (n == 2)) ? 'X' + : (((c == 'y') && (n < 4)) ? 'y' : ((c == 'y') ? 'M' : (((c == 'M') && (n == 2)) ? 'Y' + : (((c == 'M') && (n < 3)) ? 'M' : ((c == 'M') ? 'd' : (((c == 'd') && (n < 2)) ? 'd' : ((c == 'd') ? 'H' : (((c == 'H') && (n < 2)) + ? 'H' : ((c == 'H') ? 'm' + : (((c == 'm') && (n < 2)) ? 'm' : ((c == 'm') ? 's' : (((c == 's') && (n < 2)) ? 's' : 'W')))))))))))); } /** @@ -2698,8 +2706,8 @@ if (this.numberOfExecutions <= 1) { String message = Messages.getString("PreparedStatement.43"); - this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", this.currentCatalog, this.connectionId, this.getId(), -1, System - .currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, message)); + this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", this.currentCatalog, this.connectionId, this.getId(), -1, + System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, message)); } } @@ -2812,9 +2820,10 @@ int parameterIndexOffset = getParameterIndexOffset(); if ((parameterIndex < 1) || (parameterIndex > this.staticSqlStrings.length)) { - throw SQLError.createSQLException(Messages.getString("PreparedStatement.2") + parameterIndex + Messages.getString("PreparedStatement.3") - + this.staticSqlStrings.length + Messages.getString("PreparedStatement.4"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, - getExceptionInterceptor()); + throw SQLError.createSQLException( + Messages.getString("PreparedStatement.2") + parameterIndex + Messages.getString("PreparedStatement.3") + + this.staticSqlStrings.length + Messages.getString("PreparedStatement.4"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } else if (parameterIndexOffset == -1 && parameterIndex == 1) { throw SQLError.createSQLException("Can't set IN parameter for return value of stored function call.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); @@ -2929,9 +2938,8 @@ String connectionEncoding = this.connection.getEncoding(); try { - if (this.connection.isNoBackslashEscapesSet() - || (escapeForMBChars && this.connection.getUseUnicode() && connectionEncoding != null && CharsetMapping - .isMultibyteCharset(connectionEncoding))) { + if (this.connection.isNoBackslashEscapesSet() || (escapeForMBChars && this.connection.getUseUnicode() && connectionEncoding != null + && CharsetMapping.isMultibyteCharset(connectionEncoding))) { // Send as hex @@ -3316,9 +3324,11 @@ throw SQLError.createSQLException(Messages.getString("PreparedStatement.49") + paramIndex + Messages.getString("PreparedStatement.50"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } else if (paramIndex > this.parameterCount) { - throw SQLError.createSQLException(Messages.getString("PreparedStatement.51") + paramIndex + Messages.getString("PreparedStatement.52") - + (this.parameterValues.length) + Messages.getString("PreparedStatement.53"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, - getExceptionInterceptor()); + throw SQLError + .createSQLException( + Messages.getString("PreparedStatement.51") + paramIndex + Messages.getString("PreparedStatement.52") + + (this.parameterValues.length) + Messages.getString("PreparedStatement.53"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } else if (parameterIndexOffset == -1 && paramIndex == 1) { throw SQLError.createSQLException("Can't set IN parameter for return value of stored function call.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); @@ -3750,8 +3760,8 @@ SQLException sqlEx = SQLError.createSQLException( Messages.getString("PreparedStatement.17") + parameterObj.getClass().toString() + Messages.getString("PreparedStatement.18") - + ex.getClass().getName() + Messages.getString("PreparedStatement.19") + ex.getMessage(), SQLError.SQL_STATE_GENERAL_ERROR, - getExceptionInterceptor()); + + ex.getClass().getName() + Messages.getString("PreparedStatement.19") + ex.getMessage(), + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); sqlEx.initCause(ex); @@ -3986,7 +3996,8 @@ buf.append('\\'); } } - // fall through + buf.append(c); + break; default: buf.append(c); @@ -4212,7 +4223,7 @@ x = TimeUtil.changeTimezone(this.connection, sessionCalendar, targetCalendar, x, tz, this.connection.getServerTimezoneTZ(), rollForward); if (this.connection.getUseSSPSCompatibleTimezoneShift()) { - doSSPSCompatibleTimezoneShift(parameterIndex, x, sessionCalendar); + doSSPSCompatibleTimezoneShift(parameterIndex, x); } else { synchronized (this) { if (this.tsdf == null) { @@ -4234,7 +4245,7 @@ buf.append('\''); setInternal(parameterIndex, buf.toString()); // SimpleDateFormat is not - // thread-safe + // thread-safe } } } @@ -4299,7 +4310,7 @@ } } - private void doSSPSCompatibleTimezoneShift(int parameterIndex, Timestamp x, Calendar sessionCalendar) throws SQLException { + private void doSSPSCompatibleTimezoneShift(int parameterIndex, Timestamp x) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { Calendar sessionCalendar2 = (this.connection.getUseJDBCCompliantTimezoneShift()) ? this.connection.getUtcCalendar() : getCalendarInstanceForSessionOrNew(); @@ -4435,9 +4446,8 @@ boolean hexEscape = false; try { - if (this.connection.isNoBackslashEscapesSet() - || (this.connection.getUseUnicode() && connectionEncoding != null && CharsetMapping.isMultibyteCharset(connectionEncoding) && !this.connection - .parserKnowsUnicode())) { + if (this.connection.isNoBackslashEscapesSet() || (this.connection.getUseUnicode() && connectionEncoding != null + && CharsetMapping.isMultibyteCharset(connectionEncoding) && !this.connection.parserKnowsUnicode())) { hexEscape = true; } } catch (RuntimeException ex) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReflectiveStatementInterceptorAdapter.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReflectiveStatementInterceptorAdapter.java (.../ReflectiveStatementInterceptorAdapter.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReflectiveStatementInterceptorAdapter.java (.../ReflectiveStatementInterceptorAdapter.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -54,9 +54,9 @@ public ResultSetInternalMethods postProcess(String sql, Statement interceptedStatement, ResultSetInternalMethods originalResultSet, Connection connection, int warningCount, boolean noIndexUsed, boolean noGoodIndexUsed, SQLException statementException) throws SQLException { try { - return (ResultSetInternalMethods) this.v2PostProcessMethod.invoke(this.toProxy, new Object[] { sql, interceptedStatement, originalResultSet, - connection, Integer.valueOf(warningCount), noIndexUsed ? Boolean.TRUE : Boolean.FALSE, noGoodIndexUsed ? Boolean.TRUE : Boolean.FALSE, - statementException }); + return (ResultSetInternalMethods) this.v2PostProcessMethod.invoke(this.toProxy, + new Object[] { sql, interceptedStatement, originalResultSet, connection, Integer.valueOf(warningCount), + noIndexUsed ? Boolean.TRUE : Boolean.FALSE, noGoodIndexUsed ? Boolean.TRUE : Boolean.FALSE, statementException }); } catch (IllegalArgumentException e) { SQLException sqlEx = new SQLException("Unable to reflectively invoke interceptor"); sqlEx.initCause(e); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionGroup.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionGroup.java (.../ReplicationConnectionGroup.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionGroup.java (.../ReplicationConnectionGroup.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -26,26 +26,25 @@ import java.sql.SQLException; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; /** * Group of connection objects which can be configured as a group. This is used for promotion/demotion of slaves and masters in a replication configuration, * and for exposing metrics around replication-aware connections. */ public class ReplicationConnectionGroup { - private String groupName; private long connections = 0; private long slavesAdded = 0; private long slavesRemoved = 0; private long slavesPromoted = 0; private long activeConnections = 0; private HashMap replicationConnections = new HashMap(); - private Set slaveHostList = new HashSet(); + private Set slaveHostList = new CopyOnWriteArraySet(); private boolean isInitialized = false; - private Set masterHostList = new HashSet(); + private Set masterHostList = new CopyOnWriteArraySet(); ReplicationConnectionGroup(String groupName) { this.groupName = groupName; @@ -74,7 +73,6 @@ this.activeConnections++; return currentConnectionId; - } public String getGroupName() { @@ -99,17 +97,17 @@ * * This is a no-op if the group already has this host in a slave role. * - * @param host + * @param hostPortPair * @throws SQLException */ - public void addSlaveHost(String host) throws SQLException { + public void addSlaveHost(String hostPortPair) throws SQLException { // only add if it's not already a slave host - if (this.slaveHostList.add(host)) { + if (this.slaveHostList.add(hostPortPair)) { this.slavesAdded++; // add the slave to all connections: for (ReplicationConnection c : this.replicationConnections.values()) { - c.addSlaveHost(host); + c.addSlaveHost(hostPortPair); } } } @@ -129,17 +127,17 @@ * * This is a no-op if the group doesn't have this host in a slave role. * - * @param host + * @param hostPortPair * @param closeGently * @throws SQLException */ - public void removeSlaveHost(String host, boolean closeGently) throws SQLException { - if (this.slaveHostList.remove(host)) { + public void removeSlaveHost(String hostPortPair, boolean closeGently) throws SQLException { + if (this.slaveHostList.remove(hostPortPair)) { this.slavesRemoved++; // remove the slave from all connections: for (ReplicationConnection c : this.replicationConnections.values()) { - c.removeSlave(host, closeGently); + c.removeSlave(hostPortPair, closeGently); } } } @@ -154,16 +152,16 @@ * * This is a no-op if the group already has this host in a master role and not in slave role. * - * @param host + * @param hostPortPair * @throws SQLException */ - public void promoteSlaveToMaster(String host) throws SQLException { + public void promoteSlaveToMaster(String hostPortPair) throws SQLException { // remove host from slaves AND add host to masters, note that both operands need to be evaluated. - if (this.slaveHostList.remove(host) | this.masterHostList.add(host)) { + if (this.slaveHostList.remove(hostPortPair) | this.masterHostList.add(hostPortPair)) { this.slavesPromoted++; for (ReplicationConnection c : this.replicationConnections.values()) { - c.promoteSlaveToMaster(host); + c.promoteSlaveToMaster(hostPortPair); } } } @@ -173,8 +171,8 @@ * * @see #removeMasterHost(String, boolean) */ - public void removeMasterHost(String host) throws SQLException { - this.removeMasterHost(host, true); + public void removeMasterHost(String hostPortPair) throws SQLException { + this.removeMasterHost(hostPortPair, true); } /** @@ -187,35 +185,35 @@ * * This is a no-op if the group doesn't have this host in a master role. * - * @param host + * @param hostPortPair * @param closeGently * @throws SQLException */ - public void removeMasterHost(String host, boolean closeGently) throws SQLException { - if (this.masterHostList.remove(host)) { + public void removeMasterHost(String hostPortPair, boolean closeGently) throws SQLException { + if (this.masterHostList.remove(hostPortPair)) { // remove the master from all connections: for (ReplicationConnection c : this.replicationConnections.values()) { - c.removeMasterHost(host, closeGently); + c.removeMasterHost(hostPortPair, closeGently); } } } - public int getConnectionCountWithHostAsSlave(String host) { + public int getConnectionCountWithHostAsSlave(String hostPortPair) { int matched = 0; for (ReplicationConnection c : this.replicationConnections.values()) { - if (c.isHostSlave(host)) { + if (c.isHostSlave(hostPortPair)) { matched++; } } return matched; } - public int getConnectionCountWithHostAsMaster(String host) { + public int getConnectionCountWithHostAsMaster(String hostPortPair) { int matched = 0; for (ReplicationConnection c : this.replicationConnections.values()) { - if (c.isHostMaster(host)) { + if (c.isHostMaster(hostPortPair)) { matched++; } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionGroupManager.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionGroupManager.java (.../ReplicationConnectionGroupManager.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionGroupManager.java (.../ReplicationConnectionGroupManager.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -47,7 +47,6 @@ } public static void registerJmx() throws SQLException { - if (hasRegisteredJmx) { return; } @@ -73,33 +72,31 @@ s.add(o); } return s; - } - public static void addSlaveHost(String group, String host) throws SQLException { + public static void addSlaveHost(String group, String hostPortPair) throws SQLException { Collection s = getGroupsMatching(group); for (ReplicationConnectionGroup cg : s) { - cg.addSlaveHost(host); + cg.addSlaveHost(hostPortPair); } } - public static void removeSlaveHost(String group, String host) throws SQLException { - removeSlaveHost(group, host, true); + public static void removeSlaveHost(String group, String hostPortPair) throws SQLException { + removeSlaveHost(group, hostPortPair, true); } - public static void removeSlaveHost(String group, String host, boolean closeGently) throws SQLException { + public static void removeSlaveHost(String group, String hostPortPair, boolean closeGently) throws SQLException { Collection s = getGroupsMatching(group); for (ReplicationConnectionGroup cg : s) { - cg.removeSlaveHost(host, closeGently); + cg.removeSlaveHost(hostPortPair, closeGently); } } - public static void promoteSlaveToMaster(String group, String newMasterHost) throws SQLException { + public static void promoteSlaveToMaster(String group, String hostPortPair) throws SQLException { Collection s = getGroupsMatching(group); for (ReplicationConnectionGroup cg : s) { - cg.promoteSlaveToMaster(newMasterHost); + cg.promoteSlaveToMaster(hostPortPair); } - } public static long getSlavePromotionCount(String group) throws SQLException { @@ -112,17 +109,16 @@ } } return promoted; - } - public static void removeMasterHost(String group, String host) throws SQLException { - removeMasterHost(group, host, true); + public static void removeMasterHost(String group, String hostPortPair) throws SQLException { + removeMasterHost(group, hostPortPair, true); } - public static void removeMasterHost(String group, String host, boolean closeGently) throws SQLException { + public static void removeMasterHost(String group, String hostPortPair, boolean closeGently) throws SQLException { Collection s = getGroupsMatching(group); for (ReplicationConnectionGroup cg : s) { - cg.removeMasterHost(host, closeGently); + cg.removeMasterHost(hostPortPair, closeGently); } } @@ -137,7 +133,6 @@ sep = ","; } return sb.toString(); - } public static int getNumberOfMasterPromotion(String groupFilter) { @@ -149,20 +144,20 @@ return total; } - public static int getConnectionCountWithHostAsSlave(String groupFilter, String host) { + public static int getConnectionCountWithHostAsSlave(String groupFilter, String hostPortPair) { int total = 0; Collection s = getGroupsMatching(groupFilter); for (ReplicationConnectionGroup cg : s) { - total += cg.getConnectionCountWithHostAsSlave(host); + total += cg.getConnectionCountWithHostAsSlave(hostPortPair); } return total; } - public static int getConnectionCountWithHostAsMaster(String groupFilter, String host) { + public static int getConnectionCountWithHostAsMaster(String groupFilter, String hostPortPair) { int total = 0; Collection s = getGroupsMatching(groupFilter); for (ReplicationConnectionGroup cg : s) { - total += cg.getConnectionCountWithHostAsMaster(host); + total += cg.getConnectionCountWithHostAsMaster(hostPortPair); } return total; } @@ -201,7 +196,5 @@ connections += cg.getActiveConnectionCount(); } return connections; - } - } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionProxy.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionProxy.java (.../ReplicationConnectionProxy.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionProxy.java (.../ReplicationConnectionProxy.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -24,6 +24,7 @@ package com.mysql.jdbc; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.SQLException; import java.util.ArrayList; @@ -144,7 +145,6 @@ } String group = masterProperties.getProperty("replicationConnectionGroup", null); - if (group != null) { this.connectionGroup = ReplicationConnectionGroupManager.getConnectionGroupInstance(group); if (this.enableJMX) { @@ -170,19 +170,34 @@ initializeSlavesConnection(); } catch (SQLException e) { if (!this.allowSlaveDownConnections) { + if (this.connectionGroup != null) { + this.connectionGroup.handleCloseConnection(this.thisAsReplicationConnection); + } throw e; } // Else swallow this exception. } + SQLException exCaught = null; try { this.currentConnection = initializeMasterConnection(); } catch (SQLException e) { + exCaught = e; + } + + if (this.currentConnection == null) { if (this.allowMasterDownConnections && this.slavesConnection != null) { // Set read-only and fail over to the slaves connection. this.readOnly = true; this.currentConnection = this.slavesConnection; } else { - throw e; + if (this.connectionGroup != null) { + this.connectionGroup.handleCloseConnection(this.thisAsReplicationConnection); + } + if (exCaught != null) { + throw exCaught; + } + throw SQLError.createSQLException(Messages.getString("ReplicationConnectionProxy.initializationWithEmptyHostsLists"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); } } } @@ -250,16 +265,12 @@ @Override void doClose() throws SQLException { - MySQLConnection prevConnection = this.currentConnection; if (this.masterConnection != null) { - this.currentConnection = this.masterConnection; this.masterConnection.close(); } if (this.slavesConnection != null) { - this.currentConnection = this.slavesConnection; this.slavesConnection.close(); } - this.currentConnection = prevConnection; if (this.connectionGroup != null) { this.connectionGroup.handleCloseConnection(this.thisAsReplicationConnection); @@ -290,14 +301,50 @@ */ @Override Object invokeMore(Object proxy, Method method, Object[] args) throws Throwable { - Object result = method.invoke(this.thisAsConnection, args); - if (result != null && result instanceof Statement) { - ((Statement) result).setPingTarget(this); + checkConnectionCapabilityForMethod(method); + + boolean invokeAgain = false; + while (true) { + try { + Object result = method.invoke(this.thisAsConnection, args); + if (result != null && result instanceof Statement) { + ((Statement) result).setPingTarget(this); + } + return result; + } catch (InvocationTargetException e) { + if (invokeAgain) { + invokeAgain = false; + } else if (e.getCause() != null && e.getCause() instanceof SQLException + && ((SQLException) e.getCause()).getSQLState() == SQLError.SQL_STATE_INVALID_TRANSACTION_STATE + && ((SQLException) e.getCause()).getErrorCode() == MysqlErrorNumbers.ERROR_CODE_NULL_LOAD_BALANCED_CONNECTION) { + try { + // Try to re-establish the connection with the last known read-only state. + setReadOnly(this.readOnly); + invokeAgain = true; + } catch (SQLException sqlEx) { + // Still not good. Swallow this exception. + } + } + if (!invokeAgain) { + throw e; + } + } } - return result; } /** + * Checks if this connection is in a state capable to invoke the provided method. If the connection is in an inconsistent state, i.e. it has no hosts for + * both sub-connections, then throw an invalid transaction state exception. Nevertheless, the methods defined in the ReplicationConnection interface will be + * allowed as they are the only way to leave from an empty hosts lists situation. + */ + private void checkConnectionCapabilityForMethod(Method method) throws Throwable { + if (this.masterHosts.isEmpty() && this.slaveHosts.isEmpty() && !ReplicationConnection.class.isAssignableFrom(method.getDeclaringClass())) { + throw SQLError.createSQLException(Messages.getString("ReplicationConnectionProxy.noHostsInconsistentState"), + SQLError.SQL_STATE_INVALID_TRANSACTION_STATE, MysqlErrorNumbers.ERROR_CODE_REPLICATION_CONNECTION_WITH_NO_HOSTS, true, null); + } + } + + /** * Pings both l/b connections. Switch to another connection in case of failure. */ public void doPing() throws SQLException { @@ -329,7 +376,7 @@ isMasterConn = false; } } catch (SQLException e) { - if (!this.readFromMasterWhenNoSlaves) { + if (this.masterConnection == null || !this.readFromMasterWhenNoSlaves) { throw e; } // Else swallow this exception. } @@ -346,7 +393,7 @@ } else if (!isMasterConn && (slavesPingException != null || this.slavesConnection == null)) { // Switch to masters connection, setting read-only state, if 'readFromMasterWhenNoSlaves=true'. - if (this.readFromMasterWhenNoSlaves && mastersPingException == null) { + if (this.masterConnection != null && this.readFromMasterWhenNoSlaves && mastersPingException == null) { this.slavesConnection = null; this.currentConnection = this.masterConnection; this.readOnly = true; @@ -356,7 +403,6 @@ throw slavesPingException; } } - } private MySQLConnection initializeMasterConnection() throws SQLException { @@ -410,10 +456,12 @@ return url.toString(); } - private synchronized void switchToMasterConnection() throws SQLException { + private synchronized boolean switchToMasterConnection() throws SQLException { if (this.masterConnection == null || this.masterConnection.isClosed()) { try { - initializeMasterConnection(); + if (initializeMasterConnection() == null) { + return false; + } } catch (SQLException e) { this.currentConnection = null; throw e; @@ -423,12 +471,15 @@ syncSessionState(this.currentConnection, this.masterConnection, false); this.currentConnection = this.masterConnection; } + return true; } - private synchronized void switchToSlavesConnection() throws SQLException { + private synchronized boolean switchToSlavesConnection() throws SQLException { if (this.slavesConnection == null || this.slavesConnection.isClosed()) { try { - initializeSlavesConnection(); + if (initializeSlavesConnection() == null) { + return false; + } } catch (SQLException e) { this.currentConnection = null; throw e; @@ -438,19 +489,24 @@ syncSessionState(this.currentConnection, this.slavesConnection, true); this.currentConnection = this.slavesConnection; } + return true; } private boolean switchToSlavesConnectionIfNecessary() throws SQLException { - // Switch to slaves connection if we're in read-only mode and currently on the master. This means we didn't have any slaves to use until now. - if (isMasterConnection() && this.readOnly) { - switchToSlavesConnection(); - return true; + // Switch to slaves connection: + // - If the current connection is null. Or, + // - If we're currently on the master and in read-only mode - we didn't have any slaves to use until now. Or, + // - If we're currently on a closed master connection and there are no masters to connect to. Or, + // - If we're currently not on a master connection that is closed - means that we were on a closed slaves connection before it was re-initialized. + if (this.currentConnection == null || isMasterConnection() && (this.readOnly || this.masterHosts.isEmpty() && this.currentConnection.isClosed()) + || !isMasterConnection() && this.currentConnection.isClosed()) { + return switchToSlavesConnection(); } return false; } public synchronized Connection getCurrentConnection() { - return this.currentConnection; + return this.currentConnection == null ? LoadBalancedConnectionProxy.getNullLoadBalancedConnectionInstance() : this.currentConnection; } public long getConnectionGroupId() { @@ -461,49 +517,62 @@ return this.masterConnection; } - public synchronized void promoteSlaveToMaster(String host) throws SQLException { - this.masterHosts.add(host); - this.removeSlave(host); + public synchronized void promoteSlaveToMaster(String hostPortPair) throws SQLException { + this.masterHosts.add(hostPortPair); + removeSlave(hostPortPair); if (this.masterConnection != null) { - this.masterConnection.addHost(host); + this.masterConnection.addHost(hostPortPair); } + + // Switch back to the masters connection if this connection was running in fail-safe mode. + if (!this.readOnly && !isMasterConnection()) { + switchToMasterConnection(); + } } - public synchronized void removeMasterHost(String host) throws SQLException { - this.removeMasterHost(host, true); + public synchronized void removeMasterHost(String hostPortPair) throws SQLException { + this.removeMasterHost(hostPortPair, true); } - public synchronized void removeMasterHost(String host, boolean waitUntilNotInUse) throws SQLException { - this.removeMasterHost(host, waitUntilNotInUse, false); + public synchronized void removeMasterHost(String hostPortPair, boolean waitUntilNotInUse) throws SQLException { + this.removeMasterHost(hostPortPair, waitUntilNotInUse, false); } - public synchronized void removeMasterHost(String host, boolean waitUntilNotInUse, boolean isNowSlave) throws SQLException { + public synchronized void removeMasterHost(String hostPortPair, boolean waitUntilNotInUse, boolean isNowSlave) throws SQLException { if (isNowSlave) { - this.slaveHosts.add(host); + this.slaveHosts.add(hostPortPair); resetReadFromMasterWhenNoSlaves(); - } - this.masterHosts.remove(host); + this.masterHosts.remove(hostPortPair); - // the master connection may have been implicitly closed by a previous op. don't let it stop us + // The master connection may have been implicitly closed by a previous op., don't let it stop us. if (this.masterConnection == null || this.masterConnection.isClosed()) { this.masterConnection = null; return; } if (waitUntilNotInUse) { - this.masterConnection.removeHostWhenNotInUse(host); + this.masterConnection.removeHostWhenNotInUse(hostPortPair); } else { - this.masterConnection.removeHost(host); + this.masterConnection.removeHost(hostPortPair); } + + // Close the connection if that was the last master. + if (this.masterHosts.isEmpty()) { + this.masterConnection.close(); + this.masterConnection = null; + + // Default behavior, no need to check this.readFromMasterWhenNoSlaves. + switchToSlavesConnectionIfNecessary(); + } } - public boolean isHostMaster(String host) { - if (host == null) { + public boolean isHostMaster(String hostPortPair) { + if (hostPortPair == null) { return false; } for (String masterHost : this.masterHosts) { - if (masterHost.equalsIgnoreCase(host)) { + if (masterHost.equalsIgnoreCase(hostPortPair)) { return true; } } @@ -514,26 +583,26 @@ return this.slavesConnection; } - public synchronized void addSlaveHost(String host) throws SQLException { - if (this.isHostSlave(host)) { + public synchronized void addSlaveHost(String hostPortPair) throws SQLException { + if (this.isHostSlave(hostPortPair)) { return; } - this.slaveHosts.add(host); + this.slaveHosts.add(hostPortPair); resetReadFromMasterWhenNoSlaves(); if (this.slavesConnection == null) { initializeSlavesConnection(); switchToSlavesConnectionIfNecessary(); } else { - this.slavesConnection.addHost(host); + this.slavesConnection.addHost(hostPortPair); } } - public synchronized void removeSlave(String host) throws SQLException { - removeSlave(host, true); + public synchronized void removeSlave(String hostPortPair) throws SQLException { + removeSlave(hostPortPair, true); } - public synchronized void removeSlave(String host, boolean closeGently) throws SQLException { - this.slaveHosts.remove(host); + public synchronized void removeSlave(String hostPortPair, boolean closeGently) throws SQLException { + this.slaveHosts.remove(hostPortPair); resetReadFromMasterWhenNoSlaves(); if (this.slavesConnection == null || this.slavesConnection.isClosed()) { @@ -542,28 +611,30 @@ } if (closeGently) { - this.slavesConnection.removeHostWhenNotInUse(host); + this.slavesConnection.removeHostWhenNotInUse(hostPortPair); } else { - this.slavesConnection.removeHost(host); + this.slavesConnection.removeHost(hostPortPair); } - // close the connection if it's the last slave + // Close the connection if that was the last slave. if (this.slaveHosts.isEmpty()) { this.slavesConnection.close(); this.slavesConnection = null; - // Default behavior, no need to check this.readFromMasterWhenNoSlaves + // Default behavior, no need to check this.readFromMasterWhenNoSlaves. switchToMasterConnection(); - this.currentConnection.setReadOnly(this.readOnly); // maintain + if (isMasterConnection()) { + this.currentConnection.setReadOnly(this.readOnly); // Maintain. + } } } - public boolean isHostSlave(String host) { - if (host == null) { + public boolean isHostSlave(String hostPortPair) { + if (hostPortPair == null) { return false; } for (String test : this.slaveHosts) { - if (test.equalsIgnoreCase(host)) { + if (test.equalsIgnoreCase(hostPortPair)) { return true; } } @@ -574,19 +645,37 @@ public synchronized void setReadOnly(boolean readOnly) throws SQLException { if (readOnly) { if (!isSlavesConnection() || this.currentConnection.isClosed()) { + boolean switched = true; + SQLException exceptionCaught = null; try { - switchToSlavesConnection(); + switched = switchToSlavesConnection(); } catch (SQLException e) { - if (this.readFromMasterWhenNoSlaves) { - switchToMasterConnection(); - } else { - throw e; - } + switched = false; + exceptionCaught = e; } + if (!switched && this.readFromMasterWhenNoSlaves && switchToMasterConnection()) { + exceptionCaught = null; // The connection is OK. Cancel the exception, if any. + } + if (exceptionCaught != null) { + throw exceptionCaught; + } } } else { if (!isMasterConnection() || this.currentConnection.isClosed()) { - switchToMasterConnection(); + boolean switched = true; + SQLException exceptionCaught = null; + try { + switched = switchToMasterConnection(); + } catch (SQLException e) { + switched = false; + exceptionCaught = e; + } + if (!switched && switchToSlavesConnectionIfNecessary()) { + exceptionCaught = null; // The connection is OK. Cancel the exception, if any. + } + if (exceptionCaught != null) { + throw exceptionCaught; + } } } this.readOnly = readOnly; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationMySQLConnection.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationMySQLConnection.java (.../ReplicationMySQLConnection.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationMySQLConnection.java (.../ReplicationMySQLConnection.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -37,6 +37,11 @@ return (ReplicationConnectionProxy) super.getThisAsProxy(); } + @Override + public MySQLConnection getActiveMySQLConnection() { + return (MySQLConnection) getCurrentConnection(); + } + public synchronized Connection getCurrentConnection() { return getThisAsProxy().getCurrentConnection(); } @@ -49,6 +54,15 @@ return getThisAsProxy().getMasterConnection(); } + private Connection getValidatedMasterConnection() { + Connection conn = getThisAsProxy().masterConnection; + try { + return conn == null || conn.isClosed() ? null : conn; + } catch (SQLException e) { + return null; + } + } + public void promoteSlaveToMaster(String host) throws SQLException { getThisAsProxy().promoteSlaveToMaster(host); } @@ -69,6 +83,15 @@ return getThisAsProxy().getSlavesConnection(); } + private Connection getValidatedSlavesConnection() { + Connection conn = getThisAsProxy().slavesConnection; + try { + return conn == null || conn.isClosed() ? null : conn; + } catch (SQLException e) { + return null; + } + } + public void addSlaveHost(String host) throws SQLException { getThisAsProxy().addSlaveHost(host); } @@ -97,15 +120,20 @@ @Override public synchronized void ping() throws SQLException { + Connection conn; try { - getThisAsProxy().masterConnection.ping(); + if ((conn = getValidatedMasterConnection()) != null) { + conn.ping(); + } } catch (SQLException e) { if (isMasterConnection()) { throw e; } } try { - getThisAsProxy().slavesConnection.ping(); + if ((conn = getValidatedSlavesConnection()) != null) { + conn.ping(); + } } catch (SQLException e) { if (!isMasterConnection()) { throw e; @@ -115,26 +143,46 @@ @Override public synchronized void changeUser(String userName, String newPassword) throws SQLException { - getThisAsProxy().masterConnection.changeUser(userName, newPassword); - getThisAsProxy().slavesConnection.changeUser(userName, newPassword); + Connection conn; + if ((conn = getValidatedMasterConnection()) != null) { + conn.changeUser(userName, newPassword); + } + if ((conn = getValidatedSlavesConnection()) != null) { + conn.changeUser(userName, newPassword); + } } @Override public synchronized void setStatementComment(String comment) { - getThisAsProxy().masterConnection.setStatementComment(comment); - getThisAsProxy().slavesConnection.setStatementComment(comment); + Connection conn; + if ((conn = getValidatedMasterConnection()) != null) { + conn.setStatementComment(comment); + } + if ((conn = getValidatedSlavesConnection()) != null) { + conn.setStatementComment(comment); + } } @Override public boolean hasSameProperties(Connection c) { - return getThisAsProxy().masterConnection.hasSameProperties(c) && getThisAsProxy().slavesConnection.hasSameProperties(c); + Connection connM = getValidatedMasterConnection(); + Connection connS = getValidatedSlavesConnection(); + if (connM == null && connS == null) { + return false; + } + return (connM == null || connM.hasSameProperties(c)) && (connS == null || connS.hasSameProperties(c)); } @Override public Properties getProperties() { Properties props = new Properties(); - props.putAll(getThisAsProxy().masterConnection.getProperties()); - props.putAll(getThisAsProxy().slavesConnection.getProperties()); + Connection conn; + if ((conn = getValidatedMasterConnection()) != null) { + props.putAll(conn.getProperties()); + } + if ((conn = getValidatedSlavesConnection()) != null) { + props.putAll(conn.getProperties()); + } return props; } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetImpl.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetImpl.java (.../ResultSetImpl.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetImpl.java (.../ResultSetImpl.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -106,14 +106,14 @@ if (Util.isJdbc4()) { try { String jdbc4ClassName = Util.isJdbc42() ? "com.mysql.jdbc.JDBC42ResultSet" : "com.mysql.jdbc.JDBC4ResultSet"; - JDBC_4_RS_4_ARG_CTOR = Class.forName(jdbc4ClassName).getConstructor( - new Class[] { Long.TYPE, Long.TYPE, MySQLConnection.class, com.mysql.jdbc.StatementImpl.class }); - JDBC_4_RS_5_ARG_CTOR = Class.forName(jdbc4ClassName).getConstructor( - new Class[] { String.class, Field[].class, RowData.class, MySQLConnection.class, com.mysql.jdbc.StatementImpl.class }); + JDBC_4_RS_4_ARG_CTOR = Class.forName(jdbc4ClassName) + .getConstructor(new Class[] { Long.TYPE, Long.TYPE, MySQLConnection.class, com.mysql.jdbc.StatementImpl.class }); + JDBC_4_RS_5_ARG_CTOR = Class.forName(jdbc4ClassName) + .getConstructor(new Class[] { String.class, Field[].class, RowData.class, MySQLConnection.class, com.mysql.jdbc.StatementImpl.class }); jdbc4ClassName = Util.isJdbc42() ? "com.mysql.jdbc.JDBC42UpdatableResultSet" : "com.mysql.jdbc.JDBC4UpdatableResultSet"; - JDBC_4_UPD_RS_5_ARG_CTOR = Class.forName(jdbc4ClassName).getConstructor( - new Class[] { String.class, Field[].class, RowData.class, MySQLConnection.class, com.mysql.jdbc.StatementImpl.class }); + JDBC_4_UPD_RS_5_ARG_CTOR = Class.forName(jdbc4ClassName) + .getConstructor(new Class[] { String.class, Field[].class, RowData.class, MySQLConnection.class, com.mysql.jdbc.StatementImpl.class }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { @@ -761,13 +761,13 @@ if ((columnIndex < 1)) { throw SQLError.createSQLException( Messages.getString("ResultSet.Column_Index_out_of_range_low", - new Object[] { Integer.valueOf(columnIndex), Integer.valueOf(this.fields.length) }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, - getExceptionInterceptor()); + new Object[] { Integer.valueOf(columnIndex), Integer.valueOf(this.fields.length) }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } else if ((columnIndex > this.fields.length)) { throw SQLError.createSQLException( Messages.getString("ResultSet.Column_Index_out_of_range_high", - new Object[] { Integer.valueOf(columnIndex), Integer.valueOf(this.fields.length) }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, - getExceptionInterceptor()); + new Object[] { Integer.valueOf(columnIndex), Integer.valueOf(this.fields.length) }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } if (this.profileSql || this.useUsageAdvisor) { @@ -977,7 +977,8 @@ } } - protected Timestamp fastTimestampCreate(Calendar cal, int year, int month, int day, int hour, int minute, int seconds, int secondsPart) throws SQLException { + protected Timestamp fastTimestampCreate(Calendar cal, int year, int month, int day, int hour, int minute, int seconds, int secondsPart) + throws SQLException { synchronized (checkClosed().getConnectionMutex()) { if (!this.useLegacyDatetimeCode) { return TimeUtil.fastTimestampCreate(cal.getTimeZone(), year, month, day, hour, minute, seconds, secondsPart); @@ -989,8 +990,8 @@ boolean useGmtMillis = this.connection.getUseGmtMillisForDatetimes(); - return TimeUtil - .fastTimestampCreate(useGmtMillis, useGmtMillis ? getGmtCalendar() : null, cal, year, month, day, hour, minute, seconds, secondsPart); + return TimeUtil.fastTimestampCreate(useGmtMillis, useGmtMillis ? getGmtCalendar() : null, cal, year, month, day, hour, minute, seconds, + secondsPart); } } @@ -1351,8 +1352,9 @@ try { return bdVal.setScale(scale, BigDecimal.ROUND_HALF_UP); } catch (ArithmeticException arEx) { - throw new SQLException(Messages.getString("ResultSet.Bad_format_for_BigDecimal", - new Object[] { stringVal, Integer.valueOf(columnIndex) }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw new SQLException( + Messages.getString("ResultSet.Bad_format_for_BigDecimal", new Object[] { stringVal, Integer.valueOf(columnIndex) }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } } @@ -1364,8 +1366,9 @@ try { return new BigDecimal(stringVal).setScale(scale, BigDecimal.ROUND_HALF_UP); } catch (ArithmeticException arEx) { - throw new SQLException(Messages.getString("ResultSet.Bad_format_for_BigDecimal", - new Object[] { stringVal, Integer.valueOf(columnIndex) }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw new SQLException( + Messages.getString("ResultSet.Bad_format_for_BigDecimal", new Object[] { stringVal, Integer.valueOf(columnIndex) }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } } catch (NumberFormatException ex) { @@ -1378,8 +1381,9 @@ try { return new BigDecimal(valueAsLong).setScale(scale, BigDecimal.ROUND_HALF_UP); } catch (ArithmeticException arEx2) { - throw new SQLException(Messages.getString("ResultSet.Bad_format_for_BigDecimal", - new Object[] { stringVal, Integer.valueOf(columnIndex) }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw new SQLException( + Messages.getString("ResultSet.Bad_format_for_BigDecimal", new Object[] { stringVal, Integer.valueOf(columnIndex) }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } } @@ -2448,9 +2452,8 @@ // ignore, it's not a number } - throw SQLError.createSQLException( - Messages.getString("ResultSet.Invalid_value_for_getFloat()_-____200") + val + Messages.getString("ResultSet.___in_column__201") - + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + throw SQLError.createSQLException(Messages.getString("ResultSet.Invalid_value_for_getFloat()_-____200") + val + + Messages.getString("ResultSet.___in_column__201") + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @@ -2467,22 +2470,28 @@ */ public int getInt(int columnIndex) throws SQLException { checkRowPos(); + checkColumnBounds(columnIndex); if (!this.isBinaryEncoded) { int columnIndexMinusOne = columnIndex - 1; - if (this.useFastIntParsing) { - checkColumnBounds(columnIndex); - if (this.thisRow.isNull(columnIndexMinusOne)) { - this.wasNullFlag = true; - } else { - this.wasNullFlag = false; - } + if (this.thisRow.isNull(columnIndexMinusOne)) { + this.wasNullFlag = true; + return 0; + } + this.wasNullFlag = false; - if (this.wasNullFlag) { - return 0; + if (this.fields[columnIndexMinusOne].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) { + long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex); + + if (this.jdbcCompliantTruncationForReads && (valueAsLong < Integer.MIN_VALUE || valueAsLong > Integer.MAX_VALUE)) { + throwRangeException(String.valueOf(valueAsLong), columnIndex, Types.INTEGER); } + return (int) valueAsLong; + } + + if (this.useFastIntParsing) { if (this.thisRow.length(columnIndexMinusOne) == 0) { return convertToZeroWithEmptyCheck(); } @@ -2494,23 +2503,12 @@ return getIntWithOverflowCheck(columnIndexMinusOne); } catch (NumberFormatException nfe) { try { - return parseIntAsDouble(columnIndex, this.thisRow.getString(columnIndexMinusOne, this.fields[columnIndexMinusOne].getEncoding(), this.connection)); } catch (NumberFormatException newNfe) { // ignore, it's not a number } - if (this.fields[columnIndexMinusOne].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) { - long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex); - - if (this.connection.getJdbcCompliantTruncationForReads() && (valueAsLong < Integer.MIN_VALUE || valueAsLong > Integer.MAX_VALUE)) { - throwRangeException(String.valueOf(valueAsLong), columnIndex, Types.INTEGER); - } - - return (int) valueAsLong; - } - throw SQLError.createSQLException( Messages.getString("ResultSet.Invalid_value_for_getInt()_-____74") + this.thisRow.getString(columnIndexMinusOne, this.fields[columnIndexMinusOne].getEncoding(), this.connection) + "'", @@ -2520,49 +2518,38 @@ } String val = null; - try { val = getString(columnIndex); + if ((val == null)) { + return 0; + } - if ((val != null)) { - if (val.length() == 0) { - return convertToZeroWithEmptyCheck(); - } + if (val.length() == 0) { + return convertToZeroWithEmptyCheck(); + } - if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1) && (val.indexOf(".") == -1)) { - int intVal = Integer.parseInt(val); + if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1) && (val.indexOf(".") == -1)) { + int intVal = Integer.parseInt(val); - checkForIntegerTruncation(columnIndexMinusOne, null, intVal); + checkForIntegerTruncation(columnIndexMinusOne, null, intVal); - return intVal; - } + return intVal; + } - // Convert floating point - int intVal = parseIntAsDouble(columnIndex, val); + // Convert floating point + int intVal = parseIntAsDouble(columnIndex, val); - checkForIntegerTruncation(columnIndex, null, intVal); + checkForIntegerTruncation(columnIndex, null, intVal); - return intVal; - } + return intVal; - return 0; } catch (NumberFormatException nfe) { try { return parseIntAsDouble(columnIndex, val); } catch (NumberFormatException newNfe) { // ignore, it's not a number } - if (this.fields[columnIndexMinusOne].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) { - long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex); - - if (this.jdbcCompliantTruncationForReads && (valueAsLong < Integer.MIN_VALUE || valueAsLong > Integer.MAX_VALUE)) { - throwRangeException(String.valueOf(valueAsLong), columnIndex, Types.INTEGER); - } - - return (int) valueAsLong; - } - throw SQLError.createSQLException(Messages.getString("ResultSet.Invalid_value_for_getInt()_-____74") + val + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } @@ -2642,10 +2629,9 @@ // ignore, it's not a number } - throw SQLError - .createSQLException( - Messages.getString("ResultSet.Invalid_value_for_getInt()_-____206") + val + Messages.getString("ResultSet.___in_column__207") - + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + throw SQLError.createSQLException( + Messages.getString("ResultSet.Invalid_value_for_getInt()_-____206") + val + Messages.getString("ResultSet.___in_column__207") + columnIndex, + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @@ -2665,25 +2651,23 @@ } private long getLong(int columnIndex, boolean overflowCheck) throws SQLException { - if (!this.isBinaryEncoded) { - checkRowPos(); + checkRowPos(); + checkColumnBounds(columnIndex); + if (!this.isBinaryEncoded) { int columnIndexMinusOne = columnIndex - 1; - if (this.useFastIntParsing) { + if (this.thisRow.isNull(columnIndexMinusOne)) { + this.wasNullFlag = true; + return 0; + } + this.wasNullFlag = false; - checkColumnBounds(columnIndex); + if (this.fields[columnIndexMinusOne].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) { + return getNumericRepresentationOfSQLBitType(columnIndex); + } - if (this.thisRow.isNull(columnIndexMinusOne)) { - this.wasNullFlag = true; - } else { - this.wasNullFlag = false; - } - - if (this.wasNullFlag) { - return 0; - } - + if (this.useFastIntParsing) { if (this.thisRow.length(columnIndexMinusOne) == 0) { return convertToZeroWithEmptyCheck(); } @@ -2695,17 +2679,12 @@ return getLongWithOverflowCheck(columnIndexMinusOne, overflowCheck); } catch (NumberFormatException nfe) { try { - // To do: Warn of over/underflow??? return parseLongAsDouble(columnIndexMinusOne, this.thisRow.getString(columnIndexMinusOne, this.fields[columnIndexMinusOne].getEncoding(), this.connection)); } catch (NumberFormatException newNfe) { - // ; // ignore, it's not a number + // ignore, it's not a number } - if (this.fields[columnIndexMinusOne].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) { - return getNumericRepresentationOfSQLBitType(columnIndex); - } - throw SQLError.createSQLException( Messages.getString("ResultSet.Invalid_value_for_getLong()_-____79") + this.thisRow.getString(columnIndexMinusOne, this.fields[columnIndexMinusOne].getEncoding(), this.connection) + "'", @@ -2715,29 +2694,28 @@ } String val = null; - try { val = getString(columnIndex); + if (val == null) { + return 0; + } - if ((val != null)) { - if (val.length() == 0) { - return convertToZeroWithEmptyCheck(); - } + if (val.length() == 0) { + return convertToZeroWithEmptyCheck(); + } - if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)) { - return parseLongWithOverflowCheck(columnIndexMinusOne, null, val, overflowCheck); - } - - // Convert floating point - return parseLongAsDouble(columnIndexMinusOne, val); + if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)) { + return parseLongWithOverflowCheck(columnIndexMinusOne, null, val, overflowCheck); } - return 0; // for NULL + // Convert floating point + return parseLongAsDouble(columnIndexMinusOne, val); + } catch (NumberFormatException nfe) { try { return parseLongAsDouble(columnIndexMinusOne, val); } catch (NumberFormatException newNfe) { - // ; // ignore, it's not a number + // ignore, it's not a number } throw SQLError.createSQLException(Messages.getString("ResultSet.Invalid_value_for_getLong()_-____79") + val + "'", @@ -2782,9 +2760,9 @@ // ignore, it's not a number } - throw SQLError.createSQLException( - Messages.getString("ResultSet.Invalid_value_for_getLong()_-____211") + val + Messages.getString("ResultSet.___in_column__212") - + (columnIndexZeroBased + 1), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + throw SQLError.createSQLException(Messages.getString("ResultSet.Invalid_value_for_getLong()_-____211") + val + + Messages.getString("ResultSet.___in_column__212") + (columnIndexZeroBased + 1), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, + getExceptionInterceptor()); } } @@ -3214,16 +3192,17 @@ if (value instanceof byte[]) { return (byte[]) value; } - // fallthrough + break; default: - int sqlType = field.getSQLType(); + break; + } + int sqlType = field.getSQLType(); - if (sqlType == Types.VARBINARY || sqlType == Types.BINARY) { - return (byte[]) value; - } - - return getBytesFromString(getNativeString(columnIndex)); + if (sqlType == Types.VARBINARY || sqlType == Types.BINARY) { + return (byte[]) value; } + + return getBytesFromString(getNativeString(columnIndex)); } /** @@ -3440,25 +3419,26 @@ byte[] data = getBytes(columnIndex); Object obj = data; - if ((data != null) && (data.length >= 2)) { - if ((data[0] == -84) && (data[1] == -19)) { - // Serialized object? - try { - ByteArrayInputStream bytesIn = new ByteArrayInputStream(data); - ObjectInputStream objIn = new ObjectInputStream(bytesIn); - obj = objIn.readObject(); - objIn.close(); - bytesIn.close(); - } catch (ClassNotFoundException cnfe) { - throw SQLError.createSQLException( - Messages.getString("ResultSet.Class_not_found___91") + cnfe.toString() - + Messages.getString("ResultSet._while_reading_serialized_object_92"), getExceptionInterceptor()); - } catch (IOException ex) { - obj = data; // not serialized? + if (this.connection.getAutoDeserialize()) { + if ((data != null) && (data.length >= 2)) { + if ((data[0] == -84) && (data[1] == -19)) { + // Serialized object? + try { + ByteArrayInputStream bytesIn = new ByteArrayInputStream(data); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + obj = objIn.readObject(); + objIn.close(); + bytesIn.close(); + } catch (ClassNotFoundException cnfe) { + throw SQLError.createSQLException(Messages.getString("ResultSet.Class_not_found___91") + cnfe.toString() + + Messages.getString("ResultSet._while_reading_serialized_object_92"), getExceptionInterceptor()); + } catch (IOException ex) { + obj = data; // not serialized? + } } - } - return obj.toString(); + return obj.toString(); + } } return extractStringFromNativeColumn(columnIndex, mysqlType); @@ -3571,6 +3551,7 @@ if (result.endsWith(".0")) { return result.substring(0, result.length() - 2); } + return extractStringFromNativeColumn(columnIndex, mysqlType); default: return extractStringFromNativeColumn(columnIndex, mysqlType); @@ -3728,9 +3709,9 @@ String stringVal = getNativeString(columnIndex + 1); if (this.useUsageAdvisor) { - issueConversionViaParsingWarning("getDouble()", columnIndex, stringVal, this.fields[columnIndex], new int[] { MysqlDefs.FIELD_TYPE_DOUBLE, - MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, MysqlDefs.FIELD_TYPE_LONG, MysqlDefs.FIELD_TYPE_LONGLONG, - MysqlDefs.FIELD_TYPE_FLOAT }); + issueConversionViaParsingWarning("getDouble()", columnIndex, stringVal, this.fields[columnIndex], + new int[] { MysqlDefs.FIELD_TYPE_DOUBLE, MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, MysqlDefs.FIELD_TYPE_LONG, + MysqlDefs.FIELD_TYPE_LONGLONG, MysqlDefs.FIELD_TYPE_FLOAT }); } return getDoubleFromString(stringVal, columnIndex + 1); @@ -3822,9 +3803,9 @@ String stringVal = getNativeString(columnIndex + 1); if (this.useUsageAdvisor) { - issueConversionViaParsingWarning("getFloat()", columnIndex, stringVal, this.fields[columnIndex], new int[] { MysqlDefs.FIELD_TYPE_DOUBLE, - MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, MysqlDefs.FIELD_TYPE_LONG, MysqlDefs.FIELD_TYPE_LONGLONG, - MysqlDefs.FIELD_TYPE_FLOAT }); + issueConversionViaParsingWarning("getFloat()", columnIndex, stringVal, this.fields[columnIndex], + new int[] { MysqlDefs.FIELD_TYPE_DOUBLE, MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, MysqlDefs.FIELD_TYPE_LONG, + MysqlDefs.FIELD_TYPE_LONGLONG, MysqlDefs.FIELD_TYPE_FLOAT }); } return getFloatFromString(stringVal, columnIndex + 1); @@ -3870,7 +3851,7 @@ throwRangeException(String.valueOf(valueAsLong), columnIndex + 1, Types.INTEGER); } - return (short) valueAsLong; + return (int) valueAsLong; case MysqlDefs.FIELD_TYPE_TINY: byte tinyintVal = getNativeByte(columnIndex + 1, false); @@ -3939,9 +3920,9 @@ String stringVal = getNativeString(columnIndex + 1); if (this.useUsageAdvisor) { - issueConversionViaParsingWarning("getInt()", columnIndex, stringVal, this.fields[columnIndex], new int[] { MysqlDefs.FIELD_TYPE_DOUBLE, - MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, MysqlDefs.FIELD_TYPE_LONG, MysqlDefs.FIELD_TYPE_LONGLONG, - MysqlDefs.FIELD_TYPE_FLOAT }); + issueConversionViaParsingWarning("getInt()", columnIndex, stringVal, this.fields[columnIndex], + new int[] { MysqlDefs.FIELD_TYPE_DOUBLE, MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, MysqlDefs.FIELD_TYPE_LONG, + MysqlDefs.FIELD_TYPE_LONGLONG, MysqlDefs.FIELD_TYPE_FLOAT }); } return getIntFromString(stringVal, columnIndex + 1); @@ -4015,10 +3996,8 @@ BigInteger asBigInt = convertLongToUlong(valueAsLong); - if (overflowCheck - && this.jdbcCompliantTruncationForReads - && ((asBigInt.compareTo(new BigInteger(String.valueOf(Long.MAX_VALUE))) > 0) || (asBigInt.compareTo(new BigInteger(String - .valueOf(Long.MIN_VALUE))) < 0))) { + if (overflowCheck && this.jdbcCompliantTruncationForReads && ((asBigInt.compareTo(new BigInteger(String.valueOf(Long.MAX_VALUE))) > 0) + || (asBigInt.compareTo(new BigInteger(String.valueOf(Long.MIN_VALUE))) < 0))) { throwRangeException(asBigInt.toString(), columnIndex + 1, Types.BIGINT); } @@ -4048,9 +4027,9 @@ String stringVal = getNativeString(columnIndex + 1); if (this.useUsageAdvisor) { - issueConversionViaParsingWarning("getLong()", columnIndex, stringVal, this.fields[columnIndex], new int[] { MysqlDefs.FIELD_TYPE_DOUBLE, - MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, MysqlDefs.FIELD_TYPE_LONG, MysqlDefs.FIELD_TYPE_LONGLONG, - MysqlDefs.FIELD_TYPE_FLOAT }); + issueConversionViaParsingWarning("getLong()", columnIndex, stringVal, this.fields[columnIndex], + new int[] { MysqlDefs.FIELD_TYPE_DOUBLE, MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, MysqlDefs.FIELD_TYPE_LONG, + MysqlDefs.FIELD_TYPE_LONGLONG, MysqlDefs.FIELD_TYPE_FLOAT }); } return getLongFromString(stringVal, columnIndex + 1); @@ -4105,7 +4084,15 @@ Field f = this.fields[columnIndex]; switch (f.getMysqlType()) { + case MysqlDefs.FIELD_TYPE_BIT: + long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex + 1); + if (overflowCheck && this.jdbcCompliantTruncationForReads && (valueAsLong < Short.MIN_VALUE || valueAsLong > Short.MAX_VALUE)) { + throwRangeException(String.valueOf(valueAsLong), columnIndex + 1, Types.SMALLINT); + } + + return (short) valueAsLong; + case MysqlDefs.FIELD_TYPE_TINY: byte tinyintVal = getNativeByte(columnIndex + 1, false); @@ -4142,7 +4129,7 @@ return (short) valueAsInt; } - long valueAsLong = getNativeLong(columnIndex + 1, false, true); + valueAsLong = getNativeLong(columnIndex + 1, false, true); if (overflowCheck && this.jdbcCompliantTruncationForReads && valueAsLong > Short.MAX_VALUE) { throwRangeException(String.valueOf(valueAsLong), columnIndex + 1, Types.SMALLINT); @@ -4165,10 +4152,8 @@ BigInteger asBigInt = convertLongToUlong(valueAsLong); - if (overflowCheck - && this.jdbcCompliantTruncationForReads - && ((asBigInt.compareTo(new BigInteger(String.valueOf(Short.MAX_VALUE))) > 0) || (asBigInt.compareTo(new BigInteger(String - .valueOf(Short.MIN_VALUE))) < 0))) { + if (overflowCheck && this.jdbcCompliantTruncationForReads && ((asBigInt.compareTo(new BigInteger(String.valueOf(Short.MAX_VALUE))) > 0) + || (asBigInt.compareTo(new BigInteger(String.valueOf(Short.MIN_VALUE))) < 0))) { throwRangeException(asBigInt.toString(), columnIndex + 1, Types.SMALLINT); } @@ -4198,9 +4183,9 @@ String stringVal = getNativeString(columnIndex + 1); if (this.useUsageAdvisor) { - issueConversionViaParsingWarning("getShort()", columnIndex, stringVal, this.fields[columnIndex], new int[] { MysqlDefs.FIELD_TYPE_DOUBLE, - MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, MysqlDefs.FIELD_TYPE_LONG, MysqlDefs.FIELD_TYPE_LONGLONG, - MysqlDefs.FIELD_TYPE_FLOAT }); + issueConversionViaParsingWarning("getShort()", columnIndex, stringVal, this.fields[columnIndex], + new int[] { MysqlDefs.FIELD_TYPE_DOUBLE, MysqlDefs.FIELD_TYPE_TINY, MysqlDefs.FIELD_TYPE_SHORT, MysqlDefs.FIELD_TYPE_LONG, + MysqlDefs.FIELD_TYPE_LONGLONG, MysqlDefs.FIELD_TYPE_FLOAT }); } return getShortFromString(stringVal, columnIndex + 1); @@ -4325,8 +4310,8 @@ default: - tsVal = (Timestamp) this.thisRow.getNativeDateTimeValue(columnIndexMinusOne, null, Types.TIMESTAMP, mysqlType, tz, rollForward, - this.connection, this); + tsVal = (Timestamp) this.thisRow.getNativeDateTimeValue(columnIndexMinusOne, null, Types.TIMESTAMP, mysqlType, tz, rollForward, this.connection, + this); } // @@ -4448,12 +4433,12 @@ switch (field.getSQLType()) { case Types.BIT: - case Types.BOOLEAN: if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_BIT && !field.isSingleBit()) { - return getBytes(columnIndex); + return getObjectDeserializingIfNeeded(columnIndex); } + return Boolean.valueOf(getBoolean(columnIndex)); - // valueOf would be nicer here, but it isn't present in JDK-1.3.1, which is what the CTS uses. + case Types.BOOLEAN: return Boolean.valueOf(getBoolean(columnIndex)); case Types.TINYINT: @@ -4547,41 +4532,9 @@ case Types.LONGVARBINARY: if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_GEOMETRY) { return getBytes(columnIndex); - } else if (field.isBinary() || field.isBlob()) { - byte[] data = getBytes(columnIndex); - - if (this.connection.getAutoDeserialize()) { - Object obj = data; - - if ((data != null) && (data.length >= 2)) { - if ((data[0] == -84) && (data[1] == -19)) { - // Serialized object? - try { - ByteArrayInputStream bytesIn = new ByteArrayInputStream(data); - ObjectInputStream objIn = new ObjectInputStream(bytesIn); - obj = objIn.readObject(); - objIn.close(); - bytesIn.close(); - } catch (ClassNotFoundException cnfe) { - throw SQLError.createSQLException( - Messages.getString("ResultSet.Class_not_found___91") + cnfe.toString() - + Messages.getString("ResultSet._while_reading_serialized_object_92"), getExceptionInterceptor()); - } catch (IOException ex) { - obj = data; // not serialized? - } - } else { - return getString(columnIndex); - } - } - - return obj; - } - - return data; } + return getObjectDeserializingIfNeeded(columnIndex); - return getBytes(columnIndex); - case Types.DATE: if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR && !this.connection.getYearIsDateType()) { return Short.valueOf(getShort(columnIndex)); @@ -4600,6 +4553,44 @@ } } + private Object getObjectDeserializingIfNeeded(int columnIndex) throws SQLException { + final Field field = this.fields[columnIndex - 1]; + + if (field.isBinary() || field.isBlob()) { + byte[] data = getBytes(columnIndex); + + if (this.connection.getAutoDeserialize()) { + Object obj = data; + + if ((data != null) && (data.length >= 2)) { + if ((data[0] == -84) && (data[1] == -19)) { + // Serialized object? + try { + ByteArrayInputStream bytesIn = new ByteArrayInputStream(data); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + obj = objIn.readObject(); + objIn.close(); + bytesIn.close(); + } catch (ClassNotFoundException cnfe) { + throw SQLError.createSQLException(Messages.getString("ResultSet.Class_not_found___91") + cnfe.toString() + + Messages.getString("ResultSet._while_reading_serialized_object_92"), getExceptionInterceptor()); + } catch (IOException ex) { + obj = data; // not serialized? + } + } else { + return getString(columnIndex); + } + } + + return obj; + } + + return data; + } + + return getBytes(columnIndex); + } + @SuppressWarnings("unchecked") public T getObject(int columnIndex, Class type) throws SQLException { if (type == null) { @@ -4643,8 +4634,8 @@ try { return type.cast(getObject(columnIndex)); } catch (ClassCastException cce) { - SQLException sqlEx = SQLError.createSQLException("Conversion not supported for type " + type.getName(), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + SQLException sqlEx = SQLError.createSQLException("Conversion not supported for type " + type.getName(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, + getExceptionInterceptor()); sqlEx.initCause(cce); throw sqlEx; @@ -4803,7 +4794,7 @@ return new Double(getFloat(columnIndex)); } return new Float(getFloat(columnIndex)); // NB - bug in JDBC compliance test, according to JDBC spec, FLOAT type should return DOUBLE - // but causes ClassCastException in CTS :( + // but causes ClassCastException in CTS :( case Types.DOUBLE: return new Double(getDouble(columnIndex)); @@ -4969,26 +4960,28 @@ * if a database access error occurs */ public short getShort(int columnIndex) throws SQLException { + checkRowPos(); + checkColumnBounds(columnIndex); + if (!this.isBinaryEncoded) { - checkRowPos(); + if (this.thisRow.isNull(columnIndex - 1)) { + this.wasNullFlag = true; + return 0; + } + this.wasNullFlag = false; - if (this.useFastIntParsing) { + if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) { + long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex); - checkColumnBounds(columnIndex); - - Object value = this.thisRow.getColumnValue(columnIndex - 1); - - if (value == null) { - this.wasNullFlag = true; - } else { - this.wasNullFlag = false; + if (this.jdbcCompliantTruncationForReads && (valueAsLong < Short.MIN_VALUE || valueAsLong > Short.MAX_VALUE)) { + throwRangeException(String.valueOf(valueAsLong), columnIndex, Types.SMALLINT); } - if (this.wasNullFlag) { - return 0; - } + return (short) valueAsLong; + } - byte[] shortAsBytes = (byte[]) value; + if (this.useFastIntParsing) { + byte[] shortAsBytes = this.thisRow.getColumnValue(columnIndex - 1); if (shortAsBytes.length == 0) { return (short) convertToZeroWithEmptyCheck(); @@ -5009,22 +5002,11 @@ return parseShortWithOverflowCheck(columnIndex, shortAsBytes, null); } catch (NumberFormatException nfe) { try { - // To do: Warn of over/underflow??? return parseShortAsDouble(columnIndex, StringUtils.toString(shortAsBytes)); } catch (NumberFormatException newNfe) { // ignore, it's not a number } - if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) { - long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex); - - if (this.jdbcCompliantTruncationForReads && (valueAsLong < Short.MIN_VALUE || valueAsLong > Short.MAX_VALUE)) { - throwRangeException(String.valueOf(valueAsLong), columnIndex, Types.SMALLINT); - } - - return (short) valueAsLong; - } - throw SQLError.createSQLException( Messages.getString("ResultSet.Invalid_value_for_getShort()_-____96") + StringUtils.toString(shortAsBytes) + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); @@ -5033,42 +5015,30 @@ } String val = null; - try { val = getString(columnIndex); + if (val == null) { + return 0; + } - if ((val != null)) { + if (val.length() == 0) { + return (short) convertToZeroWithEmptyCheck(); + } - if (val.length() == 0) { - return (short) convertToZeroWithEmptyCheck(); - } - - if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1) && (val.indexOf(".") == -1)) { - return parseShortWithOverflowCheck(columnIndex, null, val); - } - - // Convert floating point - return parseShortAsDouble(columnIndex, val); + if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1) && (val.indexOf(".") == -1)) { + return parseShortWithOverflowCheck(columnIndex, null, val); } - return 0; // for NULL + // Convert floating point + return parseShortAsDouble(columnIndex, val); + } catch (NumberFormatException nfe) { try { return parseShortAsDouble(columnIndex, val); } catch (NumberFormatException newNfe) { // ignore, it's not a number } - if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_BIT) { - long valueAsLong = getNumericRepresentationOfSQLBitType(columnIndex); - - if (this.jdbcCompliantTruncationForReads && (valueAsLong < Short.MIN_VALUE || valueAsLong > Short.MAX_VALUE)) { - throwRangeException(String.valueOf(valueAsLong), columnIndex, Types.SMALLINT); - } - - return (short) valueAsLong; - } - throw SQLError.createSQLException(Messages.getString("ResultSet.Invalid_value_for_getShort()_-____96") + val + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } @@ -5110,9 +5080,8 @@ // ignore, it's not a number } - throw SQLError.createSQLException( - Messages.getString("ResultSet.Invalid_value_for_getShort()_-____217") + val + Messages.getString("ResultSet.___in_column__218") - + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + throw SQLError.createSQLException(Messages.getString("ResultSet.Invalid_value_for_getShort()_-____217") + val + + Messages.getString("ResultSet.___in_column__218") + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @@ -5137,10 +5106,9 @@ } catch (SQLException sqlEx) { if (!this.retainOwningStatement) { - throw SQLError.createSQLException( - "Operation not allowed on closed ResultSet. Statements " - + "can be retained over result set closure by setting the connection property " - + "\"retainStatementAfterResultSetClose\" to \"true\".", SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + throw SQLError.createSQLException("Operation not allowed on closed ResultSet. Statements " + + "can be retained over result set closure by setting the connection property " + "\"retainStatementAfterResultSetClose\" to \"true\".", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } if (this.wrapperStatement != null) { @@ -5170,7 +5138,7 @@ Field f = this.fields[columnIndex - 1]; if (f.getMysqlType() == MysqlDefs.FIELD_TYPE_STRING) { - int fieldLength = (int) f.getLength() /* safe, bytes in a CHAR <= 1024 *// f.getMaxBytesPerCharacter(); /* safe, this will never be 0 */ + int fieldLength = (int) f.getLength() /* safe, bytes in a CHAR <= 1024 */ / f.getMaxBytesPerCharacter(); /* safe, this will never be 0 */ int currentLength = stringVal.length(); @@ -5388,7 +5356,7 @@ * if a database-access error occurs. */ public java.sql.Time getTime(int columnIndex, Calendar cal) throws SQLException { - return getTimeInternal(columnIndex, cal, cal.getTimeZone(), true); + return getTimeInternal(columnIndex, cal, cal != null ? cal.getTimeZone() : this.getDefaultTimeZone(), true); } /** @@ -5537,9 +5505,11 @@ } else { // convert a String to a Time if ((timeAsString.length() != 5) && (timeAsString.length() != 8)) { - throw SQLError.createSQLException( - Messages.getString("ResultSet.Bad_format_for_Time____267") + timeAsString + Messages.getString("ResultSet.___in_column__268") - + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + throw SQLError + .createSQLException( + Messages.getString("ResultSet.Bad_format_for_Time____267") + timeAsString + + Messages.getString("ResultSet.___in_column__268") + columnIndex, + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } hr = Integer.parseInt(timeAsString.substring(0, 2)); @@ -5635,7 +5605,7 @@ * if a database-access error occurs. */ public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { - return getTimestampInternal(columnIndex, cal, cal.getTimeZone(), true); + return getTimestampInternal(columnIndex, cal, cal != null ? cal.getTimeZone() : this.getDefaultTimeZone(), true); } /** @@ -5692,10 +5662,8 @@ Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ? this.connection.getUtcCalendar() : getCalendarInstanceForSessionOrNew(); - if ((length > 0) - && (timestampValue.charAt(0) == '0') - && (timestampValue.equals("0000-00-00") || timestampValue.equals("0000-00-00 00:00:00") || timestampValue.equals("00000000000000") || timestampValue - .equals("0"))) { + if ((length > 0) && (timestampValue.charAt(0) == '0') && (timestampValue.equals("0000-00-00") || timestampValue.equals("0000-00-00 00:00:00") + || timestampValue.equals("00000000000000") || timestampValue.equals("0"))) { if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(this.connection.getZeroDateTimeBehavior())) { this.wasNullFlag = true; @@ -6199,21 +6167,18 @@ convertibleTypesBuf.append("\n"); } - String message = Messages.getString( - "ResultSet.CostlyConversion", - new Object[] { - methodName, - Integer.valueOf(columnIndex + 1), - fieldInfo.getOriginalName(), - fieldInfo.getOriginalTableName(), + String message = Messages.getString("ResultSet.CostlyConversion", + new Object[] { methodName, Integer.valueOf(columnIndex + 1), fieldInfo.getOriginalName(), fieldInfo.getOriginalTableName(), originalQueryBuf.toString(), - value != null ? value.getClass().getName() : ResultSetMetaData.getClassNameForJavaType(fieldInfo.getSQLType(), - fieldInfo.isUnsigned(), fieldInfo.getMysqlType(), fieldInfo.isBinary() || fieldInfo.isBlob(), fieldInfo.isOpaqueBinary(), - this.connection.getYearIsDateType()), MysqlDefs.typeToName(fieldInfo.getMysqlType()), convertibleTypesBuf.toString() }); + value != null ? value.getClass().getName() + : ResultSetMetaData.getClassNameForJavaType(fieldInfo.getSQLType(), fieldInfo.isUnsigned(), fieldInfo.getMysqlType(), + fieldInfo.isBinary() || fieldInfo.isBlob(), fieldInfo.isOpaqueBinary(), this.connection.getYearIsDateType()), + MysqlDefs.typeToName(fieldInfo.getMysqlType()), convertibleTypesBuf.toString() }); - this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", (this.owningStatement == null) ? "N/A" - : this.owningStatement.currentCatalog, this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), - this.resultId, System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, message)); + this.eventSink + .consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", (this.owningStatement == null) ? "N/A" : this.owningStatement.currentCatalog, + this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), this.resultId, System.currentTimeMillis(), + 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, message)); } } @@ -6427,8 +6392,8 @@ return longValue; } - private long parseLongWithOverflowCheck(int columnIndexZeroBased, byte[] valueAsBytes, String valueAsString, boolean doCheck) throws NumberFormatException, - SQLException { + private long parseLongWithOverflowCheck(int columnIndexZeroBased, byte[] valueAsBytes, String valueAsString, boolean doCheck) + throws NumberFormatException, SQLException { long longValue = 0; @@ -6640,31 +6605,32 @@ // Report on result set closed by driver instead of application if (!calledExplicitly) { - this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", (this.owningStatement == null) ? "N/A" - : this.owningStatement.currentCatalog, this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), - this.resultId, System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, Messages - .getString("ResultSet.ResultSet_implicitly_closed_by_driver"))); + this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", + (this.owningStatement == null) ? "N/A" : this.owningStatement.currentCatalog, this.connectionId, + (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), this.resultId, System.currentTimeMillis(), 0, + Constants.MILLIS_I18N, null, this.pointOfOrigin, Messages.getString("ResultSet.ResultSet_implicitly_closed_by_driver"))); } if (this.rowData instanceof RowDataStatic) { // Report on possibly too-large result sets if (this.rowData.size() > this.connection.getResultSetSizeThreshold()) { - this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", (this.owningStatement == null) ? Messages - .getString("ResultSet.N/A_159") : this.owningStatement.currentCatalog, this.connectionId, - (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), this.resultId, System.currentTimeMillis(), 0, - Constants.MILLIS_I18N, null, this.pointOfOrigin, Messages.getString("ResultSet.Too_Large_Result_Set", new Object[] { - Integer.valueOf(this.rowData.size()), Integer.valueOf(this.connection.getResultSetSizeThreshold()) }))); + this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", + (this.owningStatement == null) ? Messages.getString("ResultSet.N/A_159") : this.owningStatement.currentCatalog, + this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), this.resultId, + System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, + Messages.getString("ResultSet.Too_Large_Result_Set", new Object[] { Integer.valueOf(this.rowData.size()), + Integer.valueOf(this.connection.getResultSetSizeThreshold()) }))); } if (!isLast() && !isAfterLast() && (this.rowData.size() != 0)) { - this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", (this.owningStatement == null) ? Messages - .getString("ResultSet.N/A_159") : this.owningStatement.currentCatalog, this.connectionId, - (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), this.resultId, System.currentTimeMillis(), 0, - Constants.MILLIS_I18N, null, this.pointOfOrigin, Messages.getString( - "ResultSet.Possible_incomplete_traversal_of_result_set", + this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", + (this.owningStatement == null) ? Messages.getString("ResultSet.N/A_159") : this.owningStatement.currentCatalog, + this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), this.resultId, + System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, + Messages.getString("ResultSet.Possible_incomplete_traversal_of_result_set", new Object[] { Integer.valueOf(getRow()), Integer.valueOf(this.rowData.size()) }))); } } @@ -6691,9 +6657,10 @@ } if (issueWarn) { - this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", (this.owningStatement == null) ? "N/A" - : this.owningStatement.currentCatalog, this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement - .getId(), 0, System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, buf.toString())); + this.eventSink.consumeEvent( + new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", (this.owningStatement == null) ? "N/A" : this.owningStatement.currentCatalog, + this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), 0, + System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, buf.toString())); } } } @@ -7022,7 +6989,7 @@ * @param info * the server info message */ - protected synchronized void setServerInfo(String info) { + protected void setServerInfo(String info) { try { synchronized (checkClosed().getConnectionMutex()) { this.serverInfo = info; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetMetaData.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetMetaData.java (.../ResultSetMetaData.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetMetaData.java (.../ResultSetMetaData.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -430,7 +430,7 @@ case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB: case MysqlDefs.FIELD_TYPE_LONG_BLOB: return clampedGetLength(f); // this may change in the future for now, the server only returns FIELD_TYPE_BLOB for _all_ BLOB types, but varying - // lengths indicating the _maximum_ size for each BLOB type. + // lengths indicating the _maximum_ size for each BLOB type. default: return clampedGetLength(f) / f.getMaxBytesPerCharacter(); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetRow.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetRow.java (.../ResultSetRow.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetRow.java (.../ResultSetRow.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -240,8 +240,8 @@ throw SQLError.createSQLException( Messages.getString("ResultSet.Bad_format_for_Date", - new Object[] { StringUtils.toString(dateAsBytes), Integer.valueOf(columnIndex + 1) }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, - this.exceptionInterceptor); + new Object[] { StringUtils.toString(dateAsBytes), Integer.valueOf(columnIndex + 1) }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } if (length != 18) { @@ -383,15 +383,16 @@ if (length > 7) { // MySQL uses microseconds - nanos = ((bits[offset + 7] & 0xff) | ((bits[offset + 8] & 0xff) << 8) | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff) << 24)) * 1000; + nanos = ((bits[offset + 7] & 0xff) | ((bits[offset + 8] & 0xff) << 8) | ((bits[offset + 9] & 0xff) << 16) + | ((bits[offset + 10] & 0xff) << 24)) * 1000; } } break; case MysqlDefs.FIELD_TYPE_DATE: populatedFromDateTimeValue = true; - if (bits.length != 0) { + if (length != 0) { year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8); month = bits[offset + 2]; day = bits[offset + 3]; @@ -401,7 +402,7 @@ case MysqlDefs.FIELD_TYPE_TIME: populatedFromDateTimeValue = true; - if (bits.length != 0) { + if (length != 0) { // bits[0] // skip tm->neg // binaryData.readLong(); // skip daysPart hour = bits[offset + 5]; @@ -581,8 +582,8 @@ public abstract Time getNativeTime(int columnIndex, Calendar targetCalendar, TimeZone tz, boolean rollForward, MySQLConnection conn, ResultSetImpl rs) throws SQLException; - protected Timestamp getNativeTimestamp(byte[] bits, int offset, int length, Calendar targetCalendar, TimeZone tz, boolean rollForward, - MySQLConnection conn, ResultSetImpl rs) throws SQLException { + protected Timestamp getNativeTimestamp(byte[] bits, int offset, int length, Calendar targetCalendar, TimeZone tz, boolean rollForward, MySQLConnection conn, + ResultSetImpl rs) throws SQLException { int year = 0; int month = 0; int day = 0; @@ -606,7 +607,8 @@ if (length > 7) { // MySQL uses microseconds - nanos = ((bits[offset + 7] & 0xff) | ((bits[offset + 8] & 0xff) << 8) | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff) << 24)) * 1000; + nanos = ((bits[offset + 7] & 0xff) | ((bits[offset + 8] & 0xff) << 8) | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff) << 24)) + * 1000; } } @@ -861,8 +863,8 @@ if ((length != 5) && (length != 8)) { throw SQLError.createSQLException( Messages.getString("ResultSet.Bad_format_for_Time____267") + StringUtils.toString(timeAsBytes) - + Messages.getString("ResultSet.___in_column__268") + (columnIndex + 1), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, - this.exceptionInterceptor); + + Messages.getString("ResultSet.___in_column__268") + (columnIndex + 1), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } hr = StringUtils.getInt(timeAsBytes, offset + 0, offset + 2); @@ -1152,8 +1154,9 @@ } default: - throw new java.sql.SQLException("Bad format for Timestamp '" + StringUtils.toString(timestampAsBytes) + "' in column " - + (columnIndex + 1) + ".", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw new java.sql.SQLException( + "Bad format for Timestamp '" + StringUtils.toString(timestampAsBytes) + "' in column " + (columnIndex + 1) + ".", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } if (!rs.useLegacyDatetimeCode) { @@ -1164,8 +1167,9 @@ rs.fastTimestampCreate(sessionCalendar, year, month, day, hour, minutes, seconds, nanos), conn.getServerTimezoneTZ(), tz, rollForward); } } catch (RuntimeException e) { - SQLException sqlEx = SQLError.createSQLException("Cannot convert value '" + getString(columnIndex, "ISO8859_1", conn) + "' from column " - + (columnIndex + 1) + " to TIMESTAMP.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + SQLException sqlEx = SQLError.createSQLException( + "Cannot convert value '" + getString(columnIndex, "ISO8859_1", conn) + "' from column " + (columnIndex + 1) + " to TIMESTAMP.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); sqlEx.initCause(e); throw sqlEx; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataCursor.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataCursor.java (.../RowDataCursor.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataCursor.java (.../RowDataCursor.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -352,7 +352,7 @@ return null; } - if (this.currentPositionInFetchedRows > (this.fetchedRows.size() - 1)) { + if ((this.fetchedRows == null) || (this.currentPositionInFetchedRows > (this.fetchedRows.size() - 1))) { fetchMoreRows(); this.currentPositionInFetchedRows = 0; } @@ -365,7 +365,7 @@ } /** - */ + */ private void fetchMoreRows() throws SQLException { if (this.lastRowFetched) { this.fetchedRows = new ArrayList(0); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataDynamic.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataDynamic.java (.../RowDataDynamic.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataDynamic.java (.../RowDataDynamic.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -188,14 +188,13 @@ ProfilerEventHandler eventSink = ProfilerEventHandlerFactory.getInstance(conn); - eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", this.owner.owningStatement == null ? "N/A" - : this.owner.owningStatement.currentCatalog, this.owner.connectionId, this.owner.owningStatement == null ? -1 - : this.owner.owningStatement.getId(), -1, System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, null, Messages - .getString("RowDataDynamic.2") - + howMuchMore - + Messages.getString("RowDataDynamic.3") - + Messages.getString("RowDataDynamic.4") - + Messages.getString("RowDataDynamic.5") + Messages.getString("RowDataDynamic.6") + this.owner.pointOfOrigin)); + eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", + this.owner.owningStatement == null ? "N/A" : this.owner.owningStatement.currentCatalog, this.owner.connectionId, + this.owner.owningStatement == null ? -1 : this.owner.owningStatement.getId(), -1, System.currentTimeMillis(), 0, + Constants.MILLIS_I18N, null, null, + Messages.getString("RowDataDynamic.2") + howMuchMore + Messages.getString("RowDataDynamic.3") + + Messages.getString("RowDataDynamic.4") + Messages.getString("RowDataDynamic.5") + + Messages.getString("RowDataDynamic.6") + this.owner.pointOfOrigin)); } } } @@ -405,8 +404,9 @@ exceptionMessage += Messages.getString("RowDataDynamic.7"); exceptionMessage += Util.stackTraceToString(ex); - SQLException sqlEx = SQLError.createSQLException(Messages.getString("RowDataDynamic.8") + exceptionType + Messages.getString("RowDataDynamic.9") - + exceptionMessage, SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + SQLException sqlEx = SQLError.createSQLException( + Messages.getString("RowDataDynamic.8") + exceptionType + Messages.getString("RowDataDynamic.9") + exceptionMessage, + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); sqlEx.initCause(ex); throw sqlEx; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/SQLError.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/SQLError.java (.../SQLError.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/SQLError.java (.../SQLError.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -55,7 +55,7 @@ // SQL-92 public static final String SQL_STATE_WARNING = "01000"; public static final String SQL_STATE_DISCONNECT_ERROR = "01002"; - public static final String SQL_STATE_DATE_TRUNCATED = "01004"; + public static final String SQL_STATE_DATA_TRUNCATED = "01004"; public static final String SQL_STATE_PRIVILEGE_NOT_REVOKED = "01006"; public static final String SQL_STATE_NO_DATA = "02000"; public static final String SQL_STATE_WRONG_NO_OF_PARAMETERS = "07001"; @@ -145,8 +145,8 @@ static { if (Util.isJdbc4()) { try { - JDBC_4_COMMUNICATIONS_EXCEPTION_CTOR = Class.forName("com.mysql.jdbc.exceptions.jdbc4.CommunicationsException").getConstructor( - new Class[] { MySQLConnection.class, Long.TYPE, Long.TYPE, Exception.class }); + JDBC_4_COMMUNICATIONS_EXCEPTION_CTOR = Class.forName("com.mysql.jdbc.exceptions.jdbc4.CommunicationsException") + .getConstructor(new Class[] { MySQLConnection.class, Long.TYPE, Long.TYPE, Exception.class }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { @@ -160,7 +160,7 @@ sqlStateMessages = new HashMap(); sqlStateMessages.put(SQL_STATE_DISCONNECT_ERROR, Messages.getString("SQLError.35")); - sqlStateMessages.put(SQL_STATE_DATE_TRUNCATED, Messages.getString("SQLError.36")); + sqlStateMessages.put(SQL_STATE_DATA_TRUNCATED, Messages.getString("SQLError.36")); sqlStateMessages.put(SQL_STATE_PRIVILEGE_NOT_REVOKED, Messages.getString("SQLError.37")); sqlStateMessages.put(SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, Messages.getString("SQLError.38")); sqlStateMessages.put(SQL_STATE_ERROR_IN_ROW, Messages.getString("SQLError.39")); @@ -874,10 +874,11 @@ } public static SQLException createSQLException(String message, String sqlState, Throwable cause, ExceptionInterceptor interceptor, Connection conn) { - SQLException sqlEx = createSQLException(message, sqlState, interceptor); - - sqlEx.initCause(cause); - + SQLException sqlEx = createSQLException(message, sqlState, null); + if (sqlEx.getCause() == null) { + sqlEx.initCause(cause); + } + // Run through the exception interceptor after setting the init cause. return runThroughExceptionInterceptor(interceptor, sqlEx, conn); } @@ -907,51 +908,57 @@ if (!Util.isJdbc4()) { sqlEx = new MySQLTransientConnectionException(message, sqlState, vendorErrorCode); } else { - sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLTransientConnectionException", new Class[] { - String.class, String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, - interceptor); + sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLTransientConnectionException", + new Class[] { String.class, String.class, Integer.TYPE }, + new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, interceptor); } } else if (!Util.isJdbc4()) { sqlEx = new MySQLNonTransientConnectionException(message, sqlState, vendorErrorCode); } else { - sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException", new Class[] { - String.class, String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, interceptor); + sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException", + new Class[] { String.class, String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, + interceptor); } } else if (sqlState.startsWith("22")) { if (!Util.isJdbc4()) { sqlEx = new MySQLDataException(message, sqlState, vendorErrorCode); } else { - sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLDataException", new Class[] { String.class, String.class, - Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, interceptor); + sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLDataException", + new Class[] { String.class, String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, + interceptor); } } else if (sqlState.startsWith("23")) { if (!Util.isJdbc4()) { sqlEx = new MySQLIntegrityConstraintViolationException(message, sqlState, vendorErrorCode); } else { - sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException", new Class[] { - String.class, String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, interceptor); + sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException", + new Class[] { String.class, String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, + interceptor); } } else if (sqlState.startsWith("42")) { if (!Util.isJdbc4()) { sqlEx = new MySQLSyntaxErrorException(message, sqlState, vendorErrorCode); } else { - sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException", new Class[] { String.class, - String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, interceptor); + sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException", + new Class[] { String.class, String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, + interceptor); } } else if (sqlState.startsWith("40")) { if (!Util.isJdbc4()) { sqlEx = new MySQLTransactionRollbackException(message, sqlState, vendorErrorCode); } else { - sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException", new Class[] { - String.class, String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, interceptor); + sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException", + new Class[] { String.class, String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, + interceptor); } } else if (sqlState.startsWith("70100")) { if (!Util.isJdbc4()) { sqlEx = new MySQLQueryInterruptedException(message, sqlState, vendorErrorCode); } else { - sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLQueryInterruptedException", new Class[] { String.class, - String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, interceptor); + sqlEx = (SQLException) Util.getInstance("com.mysql.jdbc.exceptions.jdbc4.MySQLQueryInterruptedException", + new Class[] { String.class, String.class, Integer.TYPE }, new Object[] { message, sqlState, Integer.valueOf(vendorErrorCode) }, + interceptor); } } else { sqlEx = new SQLException(message, sqlState, vendorErrorCode); @@ -962,8 +969,9 @@ return runThroughExceptionInterceptor(interceptor, sqlEx, conn); } catch (SQLException sqlEx) { - SQLException unexpectedEx = new SQLException("Unable to create correct SQLException class instance, error class/codes may be incorrect. Reason: " - + Util.stackTraceToString(sqlEx), SQL_STATE_GENERAL_ERROR); + SQLException unexpectedEx = new SQLException( + "Unable to create correct SQLException class instance, error class/codes may be incorrect. Reason: " + Util.stackTraceToString(sqlEx), + SQL_STATE_GENERAL_ERROR); return runThroughExceptionInterceptor(interceptor, unexpectedEx, conn); } @@ -1073,8 +1081,8 @@ Object[] timingInfo = { Long.valueOf(timeSinceLastPacketReceivedMs), Long.valueOf(timeSinceLastPacketSentMs) }; exceptionMessageBuf.append(Messages.getString("CommunicationsException.ServerPacketTimingInfo", timingInfo)); } else { - exceptionMessageBuf.append(Messages.getString("CommunicationsException.ServerPacketTimingInfoNoRecv", - new Object[] { Long.valueOf(timeSinceLastPacketSentMs) })); + exceptionMessageBuf.append( + Messages.getString("CommunicationsException.ServerPacketTimingInfoNoRecv", new Object[] { Long.valueOf(timeSinceLastPacketSentMs) })); } if (timeoutMessageBuf != null) { @@ -1090,7 +1098,6 @@ // Attempt to determine the reason for the underlying exception (we can only make a best-guess here) // - Throwable cause; if (underlyingException instanceof BindException) { if (conn.getLocalSocketAddress() != null && !Util.interfaceExists(conn.getLocalSocketAddress())) { exceptionMessageBuf.append(Messages.getString("CommunicationsException.LocalSocketAddressNotAvailable")); @@ -1147,13 +1154,15 @@ * @param updateCounts * @param interceptor */ - public static SQLException createBatchUpdateException(SQLException underlyingEx, long[] updateCounts, ExceptionInterceptor interceptor) throws SQLException { + public static SQLException createBatchUpdateException(SQLException underlyingEx, long[] updateCounts, ExceptionInterceptor interceptor) + throws SQLException { SQLException newEx; if (Util.isJdbc42()) { - newEx = (SQLException) Util.getInstance("java.sql.BatchUpdateException", new Class[] { String.class, String.class, int.class, long[].class, - Throwable.class }, new Object[] { underlyingEx.getMessage(), underlyingEx.getSQLState(), underlyingEx.getErrorCode(), updateCounts, - underlyingEx }, interceptor); + newEx = (SQLException) Util.getInstance("java.sql.BatchUpdateException", + new Class[] { String.class, String.class, int.class, long[].class, Throwable.class }, + new Object[] { underlyingEx.getMessage(), underlyingEx.getSQLState(), underlyingEx.getErrorCode(), updateCounts, underlyingEx }, + interceptor); } else { // return pre-JDBC4.2 BatchUpdateException (updateCounts are limited to int[]) newEx = new BatchUpdateException(underlyingEx.getMessage(), underlyingEx.getSQLState(), underlyingEx.getErrorCode(), Util.truncateAndConvertToInt(updateCounts)); @@ -1188,8 +1197,8 @@ SQLException newEx; if (Util.isJdbc4()) { - newEx = (SQLException) Util.getInstance("java.sql.SQLFeatureNotSupportedException", new Class[] { String.class, String.class }, new Object[] { - message, sqlState }, interceptor); + newEx = (SQLException) Util.getInstance("java.sql.SQLFeatureNotSupportedException", new Class[] { String.class, String.class }, + new Object[] { message, sqlState }, interceptor); } else { newEx = new NotImplemented(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Security.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Security.java (.../Security.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Security.java (.../Security.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -89,10 +89,10 @@ byte[] binaryPassword = new byte[SHA1_HASH_SIZE]; /* Binary password loop pointer */ - if (usingNewPasswords) /* New password version assumed */{ + if (usingNewPasswords) /* New password version assumed */ { int pos = 0; - for (int i = 0; i < 4; i++) /* Iterate over these elements */{ + for (int i = 0; i < 4; i++) /* Iterate over these elements */ { val = salt[i]; for (int t = 3; t >= 0; t--) { @@ -106,7 +106,7 @@ int offset = 0; - for (int i = 0; i < 2; i++) /* Iterate over these elements */{ + for (int i = 0; i < 2; i++) /* Iterate over these elements */ { val = salt[i]; for (int t = 3; t >= 0; t--) { @@ -303,8 +303,8 @@ public static byte[] scramble411(String password, String seed, String passwordEncoding) throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] passwordHashStage1 = md.digest((passwordEncoding == null || passwordEncoding.length() == 0) ? StringUtils.getBytes(password) : StringUtils - .getBytes(password, passwordEncoding)); + byte[] passwordHashStage1 = md.digest((passwordEncoding == null || passwordEncoding.length() == 0) ? StringUtils.getBytes(password) + : StringUtils.getBytes(password, passwordEncoding)); md.reset(); byte[] passwordHashStage2 = md.digest(passwordHashStage1); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerAffinityStrategy.java =================================================================== diff -u --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerAffinityStrategy.java (revision 0) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerAffinityStrategy.java (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -0,0 +1,72 @@ +/* + Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + + The MySQL Connector/J is licensed under the terms of the GPLv2 + , like most MySQL Connectors. + There are special exceptions to the terms and conditions of the GPLv2 as it is applied to + this software, see the FOSS License Exception + . + + This program is free software; you can redistribute it and/or modify it under the terms + of the GNU General Public License as published by the Free Software Foundation; version 2 + of the License. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this + program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth + Floor, Boston, MA 02110-1301 USA + + */ + +package com.mysql.jdbc; + +import java.sql.SQLException; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +public class ServerAffinityStrategy extends RandomBalanceStrategy { + public static final String AFFINITY_ORDER = "serverAffinityOrder"; + public String[] affinityOrderedServers = null; + + @Override + public void init(Connection conn, Properties props) throws SQLException { + super.init(conn, props); + String hosts = props.getProperty(AFFINITY_ORDER); + if (!StringUtils.isNullOrEmpty(hosts)) { + this.affinityOrderedServers = hosts.split(","); + } + } + + @Override + public ConnectionImpl pickConnection(LoadBalancedConnectionProxy proxy, List configuredHosts, Map liveConnections, + long[] responseTimes, int numRetries) throws SQLException { + if (this.affinityOrderedServers == null) { + return super.pickConnection(proxy, configuredHosts, liveConnections, responseTimes, numRetries); + } + Map blackList = proxy.getGlobalBlacklist(); + + for (String host : this.affinityOrderedServers) { + if (configuredHosts.contains(host) && !blackList.containsKey(host)) { + ConnectionImpl conn = liveConnections.get(host); + if (conn != null) { + return conn; + } + try { + conn = proxy.createConnectionForHost(host); + return conn; + } catch (SQLException sqlEx) { + if (proxy.shouldExceptionTriggerConnectionSwitch(sqlEx)) { + proxy.addToGlobalBlacklist(host); + } + } + } + } + + // Failed to connect to all hosts in the affinity list. Delegate to RandomBalanceStrategy. + return super.pickConnection(proxy, configuredHosts, liveConnections, responseTimes, numRetries); + } +} \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerPreparedStatement.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerPreparedStatement.java (.../ServerPreparedStatement.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerPreparedStatement.java (.../ServerPreparedStatement.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -62,8 +62,8 @@ if (Util.isJdbc4()) { try { String jdbc4ClassName = Util.isJdbc42() ? "com.mysql.jdbc.JDBC42ServerPreparedStatement" : "com.mysql.jdbc.JDBC4ServerPreparedStatement"; - JDBC_4_SPS_CTOR = Class.forName(jdbc4ClassName).getConstructor( - new Class[] { MySQLConnection.class, String.class, String.class, Integer.TYPE, Integer.TYPE }); + JDBC_4_SPS_CTOR = Class.forName(jdbc4ClassName) + .getConstructor(new Class[] { MySQLConnection.class, String.class, String.class, Integer.TYPE, Integer.TYPE }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { @@ -130,6 +130,7 @@ } void reset() { + this.isNull = false; this.isSet = false; this.value = null; this.isLongData = false; @@ -149,6 +150,10 @@ return "' STREAM DATA '"; } + if (this.isNull) { + return "NULL"; + } + switch (this.bufferType) { case MysqlDefs.FIELD_TYPE_TINY: case MysqlDefs.FIELD_TYPE_SHORT: @@ -324,8 +329,8 @@ } try { - return (ServerPreparedStatement) JDBC_4_SPS_CTOR.newInstance(new Object[] { conn, sql, catalog, Integer.valueOf(resultSetType), - Integer.valueOf(resultSetConcurrency) }); + return (ServerPreparedStatement) JDBC_4_SPS_CTOR + .newInstance(new Object[] { conn, sql, catalog, Integer.valueOf(resultSetType), Integer.valueOf(resultSetConcurrency) }); } catch (IllegalArgumentException e) { throw new SQLException(e.toString(), SQLError.SQL_STATE_GENERAL_ERROR); } catch (InstantiationException e) { @@ -559,12 +564,9 @@ } synchronized (locallyScopedConn.getConnectionMutex()) { - - if (this.isCached && !this.isClosed) { + if (this.isCached && isPoolable() && !this.isClosed) { clearParameters(); - this.isClosed = true; - this.connection.recachePreparedStatement(this); return; } @@ -857,9 +859,9 @@ parameterIndex--; if ((parameterIndex < 0) || (parameterIndex >= this.parameterBindings.length)) { - throw SQLError.createSQLException( - Messages.getString("ServerPreparedStatement.9") + (parameterIndex + 1) + Messages.getString("ServerPreparedStatement.10") - + this.parameterBindings.length, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + throw SQLError.createSQLException(Messages.getString("ServerPreparedStatement.9") + (parameterIndex + 1) + + Messages.getString("ServerPreparedStatement.10") + this.parameterBindings.length, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, + getExceptionInterceptor()); } if (this.parameterBindings[parameterIndex] == null) { @@ -870,9 +872,6 @@ } } - this.parameterBindings[parameterIndex].isSet = true; - this.parameterBindings[parameterIndex].boundBeforeExecutionNum = this.numberOfExecutions; - return this.parameterBindings[parameterIndex]; } } @@ -1088,6 +1087,17 @@ } } + @Override + boolean isCursorRequired() throws SQLException { + // we only create cursor-backed result sets if + // a) The query is a SELECT + // b) The server supports it + // c) We know it is forward-only (note this doesn't preclude updatable result sets) + // d) The user has set a fetch size + return this.resultFields != null && this.connection.isCursorFetchEnabled() && getResultSetType() == ResultSet.TYPE_FORWARD_ONLY + && getResultSetConcurrency() == ResultSet.CONCUR_READ_ONLY && getFetchSize() > 0; + } + /** * Tells the server to execute this prepared statement with the current * parameter bindings. @@ -1184,18 +1194,9 @@ packet.writeByte((byte) MysqlDefs.COM_EXECUTE); packet.writeLong(this.serverStatementId); - // boolean usingCursor = false; - if (this.connection.versionMeetsMinimum(4, 1, 2)) { - // we only create cursor-backed result sets if - // a) The query is a SELECT - // b) The server supports it - // c) We know it is forward-only (note this doesn't preclude updatable result sets) - // d) The user has set a fetch size - if (this.resultFields != null && this.connection.isCursorFetchEnabled() && getResultSetType() == ResultSet.TYPE_FORWARD_ONLY - && getResultSetConcurrency() == ResultSet.CONCUR_READ_ONLY && getFetchSize() > 0) { + if (isCursorRequired()) { packet.writeByte(MysqlDefs.OPEN_CURSOR_FLAG); - // usingCursor = true; } else { packet.writeByte((byte) 0); // placeholder for flags } @@ -1264,6 +1265,12 @@ CancelTask timeoutTask = null; try { + // Get this before executing to avoid a shared packet pollution in the case some other query is issued internally, such as when using I_S. + String queryAsString = ""; + if (this.profileSQL || logSlowQueries || gatherPerformanceMetrics) { + queryAsString = asSql(true); + } + if (this.connection.getEnableQueryTimeouts() && this.timeoutInMillis != 0 && this.connection.versionMeetsMinimum(5, 0, 0)) { timeoutTask = new CancelTask(this); this.connection.getCancelTimer().schedule(timeoutTask, this.timeoutInMillis); @@ -1334,11 +1341,11 @@ mesgBuf.append("as prepared: "); mesgBuf.append(this.originalSql); mesgBuf.append("\n\n with parameters bound:\n\n"); - mesgBuf.append(asSql(true)); + mesgBuf.append(queryAsString); this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_SLOW_QUERY, "", this.currentCatalog, this.connection.getId(), getId(), - 0, System.currentTimeMillis(), elapsedTime, mysql.getQueryTimingUnits(), null, LogUtils - .findCallingClassAndMethod(new Throwable()), mesgBuf.toString())); + 0, System.currentTimeMillis(), elapsedTime, mysql.getQueryTimingUnits(), null, + LogUtils.findCallingClassAndMethod(new Throwable()), mesgBuf.toString())); } if (gatherPerformanceMetrics) { @@ -1352,8 +1359,8 @@ this.eventSink = ProfilerEventHandlerFactory.getInstance(this.connection); this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_EXECUTE, "", this.currentCatalog, this.connectionId, this.statementId, -1, - System.currentTimeMillis(), mysql.getCurrentTimeNanosOrMillis() - begin, mysql.getQueryTimingUnits(), null, LogUtils - .findCallingClassAndMethod(new Throwable()), truncateQueryToLog(asSql(true)))); + System.currentTimeMillis(), mysql.getCurrentTimeNanosOrMillis() - begin, mysql.getQueryTimingUnits(), null, + LogUtils.findCallingClassAndMethod(new Throwable()), truncateQueryToLog(queryAsString))); } com.mysql.jdbc.ResultSetInternalMethods rs = mysql.readAllResults(this, maxRowsToRetrieve, this.resultSetType, this.resultSetConcurrency, @@ -1375,13 +1382,11 @@ * rs. * resultId */, - System.currentTimeMillis(), (fetchEndTime - queryEndTime), mysql.getQueryTimingUnits(), null, LogUtils - .findCallingClassAndMethod(new Throwable()), null)); + System.currentTimeMillis(), (fetchEndTime - queryEndTime), mysql.getQueryTimingUnits(), null, + LogUtils.findCallingClassAndMethod(new Throwable()), null)); } if (queryWasSlow && this.connection.getExplainSlowQueries()) { - String queryAsString = asSql(true); - mysql.explainSlowQuery(StringUtils.getBytes(queryAsString), queryAsString); } @@ -1520,37 +1525,37 @@ if (this.profileSQL) { this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_PREPARE, "", this.currentCatalog, this.connectionId, this.statementId, -1, - System.currentTimeMillis(), mysql.getCurrentTimeNanosOrMillis() - begin, mysql.getQueryTimingUnits(), null, LogUtils - .findCallingClassAndMethod(new Throwable()), truncateQueryToLog(sql))); + System.currentTimeMillis(), mysql.getCurrentTimeNanosOrMillis() - begin, mysql.getQueryTimingUnits(), null, + LogUtils.findCallingClassAndMethod(new Throwable()), truncateQueryToLog(sql))); } - if (this.parameterCount > 0) { - if (this.connection.versionMeetsMinimum(4, 1, 2) && !mysql.isVersion(5, 0, 0)) { - this.parameterFields = new Field[this.parameterCount]; + boolean checkEOF = !mysql.isEOFDeprecated(); - Buffer metaDataPacket = mysql.readPacket(); + if (this.parameterCount > 0 && this.connection.versionMeetsMinimum(4, 1, 2) && !mysql.isVersion(5, 0, 0)) { + this.parameterFields = new Field[this.parameterCount]; - int i = 0; - - while (!metaDataPacket.isLastDataPacket() && (i < this.parameterCount)) { - this.parameterFields[i++] = mysql.unpackField(metaDataPacket, false); - metaDataPacket = mysql.readPacket(); - } + Buffer metaDataPacket; + for (int i = 0; i < this.parameterCount; i++) { + metaDataPacket = mysql.readPacket(); + this.parameterFields[i] = mysql.unpackField(metaDataPacket, false); } + if (checkEOF) { // Skip the following EOF packet. + mysql.readPacket(); + } } + // Read in the result set column information if (this.fieldCount > 0) { this.resultFields = new Field[this.fieldCount]; - Buffer fieldPacket = mysql.readPacket(); - - int i = 0; - - // Read in the result set column information - while (!fieldPacket.isLastDataPacket() && (i < this.fieldCount)) { - this.resultFields[i++] = mysql.unpackField(fieldPacket, false); + Buffer fieldPacket; + for (int i = 0; i < this.fieldCount; i++) { fieldPacket = mysql.readPacket(); + this.resultFields[i] = mysql.unpackField(fieldPacket, false); } + if (checkEOF) { // Skip the following EOF packet. + mysql.readPacket(); + } } } catch (SQLException sqlEx) { if (this.connection.getDumpQueriesOnException()) { @@ -1631,10 +1636,9 @@ setNull(parameterIndex, java.sql.Types.BINARY); } else { BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + resetToType(binding, MysqlDefs.FIELD_TYPE_BLOB); binding.value = x; - binding.isNull = false; binding.isLongData = true; if (this.connection.getUseStreamLengthsInPrepStmts()) { @@ -1660,14 +1664,12 @@ BindValue binding = getBinding(parameterIndex, false); if (this.connection.versionMeetsMinimum(5, 0, 3)) { - setType(binding, MysqlDefs.FIELD_TYPE_NEW_DECIMAL); + resetToType(binding, MysqlDefs.FIELD_TYPE_NEW_DECIMAL); } else { - setType(binding, this.stringTypeCode); + resetToType(binding, this.stringTypeCode); } binding.value = StringUtils.fixDecimalExponent(StringUtils.consistentToString(x)); - binding.isNull = false; - binding.isLongData = false; } } } @@ -1683,10 +1685,9 @@ setNull(parameterIndex, java.sql.Types.BINARY); } else { BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + resetToType(binding, MysqlDefs.FIELD_TYPE_BLOB); binding.value = x; - binding.isNull = false; binding.isLongData = true; if (this.connection.getUseStreamLengthsInPrepStmts()) { @@ -1709,10 +1710,9 @@ setNull(parameterIndex, java.sql.Types.BINARY); } else { BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + resetToType(binding, MysqlDefs.FIELD_TYPE_BLOB); binding.value = x; - binding.isNull = false; binding.isLongData = true; if (this.connection.getUseStreamLengthsInPrepStmts()) { @@ -1740,12 +1740,9 @@ checkClosed(); BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_TINY); + resetToType(binding, MysqlDefs.FIELD_TYPE_TINY); - binding.value = null; binding.longBinding = x; - binding.isNull = false; - binding.isLongData = false; } /** @@ -1759,11 +1756,9 @@ setNull(parameterIndex, java.sql.Types.BINARY); } else { BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_VAR_STRING); + resetToType(binding, MysqlDefs.FIELD_TYPE_VAR_STRING); binding.value = x; - binding.isNull = false; - binding.isLongData = false; } } @@ -1778,10 +1773,9 @@ setNull(parameterIndex, java.sql.Types.BINARY); } else { BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + resetToType(binding, MysqlDefs.FIELD_TYPE_BLOB); binding.value = reader; - binding.isNull = false; binding.isLongData = true; if (this.connection.getUseStreamLengthsInPrepStmts()) { @@ -1804,10 +1798,9 @@ setNull(parameterIndex, java.sql.Types.BINARY); } else { BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + resetToType(binding, MysqlDefs.FIELD_TYPE_BLOB); binding.value = x.getCharacterStream(); - binding.isNull = false; binding.isLongData = true; if (this.connection.getUseStreamLengthsInPrepStmts()) { @@ -1856,11 +1849,9 @@ setNull(parameterIndex, java.sql.Types.DATE); } else { BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_DATE); + resetToType(binding, MysqlDefs.FIELD_TYPE_DATE); binding.value = x; - binding.isNull = false; - binding.isLongData = false; } } @@ -1878,12 +1869,9 @@ } BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_DOUBLE); + resetToType(binding, MysqlDefs.FIELD_TYPE_DOUBLE); - binding.value = null; binding.doubleBinding = x; - binding.isNull = false; - binding.isLongData = false; } } @@ -1895,12 +1883,9 @@ checkClosed(); BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_FLOAT); + resetToType(binding, MysqlDefs.FIELD_TYPE_FLOAT); - binding.value = null; binding.floatBinding = x; - binding.isNull = false; - binding.isLongData = false; } /** @@ -1911,12 +1896,9 @@ checkClosed(); BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_LONG); + resetToType(binding, MysqlDefs.FIELD_TYPE_LONG); - binding.value = null; binding.longBinding = x; - binding.isNull = false; - binding.isLongData = false; } /** @@ -1927,12 +1909,9 @@ checkClosed(); BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_LONGLONG); + resetToType(binding, MysqlDefs.FIELD_TYPE_LONGLONG); - binding.value = null; binding.longBinding = x; - binding.isNull = false; - binding.isLongData = false; } /** @@ -1943,18 +1922,9 @@ checkClosed(); BindValue binding = getBinding(parameterIndex, false); + resetToType(binding, MysqlDefs.FIELD_TYPE_NULL); - // - // Don't re-set types, but use something if this - // parameter was never specified - // - if (binding.bufferType == 0) { - setType(binding, MysqlDefs.FIELD_TYPE_NULL); - } - - binding.value = null; binding.isNull = true; - binding.isLongData = false; } /** @@ -1965,17 +1935,9 @@ checkClosed(); BindValue binding = getBinding(parameterIndex, false); + resetToType(binding, MysqlDefs.FIELD_TYPE_NULL); - // - // Don't re-set types, but use something if this parameter was never specified - // - if (binding.bufferType == 0) { - setType(binding, MysqlDefs.FIELD_TYPE_NULL); - } - - binding.value = null; binding.isNull = true; - binding.isLongData = false; } /** @@ -1994,12 +1956,9 @@ checkClosed(); BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_SHORT); + resetToType(binding, MysqlDefs.FIELD_TYPE_SHORT); - binding.value = null; binding.longBinding = x; - binding.isNull = false; - binding.isLongData = false; } /** @@ -2013,12 +1972,9 @@ setNull(parameterIndex, java.sql.Types.CHAR); } else { BindValue binding = getBinding(parameterIndex, false); + resetToType(binding, this.stringTypeCode); - setType(binding, this.stringTypeCode); - binding.value = x; - binding.isNull = false; - binding.isLongData = false; } } @@ -2082,7 +2038,7 @@ setNull(parameterIndex, java.sql.Types.TIME); } else { BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_TIME); + resetToType(binding, MysqlDefs.FIELD_TYPE_TIME); if (!this.useLegacyDatetimeCode) { binding.value = x; @@ -2092,9 +2048,6 @@ binding.value = TimeUtil.changeTimezone(this.connection, sessionCalendar, targetCalendar, x, tz, this.connection.getServerTimezoneTZ(), rollForward); } - - binding.isNull = false; - binding.isLongData = false; } } @@ -2143,7 +2096,7 @@ setNull(parameterIndex, java.sql.Types.TIMESTAMP); } else { BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_DATETIME); + resetToType(binding, MysqlDefs.FIELD_TYPE_DATETIME); if (!this.sendFractionalSeconds) { x = TimeUtil.truncateFractionalSeconds(x); @@ -2157,20 +2110,28 @@ binding.value = TimeUtil.changeTimezone(this.connection, sessionCalendar, targetCalendar, x, tz, this.connection.getServerTimezoneTZ(), rollForward); - - binding.isNull = false; - binding.isLongData = false; } } } - protected void setType(BindValue oldValue, int bufferType) throws SQLException { + /** + * Reset a bind value to be used for a new value of the given type. + */ + protected void resetToType(BindValue oldValue, int bufferType) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { - if (oldValue.bufferType != bufferType) { + // clear any possible old value + oldValue.reset(); + + if (bufferType == MysqlDefs.FIELD_TYPE_NULL && oldValue.bufferType != 0) { + // preserve the previous type to (possibly) avoid sending types at execution time + } else if (oldValue.bufferType != bufferType) { this.sendTypesToServer = true; + oldValue.bufferType = bufferType; } - oldValue.bufferType = bufferType; + // setup bind value for use + oldValue.isSet = true; + oldValue.boundBeforeExecutionNum = this.numberOfExecutions; } } @@ -2690,7 +2651,7 @@ @Override protected long[] computeMaxParameterSetSizeAndBatchSize(int numBatchedArgs) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { - long sizeOfEntireBatch = 1 + /* com_execute */+4 /* stmt id */+ 1 /* flags */+ 4 /* batch count padding */; + long sizeOfEntireBatch = 1 + /* com_execute */+4 /* stmt id */ + 1 /* flags */ + 4 /* batch count padding */; long maxSizeOfParameterSet = 0; for (int i = 0; i < numBatchedArgs; i++) { @@ -2800,8 +2761,8 @@ break; default: - throw new IllegalArgumentException("Unknown type when re-binding parameter into batched statement for parameter index " - + batchedParamIndex); + throw new IllegalArgumentException( + "Unknown type when re-binding parameter into batched statement for parameter index " + batchedParamIndex); } } } @@ -2819,8 +2780,8 @@ protected PreparedStatement prepareBatchedInsertSQL(MySQLConnection localConn, int numBatches) throws SQLException { synchronized (checkClosed().getConnectionMutex()) { try { - PreparedStatement pstmt = new ServerPreparedStatement(localConn, this.parseInfo.getSqlForBatch(numBatches), this.currentCatalog, - this.resultSetConcurrency, this.resultSetType); + PreparedStatement pstmt = ((Wrapper) localConn.prepareStatement(this.parseInfo.getSqlForBatch(numBatches), this.resultSetType, + this.resultSetConcurrency)).unwrap(PreparedStatement.class); pstmt.setRetrieveGeneratedKeys(this.retrieveGeneratedKeys); return pstmt; @@ -2833,4 +2794,12 @@ } } } + + @Override + public void setPoolable(boolean poolable) throws SQLException { + if (!poolable) { + this.connection.decachePreparedStatement(this); + } + super.setPoolable(poolable); + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/SocketMetadata.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/SocketMetadata.java (.../SocketMetadata.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/SocketMetadata.java (.../SocketMetadata.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -36,7 +36,7 @@ /* * Provides a standard way of determining whether a socket connection is local. - * + * * This ensures socket factories (e.g. StandardSocketFactory, StandardSSLSocketFactory) which need to implement this interface, can delegate to a generic * implementation. */ Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/StatementImpl.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/StatementImpl.java (.../StatementImpl.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/StatementImpl.java (.../StatementImpl.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -24,6 +24,8 @@ package com.mysql.jdbc; import java.io.InputStream; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import java.math.BigInteger; import java.sql.BatchUpdateException; import java.sql.DriverManager; @@ -67,17 +69,13 @@ * and simple way to implement a feature that isn't used all that often. */ class CancelTask extends TimerTask { - - long connectionId = 0; - String origHost = ""; SQLException caughtWhileCancelling = null; StatementImpl toCancel; Properties origConnProps = null; String origConnURL = ""; + long origConnId = 0; CancelTask(StatementImpl cancellee) throws SQLException { - this.connectionId = cancellee.connectionId; - this.origHost = StatementImpl.this.connection.getHost(); this.toCancel = cancellee; this.origConnProps = new Properties(); @@ -91,6 +89,7 @@ } this.origConnURL = StatementImpl.this.connection.getURL(); + this.origConnId = StatementImpl.this.connection.getId(); } @Override @@ -105,38 +104,40 @@ java.sql.Statement cancelStmt = null; try { - if (StatementImpl.this.connection.getQueryTimeoutKillsConnection()) { - CancelTask.this.toCancel.wasCancelled = true; - CancelTask.this.toCancel.wasCancelledByTimeout = true; - StatementImpl.this.connection.realClose(false, false, true, - new MySQLStatementCancelledException(Messages.getString("Statement.ConnectionKilledDueToTimeout"))); - } else { - synchronized (StatementImpl.this.cancelTimeoutMutex) { - if (CancelTask.this.origConnURL.equals(StatementImpl.this.connection.getURL())) { - //All's fine - cancelConn = StatementImpl.this.connection.duplicate(); - cancelStmt = cancelConn.createStatement(); - cancelStmt.execute("KILL QUERY " + CancelTask.this.connectionId); - } else { - try { - cancelConn = (Connection) DriverManager.getConnection(CancelTask.this.origConnURL, CancelTask.this.origConnProps); + MySQLConnection physicalConn = StatementImpl.this.physicalConnection.get(); + if (physicalConn != null) { + if (physicalConn.getQueryTimeoutKillsConnection()) { + CancelTask.this.toCancel.wasCancelled = true; + CancelTask.this.toCancel.wasCancelledByTimeout = true; + physicalConn.realClose(false, false, true, + new MySQLStatementCancelledException(Messages.getString("Statement.ConnectionKilledDueToTimeout"))); + } else { + synchronized (StatementImpl.this.cancelTimeoutMutex) { + if (CancelTask.this.origConnURL.equals(physicalConn.getURL())) { + // All's fine + cancelConn = physicalConn.duplicate(); cancelStmt = cancelConn.createStatement(); - cancelStmt.execute("KILL QUERY " + CancelTask.this.connectionId); - } catch (NullPointerException npe) { - //Log this? "Failed to connect to " + origConnURL + " and KILL query" + cancelStmt.execute("KILL QUERY " + physicalConn.getId()); + } else { + try { + cancelConn = (Connection) DriverManager.getConnection(CancelTask.this.origConnURL, CancelTask.this.origConnProps); + cancelStmt = cancelConn.createStatement(); + cancelStmt.execute("KILL QUERY " + CancelTask.this.origConnId); + } catch (NullPointerException npe) { + // Log this? "Failed to connect to " + origConnURL + " and KILL query" + } } + CancelTask.this.toCancel.wasCancelled = true; + CancelTask.this.toCancel.wasCancelledByTimeout = true; } - CancelTask.this.toCancel.wasCancelled = true; - CancelTask.this.toCancel.wasCancelledByTimeout = true; } } } catch (SQLException sqlEx) { CancelTask.this.caughtWhileCancelling = sqlEx; } catch (NullPointerException npe) { - // Case when connection closed while starting to cancel - // We can't easily synchronize this, because then one thread can't cancel() a running query - - // ignore, we shouldn't re-throw this, because the connection's already closed, so the statement has been timed out. + // Case when connection closed while starting to cancel. + // We can't easily synchronize this, because then one thread can't cancel() a running query. + // Ignore, we shouldn't re-throw this, because the connection's already closed, so the statement has been timed out. } finally { if (cancelStmt != null) { try { @@ -196,6 +197,9 @@ /** The connection that created us */ protected volatile MySQLConnection connection = null; + /** The physical connection used to effectively execute the statement */ + protected Reference physicalConnection = null; + protected long connectionId = 0; /** The catalog in use */ @@ -302,7 +306,7 @@ * Constructor for a Statement. * * @param c - * the Connection instantation that creates us + * the Connection instance that creates us * @param catalog * the database name in use when we were created * @@ -679,7 +683,8 @@ * than read all at once. */ protected boolean createStreamingResultSet() { - return ((this.resultSetType == java.sql.ResultSet.TYPE_FORWARD_ONLY) && (this.resultSetConcurrency == java.sql.ResultSet.CONCUR_READ_ONLY) && (this.fetchSize == Integer.MIN_VALUE)); + return ((this.resultSetType == java.sql.ResultSet.TYPE_FORWARD_ONLY) && (this.resultSetConcurrency == java.sql.ResultSet.CONCUR_READ_ONLY) + && (this.fetchSize == Integer.MIN_VALUE)); } private int originalResultSetType = 0; @@ -750,6 +755,16 @@ resetCancelledState(); + implicitlyCloseAllOpenResults(); + + if (sql.charAt(0) == '/') { + if (sql.startsWith(PING_MARKER)) { + doPingInstead(); + + return true; + } + } + char firstNonWsChar = StringUtils.firstAlphaCharUc(sql, findStartOfStatement(sql)); boolean maybeSelect = firstNonWsChar == 'S'; @@ -782,16 +797,6 @@ } } - implicitlyCloseAllOpenResults(); - - if (sql.charAt(0) == '/') { - if (sql.startsWith(PING_MARKER)) { - doPingInstead(); - - return true; - } - } - CachedResultSetMetaData cachedMetaData = null; ResultSetInternalMethods rs = null; @@ -837,8 +842,8 @@ statementBegins(); - rs = locallyScopedConn.execSQL(this, sql, this.maxRows, null, this.resultSetType, this.resultSetConcurrency, - createStreamingResultSet(), this.currentCatalog, cachedFields); + rs = locallyScopedConn.execSQL(this, sql, this.maxRows, null, this.resultSetType, this.resultSetConcurrency, createStreamingResultSet(), + this.currentCatalog, cachedFields); if (timeoutTask != null) { if (timeoutTask.caughtWhileCancelling != null) { @@ -906,6 +911,12 @@ protected void statementBegins() { this.clearWarningsCalled = false; this.statementExecuting.set(true); + + MySQLConnection physicalConn = this.connection.getMultiHostSafeProxy().getActiveMySQLConnection(); + while (!(physicalConn instanceof ConnectionImpl)) { + physicalConn = physicalConn.getMultiHostSafeProxy().getActiveMySQLConnection(); + } + this.physicalConnection = new WeakReference(physicalConn); } protected void resetCancelledState() throws SQLException { @@ -1163,7 +1174,7 @@ String nextQuery = (String) this.batchedArgs.get(commandIndex); if (((((queryBuf.length() + nextQuery.length()) * numberOfBytesPerChar) + 1 /* for semicolon */ - + MysqlIO.HEADER_LENGTH) * escapeAdjust) + 32 > this.connection.getMaxAllowedPacket()) { + + MysqlIO.HEADER_LENGTH) * escapeAdjust) + 32 > this.connection.getMaxAllowedPacket()) { try { batchStmt.execute(queryBuf.toString(), java.sql.Statement.RETURN_GENERATED_KEYS); } catch (SQLException ex) { @@ -1296,10 +1307,20 @@ this.retrieveGeneratedKeys = false; + checkNullOrEmptyQuery(sql); + resetCancelledState(); - checkNullOrEmptyQuery(sql); + implicitlyCloseAllOpenResults(); + if (sql.charAt(0) == '/') { + if (sql.startsWith(PING_MARKER)) { + doPingInstead(); + + return this.results; + } + } + setupStreamingTimeout(locallyScopedConn); if (this.doEscapeProcessing) { @@ -1314,18 +1335,8 @@ char firstStatementChar = StringUtils.firstAlphaCharUc(sql, findStartOfStatement(sql)); - if (sql.charAt(0) == '/') { - if (sql.startsWith(PING_MARKER)) { - doPingInstead(); - - return this.results; - } - } - checkForDml(sql, firstStatementChar); - implicitlyCloseAllOpenResults(); - CachedResultSetMetaData cachedMetaData = null; if (useServerFetch()) { @@ -2170,67 +2181,58 @@ protected void realClose(boolean calledExplicitly, boolean closeOpenResults) throws SQLException { MySQLConnection locallyScopedConn = this.connection; - if (locallyScopedConn == null) { + if (locallyScopedConn == null || this.isClosed) { return; // already closed } - synchronized (locallyScopedConn.getConnectionMutex()) { + // do it ASAP to reduce the chance of calling this method concurrently from ConnectionImpl.closeAllOpenStatements() + if (!locallyScopedConn.getDontTrackOpenResources()) { + locallyScopedConn.unregisterStatement(this); + } - // additional check in case Statement was closed while current thread was waiting for lock - if (this.isClosed) { - return; - } + if (this.useUsageAdvisor) { + if (!calledExplicitly) { + String message = Messages.getString("Statement.63") + Messages.getString("Statement.64"); - if (this.useUsageAdvisor) { - if (!calledExplicitly) { - String message = Messages.getString("Statement.63") + Messages.getString("Statement.64"); - - this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", this.currentCatalog, this.connectionId, this.getId(), -1, System - .currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, message)); - } + this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", this.currentCatalog, this.connectionId, this.getId(), -1, + System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, message)); } + } - if (closeOpenResults) { - closeOpenResults = !(this.holdResultsOpenOverClose || this.connection.getDontTrackOpenResources()); - } + if (closeOpenResults) { + closeOpenResults = !(this.holdResultsOpenOverClose || this.connection.getDontTrackOpenResources()); + } - if (closeOpenResults) { - if (this.results != null) { + if (closeOpenResults) { + if (this.results != null) { - try { - this.results.close(); - } catch (Exception ex) { - } + try { + this.results.close(); + } catch (Exception ex) { } + } - if (this.generatedKeysResults != null) { + if (this.generatedKeysResults != null) { - try { - this.generatedKeysResults.close(); - } catch (Exception ex) { - } + try { + this.generatedKeysResults.close(); + } catch (Exception ex) { } - - closeAllOpenResults(); } - if (this.connection != null) { - if (!this.connection.getDontTrackOpenResources()) { - this.connection.unregisterStatement(this); - } - } + closeAllOpenResults(); + } - this.isClosed = true; + this.isClosed = true; - this.results = null; - this.generatedKeysResults = null; - this.connection = null; - this.warningChain = null; - this.openResults = null; - this.batchedGeneratedKeys = null; - this.localInfileInputStream = null; - this.pingTarget = null; - } + this.results = null; + this.generatedKeysResults = null; + this.connection = null; + this.warningChain = null; + this.openResults = null; + this.batchedGeneratedKeys = null; + this.localInfileInputStream = null; + this.pingTarget = null; } /** @@ -2674,4 +2676,8 @@ this.maxRows = (int) max; } } + + boolean isCursorRequired() throws SQLException { + return false; + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/StringUtils.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/StringUtils.java (.../StringUtils.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/StringUtils.java (.../StringUtils.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -37,6 +37,7 @@ import java.nio.charset.UnsupportedCharsetException; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.List; @@ -64,32 +65,32 @@ /** * Search mode: skip between markers, skip block comments, skip line comments and skip white space. */ - public static final Set SEARCH_MODE__MRK_COM_WS = Collections.unmodifiableSet(EnumSet.of(SearchMode.SKIP_BETWEEN_MARKERS, - SearchMode.SKIP_BLOCK_COMMENTS, SearchMode.SKIP_LINE_COMMENTS, SearchMode.SKIP_WHITE_SPACE)); + public static final Set SEARCH_MODE__MRK_COM_WS = Collections.unmodifiableSet( + EnumSet.of(SearchMode.SKIP_BETWEEN_MARKERS, SearchMode.SKIP_BLOCK_COMMENTS, SearchMode.SKIP_LINE_COMMENTS, SearchMode.SKIP_WHITE_SPACE)); /** * Search mode: allow backslash escape, skip block comments, skip line comments and skip white space. */ - public static final Set SEARCH_MODE__BSESC_COM_WS = Collections.unmodifiableSet(EnumSet.of(SearchMode.ALLOW_BACKSLASH_ESCAPE, - SearchMode.SKIP_BLOCK_COMMENTS, SearchMode.SKIP_LINE_COMMENTS, SearchMode.SKIP_WHITE_SPACE)); + public static final Set SEARCH_MODE__BSESC_COM_WS = Collections.unmodifiableSet( + EnumSet.of(SearchMode.ALLOW_BACKSLASH_ESCAPE, SearchMode.SKIP_BLOCK_COMMENTS, SearchMode.SKIP_LINE_COMMENTS, SearchMode.SKIP_WHITE_SPACE)); /** * Search mode: allow backslash escape, skip between markers and skip white space. */ - public static final Set SEARCH_MODE__BSESC_MRK_WS = Collections.unmodifiableSet(EnumSet.of(SearchMode.ALLOW_BACKSLASH_ESCAPE, - SearchMode.SKIP_BETWEEN_MARKERS, SearchMode.SKIP_WHITE_SPACE)); + public static final Set SEARCH_MODE__BSESC_MRK_WS = Collections + .unmodifiableSet(EnumSet.of(SearchMode.ALLOW_BACKSLASH_ESCAPE, SearchMode.SKIP_BETWEEN_MARKERS, SearchMode.SKIP_WHITE_SPACE)); /** * Search mode: skip block comments, skip line comments and skip white space. */ - public static final Set SEARCH_MODE__COM_WS = Collections.unmodifiableSet(EnumSet.of(SearchMode.SKIP_BLOCK_COMMENTS, - SearchMode.SKIP_LINE_COMMENTS, SearchMode.SKIP_WHITE_SPACE)); + public static final Set SEARCH_MODE__COM_WS = Collections + .unmodifiableSet(EnumSet.of(SearchMode.SKIP_BLOCK_COMMENTS, SearchMode.SKIP_LINE_COMMENTS, SearchMode.SKIP_WHITE_SPACE)); /** * Search mode: skip between markers and skip white space. */ - public static final Set SEARCH_MODE__MRK_WS = Collections.unmodifiableSet(EnumSet.of(SearchMode.SKIP_BETWEEN_MARKERS, - SearchMode.SKIP_WHITE_SPACE)); + public static final Set SEARCH_MODE__MRK_WS = Collections + .unmodifiableSet(EnumSet.of(SearchMode.SKIP_BETWEEN_MARKERS, SearchMode.SKIP_WHITE_SPACE)); /** * Empty search mode. @@ -107,12 +108,14 @@ private static Method toPlainStringMethod; - static final int WILD_COMPARE_MATCH_NO_WILD = 0; + private static final int WILD_COMPARE_MATCH = 0; + private static final int WILD_COMPARE_CONTINUE_WITH_WILD = 1; + private static final int WILD_COMPARE_NO_MATCH = -1; - static final int WILD_COMPARE_MATCH_WITH_WILD = 1; + static final char WILDCARD_MANY = '%'; + static final char WILDCARD_ONE = '_'; + static final char WILDCARD_ESCAPE = '\\'; - static final int WILD_COMPARE_NO_MATCH = -1; - private static final ConcurrentHashMap charsetsByAlias = new ConcurrentHashMap(); private static final String platformEncoding = System.getProperty("file.encoding"); @@ -125,7 +128,11 @@ if (cs == null) { cs = Charset.forName(alias); - charsetsByAlias.putIfAbsent(alias, cs); + Charset oldCs = charsetsByAlias.putIfAbsent(alias, cs); + if (oldCs != null) { + // if the previous value was recently set by another thread we return it instead of value we found here + cs = oldCs; + } } return cs; @@ -1044,7 +1051,7 @@ int wc = 0; boolean match = true; while (++wc < searchForWordsCount && match) { - int positionOfNextWord = indexOfNextChar(startingPositionForNextWord, searchInLength - 1, searchIn, null, null, searchMode2); + int positionOfNextWord = indexOfNextChar(startingPositionForNextWord, searchInLength - 1, searchIn, null, null, null, searchMode2); if (startingPositionForNextWord == positionOfNextWord || !startsWithIgnoreCase(searchIn, positionOfNextWord, searchForSequence[wc])) { // either no gap between words or match failed match = false; @@ -1081,6 +1088,33 @@ */ public static int indexOfIgnoreCase(int startingPosition, String searchIn, String searchFor, String openingMarkers, String closingMarkers, Set searchMode) { + return indexOfIgnoreCase(startingPosition, searchIn, searchFor, openingMarkers, closingMarkers, "", searchMode); + } + + /** + * Finds the position of a substring within a string, ignoring case, with the option to skip text delimited by given markers or within comments. + * + * @param startingPosition + * the position to start the search from + * @param searchIn + * the string to search in + * @param searchFor + * the string to search for + * @param openingMarkers + * characters which delimit the beginning of a text block to skip + * @param closingMarkers + * characters which delimit the end of a text block to skip + * @param overridingMarkers + * the subset of openingMarkers that override the remaining markers, e.g., if openingMarkers = "'(" and + * overridingMarkers = "'" then the block between the outer parenthesis in "start ('max('); end" is strictly consumed, + * otherwise the suffix " end" would end up being consumed too in the process of handling the nested parenthesis. + * @param searchMode + * a Set, ideally an EnumSet, containing the flags from the enum StringUtils.SearchMode that determine the + * behavior of the search + * @return the position where searchFor is found within searchIn starting from startingPosition. + */ + public static int indexOfIgnoreCase(int startingPosition, String searchIn, String searchFor, String openingMarkers, String closingMarkers, + String overridingMarkers, Set searchMode) { if (searchIn == null || searchFor == null) { return -1; } @@ -1093,9 +1127,18 @@ return -1; } - if (searchMode.contains(SearchMode.SKIP_BETWEEN_MARKERS) - && (openingMarkers == null || closingMarkers == null || openingMarkers.length() != closingMarkers.length())) { - throw new IllegalArgumentException(Messages.getString("StringUtils.15", new String[] { openingMarkers, closingMarkers })); + if (searchMode.contains(SearchMode.SKIP_BETWEEN_MARKERS)) { + if (openingMarkers == null || closingMarkers == null || openingMarkers.length() != closingMarkers.length()) { + throw new IllegalArgumentException(Messages.getString("StringUtils.15", new String[] { openingMarkers, closingMarkers })); + } + if (overridingMarkers == null) { + throw new IllegalArgumentException(Messages.getString("StringUtils.16", new String[] { overridingMarkers, openingMarkers })); + } + for (char c : overridingMarkers.toCharArray()) { + if (openingMarkers.indexOf(c) == -1) { + throw new IllegalArgumentException(Messages.getString("StringUtils.16", new String[] { overridingMarkers, openingMarkers })); + } + } } // Some locales don't follow upper-case rule, so need to check both @@ -1109,7 +1152,7 @@ } for (int i = startingPosition; i <= stopSearchingAt; i++) { - i = indexOfNextChar(i, stopSearchingAt, searchIn, openingMarkers, closingMarkers, searchMode); + i = indexOfNextChar(i, stopSearchingAt, searchIn, openingMarkers, closingMarkers, overridingMarkers, searchMode); if (i == -1) { return -1; @@ -1144,7 +1187,7 @@ * @return the position where searchFor is found within searchIn starting from startingPosition. */ private static int indexOfNextChar(int startingPosition, int stopPosition, String searchIn, String openingMarkers, String closingMarkers, - Set searchMode) { + String overridingMarkers, Set searchMode) { if (searchIn == null) { return -1; } @@ -1178,8 +1221,25 @@ int nestedMarkersCount = 0; char openingMarker = c0; char closingMarker = closingMarkers.charAt(markerIndex); + boolean outerIsAnOverridingMarker = overridingMarkers.indexOf(openingMarker) != -1; while (++i <= stopPosition && ((c0 = searchIn.charAt(i)) != closingMarker || nestedMarkersCount != 0)) { - if (c0 == openingMarker) { + if (!outerIsAnOverridingMarker && overridingMarkers.indexOf(c0) != -1) { + // there is an overriding marker that needs to be consumed before returning to the previous marker + int overridingMarkerIndex = openingMarkers.indexOf(c0); // overridingMarkers must be a sub-list of openingMarkers + int overridingNestedMarkersCount = 0; + char overridingOpeningMarker = c0; + char overridingClosingMarker = closingMarkers.charAt(overridingMarkerIndex); + while (++i <= stopPosition && ((c0 = searchIn.charAt(i)) != overridingClosingMarker || overridingNestedMarkersCount != 0)) { + // do as before, but this marker can't be overridden + if (c0 == overridingOpeningMarker) { + overridingNestedMarkersCount++; + } else if (c0 == overridingClosingMarker) { + overridingNestedMarkersCount--; + } else if (searchMode.contains(SearchMode.ALLOW_BACKSLASH_ESCAPE) && c0 == '\\') { + i++; // next char is escaped, skip it + } + } + } else if (c0 == openingMarker) { nestedMarkersCount++; } else if (c0 == closingMarker) { nestedMarkersCount--; @@ -1195,7 +1255,8 @@ if (c2 != '!') { // comments block found, skip until end of block ("*/") (backslash escape doesn't work on comments) i++; // move to next char ('*') - while (++i <= stopPosition && (searchIn.charAt(i) != '*' || (i + 1 < searchInLength ? searchIn.charAt(i + 1) : Character.MIN_VALUE) != '/')) { + while (++i <= stopPosition + && (searchIn.charAt(i) != '*' || (i + 1 < searchInLength ? searchIn.charAt(i + 1) : Character.MIN_VALUE) != '/')) { // continue } i++; // move to next char ('/') @@ -1228,7 +1289,8 @@ c2 = i + 2 < searchInLength ? searchIn.charAt(i + 2) : Character.MIN_VALUE; } else if (searchMode.contains(SearchMode.SKIP_LINE_COMMENTS) - && ((c0 == '-' && c1 == '-' && (Character.isWhitespace(c2) || (dashDashCommentImmediateEnd = c2 == ';') || c2 == Character.MIN_VALUE)) || c0 == '#')) { + && ((c0 == '-' && c1 == '-' && (Character.isWhitespace(c2) || (dashDashCommentImmediateEnd = c2 == ';') || c2 == Character.MIN_VALUE)) + || c0 == '#')) { if (dashDashCommentImmediateEnd) { // comments line found but closed immediately by query delimiter marker i++; // move to next char ('-') @@ -1308,20 +1370,51 @@ } /** - * Splits stringToSplit into a list, using the given delimiter + * Splits stringToSplit into a list, using the given delimiter and skipping all between the given markers. * * @param stringToSplit * the string to split * @param delimiter * the string to split on + * @param openingMarkers + * characters which delimit the beginning of a text block to skip + * @param closingMarkers + * characters which delimit the end of a text block to skip * @param trim * should the split strings be whitespace trimmed? * * @return the list of strings, split by delimiter * * @throws IllegalArgumentException */ - public static List split(String stringToSplit, String delimiter, String markers, String markerCloses, boolean trim) { + public static List split(String stringToSplit, String delimiter, String openingMarkers, String closingMarkers, boolean trim) { + return split(stringToSplit, delimiter, openingMarkers, closingMarkers, "", trim); + } + + /** + * Splits stringToSplit into a list, using the given delimiter and skipping all between the given markers. + * + * @param stringToSplit + * the string to split + * @param delimiter + * the string to split on + * @param openingMarkers + * characters which delimit the beginning of a text block to skip + * @param closingMarkers + * characters which delimit the end of a text block to skip + * @param overridingMarkers + * the subset of openingMarkers that override the remaining markers, e.g., if openingMarkers = "'(" and + * overridingMarkers = "'" then the block between the outer parenthesis in "start ('max('); end" is strictly consumed, + * otherwise the suffix " end" would end up being consumed too in the process of handling the nested parenthesis. + * @param trim + * should the split strings be whitespace trimmed? + * + * @return the list of strings, split by delimiter + * + * @throws IllegalArgumentException + */ + public static List split(String stringToSplit, String delimiter, String openingMarkers, String closingMarkers, String overridingMarkers, + boolean trim) { if (stringToSplit == null) { return new ArrayList(); } @@ -1335,7 +1428,8 @@ List splitTokens = new ArrayList(); - while ((delimPos = indexOfIgnoreCase(currentPos, stringToSplit, delimiter, markers, markerCloses, SEARCH_MODE__MRK_COM_WS)) != -1) { + while ((delimPos = indexOfIgnoreCase(currentPos, stringToSplit, delimiter, openingMarkers, closingMarkers, overridingMarkers, + SEARCH_MODE__MRK_COM_WS)) != -1) { String token = stringToSplit.substring(currentPos, delimPos); if (trim) { @@ -1559,138 +1653,135 @@ } /** - * Compares searchIn against searchForWildcard with wildcards (heavily - * borrowed from strings/ctype-simple.c in the server sources) + * Compares searchIn against searchForWildcard with wildcards, in a case insensitive manner. * * @param searchIn * the string to search in - * @param searchForWildcard - * the string to search for, using the 'standard' SQL wildcard - * chars of '%' and '_' + * @param searchFor + * the string to search for, using the 'standard' SQL wildcard chars of '%' and '_' + */ + public static boolean wildCompareIgnoreCase(String searchIn, String searchFor) { + return wildCompareInternal(searchIn, searchFor) == WILD_COMPARE_MATCH; + } + + /** + * Compares searchIn against searchForWildcard with wildcards (heavily borrowed from strings/ctype-simple.c in the server sources) * - * @return WILD_COMPARE_MATCH_NO_WILD if matched, WILD_COMPARE_NO_MATCH if - * not matched with wildcard, WILD_COMPARE_MATCH_WITH_WILD if - * matched with wildcard + * This method does a single passage matching for normal characters and WILDCARD_ONE (_), and recursive matching for WILDCARD_MANY (%) which may be repeated + * for as many anchor chars are found. + * + * @param searchIn + * the string to search in + * @param searchFor + * the string to search for, using the 'standard' SQL wildcard chars of '%' and '_' + * + * @return WILD_COMPARE_MATCH if matched, WILD_COMPARE_NO_MATCH if not matched, WILD_COMPARE_CONTINUE_WITH_WILD if not matched yet, but it may in one of + * following recursion rounds */ - public static int wildCompare(String searchIn, String searchForWildcard) { - if ((searchIn == null) || (searchForWildcard == null)) { + private static int wildCompareInternal(String searchIn, String searchFor) { + if ((searchIn == null) || (searchFor == null)) { return WILD_COMPARE_NO_MATCH; } - if (searchForWildcard.equals("%")) { - - return WILD_COMPARE_MATCH_WITH_WILD; + if (searchFor.equals("%")) { + return WILD_COMPARE_MATCH; } - int result = WILD_COMPARE_NO_MATCH; /* Not found, using wildcards */ - - char wildcardMany = '%'; - char wildcardOne = '_'; - char wildcardEscape = '\\'; - int searchForPos = 0; - int searchForEnd = searchForWildcard.length(); + int searchForEnd = searchFor.length(); int searchInPos = 0; int searchInEnd = searchIn.length(); - while (searchForPos != searchForEnd) { - char wildstrChar = searchForWildcard.charAt(searchForPos); + int result = WILD_COMPARE_NO_MATCH; /* Not found, using wildcards */ - while ((searchForWildcard.charAt(searchForPos) != wildcardMany) && (wildstrChar != wildcardOne)) { - if ((searchForWildcard.charAt(searchForPos) == wildcardEscape) && ((searchForPos + 1) != searchForEnd)) { + while (searchForPos != searchForEnd) { + while ((searchFor.charAt(searchForPos) != WILDCARD_MANY) && (searchFor.charAt(searchForPos) != WILDCARD_ONE)) { + if ((searchFor.charAt(searchForPos) == WILDCARD_ESCAPE) && ((searchForPos + 1) != searchForEnd)) { searchForPos++; } if ((searchInPos == searchInEnd) - || (Character.toUpperCase(searchForWildcard.charAt(searchForPos++)) != Character.toUpperCase(searchIn.charAt(searchInPos++)))) { - return WILD_COMPARE_MATCH_WITH_WILD; /* No match */ + || (Character.toUpperCase(searchFor.charAt(searchForPos++)) != Character.toUpperCase(searchIn.charAt(searchInPos++)))) { + return WILD_COMPARE_CONTINUE_WITH_WILD; /* No match */ } if (searchForPos == searchForEnd) { - return ((searchInPos != searchInEnd) ? WILD_COMPARE_MATCH_WITH_WILD : WILD_COMPARE_MATCH_NO_WILD); /* Match if both are at end */ + return ((searchInPos != searchInEnd) ? WILD_COMPARE_CONTINUE_WITH_WILD : WILD_COMPARE_MATCH); /* Match if both are at end */ } - result = WILD_COMPARE_MATCH_WITH_WILD; /* Found an anchor char */ + result = WILD_COMPARE_CONTINUE_WITH_WILD; /* Found an anchor char */ } - if (searchForWildcard.charAt(searchForPos) == wildcardOne) { + if (searchFor.charAt(searchForPos) == WILDCARD_ONE) { do { if (searchInPos == searchInEnd) { /* Skip one char if possible */ - - return (result); + return result; } - searchInPos++; - } while ((++searchForPos < searchForEnd) && (searchForWildcard.charAt(searchForPos) == wildcardOne)); + } while ((++searchForPos < searchForEnd) && (searchFor.charAt(searchForPos) == WILDCARD_ONE)); if (searchForPos == searchForEnd) { break; } } - if (searchForWildcard.charAt(searchForPos) == wildcardMany) { /* Found w_many */ - - char cmp; - + if (searchFor.charAt(searchForPos) == WILDCARD_MANY) { /* Found w_many */ searchForPos++; /* Remove any '%' and '_' from the wild search string */ for (; searchForPos != searchForEnd; searchForPos++) { - if (searchForWildcard.charAt(searchForPos) == wildcardMany) { + if (searchFor.charAt(searchForPos) == WILDCARD_MANY) { continue; } - if (searchForWildcard.charAt(searchForPos) == wildcardOne) { - if (searchInPos == searchInEnd) { - return (WILD_COMPARE_NO_MATCH); + if (searchFor.charAt(searchForPos) == WILDCARD_ONE) { + if (searchInPos == searchInEnd) { /* Skip one char if possible */ + return WILD_COMPARE_NO_MATCH; } - searchInPos++; - continue; } break; /* Not a wild character */ } if (searchForPos == searchForEnd) { - return WILD_COMPARE_MATCH_NO_WILD; /* Ok if w_many is last */ + return WILD_COMPARE_MATCH; /* Ok if w_many is last */ } if (searchInPos == searchInEnd) { return WILD_COMPARE_NO_MATCH; } - if (((cmp = searchForWildcard.charAt(searchForPos)) == wildcardEscape) && ((searchForPos + 1) != searchForEnd)) { - cmp = searchForWildcard.charAt(++searchForPos); + char cmp; + if (((cmp = searchFor.charAt(searchForPos)) == WILDCARD_ESCAPE) && ((searchForPos + 1) != searchForEnd)) { + cmp = searchFor.charAt(++searchForPos); } searchForPos++; do { while ((searchInPos != searchInEnd) && (Character.toUpperCase(searchIn.charAt(searchInPos)) != Character.toUpperCase(cmp))) { searchInPos++; - } + } /* Searches for an anchor char */ if (searchInPos++ == searchInEnd) { return WILD_COMPARE_NO_MATCH; } - { - int tmp = wildCompare(searchIn, searchForWildcard); - - if (tmp <= 0) { - return (tmp); - } + int tmp = wildCompareInternal(searchIn.substring(searchInPos), searchFor.substring(searchForPos)); + if (tmp <= 0) { + return tmp; } - } while ((searchInPos != searchInEnd) && (searchForWildcard.charAt(0) != wildcardMany)); + } while (searchInPos != searchInEnd); + return WILD_COMPARE_NO_MATCH; } } - return ((searchInPos != searchInEnd) ? WILD_COMPARE_MATCH_WITH_WILD : WILD_COMPARE_MATCH_NO_WILD); + return ((searchInPos != searchInEnd) ? WILD_COMPARE_CONTINUE_WITH_WILD : WILD_COMPARE_MATCH); } static byte[] s2b(String s, MySQLConnection conn) throws SQLException { @@ -1799,9 +1890,7 @@ try { while ((currentChar = sourceReader.read()) != -1) { - if (false && currentChar == '\\') { - escaped = !escaped; - } else if (markerTypeFound != -1 && currentChar == stringCloses.charAt(markerTypeFound) && !escaped) { + if (markerTypeFound != -1 && currentChar == stringCloses.charAt(markerTypeFound) && !escaped) { contextMarker = Character.MIN_VALUE; markerTypeFound = -1; } else if ((ind = stringOpens.indexOf(currentChar)) != -1 && !escaped && contextMarker == Character.MIN_VALUE) { @@ -1847,7 +1936,7 @@ strBuilder.append('-'); if (currentChar != -1) { - strBuilder.append(currentChar); + strBuilder.append((char) currentChar); } continue; @@ -1891,69 +1980,42 @@ } /** - * Next we check if there is anything to split. If so - * we return result in form of "database";"name" - * If string is NULL or wildcard (%), returns null and exits. + * Splits an entity identifier into its parts (database and entity name) and returns a list containing the two elements. If the identifier doesn't contain + * the database part then the argument catalog is used in its place and source corresponds to the full entity name. + * If argument source is NULL or wildcard (%), returns an empty list. * - * @param src + * @param source * the source string - * @param cat + * @param catalog * Catalog, if available - * @param quotId - * quoteId as defined on server + * @param quoteId + * quote character as defined on server * @param isNoBslashEscSet - * Is our connection in BackSlashEscape mode + * is our connection in no BackSlashEscape mode * @return the input string with all comment-delimited data removed */ - public static List splitDBdotName(String src, String cat, String quotId, boolean isNoBslashEscSet) { - if ((src == null) || (src.equals("%"))) { - return new ArrayList(); + public static List splitDBdotName(String source, String catalog, String quoteId, boolean isNoBslashEscSet) { + if ((source == null) || (source.equals("%"))) { + return Collections.emptyList(); } - boolean isQuoted = StringUtils.indexOfIgnoreCase(0, src, quotId) > -1; - - String retval = src; - String tmpCat = cat; - //I.e., what if database is named `MyDatabase 1.0.0`... thus trueDotIndex - int trueDotIndex = -1; - if (!" ".equals(quotId)) { - //Presumably, if there is a database name attached and it contains dots, then it should be quoted so we first check for that - if (isQuoted) { - trueDotIndex = StringUtils.indexOfIgnoreCase(0, retval, quotId + "." + quotId); - } else { - // NOT quoted, fetch first DOT - // ex: cStmt = this.conn.prepareCall("{call bug57022.procbug57022(?, ?)}"); - trueDotIndex = StringUtils.indexOfIgnoreCase(0, retval, "."); - } + int dotIndex = -1; + if (" ".equals(quoteId)) { + dotIndex = source.indexOf("."); } else { - trueDotIndex = retval.indexOf("."); + dotIndex = indexOfIgnoreCase(0, source, ".", quoteId, quoteId, isNoBslashEscSet ? SEARCH_MODE__MRK_WS : SEARCH_MODE__BSESC_MRK_WS); } - List retTokens = new ArrayList(2); - - if (trueDotIndex != -1) { - //There is a catalog attached - if (isQuoted) { - tmpCat = StringUtils.toString(StringUtils.stripEnclosure(retval.substring(0, trueDotIndex + 1).getBytes(), quotId, quotId)); - if (StringUtils.startsWithIgnoreCaseAndWs(tmpCat, quotId)) { - tmpCat = tmpCat.substring(1, tmpCat.length() - 1); - } - - retval = retval.substring(trueDotIndex + 2); - retval = StringUtils.toString(StringUtils.stripEnclosure(retval.getBytes(), quotId, quotId)); - } else { - //NOT quoted, adjust indexOf - tmpCat = retval.substring(0, trueDotIndex); - retval = retval.substring(trueDotIndex + 1); - } + String database = catalog; + String entityName; + if (dotIndex != -1) { + database = unQuoteIdentifier(source.substring(0, dotIndex), quoteId); + entityName = unQuoteIdentifier(source.substring(dotIndex + 1), quoteId); } else { - //No catalog attached, strip retval and return - retval = StringUtils.toString(StringUtils.stripEnclosure(retval.getBytes(), quotId, quotId)); + entityName = unQuoteIdentifier(source, quoteId); } - retTokens.add(tmpCat); - retTokens.add(retval); - return retTokens; + return Arrays.asList(database, entityName); } public static boolean isEmptyOrWhitespaceOnly(String str) { @@ -2355,4 +2417,24 @@ return asBytes; } + + /** + * Checks is the CharSequence contains digits only. No leading sign and thousands or decimal separators are allowed. + * + * @param cs + * The CharSequence to check. + * @return + * {@code true} if the CharSequence not empty and contains only digits, {@code false} otherwise. + */ + public static boolean isStrictlyNumeric(CharSequence cs) { + if (cs == null || cs.length() == 0) { + return false; + } + for (int i = 0; i < cs.length(); i++) { + if (!Character.isDigit(cs.charAt(i))) { + return false; + } + } + return true; + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/TimeUtil.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/TimeUtil.java (.../TimeUtil.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/TimeUtil.java (.../TimeUtil.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -283,8 +283,9 @@ final static Time fastTimeCreate(Calendar cal, int hour, int minute, int second, ExceptionInterceptor exceptionInterceptor) throws SQLException { if (hour < 0 || hour > 24) { - throw SQLError.createSQLException("Illegal hour value '" + hour + "' for java.sql.Time type in value '" + timeFormattedString(hour, minute, second) - + ".", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + throw SQLError.createSQLException( + "Illegal hour value '" + hour + "' for java.sql.Time type in value '" + timeFormattedString(hour, minute, second) + ".", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } if (minute < 0 || minute > 59) { @@ -318,8 +319,9 @@ final static Time fastTimeCreate(int hour, int minute, int second, Calendar targetCalendar, ExceptionInterceptor exceptionInterceptor) throws SQLException { if (hour < 0 || hour > 23) { - throw SQLError.createSQLException("Illegal hour value '" + hour + "' for java.sql.Time type in value '" + timeFormattedString(hour, minute, second) - + ".", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + throw SQLError.createSQLException( + "Illegal hour value '" + hour + "' for java.sql.Time type in value '" + timeFormattedString(hour, minute, second) + ".", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } if (minute < 0 || minute > 59) { @@ -521,7 +523,7 @@ private static void loadTimeZoneMappings(ExceptionInterceptor exceptionInterceptor) throws SQLException { timeZoneMappings = new Properties(); try { - timeZoneMappings.load(TimeZone.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE)); + timeZoneMappings.load(TimeUtil.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE)); } catch (IOException e) { throw SQLError.createSQLException(Messages.getString("TimeUtil.LoadTimeZoneMappingError"), SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, exceptionInterceptor); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/TimeZoneMapping.properties =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/TimeZoneMapping.properties (.../TimeZoneMapping.properties) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/TimeZoneMapping.properties (.../TimeZoneMapping.properties) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ #Windows Zones -#Mon Sep 28 16:41:59 WEST 2015 +#Mon Apr 24 23:22:45 WEST 2017 AUS\ Central\ Daylight\ Time=Australia/Darwin AUS\ Central\ Standard\ Time=Australia/Darwin AUS\ Eastern\ Daylight\ Time=Australia/Sydney @@ -8,6 +8,10 @@ Afghanistan\ Standard\ Time=Asia/Kabul Alaskan\ Daylight\ Time=America/Anchorage Alaskan\ Standard\ Time=America/Anchorage +Aleutian\ Daylight\ Time=America/Adak +Aleutian\ Standard\ Time=America/Adak +Altai\ Daylight\ Time=Asia/Barnaul +Altai\ Standard\ Time=Asia/Barnaul Arab\ Daylight\ Time=Asia/Riyadh Arab\ Standard\ Time=Asia/Riyadh Arabian\ Daylight\ Time=Asia/Dubai @@ -16,8 +20,12 @@ Arabic\ Standard\ Time=Asia/Baghdad Argentina\ Daylight\ Time=America/Buenos_Aires Argentina\ Standard\ Time=America/Buenos_Aires +Astrakhan\ Daylight\ Time=Europe/Astrakhan +Astrakhan\ Standard\ Time=Europe/Astrakhan Atlantic\ Daylight\ Time=America/Halifax Atlantic\ Standard\ Time=America/Halifax +Aus\ Central\ W.\ Daylight\ Time=Australia/Eucla +Aus\ Central\ W.\ Standard\ Time=Australia/Eucla Azerbaijan\ Daylight\ Time=Asia/Baku Azerbaijan\ Standard\ Time=Asia/Baku Azores\ Daylight\ Time=Atlantic/Azores @@ -28,6 +36,8 @@ Bangladesh\ Standard\ Time=Asia/Dhaka Belarus\ Daylight\ Time=Europe/Minsk Belarus\ Standard\ Time=Europe/Minsk +Bougainville\ Daylight\ Time=Pacific/Bougainville +Bougainville\ Standard\ Time=Pacific/Bougainville Canada\ Central\ Daylight\ Time=America/Regina Canada\ Central\ Standard\ Time=America/Regina Cape\ Verde\ Daylight\ Time=Atlantic/Cape_Verde @@ -52,16 +62,24 @@ Central\ Pacific\ Standard\ Time=Pacific/Guadalcanal Central\ Standard\ Time=America/Chicago Central\ Standard\ Time\ (Mexico)=America/Mexico_City +Chatham\ Islands\ Daylight\ Time=Pacific/Chatham +Chatham\ Islands\ Standard\ Time=Pacific/Chatham China\ Daylight\ Time=Asia/Shanghai China\ Standard\ Time=Asia/Shanghai +Cuba\ Daylight\ Time=America/Havana +Cuba\ Standard\ Time=America/Havana Dateline\ Daylight\ Time=Etc/GMT+12 Dateline\ Standard\ Time=Etc/GMT+12 E.\ Africa\ Daylight\ Time=Africa/Nairobi E.\ Africa\ Standard\ Time=Africa/Nairobi E.\ Australia\ Daylight\ Time=Australia/Brisbane E.\ Australia\ Standard\ Time=Australia/Brisbane +E.\ Europe\ Daylight\ Time=Europe/Chisinau +E.\ Europe\ Standard\ Time=Europe/Chisinau E.\ South\ America\ Daylight\ Time=America/Sao_Paulo E.\ South\ America\ Standard\ Time=America/Sao_Paulo +Easter\ Island\ Daylight\ Time=Pacific/Easter +Easter\ Island\ Standard\ Time=Pacific/Easter Eastern\ Daylight\ Time=America/New_York Eastern\ Daylight\ Time\ (Mexico)=America/Cancun Eastern\ Standard\ Time=America/New_York @@ -84,6 +102,8 @@ Greenland\ Standard\ Time=America/Godthab Greenwich\ Daylight\ Time=Atlantic/Reykjavik Greenwich\ Standard\ Time=Atlantic/Reykjavik +Haiti\ Daylight\ Time=America/Port-au-Prince +Haiti\ Standard\ Time=America/Port-au-Prince Hawaiian\ Daylight\ Time=Pacific/Honolulu Hawaiian\ Standard\ Time=Pacific/Honolulu India\ Daylight\ Time=Asia/Calcutta @@ -102,8 +122,12 @@ Libya\ Standard\ Time=Africa/Tripoli Line\ Islands\ Daylight\ Time=Pacific/Kiritimati Line\ Islands\ Standard\ Time=Pacific/Kiritimati +Lord\ Howe\ Daylight\ Time=Australia/Lord_Howe +Lord\ Howe\ Standard\ Time=Australia/Lord_Howe Magadan\ Daylight\ Time=Asia/Magadan Magadan\ Standard\ Time=Asia/Magadan +Marquesas\ Daylight\ Time=Pacific/Marquesas +Marquesas\ Standard\ Time=Pacific/Marquesas Mauritius\ Daylight\ Time=Indian/Mauritius Mauritius\ Standard\ Time=Indian/Mauritius Middle\ East\ Daylight\ Time=Asia/Beirut @@ -128,16 +152,22 @@ New\ Zealand\ Standard\ Time=Pacific/Auckland Newfoundland\ Daylight\ Time=America/St_Johns Newfoundland\ Standard\ Time=America/St_Johns +Norfolk\ Daylight\ Time=Pacific/Norfolk +Norfolk\ Standard\ Time=Pacific/Norfolk North\ Asia\ Daylight\ Time=Asia/Krasnoyarsk North\ Asia\ East\ Daylight\ Time=Asia/Irkutsk North\ Asia\ East\ Standard\ Time=Asia/Irkutsk North\ Asia\ Standard\ Time=Asia/Krasnoyarsk +North\ Korea\ Daylight\ Time=Asia/Pyongyang +North\ Korea\ Standard\ Time=Asia/Pyongyang +Omsk\ Daylight\ Time=Asia/Omsk +Omsk\ Standard\ Time=Asia/Omsk Pacific\ Daylight\ Time=America/Los_Angeles -Pacific\ Daylight\ Time\ (Mexico)=America/Santa_Isabel +Pacific\ Daylight\ Time\ (Mexico)=America/Tijuana Pacific\ SA\ Daylight\ Time=America/Santiago Pacific\ SA\ Standard\ Time=America/Santiago Pacific\ Standard\ Time=America/Los_Angeles -Pacific\ Standard\ Time\ (Mexico)=America/Santa_Isabel +Pacific\ Standard\ Time\ (Mexico)=America/Tijuana Pakistan\ Daylight\ Time=Asia/Karachi Pakistan\ Standard\ Time=Asia/Karachi Paraguay\ Daylight\ Time=America/Asuncion @@ -157,6 +187,10 @@ SA\ Western\ Standard\ Time=America/La_Paz SE\ Asia\ Daylight\ Time=Asia/Bangkok SE\ Asia\ Standard\ Time=Asia/Bangkok +Saint\ Pierre\ Daylight\ Time=America/Miquelon +Saint\ Pierre\ Standard\ Time=America/Miquelon +Sakhalin\ Daylight\ Time=Asia/Sakhalin +Sakhalin\ Standard\ Time=Asia/Sakhalin Samoa\ Daylight\ Time=Pacific/Apia Samoa\ Standard\ Time=Pacific/Apia Singapore\ Daylight\ Time=Asia/Singapore @@ -171,19 +205,29 @@ Taipei\ Standard\ Time=Asia/Taipei Tasmania\ Daylight\ Time=Australia/Hobart Tasmania\ Standard\ Time=Australia/Hobart +Tocantins\ Daylight\ Time=America/Araguaina +Tocantins\ Standard\ Time=America/Araguaina Tokyo\ Daylight\ Time=Asia/Tokyo Tokyo\ Standard\ Time=Asia/Tokyo +Tomsk\ Daylight\ Time=Asia/Tomsk +Tomsk\ Standard\ Time=Asia/Tomsk Tonga\ Daylight\ Time=Pacific/Tongatapu Tonga\ Standard\ Time=Pacific/Tongatapu +Transbaikal\ Daylight\ Time=Asia/Chita +Transbaikal\ Standard\ Time=Asia/Chita Turkey\ Daylight\ Time=Europe/Istanbul Turkey\ Standard\ Time=Europe/Istanbul +Turks\ And\ Caicos\ Daylight\ Time=America/Grand_Turk +Turks\ And\ Caicos\ Standard\ Time=America/Grand_Turk US\ Eastern\ Daylight\ Time=America/Indianapolis US\ Eastern\ Standard\ Time=America/Indianapolis US\ Mountain\ Daylight\ Time=America/Phoenix US\ Mountain\ Standard\ Time=America/Phoenix UTC=Etc/GMT UTC+12=Etc/GMT-12 UTC-02=Etc/GMT+2 +UTC-08=Etc/GMT+8 +UTC-09=Etc/GMT+9 UTC-11=Etc/GMT+11 Ulaanbaatar\ Daylight\ Time=Asia/Ulaanbaatar Ulaanbaatar\ Standard\ Time=Asia/Ulaanbaatar @@ -197,14 +241,18 @@ W.\ Central\ Africa\ Standard\ Time=Africa/Lagos W.\ Europe\ Daylight\ Time=Europe/Berlin W.\ Europe\ Standard\ Time=Europe/Berlin +W.\ Mongolia\ Daylight\ Time=Asia/Hovd +W.\ Mongolia\ Standard\ Time=Asia/Hovd West\ Asia\ Daylight\ Time=Asia/Tashkent West\ Asia\ Standard\ Time=Asia/Tashkent +West\ Bank\ Daylight\ Time=Asia/Hebron +West\ Bank\ Standard\ Time=Asia/Hebron West\ Pacific\ Daylight\ Time=Pacific/Port_Moresby West\ Pacific\ Standard\ Time=Pacific/Port_Moresby Yakutsk\ Daylight\ Time=Asia/Yakutsk Yakutsk\ Standard\ Time=Asia/Yakutsk #Linked Time Zones alias -#Mon Sep 28 16:41:59 WEST 2015 +#Mon Apr 24 23:22:45 WEST 2017 Africa/Addis_Ababa=Africa/Nairobi Africa/Asmara=Africa/Nairobi Africa/Asmera=Africa/Nairobi @@ -248,6 +296,7 @@ America/Atka=America/Adak America/Buenos_Aires=America/Argentina/Buenos_Aires America/Catamarca=America/Argentina/Catamarca +America/Cayman=America/Panama America/Coral_Harbour=America/Atikokan America/Cordoba=America/Argentina/Cordoba America/Dominica=America/Port_of_Spain @@ -267,6 +316,7 @@ America/Montserrat=America/Port_of_Spain America/Porto_Acre=America/Rio_Branco America/Rosario=America/Argentina/Cordoba +America/Santa_Isabel=America/Tijuana America/Shiprock=America/Denver America/St_Barthelemy=America/Port_of_Spain America/St_Kitts=America/Port_of_Spain @@ -293,6 +343,7 @@ Asia/Macao=Asia/Macau Asia/Muscat=Asia/Dubai Asia/Phnom_Penh=Asia/Bangkok +Asia/Rangoon=Asia/Yangon Asia/Saigon=Asia/Ho_Chi_Minh Asia/Tel_Aviv=Asia/Jerusalem Asia/Thimbu=Asia/Thimphu @@ -403,129 +454,22 @@ W-SU=Europe/Moscow Zulu=Etc/UTC #Standard (IANA) abbreviations -#Mon Sep 28 16:41:59 WEST 2015 -ACWST=Australia/Eucla -AFT=Asia/Kabul -ALMT=Asia/Almaty -ANAT=Asia/Anadyr -AZOST=Atlantic/Azores -AZOT=Atlantic/Azores -AZST=Asia/Baku -AZT=Asia/Baku -BDT=Asia/Dhaka -BNT=Asia/Brunei -BOT=America/La_Paz -BRST=America/Sao_Paulo -BTT=Asia/Thimphu +#Mon Apr 24 23:22:45 WEST 2017 +AWST=Australia/Perth +BST=Europe/London CAT=Africa/Maputo -CCT=Indian/Cocos -CHADT=Pacific/Chatham -CHAST=Pacific/Chatham -CHOST=Asia/Choibalsan -CHOT=Asia/Choibalsan -CHUT=Pacific/Chuuk -CKT=Pacific/Rarotonga -COT=America/Bogota -CVT=Atlantic/Cape_Verde -CXT=Indian/Christmas ChST=Pacific/Guam -DAVT=Antarctica/Davis -DDUT=Antarctica/DumontDUrville -EAST=Pacific/Easter -ECT=America/Guayaquil -EGST=America/Scoresbysund -EGT=America/Scoresbysund -FJST=Pacific/Fiji -FJT=Pacific/Fiji -FKST=Atlantic/Stanley -FNT=America/Noronha -GALT=Pacific/Galapagos -GAMT=Pacific/Gambier -GET=Asia/Tbilisi -GFT=America/Cayenne -GILT=Pacific/Tarawa -GYT=America/Guyana HDT=America/Adak HKT=Asia/Hong_Kong -HOVST=Asia/Hovd -HOVT=Asia/Hovd IDT=Asia/Jerusalem -IOT=Indian/Chagos -IRST=Asia/Tehran JST=Asia/Tokyo -KGT=Asia/Bishkek -KOST=Pacific/Kosrae -LHDT=Australia/Lord_Howe -LHST=Australia/Lord_Howe -LINT=Pacific/Kiritimati -MAGT=Asia/Magadan -MART=Pacific/Marquesas -MAWT=Antarctica/Mawson -MEST=MET -MET=MET -MIST=Antarctica/Macquarie -MMT=Asia/Rangoon -MUT=Indian/Mauritius -MVT=Indian/Maldives -NCT=Pacific/Noumea NDT=America/St_Johns -NFT=Pacific/Norfolk -NOVT=Asia/Novosibirsk -NPT=Asia/Kathmandu -NRT=Pacific/Nauru NST=America/St_Johns -NUT=Pacific/Niue NZDT=Pacific/Auckland NZST=Pacific/Auckland -OMST=Asia/Omsk -ORAT=Asia/Oral -PET=America/Lima -PETT=Asia/Kamchatka -PGT=Pacific/Port_Moresby -PHOT=Pacific/Enderbury -PHT=Asia/Manila PKT=Asia/Karachi -PMDT=America/Miquelon -PMST=America/Miquelon -PONT=Pacific/Pohnpei -PWT=Pacific/Palau -PYST=America/Asuncion -PYT=America/Asuncion -QYZT=Asia/Qyzylorda -RET=Indian/Reunion -ROTT=Antarctica/Rothera -SAKT=Asia/Sakhalin -SAMT=Europe/Samara SAST=Africa/Johannesburg -SBT=Pacific/Guadalcanal -SCT=Indian/Mahe -SGT=Asia/Singapore -SRET=Asia/Srednekolymsk -SRT=America/Paramaribo SST=Pacific/Pago_Pago -SYOT=Antarctica/Syowa -TAHT=Pacific/Tahiti -TFT=Indian/Kerguelen -TJT=Asia/Dushanbe -TKT=Pacific/Fakaofo -TLT=Asia/Dili -TMT=Asia/Ashgabat -TOT=Pacific/Tongatapu -TVT=Pacific/Funafuti -ULAST=Asia/Ulaanbaatar -ULAT=Asia/Ulaanbaatar -UYT=America/Montevideo -VET=America/Caracas -VOST=Antarctica/Vostok -VUT=Pacific/Efate -WAKT=Pacific/Wake WAST=Africa/Windhoek -WFT=Pacific/Wallis -WGST=America/Godthab -WGT=America/Godthab WIT=Asia/Jayapura WITA=Asia/Makassar -WSDT=Pacific/Apia -WSST=Pacific/Apia -XJT=Asia/Urumqi -YEKT=Asia/Yekaterinburg Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/UpdatableResultSet.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/UpdatableResultSet.java (.../UpdatableResultSet.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/UpdatableResultSet.java (.../UpdatableResultSet.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -145,7 +145,7 @@ * set type is TYPE_FORWARD_ONLY. */ @Override - public synchronized boolean absolute(int row) throws SQLException { + public boolean absolute(int row) throws SQLException { return super.absolute(row); } @@ -161,7 +161,7 @@ * TYPE_FORWARD_ONLY. */ @Override - public synchronized void afterLast() throws SQLException { + public void afterLast() throws SQLException { super.afterLast(); } @@ -177,7 +177,7 @@ * TYPE_FORWARD_ONLY */ @Override - public synchronized void beforeFirst() throws SQLException { + public void beforeFirst() throws SQLException { super.beforeFirst(); } @@ -192,12 +192,12 @@ * the insert row. */ @Override - public synchronized void cancelRowUpdates() throws SQLException { - checkClosed(); - - if (this.doingUpdates) { - this.doingUpdates = false; - this.updater.clearParameters(); + public void cancelRowUpdates() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (this.doingUpdates) { + this.doingUpdates = false; + this.updater.clearParameters(); + } } } @@ -207,11 +207,11 @@ * @see com.mysql.jdbc.ResultSet#checkRowPos() */ @Override - protected synchronized void checkRowPos() throws SQLException { - checkClosed(); - - if (!this.onInsertRow) { - super.checkRowPos(); + protected void checkRowPos() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + super.checkRowPos(); + } } } @@ -420,56 +420,54 @@ * if the ResultSet is not updatable or some other error occurs */ @Override - public synchronized void deleteRow() throws SQLException { - checkClosed(); + public void deleteRow() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.isUpdatable) { + throw new NotUpdatable(this.notUpdatableReason); + } - if (!this.isUpdatable) { - throw new NotUpdatable(this.notUpdatableReason); - } + if (this.onInsertRow) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.1"), getExceptionInterceptor()); + } else if (this.rowData.size() == 0) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.2"), getExceptionInterceptor()); + } else if (isBeforeFirst()) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.3"), getExceptionInterceptor()); + } else if (isAfterLast()) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.4"), getExceptionInterceptor()); + } - if (this.onInsertRow) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.1"), getExceptionInterceptor()); - } else if (this.rowData.size() == 0) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.2"), getExceptionInterceptor()); - } else if (isBeforeFirst()) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.3"), getExceptionInterceptor()); - } else if (isAfterLast()) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.4"), getExceptionInterceptor()); - } + if (this.deleter == null) { + if (this.deleteSQL == null) { + generateStatements(); + } - if (this.deleter == null) { - if (this.deleteSQL == null) { - generateStatements(); + this.deleter = (PreparedStatement) this.connection.clientPrepareStatement(this.deleteSQL); } - this.deleter = (PreparedStatement) this.connection.clientPrepareStatement(this.deleteSQL); - } + this.deleter.clearParameters(); - this.deleter.clearParameters(); + int numKeys = this.primaryKeyIndicies.size(); - int numKeys = this.primaryKeyIndicies.size(); + if (numKeys == 1) { + int index = this.primaryKeyIndicies.get(0).intValue(); + this.setParamValue(this.deleter, 1, this.thisRow, index, this.fields[index].getSQLType()); + } else { + for (int i = 0; i < numKeys; i++) { + int index = this.primaryKeyIndicies.get(i).intValue(); + this.setParamValue(this.deleter, i + 1, this.thisRow, index, this.fields[index].getSQLType()); - if (numKeys == 1) { - int index = this.primaryKeyIndicies.get(0).intValue(); - this.setParamValue(this.deleter, 1, this.thisRow, index, this.fields[index].getSQLType()); - } else { - for (int i = 0; i < numKeys; i++) { - int index = this.primaryKeyIndicies.get(i).intValue(); - this.setParamValue(this.deleter, i + 1, this.thisRow, index, this.fields[index].getSQLType()); - + } } - } - this.deleter.executeUpdate(); - this.rowData.removeRow(this.rowData.getCurrentRowNumber()); + this.deleter.executeUpdate(); + this.rowData.removeRow(this.rowData.getCurrentRowNumber()); - // position on previous row - Bug#27431 - previous(); - + // position on previous row - Bug#27431 + previous(); + } } - private synchronized void setParamValue(PreparedStatement ps, int psIdx, ResultSetRow row, int rsIdx, int sqlType) throws SQLException { - + private void setParamValue(PreparedStatement ps, int psIdx, ResultSetRow row, int rsIdx, int sqlType) throws SQLException { byte[] val = row.getColumnValue(rsIdx); if (val == null) { ps.setNull(psIdx, Types.NULL); @@ -521,7 +519,7 @@ } - private synchronized void extractDefaultValues() throws SQLException { + private void extractDefaultValues() throws SQLException { java.sql.DatabaseMetaData dbmd = this.connection.getMetaData(); this.defaultColumnValue = new byte[this.fields.length][]; @@ -571,7 +569,7 @@ * TYPE_FORWARD_ONLY. */ @Override - public synchronized boolean first() throws SQLException { + public boolean first() throws SQLException { return super.first(); } @@ -582,7 +580,7 @@ * @throws SQLException * @throws NotUpdatable */ - protected synchronized void generateStatements() throws SQLException { + protected void generateStatements() throws SQLException { if (!this.isUpdatable) { this.doingUpdates = false; this.onInsertRow = false; @@ -782,7 +780,7 @@ return nameToIndex; } - private synchronized SingleByteCharsetConverter getCharConverter() throws SQLException { + private SingleByteCharsetConverter getCharConverter() throws SQLException { if (!this.initializedCharConverter) { this.initializedCharConverter = true; @@ -806,10 +804,12 @@ */ @Override public int getConcurrency() throws SQLException { - return (this.isUpdatable ? CONCUR_UPDATABLE : CONCUR_READ_ONLY); + synchronized (checkClosed().getConnectionMutex()) { + return (this.isUpdatable ? CONCUR_UPDATABLE : CONCUR_READ_ONLY); + } } - private synchronized String getQuotedIdChar() throws SQLException { + private String getQuotedIdChar() throws SQLException { if (this.quotedIdChar == null) { boolean useQuotedIdentifiers = this.connection.supportsQuotedIdentifiers(); @@ -834,41 +834,41 @@ * insert row have not been given a value */ @Override - public synchronized void insertRow() throws SQLException { - checkClosed(); + public void insertRow() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.7"), getExceptionInterceptor()); + } - if (!this.onInsertRow) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.7"), getExceptionInterceptor()); - } + this.inserter.executeUpdate(); - this.inserter.executeUpdate(); + long autoIncrementId = this.inserter.getLastInsertID(); + int numFields = this.fields.length; + byte[][] newRow = new byte[numFields][]; - long autoIncrementId = this.inserter.getLastInsertID(); - int numFields = this.fields.length; - byte[][] newRow = new byte[numFields][]; + for (int i = 0; i < numFields; i++) { + if (this.inserter.isNull(i)) { + newRow[i] = null; + } else { + newRow[i] = this.inserter.getBytesRepresentation(i); + } - for (int i = 0; i < numFields; i++) { - if (this.inserter.isNull(i)) { - newRow[i] = null; - } else { - newRow[i] = this.inserter.getBytesRepresentation(i); + // + // WARN: This non-variant only holds if MySQL never allows more than one auto-increment key (which is the way it is _today_) + // + if (this.fields[i].isAutoIncrement() && autoIncrementId > 0) { + newRow[i] = StringUtils.getBytes(String.valueOf(autoIncrementId)); + this.inserter.setBytesNoEscapeNoQuotes(i + 1, newRow[i]); + } } - // - // WARN: This non-variant only holds if MySQL never allows more than one auto-increment key (which is the way it is _today_) - // - if (this.fields[i].isAutoIncrement() && autoIncrementId > 0) { - newRow[i] = StringUtils.getBytes(String.valueOf(autoIncrementId)); - this.inserter.setBytesNoEscapeNoQuotes(i + 1, newRow[i]); - } - } + ResultSetRow resultSetRow = new ByteArrayRow(newRow, getExceptionInterceptor()); - ResultSetRow resultSetRow = new ByteArrayRow(newRow, getExceptionInterceptor()); + refreshRow(this.inserter, resultSetRow); - refreshRow(this.inserter, resultSetRow); - - this.rowData.addRow(resultSetRow); - resetInserter(); + this.rowData.addRow(resultSetRow); + resetInserter(); + } } /** @@ -885,7 +885,7 @@ * if a database-access error occurs. */ @Override - public synchronized boolean isAfterLast() throws SQLException { + public boolean isAfterLast() throws SQLException { return super.isAfterLast(); } @@ -903,7 +903,7 @@ * if a database-access error occurs. */ @Override - public synchronized boolean isBeforeFirst() throws SQLException { + public boolean isBeforeFirst() throws SQLException { return super.isBeforeFirst(); } @@ -920,7 +920,7 @@ * if a database-access error occurs. */ @Override - public synchronized boolean isFirst() throws SQLException { + public boolean isFirst() throws SQLException { return super.isFirst(); } @@ -938,7 +938,7 @@ * if a database-access error occurs. */ @Override - public synchronized boolean isLast() throws SQLException { + public boolean isLast() throws SQLException { return super.isLast(); } @@ -960,7 +960,7 @@ * TYPE_FORWARD_ONLY. */ @Override - public synchronized boolean last() throws SQLException { + public boolean last() throws SQLException { return super.last(); } @@ -975,17 +975,17 @@ * if the ResultSet is not updatable or some other error occurs */ @Override - public synchronized void moveToCurrentRow() throws SQLException { - checkClosed(); + public void moveToCurrentRow() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.isUpdatable) { + throw new NotUpdatable(this.notUpdatableReason); + } - if (!this.isUpdatable) { - throw new NotUpdatable(this.notUpdatableReason); + if (this.onInsertRow) { + this.onInsertRow = false; + this.thisRow = this.savedCurrentRow; + } } - - if (this.onInsertRow) { - this.onInsertRow = false; - this.thisRow = this.savedCurrentRow; - } } /** @@ -1005,71 +1005,75 @@ * @throws NotUpdatable */ @Override - public synchronized void moveToInsertRow() throws SQLException { - checkClosed(); + public void moveToInsertRow() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.isUpdatable) { + throw new NotUpdatable(this.notUpdatableReason); + } - if (!this.isUpdatable) { - throw new NotUpdatable(this.notUpdatableReason); - } + if (this.inserter == null) { + if (this.insertSQL == null) { + generateStatements(); + } - if (this.inserter == null) { - if (this.insertSQL == null) { - generateStatements(); - } + this.inserter = (PreparedStatement) this.connection.clientPrepareStatement(this.insertSQL); + if (this.populateInserterWithDefaultValues) { + extractDefaultValues(); + } - this.inserter = (PreparedStatement) this.connection.clientPrepareStatement(this.insertSQL); - if (this.populateInserterWithDefaultValues) { - extractDefaultValues(); + resetInserter(); + } else { + resetInserter(); } - resetInserter(); - } else { - resetInserter(); - } + int numFields = this.fields.length; - int numFields = this.fields.length; + this.onInsertRow = true; + this.doingUpdates = false; + this.savedCurrentRow = this.thisRow; + byte[][] newRowData = new byte[numFields][]; + this.thisRow = new ByteArrayRow(newRowData, getExceptionInterceptor()); + this.thisRow.setMetadata(this.fields); - this.onInsertRow = true; - this.doingUpdates = false; - this.savedCurrentRow = this.thisRow; - byte[][] newRowData = new byte[numFields][]; - this.thisRow = new ByteArrayRow(newRowData, getExceptionInterceptor()); + for (int i = 0; i < numFields; i++) { + if (!this.populateInserterWithDefaultValues) { + this.inserter.setBytesNoEscapeNoQuotes(i + 1, StringUtils.getBytes("DEFAULT")); + newRowData = null; + } else { + if (this.defaultColumnValue[i] != null) { + Field f = this.fields[i]; - for (int i = 0; i < numFields; i++) { - if (!this.populateInserterWithDefaultValues) { - this.inserter.setBytesNoEscapeNoQuotes(i + 1, StringUtils.getBytes("DEFAULT")); - newRowData = null; - } else { - if (this.defaultColumnValue[i] != null) { - Field f = this.fields[i]; + switch (f.getMysqlType()) { + case MysqlDefs.FIELD_TYPE_DATE: + case MysqlDefs.FIELD_TYPE_DATETIME: + case MysqlDefs.FIELD_TYPE_NEWDATE: + case MysqlDefs.FIELD_TYPE_TIME: + case MysqlDefs.FIELD_TYPE_TIMESTAMP: - switch (f.getMysqlType()) { - case MysqlDefs.FIELD_TYPE_DATE: - case MysqlDefs.FIELD_TYPE_DATETIME: - case MysqlDefs.FIELD_TYPE_NEWDATE: - case MysqlDefs.FIELD_TYPE_TIME: - case MysqlDefs.FIELD_TYPE_TIMESTAMP: + if (this.defaultColumnValue[i].length > 7 && this.defaultColumnValue[i][0] == (byte) 'C' + && this.defaultColumnValue[i][1] == (byte) 'U' && this.defaultColumnValue[i][2] == (byte) 'R' + && this.defaultColumnValue[i][3] == (byte) 'R' && this.defaultColumnValue[i][4] == (byte) 'E' + && this.defaultColumnValue[i][5] == (byte) 'N' && this.defaultColumnValue[i][6] == (byte) 'T' + && this.defaultColumnValue[i][7] == (byte) '_') { + this.inserter.setBytesNoEscapeNoQuotes(i + 1, this.defaultColumnValue[i]); - if (this.defaultColumnValue[i].length > 7 && this.defaultColumnValue[i][0] == (byte) 'C' - && this.defaultColumnValue[i][1] == (byte) 'U' && this.defaultColumnValue[i][2] == (byte) 'R' - && this.defaultColumnValue[i][3] == (byte) 'R' && this.defaultColumnValue[i][4] == (byte) 'E' - && this.defaultColumnValue[i][5] == (byte) 'N' && this.defaultColumnValue[i][6] == (byte) 'T' - && this.defaultColumnValue[i][7] == (byte) '_') { - this.inserter.setBytesNoEscapeNoQuotes(i + 1, this.defaultColumnValue[i]); - + break; + } + this.inserter.setBytes(i + 1, this.defaultColumnValue[i], false, false); break; - } - default: - this.inserter.setBytes(i + 1, this.defaultColumnValue[i], false, false); - } - // This value _could_ be changed from a getBytes(), so we need a copy.... - byte[] defaultValueCopy = new byte[this.defaultColumnValue[i].length]; - System.arraycopy(this.defaultColumnValue[i], 0, defaultValueCopy, 0, defaultValueCopy.length); - newRowData[i] = defaultValueCopy; - } else { - this.inserter.setNull(i + 1, java.sql.Types.NULL); - newRowData[i] = null; + default: + this.inserter.setBytes(i + 1, this.defaultColumnValue[i], false, false); + } + + // This value _could_ be changed from a getBytes(), so we need a copy.... + byte[] defaultValueCopy = new byte[this.defaultColumnValue[i].length]; + System.arraycopy(this.defaultColumnValue[i], 0, defaultValueCopy, 0, defaultValueCopy.length); + newRowData[i] = defaultValueCopy; + } else { + this.inserter.setNull(i + 1, java.sql.Types.NULL); + newRowData[i] = null; + } } } } @@ -1094,7 +1098,7 @@ * if a database access error occurs */ @Override - public synchronized boolean next() throws SQLException { + public boolean next() throws SQLException { return super.next(); } @@ -1113,7 +1117,7 @@ * if a database access error occurs */ @Override - public synchronized boolean prev() throws SQLException { + public boolean prev() throws SQLException { return super.prev(); } @@ -1135,7 +1139,7 @@ * TYPE_FORWAR_DONLY. */ @Override - public synchronized boolean previous() throws SQLException { + public boolean previous() throws SQLException { return super.previous(); } @@ -1150,61 +1154,66 @@ * if an error occurs. */ @Override - public synchronized void realClose(boolean calledExplicitly) throws SQLException { - if (this.isClosed) { - return; + public void realClose(boolean calledExplicitly) throws SQLException { + MySQLConnection locallyScopedConn = this.connection; + + if (locallyScopedConn == null) { + return; // already closed } - SQLException sqlEx = null; + synchronized (checkClosed().getConnectionMutex()) { + SQLException sqlEx = null; - if (this.useUsageAdvisor) { - if ((this.deleter == null) && (this.inserter == null) && (this.refresher == null) && (this.updater == null)) { - this.eventSink = ProfilerEventHandlerFactory.getInstance(this.connection); + if (this.useUsageAdvisor) { + if ((this.deleter == null) && (this.inserter == null) && (this.refresher == null) && (this.updater == null)) { + this.eventSink = ProfilerEventHandlerFactory.getInstance(this.connection); - String message = Messages.getString("UpdatableResultSet.34"); + String message = Messages.getString("UpdatableResultSet.34"); - this.eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", (this.owningStatement == null) ? "N/A" - : this.owningStatement.currentCatalog, this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), - this.resultId, System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, message)); + this.eventSink.consumeEvent( + new ProfilerEvent(ProfilerEvent.TYPE_WARN, "", (this.owningStatement == null) ? "N/A" : this.owningStatement.currentCatalog, + this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), this.resultId, + System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, message)); + } } - } - try { - if (this.deleter != null) { - this.deleter.close(); + try { + if (this.deleter != null) { + this.deleter.close(); + } + } catch (SQLException ex) { + sqlEx = ex; } - } catch (SQLException ex) { - sqlEx = ex; - } - try { - if (this.inserter != null) { - this.inserter.close(); + try { + if (this.inserter != null) { + this.inserter.close(); + } + } catch (SQLException ex) { + sqlEx = ex; } - } catch (SQLException ex) { - sqlEx = ex; - } - try { - if (this.refresher != null) { - this.refresher.close(); + try { + if (this.refresher != null) { + this.refresher.close(); + } + } catch (SQLException ex) { + sqlEx = ex; } - } catch (SQLException ex) { - sqlEx = ex; - } - try { - if (this.updater != null) { - this.updater.close(); + try { + if (this.updater != null) { + this.updater.close(); + } + } catch (SQLException ex) { + sqlEx = ex; } - } catch (SQLException ex) { - sqlEx = ex; - } - super.realClose(calledExplicitly); + super.realClose(calledExplicitly); - if (sqlEx != null) { - throw sqlEx; + if (sqlEx != null) { + throw sqlEx; + } } } @@ -1228,27 +1237,27 @@ * @throws NotUpdatable */ @Override - public synchronized void refreshRow() throws SQLException { - checkClosed(); + public void refreshRow() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.isUpdatable) { + throw new NotUpdatable(); + } - if (!this.isUpdatable) { - throw new NotUpdatable(); - } + if (this.onInsertRow) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.8"), getExceptionInterceptor()); + } else if (this.rowData.size() == 0) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.9"), getExceptionInterceptor()); + } else if (isBeforeFirst()) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.10"), getExceptionInterceptor()); + } else if (isAfterLast()) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.11"), getExceptionInterceptor()); + } - if (this.onInsertRow) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.8"), getExceptionInterceptor()); - } else if (this.rowData.size() == 0) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.9"), getExceptionInterceptor()); - } else if (isBeforeFirst()) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.10"), getExceptionInterceptor()); - } else if (isAfterLast()) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.11"), getExceptionInterceptor()); + refreshRow(this.updater, this.thisRow); } - - refreshRow(this.updater, this.thisRow); } - private synchronized void refreshRow(PreparedStatement updateInsertStmt, ResultSetRow rowToRefresh) throws SQLException { + private void refreshRow(PreparedStatement updateInsertStmt, ResultSetRow rowToRefresh) throws SQLException { if (this.refresher == null) { if (this.refreshSQL == null) { generateStatements(); @@ -1359,7 +1368,7 @@ * row, or result set type is TYPE_FORWARD_ONLY. */ @Override - public synchronized boolean relative(int rows) throws SQLException { + public boolean relative(int rows) throws SQLException { return super.relative(rows); } @@ -1386,7 +1395,7 @@ * @see DatabaseMetaData#deletesAreDetected */ @Override - public synchronized boolean rowDeleted() throws SQLException { + public boolean rowDeleted() throws SQLException { throw SQLError.createSQLFeatureNotSupportedException(); } @@ -1404,7 +1413,7 @@ * @see DatabaseMetaData#insertsAreDetected */ @Override - public synchronized boolean rowInserted() throws SQLException { + public boolean rowInserted() throws SQLException { throw SQLError.createSQLFeatureNotSupportedException(); } @@ -1422,7 +1431,7 @@ * @see DatabaseMetaData#updatesAreDetected */ @Override - public synchronized boolean rowUpdated() throws SQLException { + public boolean rowUpdated() throws SQLException { throw SQLError.createSQLFeatureNotSupportedException(); } @@ -1457,7 +1466,7 @@ * * @throws SQLException */ - protected synchronized void syncUpdate() throws SQLException { + protected void syncUpdate() throws SQLException { if (this.updater == null) { if (this.updateSQL == null) { generateStatements(); @@ -1513,17 +1522,19 @@ * if a database-access error occurs */ @Override - public synchronized void updateAsciiStream(int columnIndex, java.io.InputStream x, int length) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateAsciiStream(int columnIndex, java.io.InputStream x, int length) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setAsciiStream(columnIndex, x, length); - } else { - this.inserter.setAsciiStream(columnIndex, x, length); - this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); + this.updater.setAsciiStream(columnIndex, x, length); + } else { + this.inserter.setAsciiStream(columnIndex, x, length); + this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); + } } } @@ -1545,7 +1556,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateAsciiStream(String columnName, java.io.InputStream x, int length) throws SQLException { + public void updateAsciiStream(String columnName, java.io.InputStream x, int length) throws SQLException { updateAsciiStream(findColumn(columnName), x, length); } @@ -1564,21 +1575,23 @@ * if a database-access error occurs */ @Override - public synchronized void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setBigDecimal(columnIndex, x); - } else { - this.inserter.setBigDecimal(columnIndex, x); - - if (x == null) { - this.thisRow.setColumnValue(columnIndex - 1, null); + this.updater.setBigDecimal(columnIndex, x); } else { - this.thisRow.setColumnValue(columnIndex - 1, StringUtils.getBytes(x.toString())); + this.inserter.setBigDecimal(columnIndex, x); + + if (x == null) { + this.thisRow.setColumnValue(columnIndex - 1, null); + } else { + this.thisRow.setColumnValue(columnIndex - 1, StringUtils.getBytes(x.toString())); + } } } } @@ -1598,7 +1611,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateBigDecimal(String columnName, BigDecimal x) throws SQLException { + public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException { updateBigDecimal(findColumn(columnName), x); } @@ -1620,21 +1633,23 @@ * if a database-access error occurs */ @Override - public synchronized void updateBinaryStream(int columnIndex, java.io.InputStream x, int length) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateBinaryStream(int columnIndex, java.io.InputStream x, int length) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setBinaryStream(columnIndex, x, length); - } else { - this.inserter.setBinaryStream(columnIndex, x, length); - - if (x == null) { - this.thisRow.setColumnValue(columnIndex - 1, null); + this.updater.setBinaryStream(columnIndex, x, length); } else { - this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); + this.inserter.setBinaryStream(columnIndex, x, length); + + if (x == null) { + this.thisRow.setColumnValue(columnIndex - 1, null); + } else { + this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); + } } } } @@ -1657,29 +1672,31 @@ * if a database-access error occurs */ @Override - public synchronized void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException { + public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException { updateBinaryStream(findColumn(columnName), x, length); } /** * @see ResultSetInternalMethods#updateBlob(int, Blob) */ @Override - public synchronized void updateBlob(int columnIndex, java.sql.Blob blob) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateBlob(int columnIndex, java.sql.Blob blob) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setBlob(columnIndex, blob); - } else { - this.inserter.setBlob(columnIndex, blob); - - if (blob == null) { - this.thisRow.setColumnValue(columnIndex - 1, null); + this.updater.setBlob(columnIndex, blob); } else { - this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); + this.inserter.setBlob(columnIndex, blob); + + if (blob == null) { + this.thisRow.setColumnValue(columnIndex - 1, null); + } else { + this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); + } } } } @@ -1688,7 +1705,7 @@ * @see ResultSetInternalMethods#updateBlob(String, Blob) */ @Override - public synchronized void updateBlob(String columnName, java.sql.Blob blob) throws SQLException { + public void updateBlob(String columnName, java.sql.Blob blob) throws SQLException { updateBlob(findColumn(columnName), blob); } @@ -1707,18 +1724,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateBoolean(int columnIndex, boolean x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setBoolean(columnIndex, x); - } else { - this.inserter.setBoolean(columnIndex, x); + this.updater.setBoolean(columnIndex, x); + } else { + this.inserter.setBoolean(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -1737,7 +1756,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateBoolean(String columnName, boolean x) throws SQLException { + public void updateBoolean(String columnName, boolean x) throws SQLException { updateBoolean(findColumn(columnName), x); } @@ -1756,18 +1775,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateByte(int columnIndex, byte x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateByte(int columnIndex, byte x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setByte(columnIndex, x); - } else { - this.inserter.setByte(columnIndex, x); + this.updater.setByte(columnIndex, x); + } else { + this.inserter.setByte(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -1786,7 +1807,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateByte(String columnName, byte x) throws SQLException { + public void updateByte(String columnName, byte x) throws SQLException { updateByte(findColumn(columnName), x); } @@ -1805,18 +1826,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateBytes(int columnIndex, byte[] x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateBytes(int columnIndex, byte[] x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setBytes(columnIndex, x); - } else { - this.inserter.setBytes(columnIndex, x); + this.updater.setBytes(columnIndex, x); + } else { + this.inserter.setBytes(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, x); + this.thisRow.setColumnValue(columnIndex - 1, x); + } } } @@ -1835,7 +1858,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateBytes(String columnName, byte[] x) throws SQLException { + public void updateBytes(String columnName, byte[] x) throws SQLException { updateBytes(findColumn(columnName), x); } @@ -1857,21 +1880,23 @@ * if a database-access error occurs */ @Override - public synchronized void updateCharacterStream(int columnIndex, java.io.Reader x, int length) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateCharacterStream(int columnIndex, java.io.Reader x, int length) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setCharacterStream(columnIndex, x, length); - } else { - this.inserter.setCharacterStream(columnIndex, x, length); - - if (x == null) { - this.thisRow.setColumnValue(columnIndex - 1, null); + this.updater.setCharacterStream(columnIndex, x, length); } else { - this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); + this.inserter.setCharacterStream(columnIndex, x, length); + + if (x == null) { + this.thisRow.setColumnValue(columnIndex - 1, null); + } else { + this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); + } } } } @@ -1894,7 +1919,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateCharacterStream(String columnName, java.io.Reader reader, int length) throws SQLException { + public void updateCharacterStream(String columnName, java.io.Reader reader, int length) throws SQLException { updateCharacterStream(findColumn(columnName), reader, length); } @@ -1903,10 +1928,12 @@ */ @Override public void updateClob(int columnIndex, java.sql.Clob clob) throws SQLException { - if (clob == null) { - updateNull(columnIndex); - } else { - updateCharacterStream(columnIndex, clob.getCharacterStream(), (int) clob.length()); + synchronized (checkClosed().getConnectionMutex()) { + if (clob == null) { + updateNull(columnIndex); + } else { + updateCharacterStream(columnIndex, clob.getCharacterStream(), (int) clob.length()); + } } } @@ -1925,18 +1952,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateDate(int columnIndex, java.sql.Date x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateDate(int columnIndex, java.sql.Date x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setDate(columnIndex, x); - } else { - this.inserter.setDate(columnIndex, x); + this.updater.setDate(columnIndex, x); + } else { + this.inserter.setDate(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -1955,7 +1984,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateDate(String columnName, java.sql.Date x) throws SQLException { + public void updateDate(String columnName, java.sql.Date x) throws SQLException { updateDate(findColumn(columnName), x); } @@ -1974,18 +2003,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateDouble(int columnIndex, double x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateDouble(int columnIndex, double x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setDouble(columnIndex, x); - } else { - this.inserter.setDouble(columnIndex, x); + this.updater.setDouble(columnIndex, x); + } else { + this.inserter.setDouble(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -2004,7 +2035,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateDouble(String columnName, double x) throws SQLException { + public void updateDouble(String columnName, double x) throws SQLException { updateDouble(findColumn(columnName), x); } @@ -2023,18 +2054,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateFloat(int columnIndex, float x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateFloat(int columnIndex, float x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setFloat(columnIndex, x); - } else { - this.inserter.setFloat(columnIndex, x); + this.updater.setFloat(columnIndex, x); + } else { + this.inserter.setFloat(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -2053,7 +2086,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateFloat(String columnName, float x) throws SQLException { + public void updateFloat(String columnName, float x) throws SQLException { updateFloat(findColumn(columnName), x); } @@ -2072,18 +2105,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateInt(int columnIndex, int x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateInt(int columnIndex, int x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setInt(columnIndex, x); - } else { - this.inserter.setInt(columnIndex, x); + this.updater.setInt(columnIndex, x); + } else { + this.inserter.setInt(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -2102,7 +2137,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateInt(String columnName, int x) throws SQLException { + public void updateInt(String columnName, int x) throws SQLException { updateInt(findColumn(columnName), x); } @@ -2121,18 +2156,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateLong(int columnIndex, long x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateLong(int columnIndex, long x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setLong(columnIndex, x); - } else { - this.inserter.setLong(columnIndex, x); + this.updater.setLong(columnIndex, x); + } else { + this.inserter.setLong(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -2151,7 +2188,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateLong(String columnName, long x) throws SQLException { + public void updateLong(String columnName, long x) throws SQLException { updateLong(findColumn(columnName), x); } @@ -2168,18 +2205,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateNull(int columnIndex) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateNull(int columnIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setNull(columnIndex, 0); - } else { - this.inserter.setNull(columnIndex, 0); + this.updater.setNull(columnIndex, 0); + } else { + this.inserter.setNull(columnIndex, 0); - this.thisRow.setColumnValue(columnIndex - 1, null); + this.thisRow.setColumnValue(columnIndex - 1, null); + } } } @@ -2196,7 +2235,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateNull(String columnName) throws SQLException { + public void updateNull(String columnName) throws SQLException { updateNull(findColumn(columnName)); } @@ -2215,7 +2254,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateObject(int columnIndex, Object x) throws SQLException { + public void updateObject(int columnIndex, Object x) throws SQLException { updateObjectInternal(columnIndex, x, null, 0); } @@ -2238,7 +2277,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateObject(int columnIndex, Object x, int scale) throws SQLException { + public void updateObject(int columnIndex, Object x, int scale) throws SQLException { updateObjectInternal(columnIndex, x, null, scale); } @@ -2252,26 +2291,28 @@ * @param scaleOrLength * @throws SQLException */ - protected synchronized void updateObjectInternal(int columnIndex, Object x, Integer targetType, int scaleOrLength) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + protected void updateObjectInternal(int columnIndex, Object x, Integer targetType, int scaleOrLength) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - if (targetType == null) { - this.updater.setObject(columnIndex, x); + if (targetType == null) { + this.updater.setObject(columnIndex, x); + } else { + this.updater.setObject(columnIndex, x, targetType); + } } else { - this.updater.setObject(columnIndex, x, targetType); - } - } else { - if (targetType == null) { - this.inserter.setObject(columnIndex, x); - } else { - this.inserter.setObject(columnIndex, x, targetType); - } + if (targetType == null) { + this.inserter.setObject(columnIndex, x); + } else { + this.inserter.setObject(columnIndex, x, targetType); + } - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -2290,7 +2331,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateObject(String columnName, Object x) throws SQLException { + public void updateObject(String columnName, Object x) throws SQLException { updateObject(findColumn(columnName), x); } @@ -2313,7 +2354,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateObject(String columnName, Object x, int scale) throws SQLException { + public void updateObject(String columnName, Object x, int scale) throws SQLException { updateObject(findColumn(columnName), x); } @@ -2327,23 +2368,25 @@ * @throws NotUpdatable */ @Override - public synchronized void updateRow() throws SQLException { - if (!this.isUpdatable) { - throw new NotUpdatable(this.notUpdatableReason); - } + public void updateRow() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.isUpdatable) { + throw new NotUpdatable(this.notUpdatableReason); + } - if (this.doingUpdates) { - this.updater.executeUpdate(); - refreshRow(); - this.doingUpdates = false; - } else if (this.onInsertRow) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.44"), getExceptionInterceptor()); - } + if (this.doingUpdates) { + this.updater.executeUpdate(); + refreshRow(); + this.doingUpdates = false; + } else if (this.onInsertRow) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.44"), getExceptionInterceptor()); + } - // - // fixes calling updateRow() and then doing more - // updates on same row... - syncUpdate(); + // + // fixes calling updateRow() and then doing more + // updates on same row... + syncUpdate(); + } } /** @@ -2361,18 +2404,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateShort(int columnIndex, short x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateShort(int columnIndex, short x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setShort(columnIndex, x); - } else { - this.inserter.setShort(columnIndex, x); + this.updater.setShort(columnIndex, x); + } else { + this.inserter.setShort(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -2391,7 +2436,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateShort(String columnName, short x) throws SQLException { + public void updateShort(String columnName, short x) throws SQLException { updateShort(findColumn(columnName), x); } @@ -2410,29 +2455,27 @@ * if a database-access error occurs */ @Override - public synchronized void updateString(int columnIndex, String x) throws SQLException { - checkClosed(); + public void updateString(int columnIndex, String x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } - - this.updater.setString(columnIndex, x); - } else { - this.inserter.setString(columnIndex, x); - - if (x == null) { - this.thisRow.setColumnValue(columnIndex - 1, null); + this.updater.setString(columnIndex, x); } else { - if (getCharConverter() != null) { - this.thisRow.setColumnValue( - columnIndex - 1, - StringUtils.getBytes(x, this.charConverter, this.charEncoding, this.connection.getServerCharset(), - this.connection.parserKnowsUnicode(), getExceptionInterceptor())); + this.inserter.setString(columnIndex, x); + + if (x == null) { + this.thisRow.setColumnValue(columnIndex - 1, null); } else { - this.thisRow.setColumnValue(columnIndex - 1, StringUtils.getBytes(x)); + if (getCharConverter() != null) { + this.thisRow.setColumnValue(columnIndex - 1, StringUtils.getBytes(x, this.charConverter, this.charEncoding, + this.connection.getServerCharset(), this.connection.parserKnowsUnicode(), getExceptionInterceptor())); + } else { + this.thisRow.setColumnValue(columnIndex - 1, StringUtils.getBytes(x)); + } } } } @@ -2453,7 +2496,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateString(String columnName, String x) throws SQLException { + public void updateString(String columnName, String x) throws SQLException { updateString(findColumn(columnName), x); } @@ -2472,18 +2515,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateTime(int columnIndex, java.sql.Time x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateTime(int columnIndex, java.sql.Time x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setTime(columnIndex, x); - } else { - this.inserter.setTime(columnIndex, x); + this.updater.setTime(columnIndex, x); + } else { + this.inserter.setTime(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -2502,7 +2547,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateTime(String columnName, java.sql.Time x) throws SQLException { + public void updateTime(String columnName, java.sql.Time x) throws SQLException { updateTime(findColumn(columnName), x); } @@ -2521,18 +2566,20 @@ * if a database-access error occurs */ @Override - public synchronized void updateTimestamp(int columnIndex, java.sql.Timestamp x) throws SQLException { - if (!this.onInsertRow) { - if (!this.doingUpdates) { - this.doingUpdates = true; - syncUpdate(); - } + public void updateTimestamp(int columnIndex, java.sql.Timestamp x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!this.onInsertRow) { + if (!this.doingUpdates) { + this.doingUpdates = true; + syncUpdate(); + } - this.updater.setTimestamp(columnIndex, x); - } else { - this.inserter.setTimestamp(columnIndex, x); + this.updater.setTimestamp(columnIndex, x); + } else { + this.inserter.setTimestamp(columnIndex, x); - this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter.getBytesRepresentation(columnIndex - 1)); + } } } @@ -2551,7 +2598,7 @@ * if a database-access error occurs */ @Override - public synchronized void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException { + public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException { updateTimestamp(findColumn(columnName), x); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Util.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Util.java (.../Util.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Util.java (.../Util.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -66,6 +66,8 @@ private static int jvmVersion = -1; + private static int jvmUpdateNumber = -1; + private static boolean isColdFusion = false; static { @@ -98,6 +100,17 @@ // use best approximate value jvmVersion = isJdbc42 ? 8 : isJdbc4 ? 6 : 5; } + startPos = jvmVersionString.indexOf("_"); + endPos = startPos + 1; + if (startPos != -1) { + while (Character.isDigit(jvmVersionString.charAt(endPos)) && ++endPos < jvmVersionString.length()) { + // continue + } + } + startPos++; + if (endPos > startPos) { + jvmUpdateNumber = Integer.parseInt(jvmVersionString.substring(startPos, endPos)); + } // // Detect the ColdFusion MX environment @@ -126,6 +139,14 @@ return jvmVersion; } + public static boolean jvmMeetsMinimum(int version, int updateNumber) { + return getJVMVersion() > version || getJVMVersion() == version && getJVMUpdateNumber() >= updateNumber; + } + + public static int getJVMUpdateNumber() { + return jvmUpdateNumber; + } + public static boolean isColdFusion() { return isColdFusion; } @@ -562,7 +583,7 @@ if (clazz.isInterface()) { try { - if (isJdbcPackage(clazz.getPackage().getName())) { + if (isJdbcPackage(Util.getPackageName(clazz))) { Util.isJdbcInterfaceCache.putIfAbsent(clazz, true); return true; } @@ -592,9 +613,10 @@ /** Main MySQL JDBC package name */ private static final String MYSQL_JDBC_PACKAGE_ROOT; + static { - String packageName = MultiHostConnectionProxy.class.getPackage().getName(); - // assume that packageName includes "jdbc" + String packageName = Util.getPackageName(MultiHostConnectionProxy.class); + // assume that packageName contains "jdbc" MYSQL_JDBC_PACKAGE_ROOT = packageName.substring(0, packageName.indexOf("jdbc") + 4); } @@ -634,7 +656,10 @@ } while ((superClass = superClass.getSuperclass()) != null); implementedInterfaces = interfaces.toArray(new Class[interfaces.size()]); - Util.implementedInterfacesCache.putIfAbsent(clazz, implementedInterfaces); + Class[] oldValue = Util.implementedInterfacesCache.putIfAbsent(clazz, implementedInterfaces); + if (oldValue != null) { + implementedInterfaces = oldValue; + } return implementedInterfaces; } @@ -674,4 +699,21 @@ } return intArray; } + + /** + * Returns the package name of the given class. + * Using clazz.getPackage().getName() is not an alternative because under some class loaders the method getPackage() just returns null. + * + * @param clazz + * the Class from which to get the package name + * @return the package name + */ + public static String getPackageName(Class clazz) { + String fqcn = clazz.getName(); + int classNameStartsAt = fqcn.lastIndexOf('.'); + if (classNameStartsAt > 0) { + return fqcn.substring(0, classNameStartsAt); + } + return ""; + } } \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlClearPasswordPlugin.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlClearPasswordPlugin.java (.../MysqlClearPasswordPlugin.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlClearPasswordPlugin.java (.../MysqlClearPasswordPlugin.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -75,8 +75,7 @@ String encoding = this.connection.versionMeetsMinimum(5, 7, 6) ? this.connection.getPasswordCharacterEncoding() : "UTF-8"; bresp = new Buffer(StringUtils.getBytes(this.password != null ? this.password : "", encoding)); } catch (UnsupportedEncodingException e) { - throw SQLError.createSQLException( - Messages.getString("MysqlClearPasswordPlugin.1", new Object[] { this.connection.getPasswordCharacterEncoding() }), + throw SQLError.createSQLException(Messages.getString("MysqlClearPasswordPlugin.1", new Object[] { this.connection.getPasswordCharacterEncoding() }), SQLError.SQL_STATE_GENERAL_ERROR, null); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/Sha256PasswordPlugin.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/Sha256PasswordPlugin.java (.../Sha256PasswordPlugin.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/Sha256PasswordPlugin.java (.../Sha256PasswordPlugin.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -100,8 +100,7 @@ try { bresp = new Buffer(StringUtils.getBytes(this.password, this.connection.getPasswordCharacterEncoding())); } catch (UnsupportedEncodingException e) { - throw SQLError.createSQLException( - Messages.getString("Sha256PasswordPlugin.3", new Object[] { this.connection.getPasswordCharacterEncoding() }), + throw SQLError.createSQLException(Messages.getString("Sha256PasswordPlugin.3", new Object[] { this.connection.getPasswordCharacterEncoding() }), SQLError.SQL_STATE_GENERAL_ERROR, null); } bresp.setPosition(bresp.getBufLength()); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/CommunicationsException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/CommunicationsException.java (.../CommunicationsException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/CommunicationsException.java (.../CommunicationsException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -39,6 +39,8 @@ */ public class CommunicationsException extends SQLRecoverableException implements StreamingNotifiable { + static final long serialVersionUID = 4317904269797988677L; + private String exceptionMessage; public CommunicationsException(MySQLConnection conn, long lastPacketSentTimeMs, long lastPacketReceivedTimeMs, Exception underlyingException) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLDataException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLDataException.java (.../MySQLDataException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLDataException.java (.../MySQLDataException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -27,6 +27,8 @@ public class MySQLDataException extends SQLDataException { + static final long serialVersionUID = 4317904269797988676L; + public MySQLDataException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLIntegrityConstraintViolationException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLIntegrityConstraintViolationException.java (.../MySQLIntegrityConstraintViolationException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLIntegrityConstraintViolationException.java (.../MySQLIntegrityConstraintViolationException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -27,6 +27,8 @@ public class MySQLIntegrityConstraintViolationException extends SQLIntegrityConstraintViolationException { + static final long serialVersionUID = -5528363270635808904L; + public MySQLIntegrityConstraintViolationException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLInvalidAuthorizationSpecException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLInvalidAuthorizationSpecException.java (.../MySQLInvalidAuthorizationSpecException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLInvalidAuthorizationSpecException.java (.../MySQLInvalidAuthorizationSpecException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -27,6 +27,8 @@ public class MySQLInvalidAuthorizationSpecException extends SQLInvalidAuthorizationSpecException { + static final long serialVersionUID = 6878889837492500030L; + public MySQLInvalidAuthorizationSpecException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLNonTransientConnectionException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLNonTransientConnectionException.java (.../MySQLNonTransientConnectionException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLNonTransientConnectionException.java (.../MySQLNonTransientConnectionException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -27,6 +27,8 @@ public class MySQLNonTransientConnectionException extends SQLNonTransientConnectionException { + static final long serialVersionUID = -3050543822763367670L; + public MySQLNonTransientConnectionException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLNonTransientException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLNonTransientException.java (.../MySQLNonTransientException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLNonTransientException.java (.../MySQLNonTransientException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -28,6 +28,8 @@ public class MySQLNonTransientException extends SQLNonTransientException { + static final long serialVersionUID = -8714521137552613517L; + public MySQLNonTransientException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLQueryInterruptedException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLQueryInterruptedException.java (.../MySQLQueryInterruptedException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLQueryInterruptedException.java (.../MySQLQueryInterruptedException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -25,6 +25,8 @@ public class MySQLQueryInterruptedException extends com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientException { + private static final long serialVersionUID = -8714521137662613517L; + public MySQLQueryInterruptedException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLSyntaxErrorException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLSyntaxErrorException.java (.../MySQLSyntaxErrorException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLSyntaxErrorException.java (.../MySQLSyntaxErrorException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -27,6 +27,8 @@ public class MySQLSyntaxErrorException extends SQLSyntaxErrorException { + static final long serialVersionUID = 6919059513432113764L; + public MySQLSyntaxErrorException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTimeoutException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTimeoutException.java (.../MySQLTimeoutException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTimeoutException.java (.../MySQLTimeoutException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -27,6 +27,8 @@ public class MySQLTimeoutException extends SQLTimeoutException { + static final long serialVersionUID = -789621240523230339L; + public MySQLTimeoutException(String reason, String SQLState, int vendorCode) { super(reason, SQLState, vendorCode); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransactionRollbackException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransactionRollbackException.java (.../MySQLTransactionRollbackException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransactionRollbackException.java (.../MySQLTransactionRollbackException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -29,6 +29,8 @@ public class MySQLTransactionRollbackException extends SQLTransactionRollbackException implements DeadlockTimeoutRollbackMarker { + static final long serialVersionUID = 6034999468737801730L; + public MySQLTransactionRollbackException(String reason, String SQLState, int vendorCode) { super(reason, SQLState, vendorCode); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransientConnectionException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransientConnectionException.java (.../MySQLTransientConnectionException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransientConnectionException.java (.../MySQLTransientConnectionException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -27,6 +27,8 @@ public class MySQLTransientConnectionException extends SQLTransientConnectionException { + static final long serialVersionUID = 8699144578759941201L; + public MySQLTransientConnectionException(String reason, String SQLState, int vendorCode) { super(reason, SQLState, vendorCode); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransientException.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransientException.java (.../MySQLTransientException.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransientException.java (.../MySQLTransientException.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -28,6 +28,8 @@ public class MySQLTransientException extends SQLTransientException { + static final long serialVersionUID = -1885878228558607563L; + public MySQLTransientException(String reason, String SQLState, int vendorCode) { super(reason, SQLState, vendorCode); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/interceptors/ResultSetScannerInterceptor.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/interceptors/ResultSetScannerInterceptor.java (.../ResultSetScannerInterceptor.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/interceptors/ResultSetScannerInterceptor.java (.../ResultSetScannerInterceptor.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -69,6 +69,11 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if ("equals".equals(method.getName())) { + // Let args[0] "unwrap" to its InvocationHandler if it is a proxy. + return args[0].equals(this); + } + Object invocationResult = method.invoke(finalResultSet, args); String methodName = method.getName(); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java (.../CallableStatementWrapper.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java (.../CallableStatementWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -55,8 +55,8 @@ try { String jdbc4ClassName = Util.isJdbc42() ? "com.mysql.jdbc.jdbc2.optional.JDBC42CallableStatementWrapper" : "com.mysql.jdbc.jdbc2.optional.JDBC4CallableStatementWrapper"; - JDBC_4_CALLABLE_STATEMENT_WRAPPER_CTOR = Class.forName(jdbc4ClassName).getConstructor( - new Class[] { ConnectionWrapper.class, MysqlPooledConnection.class, CallableStatement.class }); + JDBC_4_CALLABLE_STATEMENT_WRAPPER_CTOR = Class.forName(jdbc4ClassName) + .getConstructor(new Class[] { ConnectionWrapper.class, MysqlPooledConnection.class, CallableStatement.class }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { @@ -272,11 +272,6 @@ return 0; } - /* - * (non-Javadoc) - * - * @see java.sql.CallableStatement#getDouble(int) - */ public double getDouble(int parameterIndex) throws SQLException { try { if (this.wrappedStmt != null) { @@ -291,11 +286,7 @@ return 0; } - /* - * (non-Javadoc) - * - * @see java.sql.CallableStatement#getBigDecimal(int, int) - */ + @Deprecated public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException { try { if (this.wrappedStmt != null) { @@ -329,11 +320,6 @@ return null; } - /* - * (non-Javadoc) - * - * @see java.sql.CallableStatement#getDate(int) - */ public Date getDate(int parameterIndex) throws SQLException { try { if (this.wrappedStmt != null) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java (.../ConnectionWrapper.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java (.../ConnectionWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -610,13 +610,15 @@ public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException { checkClosed(); + java.sql.PreparedStatement res = null; + try { - return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc.prepareStatement(sql)); + res = PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc.prepareStatement(sql)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); } - return null; // we don't reach this code, compiler can't tell + return res; } /** @@ -806,6 +808,7 @@ } } + @Deprecated public void clearHasTriedMaster() { this.mc.clearHasTriedMaster(); } @@ -902,6 +905,7 @@ return this.mc.getStatementComment(); } + @Deprecated public boolean hasTriedMaster() { return this.mc.hasTriedMaster(); } @@ -1005,6 +1009,7 @@ } + @Deprecated public void setPreferSlaveDuringFailover(boolean flag) { this.mc.setPreferSlaveDuringFailover(flag); } @@ -1305,6 +1310,10 @@ return this.mc.getLoadBalanceStrategy(); } + public String getServerAffinityOrder() { + return this.mc.getServerAffinityOrder(); + } + public String getLocalSocketAddress() { return this.mc.getLocalSocketAddress(); } @@ -1981,6 +1990,10 @@ this.mc.setLoadBalanceStrategy(strategy); } + public void setServerAffinityOrder(String hostsList) { + this.mc.setServerAffinityOrder(hostsList); + } + public void setLocalSocketAddress(String address) { this.mc.setLocalSocketAddress(address); } @@ -2636,6 +2649,14 @@ } + public void setLoadBalanceHostRemovalGracePeriod(int loadBalanceHostRemovalGracePeriod) throws SQLException { + this.mc.setLoadBalanceHostRemovalGracePeriod(loadBalanceHostRemovalGracePeriod); + } + + public int getLoadBalanceHostRemovalGracePeriod() { + return this.mc.getLoadBalanceHostRemovalGracePeriod(); + } + public void setTypeMap(Map> map) throws SQLException { checkClosed(); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC42CallableStatementWrapper.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC42CallableStatementWrapper.java (.../JDBC42CallableStatementWrapper.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC42CallableStatementWrapper.java (.../JDBC42CallableStatementWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,23 +1,23 @@ /* - Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. - The MySQL Connector/J is licensed under the terms of the GPLv2 - , like most MySQL Connectors. - There are special exceptions to the terms and conditions of the GPLv2 as it is applied to - this software, see the FOSS License Exception - . + The MySQL Connector/J is licensed under the terms of the GPLv2 + , like most MySQL Connectors. + There are special exceptions to the terms and conditions of the GPLv2 as it is applied to + this software, see the FOSS License Exception + . - This program is free software; you can redistribute it and/or modify it under the terms - of the GNU General Public License as published by the Free Software Foundation; version 2 - of the License. + This program is free software; you can redistribute it and/or modify it under the terms + of the GNU General Public License as published by the Free Software Foundation; version 2 + of the License. - This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along with this - program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth - Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU General Public License along with this + program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth + Floor, Boston, MA 02110-1301 USA */ Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC42PreparedStatementWrapper.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC42PreparedStatementWrapper.java (.../JDBC42PreparedStatementWrapper.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC42PreparedStatementWrapper.java (.../JDBC42PreparedStatementWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,23 +1,23 @@ /* - Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. - The MySQL Connector/J is licensed under the terms of the GPLv2 - , like most MySQL Connectors. - There are special exceptions to the terms and conditions of the GPLv2 as it is applied to - this software, see the FOSS License Exception - . + The MySQL Connector/J is licensed under the terms of the GPLv2 + , like most MySQL Connectors. + There are special exceptions to the terms and conditions of the GPLv2 as it is applied to + this software, see the FOSS License Exception + . - This program is free software; you can redistribute it and/or modify it under the terms - of the GNU General Public License as published by the Free Software Foundation; version 2 - of the License. + This program is free software; you can redistribute it and/or modify it under the terms + of the GNU General Public License as published by the Free Software Foundation; version 2 + of the License. - This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along with this - program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth - Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU General Public License along with this + program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth + Floor, Boston, MA 02110-1301 USA */ Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4CallableStatementWrapper.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4CallableStatementWrapper.java (.../JDBC4CallableStatementWrapper.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4CallableStatementWrapper.java (.../JDBC4CallableStatementWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -386,14 +386,14 @@ } if (unwrappedInterfaces == null) { - unwrappedInterfaces = new HashMap(); + unwrappedInterfaces = new HashMap, Object>(); } Object cachedUnwrapped = unwrappedInterfaces.get(iface); if (cachedUnwrapped == null) { if (cachedUnwrapped == null) { - cachedUnwrapped = Proxy.newProxyInstance(this.wrappedStmt.getClass().getClassLoader(), new Class[] { iface }, + cachedUnwrapped = Proxy.newProxyInstance(this.wrappedStmt.getClass().getClassLoader(), new Class[] { iface }, new ConnectionErrorFiringInvocationHandler(this.wrappedStmt)); unwrappedInterfaces.put(iface, cachedUnwrapped); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4ConnectionWrapper.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4ConnectionWrapper.java (.../JDBC4ConnectionWrapper.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4ConnectionWrapper.java (.../JDBC4ConnectionWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -256,13 +256,13 @@ } if (unwrappedInterfaces == null) { - unwrappedInterfaces = new HashMap(); + unwrappedInterfaces = new HashMap, Object>(); } Object cachedUnwrapped = unwrappedInterfaces.get(iface); if (cachedUnwrapped == null) { - cachedUnwrapped = Proxy.newProxyInstance(this.mc.getClass().getClassLoader(), new Class[] { iface }, + cachedUnwrapped = Proxy.newProxyInstance(this.mc.getClass().getClassLoader(), new Class[] { iface }, new ConnectionErrorFiringInvocationHandler(this.mc)); unwrappedInterfaces.put(iface, cachedUnwrapped); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4PreparedStatementWrapper.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4PreparedStatementWrapper.java (.../JDBC4PreparedStatementWrapper.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4PreparedStatementWrapper.java (.../JDBC4PreparedStatementWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -405,14 +405,14 @@ } if (unwrappedInterfaces == null) { - unwrappedInterfaces = new HashMap(); + unwrappedInterfaces = new HashMap, Object>(); } Object cachedUnwrapped = unwrappedInterfaces.get(iface); if (cachedUnwrapped == null) { if (cachedUnwrapped == null) { - cachedUnwrapped = Proxy.newProxyInstance(this.wrappedStmt.getClass().getClassLoader(), new Class[] { iface }, + cachedUnwrapped = Proxy.newProxyInstance(this.wrappedStmt.getClass().getClassLoader(), new Class[] { iface }, new ConnectionErrorFiringInvocationHandler(this.wrappedStmt)); unwrappedInterfaces.put(iface, cachedUnwrapped); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4StatementWrapper.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4StatementWrapper.java (.../JDBC4StatementWrapper.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4StatementWrapper.java (.../JDBC4StatementWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -133,8 +133,8 @@ String interfaceClassName = iface.getName(); - return (interfaceClassName.equals("com.mysql.jdbc.Statement") || interfaceClassName.equals("java.sql.Statement") || interfaceClassName - .equals("java.sql.Wrapper")); + return (interfaceClassName.equals("com.mysql.jdbc.Statement") || interfaceClassName.equals("java.sql.Statement") + || interfaceClassName.equals("java.sql.Wrapper")); } /** @@ -163,13 +163,13 @@ } if (unwrappedInterfaces == null) { - unwrappedInterfaces = new HashMap(); + unwrappedInterfaces = new HashMap, Object>(); } Object cachedUnwrapped = unwrappedInterfaces.get(iface); if (cachedUnwrapped == null) { - cachedUnwrapped = Proxy.newProxyInstance(this.wrappedStmt.getClass().getClassLoader(), new Class[] { iface }, + cachedUnwrapped = Proxy.newProxyInstance(this.wrappedStmt.getClass().getClassLoader(), new Class[] { iface }, new ConnectionErrorFiringInvocationHandler(this.wrappedStmt)); unwrappedInterfaces.put(iface, cachedUnwrapped); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java (.../MysqlDataSource.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java (.../MysqlDataSource.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -36,7 +36,9 @@ import javax.sql.DataSource; import com.mysql.jdbc.ConnectionPropertiesImpl; +import com.mysql.jdbc.Messages; import com.mysql.jdbc.NonRegisteringDriver; +import com.mysql.jdbc.SQLError; /** * A JNDI DataSource for a Mysql JDBC connection @@ -407,6 +409,10 @@ // Properties urlProps = mysqlDriver.parseURL(jdbcUrlToUse, null); + if (urlProps == null) { + throw SQLError.createSQLException(Messages.getString("MysqlDataSource.BadUrl", new Object[] { jdbcUrlToUse }), + SQLError.SQL_STATE_CONNECTION_FAILURE, null); + } urlProps.remove(NonRegisteringDriver.DBNAME_PROPERTY_KEY); urlProps.remove(NonRegisteringDriver.HOST_PROPERTY_KEY); urlProps.remove(NonRegisteringDriver.PORT_PROPERTY_KEY); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlPooledConnection.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlPooledConnection.java (.../MysqlPooledConnection.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlPooledConnection.java (.../MysqlPooledConnection.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -49,8 +49,8 @@ static { if (Util.isJdbc4()) { try { - JDBC_4_POOLED_CONNECTION_WRAPPER_CTOR = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4MysqlPooledConnection").getConstructor( - new Class[] { com.mysql.jdbc.Connection.class }); + JDBC_4_POOLED_CONNECTION_WRAPPER_CTOR = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4MysqlPooledConnection") + .getConstructor(new Class[] { com.mysql.jdbc.Connection.class }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAConnection.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAConnection.java (.../MysqlXAConnection.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAConnection.java (.../MysqlXAConnection.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -73,13 +73,15 @@ static { HashMap temp = new HashMap(); - temp.put(Integer.valueOf(1397), Integer.valueOf(XAException.XAER_NOTA)); - temp.put(Integer.valueOf(1398), Integer.valueOf(XAException.XAER_INVAL)); - temp.put(Integer.valueOf(1399), Integer.valueOf(XAException.XAER_RMFAIL)); - temp.put(Integer.valueOf(1400), Integer.valueOf(XAException.XAER_OUTSIDE)); - temp.put(Integer.valueOf(1401), Integer.valueOf(XAException.XAER_RMERR)); - temp.put(Integer.valueOf(1402), Integer.valueOf(XAException.XA_RBROLLBACK)); - temp.put(Integer.valueOf(1440), Integer.valueOf(XAException.XAER_DUPID)); + temp.put(1397, XAException.XAER_NOTA); + temp.put(1398, XAException.XAER_INVAL); + temp.put(1399, XAException.XAER_RMFAIL); + temp.put(1400, XAException.XAER_OUTSIDE); + temp.put(1401, XAException.XAER_RMERR); + temp.put(1402, XAException.XA_RBROLLBACK); + temp.put(1440, XAException.XAER_DUPID); + temp.put(1613, XAException.XA_RBTIMEOUT); + temp.put(1614, XAException.XA_RBDEADLOCK); MYSQL_ERROR_CODES_TO_XA_ERROR_CODES = Collections.unmodifiableMap(temp); } @@ -89,8 +91,8 @@ static { if (Util.isJdbc4()) { try { - JDBC_4_XA_CONNECTION_WRAPPER_CTOR = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4MysqlXAConnection").getConstructor( - new Class[] { com.mysql.jdbc.Connection.class, Boolean.TYPE }); + JDBC_4_XA_CONNECTION_WRAPPER_CTOR = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4MysqlXAConnection") + .getConstructor(new Class[] { com.mysql.jdbc.Connection.class, Boolean.TYPE }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { @@ -575,7 +577,7 @@ } protected static XAException mapXAExceptionFromSQLException(SQLException sqlEx) { - Integer xaCode = MYSQL_ERROR_CODES_TO_XA_ERROR_CODES.get(Integer.valueOf(sqlEx.getErrorCode())); + Integer xaCode = MYSQL_ERROR_CODES_TO_XA_ERROR_CODES.get(sqlEx.getErrorCode()); if (xaCode != null) { return (XAException) new MysqlXAException(xaCode.intValue(), sqlEx.getMessage(), null).initCause(sqlEx); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/PreparedStatementWrapper.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/PreparedStatementWrapper.java (.../PreparedStatementWrapper.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/PreparedStatementWrapper.java (.../PreparedStatementWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -56,8 +56,8 @@ try { String jdbc4ClassName = Util.isJdbc42() ? "com.mysql.jdbc.jdbc2.optional.JDBC42PreparedStatementWrapper" : "com.mysql.jdbc.jdbc2.optional.JDBC4PreparedStatementWrapper"; - JDBC_4_PREPARED_STATEMENT_WRAPPER_CTOR = Class.forName(jdbc4ClassName).getConstructor( - new Class[] { ConnectionWrapper.class, MysqlPooledConnection.class, PreparedStatement.class }); + JDBC_4_PREPARED_STATEMENT_WRAPPER_CTOR = Class.forName(jdbc4ClassName) + .getConstructor(new Class[] { ConnectionWrapper.class, MysqlPooledConnection.class, PreparedStatement.class }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { @@ -83,11 +83,6 @@ super(c, conn, toWrap); } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setArray(int, java.sql.Array) - */ public void setArray(int parameterIndex, Array x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -100,11 +95,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setAsciiStream(int, java.io.InputStream, int) - */ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { try { if (this.wrappedStmt != null) { @@ -117,11 +107,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setBigDecimal(int, java.math.BigDecimal) - */ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -134,11 +119,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setBinaryStream(int, java.io.InputStream, int) - */ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { try { if (this.wrappedStmt != null) { @@ -151,11 +131,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setBlob(int, java.sql.Blob) - */ public void setBlob(int parameterIndex, Blob x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -168,11 +143,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setBoolean(int, boolean) - */ public void setBoolean(int parameterIndex, boolean x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -185,11 +155,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setByte(int, byte) - */ public void setByte(int parameterIndex, byte x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -202,11 +167,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setBytes(int, byte[]) - */ public void setBytes(int parameterIndex, byte[] x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -219,11 +179,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader, int) - */ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { try { if (this.wrappedStmt != null) { @@ -236,11 +191,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setClob(int, java.sql.Clob) - */ public void setClob(int parameterIndex, Clob x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -253,11 +203,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setDate(int, java.sql.Date) - */ public void setDate(int parameterIndex, Date x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -270,11 +215,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setDate(int, java.sql.Date, java.util.Calendar) - */ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { try { if (this.wrappedStmt != null) { @@ -287,11 +227,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setDouble(int, double) - */ public void setDouble(int parameterIndex, double x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -304,11 +239,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setFloat(int, float) - */ public void setFloat(int parameterIndex, float x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -321,11 +251,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setInt(int, int) - */ public void setInt(int parameterIndex, int x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -338,11 +263,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setLong(int, long) - */ public void setLong(int parameterIndex, long x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -355,11 +275,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#getMetaData() - */ public ResultSetMetaData getMetaData() throws SQLException { try { if (this.wrappedStmt != null) { @@ -374,11 +289,6 @@ return null; } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setNull(int, int) - */ public void setNull(int parameterIndex, int sqlType) throws SQLException { try { if (this.wrappedStmt != null) { @@ -391,11 +301,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setNull(int, int, java.lang.String) - */ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { try { if (this.wrappedStmt != null) { @@ -408,11 +313,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setObject(int, java.lang.Object) - */ public void setObject(int parameterIndex, Object x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -425,11 +325,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setObject(int, java.lang.Object, int) - */ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { try { if (this.wrappedStmt != null) { @@ -442,11 +337,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setObject(int, java.lang.Object, int, int) - */ public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException { try { if (this.wrappedStmt != null) { @@ -459,11 +349,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#getParameterMetaData() - */ public ParameterMetaData getParameterMetaData() throws SQLException { try { if (this.wrappedStmt != null) { @@ -478,11 +363,6 @@ return null; } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setRef(int, java.sql.Ref) - */ public void setRef(int parameterIndex, Ref x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -495,11 +375,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setShort(int, short) - */ public void setShort(int parameterIndex, short x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -512,11 +387,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setString(int, java.lang.String) - */ public void setString(int parameterIndex, String x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -529,11 +399,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setTime(int, java.sql.Time) - */ public void setTime(int parameterIndex, Time x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -546,11 +411,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setTime(int, java.sql.Time, java.util.Calendar) - */ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { try { if (this.wrappedStmt != null) { @@ -563,11 +423,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setTimestamp(int, java.sql.Timestamp) - */ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -580,11 +435,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setTimestamp(int, java.sql.Timestamp, java.util.Calendar) - */ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { try { if (this.wrappedStmt != null) { @@ -597,11 +447,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#setURL(int, java.net.URL) - */ public void setURL(int parameterIndex, URL x) throws SQLException { try { if (this.wrappedStmt != null) { @@ -637,11 +482,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#addBatch() - */ public void addBatch() throws SQLException { try { if (this.wrappedStmt != null) { @@ -654,11 +494,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#clearParameters() - */ public void clearParameters() throws SQLException { try { if (this.wrappedStmt != null) { @@ -671,11 +506,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#execute() - */ public boolean execute() throws SQLException { try { if (this.wrappedStmt != null) { @@ -690,34 +520,23 @@ return false; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#executeQuery() - */ public ResultSet executeQuery() throws SQLException { - try { - if (this.wrappedStmt != null) { - ResultSet rs = ((PreparedStatement) this.wrappedStmt).executeQuery(); - ((com.mysql.jdbc.ResultSetInternalMethods) rs).setWrapperStatement(this); - - return rs; + ResultSet rs = null; + try { + if (this.wrappedStmt == null) { + throw SQLError.createSQLException("No operations allowed after statement closed", SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } + rs = ((PreparedStatement) this.wrappedStmt).executeQuery(); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).setWrapperStatement(this); - throw SQLError.createSQLException("No operations allowed after statement closed", SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } - return null; // we actually never get here, but the compiler can't figure that out + return rs; } - /* - * (non-Javadoc) - * - * @see java.sql.PreparedStatement#executeUpdate() - */ public int executeUpdate() throws SQLException { try { if (this.wrappedStmt != null) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/StatementWrapper.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/StatementWrapper.java (.../StatementWrapper.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/StatementWrapper.java (.../StatementWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -43,8 +43,8 @@ static { if (Util.isJdbc4()) { try { - JDBC_4_STATEMENT_WRAPPER_CTOR = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4StatementWrapper").getConstructor( - new Class[] { ConnectionWrapper.class, MysqlPooledConnection.class, Statement.class }); + JDBC_4_STATEMENT_WRAPPER_CTOR = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4StatementWrapper") + .getConstructor(new Class[] { ConnectionWrapper.class, MysqlPooledConnection.class, Statement.class }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { @@ -75,11 +75,6 @@ this.wrappedConn = c; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getConnection() - */ public Connection getConnection() throws SQLException { try { if (this.wrappedStmt != null) { @@ -94,11 +89,6 @@ return null; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#setCursorName(java.lang.String) - */ public void setCursorName(String name) throws SQLException { try { if (this.wrappedStmt != null) { @@ -111,11 +101,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#setEscapeProcessing(boolean) - */ public void setEscapeProcessing(boolean enable) throws SQLException { try { if (this.wrappedStmt != null) { @@ -128,11 +113,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#setFetchDirection(int) - */ public void setFetchDirection(int direction) throws SQLException { try { if (this.wrappedStmt != null) { @@ -145,11 +125,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getFetchDirection() - */ public int getFetchDirection() throws SQLException { try { if (this.wrappedStmt != null) { @@ -164,11 +139,6 @@ return ResultSet.FETCH_FORWARD; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#setFetchSize(int) - */ public void setFetchSize(int rows) throws SQLException { try { if (this.wrappedStmt != null) { @@ -181,11 +151,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getFetchSize() - */ public int getFetchSize() throws SQLException { try { if (this.wrappedStmt != null) { @@ -200,11 +165,6 @@ return 0; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getGeneratedKeys() - */ public ResultSet getGeneratedKeys() throws SQLException { try { if (this.wrappedStmt != null) { @@ -219,11 +179,6 @@ return null; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#setMaxFieldSize(int) - */ public void setMaxFieldSize(int max) throws SQLException { try { if (this.wrappedStmt != null) { @@ -236,11 +191,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getMaxFieldSize() - */ public int getMaxFieldSize() throws SQLException { try { if (this.wrappedStmt != null) { @@ -255,11 +205,6 @@ return 0; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#setMaxRows(int) - */ public void setMaxRows(int max) throws SQLException { try { if (this.wrappedStmt != null) { @@ -272,11 +217,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getMaxRows() - */ public int getMaxRows() throws SQLException { try { if (this.wrappedStmt != null) { @@ -291,11 +231,6 @@ return 0; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getMoreResults() - */ public boolean getMoreResults() throws SQLException { try { if (this.wrappedStmt != null) { @@ -310,11 +245,6 @@ return false; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getMoreResults(int) - */ public boolean getMoreResults(int current) throws SQLException { try { if (this.wrappedStmt != null) { @@ -329,11 +259,6 @@ return false; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#setQueryTimeout(int) - */ public void setQueryTimeout(int seconds) throws SQLException { try { if (this.wrappedStmt != null) { @@ -346,11 +271,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getQueryTimeout() - */ public int getQueryTimeout() throws SQLException { try { if (this.wrappedStmt != null) { @@ -365,11 +285,6 @@ return 0; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getResultSet() - */ public ResultSet getResultSet() throws SQLException { try { if (this.wrappedStmt != null) { @@ -389,11 +304,6 @@ return null; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getResultSetConcurrency() - */ public int getResultSetConcurrency() throws SQLException { try { if (this.wrappedStmt != null) { @@ -408,11 +318,6 @@ return 0; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getResultSetHoldability() - */ public int getResultSetHoldability() throws SQLException { try { if (this.wrappedStmt != null) { @@ -427,11 +332,6 @@ return Statement.CLOSE_CURRENT_RESULT; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getResultSetType() - */ public int getResultSetType() throws SQLException { try { if (this.wrappedStmt != null) { @@ -446,11 +346,6 @@ return ResultSet.TYPE_FORWARD_ONLY; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getUpdateCount() - */ public int getUpdateCount() throws SQLException { try { if (this.wrappedStmt != null) { @@ -465,11 +360,6 @@ return -1; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#getWarnings() - */ public SQLWarning getWarnings() throws SQLException { try { if (this.wrappedStmt != null) { @@ -484,11 +374,6 @@ return null; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#addBatch(java.lang.String) - */ public void addBatch(String sql) throws SQLException { try { if (this.wrappedStmt != null) { @@ -499,11 +384,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#cancel() - */ public void cancel() throws SQLException { try { if (this.wrappedStmt != null) { @@ -514,11 +394,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#clearBatch() - */ public void clearBatch() throws SQLException { try { if (this.wrappedStmt != null) { @@ -529,11 +404,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#clearWarnings() - */ public void clearWarnings() throws SQLException { try { if (this.wrappedStmt != null) { @@ -544,11 +414,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#close() - */ public void close() throws SQLException { try { if (this.wrappedStmt != null) { @@ -562,11 +427,6 @@ } } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#execute(java.lang.String, int) - */ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { try { if (this.wrappedStmt != null) { @@ -581,11 +441,6 @@ return false; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#execute(java.lang.String, int[]) - */ public boolean execute(String sql, int[] columnIndexes) throws SQLException { try { if (this.wrappedStmt != null) { @@ -600,11 +455,6 @@ return false; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#execute(java.lang.String, java.lang.String[]) - */ public boolean execute(String sql, String[] columnNames) throws SQLException { try { if (this.wrappedStmt != null) { @@ -619,11 +469,6 @@ return false; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#execute(java.lang.String) - */ public boolean execute(String sql) throws SQLException { try { if (this.wrappedStmt != null) { @@ -638,11 +483,6 @@ return false; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#executeBatch() - */ public int[] executeBatch() throws SQLException { try { if (this.wrappedStmt != null) { @@ -657,34 +497,22 @@ return null; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#executeQuery(java.lang.String) - */ public ResultSet executeQuery(String sql) throws SQLException { + ResultSet rs = null; try { - if (this.wrappedStmt != null) { - - ResultSet rs = this.wrappedStmt.executeQuery(sql); - ((com.mysql.jdbc.ResultSetInternalMethods) rs).setWrapperStatement(this); - - return rs; + if (this.wrappedStmt == null) { + throw SQLError.createSQLException("Statement already closed", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } + rs = this.wrappedStmt.executeQuery(sql); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).setWrapperStatement(this); - throw SQLError.createSQLException("Statement already closed", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } - return null; // we actually never get here, but the compiler can't figure that out + return rs; } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#executeUpdate(java.lang.String, int) - */ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { try { if (this.wrappedStmt != null) { @@ -699,11 +527,6 @@ return -1; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#executeUpdate(java.lang.String, int[]) - */ public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { try { if (this.wrappedStmt != null) { @@ -718,12 +541,6 @@ return -1; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#executeUpdate(java.lang.String, - * java.lang.String[]) - */ public int executeUpdate(String sql, String[] columnNames) throws SQLException { try { if (this.wrappedStmt != null) { @@ -738,11 +555,6 @@ return -1; // we actually never get here, but the compiler can't figure that out } - /* - * (non-Javadoc) - * - * @see java.sql.Statement#executeUpdate(java.lang.String) - */ public int executeUpdate(String sql) throws SQLException { try { if (this.wrappedStmt != null) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/SuspendableXAConnection.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/SuspendableXAConnection.java (.../SuspendableXAConnection.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/SuspendableXAConnection.java (.../SuspendableXAConnection.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -43,8 +43,8 @@ static { if (Util.isJdbc4()) { try { - JDBC_4_XA_CONNECTION_WRAPPER_CTOR = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection").getConstructor( - new Class[] { Connection.class }); + JDBC_4_XA_CONNECTION_WRAPPER_CTOR = Class.forName("com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection") + .getConstructor(new Class[] { Connection.class }); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/WrapperBase.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/WrapperBase.java (.../WrapperBase.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/WrapperBase.java (.../WrapperBase.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -32,6 +32,7 @@ import com.mysql.jdbc.ExceptionInterceptor; import com.mysql.jdbc.SQLError; +import com.mysql.jdbc.Util; /** * Base class for all wrapped instances created by LogicalHandle @@ -57,7 +58,7 @@ throw sqlEx; } - protected Map unwrappedInterfaces = null; + protected Map, Object> unwrappedInterfaces = null; protected ExceptionInterceptor exceptionInterceptor; protected WrapperBase(MysqlPooledConnection pooledConnection) { @@ -73,6 +74,11 @@ } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if ("equals".equals(method.getName())) { + // Let args[0] "unwrap" to its InvocationHandler if it is a proxy. + return args[0].equals(this); + } + Object result = null; try { @@ -104,7 +110,7 @@ Class[] interfaces = clazz.getInterfaces(); for (Class iclass : interfaces) { - String packageName = iclass.getPackage().getName(); + String packageName = Util.getPackageName(iclass); if ("java.sql".equals(packageName) || "javax.sql".equals(packageName)) { return Proxy.newProxyInstance(toProxy.getClass().getClassLoader(), interfaces, new ConnectionErrorFiringInvocationHandler(toProxy)); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogFactory.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogFactory.java (.../LogFactory.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogFactory.java (.../LogFactory.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -29,6 +29,7 @@ import com.mysql.jdbc.ExceptionInterceptor; import com.mysql.jdbc.SQLError; +import com.mysql.jdbc.Util; /** * Creates instances of loggers for the driver to use. @@ -63,7 +64,7 @@ try { loggerClass = Class.forName(className); } catch (ClassNotFoundException nfe) { - loggerClass = Class.forName(Log.class.getPackage().getName() + "." + className); + loggerClass = Class.forName(Util.getPackageName(Log.class) + "." + className); } Constructor constructor = loggerClass.getConstructor(new Class[] { String.class }); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/profiler/ProfilerEvent.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/profiler/ProfilerEvent.java (.../ProfilerEvent.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/profiler/ProfilerEvent.java (.../ProfilerEvent.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -298,8 +298,9 @@ pos += message.length; } - return new ProfilerEvent(eventType, "", "", connectionId, statementId, resultSetId, eventCreationTime, eventDuration, StringUtils.toString( - eventDurationUnits, "ISO8859_1"), StringUtils.toString(eventCreationAsBytes, "ISO8859_1"), null, StringUtils.toString(message, "ISO8859_1")); + return new ProfilerEvent(eventType, "", "", connectionId, statementId, resultSetId, eventCreationTime, eventDuration, + StringUtils.toString(eventDurationUnits, "ISO8859_1"), StringUtils.toString(eventCreationAsBytes, "ISO8859_1"), null, + StringUtils.toString(message, "ISO8859_1")); } /** Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/Base64Decoder.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/Base64Decoder.java (.../Base64Decoder.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/Base64Decoder.java (.../Base64Decoder.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -49,7 +49,7 @@ private static byte getNextValidByte(byte[] in, IntWrapper pos, int maxPos) { while (pos.value <= maxPos) { - if (in[pos.value] <= 127 && decoderMap[in[pos.value]] >= 0) { + if (in[pos.value] >= 0 && decoderMap[in[pos.value]] >= 0) { return in[pos.value++]; } pos.value++; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ReadAheadInputStream.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ReadAheadInputStream.java (.../ReadAheadInputStream.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ReadAheadInputStream.java (.../ReadAheadInputStream.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import com.mysql.jdbc.log.Log; @@ -112,7 +113,7 @@ if (this.doDebug) { StringBuilder debugBuf = new StringBuilder(); debugBuf.append("ReadAheadInputStream.readIfNecessary("); - debugBuf.append(b); + debugBuf.append(Arrays.toString(b)); debugBuf.append(","); debugBuf.append(off); debugBuf.append(","); Index: 3rdParty_sources/versions.txt =================================================================== diff -u -r35b4d0e3b6f1cc098667826b4b23b11cc4f78843 -r5a8831deff620b6d7419f54d9e45d3a54c76af18 --- 3rdParty_sources/versions.txt (.../versions.txt) (revision 35b4d0e3b6f1cc098667826b4b23b11cc4f78843) +++ 3rdParty_sources/versions.txt (.../versions.txt) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) @@ -30,7 +30,7 @@ lucene 2.4.0 contains lucene-snowball 2.4.0 -MySQL Connector/J 5.1.38 +MySQL Connector/J 5.1.43 oauth 20100527