Index: 3rdParty_sources/versions.txt =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/versions.txt,v diff -u -r1.11 -r1.11.2.1 --- 3rdParty_sources/versions.txt 10 Dec 2013 17:07:33 -0000 1.11 +++ 3rdParty_sources/versions.txt 30 Jul 2014 08:37:35 -0000 1.11.2.1 @@ -37,7 +37,7 @@ lucene 2.4.0 contains lucene-snowball 2.4.0 -MySQL Connector/J 5.0.8 +MySQL Connector/J 5.1.31 opensaml 2.6.0 Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/DumpResponse.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/FabricCommunicationException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/FabricConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/FabricStateResponse.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/HashShardMapping.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/RangeShardMapping.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/Response.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/Server.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/ServerGroup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/ServerMode.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/ServerRole.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/ShardIndex.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/ShardMapping.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/ShardMappingFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/ShardTable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/ShardingType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/hibernate/FabricMultiTenantConnectionProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/ErrorReportingExceptionInterceptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLConnectionProperties.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLConnectionProxy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLDataSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/FabricMySQLDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/JDBC4FabricMySQLConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/jdbc/JDBC4FabricMySQLConnectionProxy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/AuthenticatedXmlRpcMethodCaller.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/DigestAuthentication.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/InternalXmlRpcMethodCaller.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/XmlRpcClient.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/proto/xmlrpc/XmlRpcMethodCaller.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/Client.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Array.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Data.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Fault.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Member.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/MethodCall.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/MethodResponse.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Param.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Params.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/ResponseParser.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Struct.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/base/Value.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/fabric/xmlrpc/exceptions/MySQLFabricException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/AbandonedConnectionCleanupThread.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/AssertionFailedException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/AssertionFailedException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/AssertionFailedException.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/AssertionFailedException.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; /** @@ -33,9 +32,13 @@ * mmatthews Exp $ */ public class AssertionFailedException extends RuntimeException { + + private static final long serialVersionUID = 1L; + // ~ Constructors // ----------------------------------------------------------- + /** * Convenience method. * Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/AuthenticationPlugin.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/BalanceStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/BestResponseTimeBalanceStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Blob.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Blob.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Blob.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Blob.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,33 +1,32 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; - import java.sql.SQLException; /** @@ -57,15 +56,26 @@ /** The binary data that makes up this BLOB */ private byte[] binaryData = null; - + private boolean isClosed = false; + private ExceptionInterceptor exceptionInterceptor; + /** + * Creates a Blob without data + */ + Blob(ExceptionInterceptor exceptionInterceptor) { + setBinaryData(Constants.EMPTY_BYTE_ARRAY); + this.exceptionInterceptor = exceptionInterceptor; + } + + /** * Creates a BLOB encapsulating the given binary data * * @param data * DOCUMENT ME! */ - Blob(byte[] data) { + Blob(byte[] data, ExceptionInterceptor exceptionInterceptor) { setBinaryData(data); + this.exceptionInterceptor = exceptionInterceptor; } /** @@ -78,11 +88,11 @@ * @param columnIndexToSet * DOCUMENT ME! */ - Blob(byte[] data, ResultSet creatorResultSetToSet, int columnIndexToSet) { + Blob(byte[] data, ResultSetInternalMethods creatorResultSetToSet, int columnIndexToSet) { setBinaryData(data); } - private byte[] getBinaryData() { + private synchronized byte[] getBinaryData() { return this.binaryData; } @@ -94,7 +104,9 @@ * @throws SQLException * if a database error occurs */ - public java.io.InputStream getBinaryStream() throws SQLException { + public synchronized java.io.InputStream getBinaryStream() throws SQLException { + checkClosed(); + return new ByteArrayInputStream(getBinaryData()); } @@ -113,14 +125,28 @@ * @throws SQLException * if a database error occurs */ - public byte[] getBytes(long pos, int length) throws SQLException { + public synchronized byte[] getBytes(long pos, int length) throws SQLException { + checkClosed(); + if (pos < 1) { throw SQLError.createSQLException(Messages.getString("Blob.2"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } + pos--; + + if (pos > this.binaryData.length) { + throw SQLError.createSQLException("\"pos\" argument can not be larger than the BLOB's length.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } + + if (pos + length > this.binaryData.length) { + throw SQLError.createSQLException("\"pos\" + \"length\" arguments can not be larger than the BLOB's length.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } + byte[] newData = new byte[length]; - System.arraycopy(getBinaryData(), (int) (pos - 1), newData, 0, length); + System.arraycopy(getBinaryData(), (int) (pos), newData, 0, length); return newData; } @@ -134,15 +160,17 @@ * @throws SQLException * if a database error occurs */ - public long length() throws SQLException { + public synchronized long length() throws SQLException { + checkClosed(); + return getBinaryData().length; } /** * @see java.sql.Blob#position(byte[], long) */ - public long position(byte[] pattern, long start) throws SQLException { - throw SQLError.createSQLException("Not implemented"); //$NON-NLS-1$ + public synchronized long position(byte[] pattern, long start) throws SQLException { + throw SQLError.createSQLException("Not implemented", this.exceptionInterceptor); //$NON-NLS-1$ } /** @@ -159,22 +187,26 @@ * @throws SQLException * if a database error occurs */ - public long position(java.sql.Blob pattern, long start) throws SQLException { + public synchronized long position(java.sql.Blob pattern, long start) throws SQLException { + checkClosed(); + return position(pattern.getBytes(0, (int) pattern.length()), start); } - private void setBinaryData(byte[] newBinaryData) { + private synchronized void setBinaryData(byte[] newBinaryData) { this.binaryData = newBinaryData; } /** * @see Blob#setBinaryStream(long) */ - public OutputStream setBinaryStream(long indexToWriteAt) + public synchronized OutputStream setBinaryStream(long indexToWriteAt) throws SQLException { + checkClosed(); + if (indexToWriteAt < 1) { throw SQLError.createSQLException(Messages.getString("Blob.0"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } WatchableOutputStream bytesOut = new WatchableOutputStream(); @@ -190,22 +222,29 @@ /** * @see Blob#setBytes(long, byte[]) */ - public int setBytes(long writeAt, byte[] bytes) throws SQLException { + public synchronized int setBytes(long writeAt, byte[] bytes) throws SQLException { + checkClosed(); + return setBytes(writeAt, bytes, 0, bytes.length); } /** * @see Blob#setBytes(long, byte[], int, int) */ - public int setBytes(long writeAt, byte[] bytes, int offset, int length) + public synchronized int setBytes(long writeAt, byte[] bytes, int offset, int length) throws SQLException { + checkClosed(); + OutputStream bytesOut = setBinaryStream(writeAt); try { bytesOut.write(bytes, offset, length); } catch (IOException ioEx) { - throw SQLError.createSQLException(Messages.getString("Blob.1"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + SQLException sqlEx = SQLError.createSQLException(Messages.getString("Blob.1"), //$NON-NLS-1$ + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + sqlEx.initCause(ioEx); + + throw sqlEx; } finally { try { bytesOut.close(); @@ -220,14 +259,14 @@ /** * @see com.mysql.jdbc.OutputStreamWatcher#streamClosed(byte[]) */ - public void streamClosed(byte[] byteData) { + public synchronized void streamClosed(byte[] byteData) { this.binaryData = byteData; } /** * @see com.mysql.jdbc.OutputStreamWatcher#streamClosed(byte[]) */ - public void streamClosed(WatchableOutputStream out) { + public synchronized void streamClosed(WatchableOutputStream out) { int streamSize = out.size(); if (streamSize < this.binaryData.length) { @@ -239,9 +278,110 @@ } /** - * @see Blob#truncate(long) - */ - public void truncate(long arg0) throws SQLException { - throw new NotImplemented(); + * Truncates the BLOB value that this Blob + * object represents to be len bytes in length. + *

+ * Note: If the value specified for len + * is greater then the length+1 of the BLOB value then the + * behavior is undefined. Some JDBC drivers may throw a + * SQLException while other drivers may support this + * operation. + * + * @param len the length, in bytes, to which the BLOB value + * that this Blob object represents should be truncated + * @exception SQLException if there is an error accessing the + * BLOB value or if len is less than 0 + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public synchronized void truncate(long len) throws SQLException { + checkClosed(); + + if (len < 0) { + throw SQLError.createSQLException("\"len\" argument can not be < 1.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } + + if (len > this.binaryData.length) { + throw SQLError.createSQLException("\"len\" argument can not be larger than the BLOB's length.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } + + // TODO: Do this without copying byte[]s by maintaining some end pointer + // on the original data + + byte[] newData = new byte[(int)len]; + System.arraycopy(getBinaryData(), 0, newData, 0, (int)len); + this.binaryData = newData; } + + /** + * This method frees the Blob object and releases the resources that + * it holds. The object is invalid once the free + * method is called. + *

+ * After free has been called, any attempt to invoke a + * method other than free will result in a SQLException + * being thrown. If free is called multiple times, the subsequent + * calls to free are treated as a no-op. + *

+ * + * @throws SQLException if an error occurs releasing + * the Blob's resources + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + + public synchronized void free() throws SQLException { + this.binaryData = null; + this.isClosed = true; + } + + /** + * Returns an InputStream object that contains a partial Blob value, + * starting with the byte specified by pos, which is length bytes in length. + * + * @param pos the offset to the first byte of the partial value to be retrieved. + * The first byte in the Blob is at position 1 + * @param length the length in bytes of the partial value to be retrieved + * @return InputStream through which the partial Blob value can be read. + * @throws SQLException if pos is less than 1 or if pos is greater than the number of bytes + * in the Blob or if pos + length is greater than the number of bytes + * in the Blob + * + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public synchronized InputStream getBinaryStream(long pos, long length) throws SQLException { + checkClosed(); + + if (pos < 1) { + throw SQLError.createSQLException("\"pos\" argument can not be < 1.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } + + pos--; + + if (pos > this.binaryData.length) { + throw SQLError.createSQLException("\"pos\" argument can not be larger than the BLOB's length.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } + + if (pos + length > this.binaryData.length) { + throw SQLError.createSQLException("\"pos\" + \"length\" arguments can not be larger than the BLOB's length.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } + + return new ByteArrayInputStream(getBinaryData(), (int)pos, (int)length); + } + + private synchronized void checkClosed() throws SQLException { + if (this.isClosed) { + throw SQLError.createSQLException("Invalid operation on closed BLOB", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/BlobFromLocator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/BlobFromLocator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/BlobFromLocator.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/BlobFromLocator.java 30 Jul 2014 08:37:25 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.BufferedInputStream; @@ -52,12 +51,12 @@ * Exp $ */ public class BlobFromLocator implements java.sql.Blob { - private List primaryKeyColumns = null; + private List primaryKeyColumns = null; - private List primaryKeyValues = null; + private List primaryKeyValues = null; /** The ResultSet that created this BLOB */ - private ResultSet creatorResultSet; + private ResultSetImpl creatorResultSet; private String blobColumnName = null; @@ -69,20 +68,23 @@ private String quotedId; + private ExceptionInterceptor exceptionInterceptor; + /** * Creates an updatable BLOB that can update in-place */ - BlobFromLocator(ResultSet creatorResultSetToSet, int blobColumnIndex) + BlobFromLocator(ResultSetImpl creatorResultSetToSet, int blobColumnIndex, ExceptionInterceptor exceptionInterceptor) throws SQLException { + this.exceptionInterceptor = exceptionInterceptor; this.creatorResultSet = creatorResultSetToSet; this.numColsInResultSet = this.creatorResultSet.fields.length; this.quotedId = this.creatorResultSet.connection.getMetaData() .getIdentifierQuoteString(); if (this.numColsInResultSet > 1) { - this.primaryKeyColumns = new ArrayList(); - this.primaryKeyValues = new ArrayList(); + this.primaryKeyColumns = new ArrayList(); + this.primaryKeyValues = new ArrayList(); for (int i = 0; i < this.numColsInResultSet; i++) { if (this.creatorResultSet.fields[i].isPrimaryKey()) { @@ -154,15 +156,15 @@ private void notEnoughInformationInQuery() throws SQLException { throw SQLError.createSQLException("Emulated BLOB locators must come from " + "a ResultSet with only one table selected, and all primary " - + "keys selected", SQLError.SQL_STATE_GENERAL_ERROR); + + "keys selected", SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } /** * @see Blob#setBinaryStream(long) */ public OutputStream setBinaryStream(long indexToWriteAt) throws SQLException { - throw new NotImplemented(); + throw SQLError.notImplemented(); } /** @@ -206,12 +208,12 @@ query.append(length); query.append(", ?) WHERE "); - query.append((String) this.primaryKeyColumns.get(0)); + query.append(this.primaryKeyColumns.get(0)); query.append(" = ?"); for (int i = 1; i < this.numPrimaryKeys; i++) { query.append(" AND "); - query.append((String) this.primaryKeyColumns.get(i)); + query.append(this.primaryKeyColumns.get(i)); query.append(" = ?"); } @@ -223,15 +225,15 @@ pStmt.setBytes(1, bytesToWrite); for (int i = 0; i < this.numPrimaryKeys; i++) { - pStmt.setString(i + 2, (String) this.primaryKeyValues.get(i)); + pStmt.setString(i + 2, this.primaryKeyValues.get(i)); } int rowsUpdated = pStmt.executeUpdate(); if (rowsUpdated != 1) { throw SQLError.createSQLException( "BLOB data not found! Did primary keys change?", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } finally { if (pStmt != null) { @@ -290,7 +292,7 @@ } } } - + /** * Returns the number of bytes in the BLOB value designated by this Blob * object. @@ -311,12 +313,12 @@ query.append(this.tableName); query.append(" WHERE "); - query.append((String) this.primaryKeyColumns.get(0)); + query.append(this.primaryKeyColumns.get(0)); query.append(" = ?"); for (int i = 1; i < this.numPrimaryKeys; i++) { query.append(" AND "); - query.append((String) this.primaryKeyColumns.get(i)); + query.append(this.primaryKeyColumns.get(i)); query.append(" = ?"); } @@ -326,7 +328,7 @@ .toString()); for (int i = 0; i < this.numPrimaryKeys; i++) { - pStmt.setString(i + 1, (String) this.primaryKeyValues.get(i)); + pStmt.setString(i + 1, this.primaryKeyValues.get(i)); } blobRs = pStmt.executeQuery(); @@ -337,7 +339,7 @@ throw SQLError.createSQLException( "BLOB data not found! Did primary keys change?", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } finally { if (blobRs != null) { try { @@ -396,12 +398,12 @@ query.append(this.tableName); query.append(" WHERE "); - query.append((String) this.primaryKeyColumns.get(0)); + query.append(this.primaryKeyColumns.get(0)); query.append(" = ?"); for (int i = 1; i < this.numPrimaryKeys; i++) { query.append(" AND "); - query.append((String) this.primaryKeyColumns.get(i)); + query.append(this.primaryKeyColumns.get(i)); query.append(" = ?"); } @@ -412,7 +414,7 @@ pStmt.setBytes(1, pattern); for (int i = 0; i < this.numPrimaryKeys; i++) { - pStmt.setString(i + 2, (String) this.primaryKeyValues.get(i)); + pStmt.setString(i + 2, this.primaryKeyValues.get(i)); } blobRs = pStmt.executeQuery(); @@ -423,7 +425,7 @@ throw SQLError.createSQLException( "BLOB data not found! Did primary keys change?", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } finally { if (blobRs != null) { try { @@ -464,12 +466,12 @@ query.append(length); query.append(") WHERE "); - query.append((String) this.primaryKeyColumns.get(0)); + query.append(this.primaryKeyColumns.get(0)); query.append(" = ?"); for (int i = 1; i < this.numPrimaryKeys; i++) { query.append(" AND "); - query.append((String) this.primaryKeyColumns.get(i)); + query.append(this.primaryKeyColumns.get(i)); query.append(" = ?"); } @@ -479,15 +481,15 @@ .toString()); for (int i = 0; i < this.numPrimaryKeys; i++) { - pStmt.setString(i + 1, (String) this.primaryKeyValues.get(i)); + pStmt.setString(i + 1, this.primaryKeyValues.get(i)); } int rowsUpdated = pStmt.executeUpdate(); if (rowsUpdated != 1) { throw SQLError.createSQLException( "BLOB data not found! Did primary keys change?", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } finally { if (pStmt != null) { @@ -514,12 +516,12 @@ query.append(this.tableName); query.append(" WHERE "); - query.append((String) this.primaryKeyColumns.get(0)); + query.append(this.primaryKeyColumns.get(0)); query.append(" = ?"); for (int i = 1; i < this.numPrimaryKeys; i++) { query.append(" AND "); - query.append((String) this.primaryKeyColumns.get(i)); + query.append(this.primaryKeyColumns.get(i)); query.append(" = ?"); } @@ -538,18 +540,18 @@ pStmt.setInt(2, length); for (int i = 0; i < this.numPrimaryKeys; i++) { - pStmt.setString(i + 3, (String) this.primaryKeyValues.get(i)); + pStmt.setString(i + 3, this.primaryKeyValues.get(i)); } blobRs = pStmt.executeQuery(); if (blobRs.next()) { - return ((com.mysql.jdbc.ResultSet) blobRs).getBytes(1, true); + return ((com.mysql.jdbc.ResultSetImpl) blobRs).getBytes(1, true); } throw SQLError.createSQLException( "BLOB data not found! Did primary keys change?", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } finally { if (blobRs != null) { try { @@ -575,6 +577,30 @@ pStmt = createGetBytesStatement(); } + @SuppressWarnings("synthetic-access") + LocatorInputStream(long pos, long len) throws SQLException { + length = pos + len; + currentPositionInBlob = pos; + long blobLength = length(); + + if (pos + len > blobLength) { + throw SQLError.createSQLException( + Messages.getString("Blob.invalidStreamLength", + new Object[] {Long.valueOf(blobLength), Long.valueOf(pos), Long.valueOf(len)}), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + } + + if (pos < 1) { + throw SQLError.createSQLException(Messages.getString("Blob.invalidStreamPos"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + } + + if (pos > blobLength) { + throw SQLError.createSQLException(Messages.getString("Blob.invalidStreamPos"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + } + } + public int read() throws IOException { if (currentPositionInBlob + 1 > length) { return -1; @@ -667,4 +693,14 @@ super.close(); } } + + public void free() throws SQLException { + this.creatorResultSet = null; + this.primaryKeyColumns = null; + this.primaryKeyValues = null; + } + + public InputStream getBinaryStream(long pos, long length) throws SQLException { + return new LocatorInputStream(pos, length); + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Buffer.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Buffer.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Buffer.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Buffer.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,33 +1,30 @@ /* - Copyright (C) 2002-2005 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.UnsupportedEncodingException; - import java.nio.ByteBuffer; - import java.sql.SQLException; /** @@ -36,7 +33,7 @@ * @version $Id$ * @author Mark Matthews */ -class Buffer { +public class Buffer { static final int MAX_BYTES_TO_DUMP = 512; static final int NO_LENGTH_LIMIT = -1; @@ -51,7 +48,7 @@ protected boolean wasMultiPacket = false; - Buffer(byte[] buf) { + public Buffer(byte[] buf) { this.byteBuffer = buf; setBufLength(buf.length); } @@ -174,14 +171,24 @@ this.position += len; - return (int) len; // this is safe, as this is only + return (int) len; } + public void fastSkipLenByteArray() { + long len = this.readFieldLength(); + + if (len == NULL_LENGTH || len == 0) { + return; + } + + this.position += len; + } + protected final byte[] getBufferSource() { return this.byteBuffer; } - int getBufLength() { + public int getBufLength() { return this.bufLength; } @@ -237,6 +244,18 @@ return ((getBufLength() < 9) && ((this.byteBuffer[0] & 0xff) == 254)); } + final boolean isAuthMethodSwitchRequestPacket() { + return ((this.byteBuffer[0] & 0xff) == 254); + } + + final boolean isOKPacket() { + return ((this.byteBuffer[0] & 0xff) == 0); + } + + final boolean isRawPacket() { + return ((this.byteBuffer[0] & 0xff) == 1); + } + final long newReadLength() { int sw = this.byteBuffer[this.position++] & 0xff; @@ -398,7 +417,7 @@ // To avoid alloc'ing a new byte array, we // do this by hand, rather than calling getNullTerminatedBytes() // - final String readString() { + public final String readString() { int i = this.position; int len = 0; int maxLen = getBufLength(); @@ -408,13 +427,20 @@ i++; } - String s = new String(this.byteBuffer, this.position, len); + String s = StringUtils.toString(this.byteBuffer, this.position, len); this.position += (len + 1); // update cursor return s; } - final String readString(String encoding) throws SQLException { + /** + * Read string[NUL] + * @param encoding + * @param exceptionInterceptor + * @return + * @throws SQLException + */ + final String readString(String encoding, ExceptionInterceptor exceptionInterceptor) throws SQLException { int i = this.position; int len = 0; int maxLen = getBufLength(); @@ -425,16 +451,35 @@ } try { - return new String(this.byteBuffer, this.position, len, encoding); + return StringUtils.toString(this.byteBuffer, this.position, len, encoding); } catch (UnsupportedEncodingException uEE) { throw SQLError.createSQLException(Messages.getString("ByteArrayBuffer.1") //$NON-NLS-1$ - + encoding + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + + encoding + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); //$NON-NLS-1$ } finally { this.position += (len + 1); // update cursor } } - void setBufLength(int bufLengthToSet) { + /** + * Read string[$len] + */ + final String readString(String encoding, ExceptionInterceptor exceptionInterceptor, int expectedLength) throws SQLException { + if (this.position + expectedLength > getBufLength()) { + throw SQLError.createSQLException(Messages.getString("ByteArrayBuffer.2"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + } + + try { + return StringUtils.toString(this.byteBuffer, this.position, expectedLength, encoding); + } catch (UnsupportedEncodingException uEE) { + throw SQLError.createSQLException(Messages.getString("ByteArrayBuffer.1") //$NON-NLS-1$ + + encoding + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); //$NON-NLS-1$ + } finally { + this.position += expectedLength; // update cursor + } + } + + public void setBufLength(int bufLengthToSet) { this.bufLength = bufLengthToSet; } @@ -485,14 +530,14 @@ return this.wasMultiPacket; } - final void writeByte(byte b) throws SQLException { + public final void writeByte(byte b) throws SQLException { ensureCapacity(1); this.byteBuffer[this.position++] = b; } // Write a byte array - final void writeBytesNoNull(byte[] bytes) throws SQLException { + public final void writeBytesNoNull(byte[] bytes) throws SQLException { int len = bytes.length; ensureCapacity(len); System.arraycopy(bytes, 0, this.byteBuffer, this.position, len); @@ -564,15 +609,15 @@ // encoding final void writeLenString(String s, String encoding, String serverEncoding, SingleByteCharsetConverter converter, boolean parserKnowsUnicode, - Connection conn) + MySQLConnection conn) throws UnsupportedEncodingException, SQLException { byte[] b = null; if (converter != null) { b = converter.toBytes(s); } else { b = StringUtils.getBytes(s, encoding, serverEncoding, - parserKnowsUnicode, conn); + parserKnowsUnicode, conn, conn.getExceptionInterceptor()); } int len = b.length; @@ -617,14 +662,14 @@ // Write null-terminated string final void writeString(String s) throws SQLException { - ensureCapacity((s.length() * 2) + 1); + ensureCapacity((s.length() * 3) + 1); writeStringNoNull(s); this.byteBuffer[this.position++] = 0; } // Write null-terminated string in the given encoding - final void writeString(String s, String encoding, Connection conn) throws SQLException { - ensureCapacity((s.length() * 2) + 1); + final void writeString(String s, String encoding, MySQLConnection conn) throws SQLException { + ensureCapacity((s.length() * 3) + 1); try { writeStringNoNull(s, encoding, encoding, false, conn); } catch (UnsupportedEncodingException ue) { @@ -637,8 +682,8 @@ // Write string, with no termination final void writeStringNoNull(String s) throws SQLException { int len = s.length(); - ensureCapacity(len * 2); - System.arraycopy(s.getBytes(), 0, this.byteBuffer, this.position, len); + ensureCapacity(len * 3); + System.arraycopy(StringUtils.getBytes(s), 0, this.byteBuffer, this.position, len); this.position += len; // for (int i = 0; i < len; i++) @@ -650,10 +695,10 @@ // Write a String using the specified character // encoding final void writeStringNoNull(String s, String encoding, - String serverEncoding, boolean parserKnowsUnicode, Connection conn) + String serverEncoding, boolean parserKnowsUnicode, MySQLConnection conn) throws UnsupportedEncodingException, SQLException { byte[] b = StringUtils.getBytes(s, encoding, serverEncoding, - parserKnowsUnicode, conn); + parserKnowsUnicode, conn, conn.getExceptionInterceptor()); int len = b.length; ensureCapacity(len); Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/BufferRow.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ByteArrayRow.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/CacheAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/CacheAdapterFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/CachedResultSetMetaData.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/CachedResultSetMetaData.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/CachedResultSetMetaData.java 17 Aug 2012 14:57:08 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/CachedResultSetMetaData.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,40 +1,56 @@ /* - Copyright (C) 2007 MySQL AB + Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + */ package com.mysql.jdbc; import java.util.Map; -class CachedResultSetMetaData { +public class CachedResultSetMetaData { /** Map column names (and all of their permutations) to column indices */ - Map columnNameToIndex = null; + Map columnNameToIndex = null; /** Cached Field info */ Field[] fields; /** Map of fully-specified column names to column indices */ - Map fullColumnNameToIndex = null; + Map fullColumnNameToIndex = null; /** Cached ResultSetMetaData */ java.sql.ResultSetMetaData metadata; + + public Map getColumnNameToIndex() { + return columnNameToIndex; + } + + public Field[] getFields() { + return fields; + } + + public Map getFullColumnNameToIndex() { + return fullColumnNameToIndex; + } + + public java.sql.ResultSetMetaData getMetadata() { + return metadata; + } } \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/CallableStatement.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/CallableStatement.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/CallableStatement.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/CallableStatement.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,52 +1,50 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + */ + package com.mysql.jdbc; import java.io.InputStream; import java.io.Reader; import java.io.UnsupportedEncodingException; - +import java.lang.reflect.Constructor; import java.math.BigDecimal; - import java.net.URL; - import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Date; import java.sql.ParameterMetaData; import java.sql.Ref; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; import java.sql.Types; - import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Locale; import java.util.Map; /** @@ -58,7 +56,38 @@ */ public class CallableStatement extends PreparedStatement implements java.sql.CallableStatement { - class CallableStatementParam { + protected final static Constructor JDBC_4_CSTMT_2_ARGS_CTOR; + + protected final static Constructor JDBC_4_CSTMT_4_ARGS_CTOR; + + static { + if (Util.isJdbc4()) { + try { + JDBC_4_CSTMT_2_ARGS_CTOR = Class.forName( + "com.mysql.jdbc.JDBC4CallableStatement") + .getConstructor( + new Class[] { MySQLConnection.class, + CallableStatementParamInfo.class }); + JDBC_4_CSTMT_4_ARGS_CTOR = Class.forName( + "com.mysql.jdbc.JDBC4CallableStatement") + .getConstructor( + new Class[] { MySQLConnection.class, + String.class, String.class, + Boolean.TYPE }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_CSTMT_4_ARGS_CTOR = null; + JDBC_4_CSTMT_2_ARGS_CTOR = null; + } + } + + protected static class CallableStatementParam { int desiredJdbcType; int index; @@ -107,7 +136,7 @@ } } - class CallableStatementParamInfo { + protected class CallableStatementParamInfo { String catalogInUse; boolean isFunctionCall; @@ -116,11 +145,22 @@ int numParameters; - List parameterList; + List parameterList; - Map parameterMap; + Map parameterMap; + /** + * synchronized externally in checkReadOnlyProcedure() + */ + boolean isReadOnlySafeProcedure = false; + + /** + * synchronized externally in checkReadOnlyProcedure() + */ + boolean isReadOnlySafeChecked = false; + + /** * Constructor that converts a full list of parameter metadata into one * that only represents the placeholders present in the {CALL ()}. * @@ -131,11 +171,14 @@ this.nativeSql = originalSql; this.catalogInUse = currentCatalog; isFunctionCall = fullParamInfo.isFunctionCall; + @SuppressWarnings("synthetic-access") int[] localParameterMap = placeholderToParameterIndexMap; int parameterMapLength = localParameterMap.length; - parameterList = new ArrayList(fullParamInfo.numParameters); - parameterMap = new HashMap(fullParamInfo.numParameters); + this.isReadOnlySafeProcedure = fullParamInfo.isReadOnlySafeProcedure; + this.isReadOnlySafeChecked = fullParamInfo.isReadOnlySafeChecked; + parameterList = new ArrayList(fullParamInfo.numParameters); + parameterMap = new HashMap(fullParamInfo.numParameters); if (isFunctionCall) { // Take the return value @@ -146,7 +189,7 @@ for (int i = 0; i < parameterMapLength; i++) { if (localParameterMap[i] != 0) { - CallableStatementParam param = (CallableStatementParam)fullParamInfo.parameterList.get(localParameterMap[i] + offset); + CallableStatementParam param = fullParamInfo.parameterList.get(localParameterMap[i] + offset); parameterList.add(param); parameterMap.put(param.paramName, param); @@ -156,6 +199,7 @@ this.numParameters = parameterList.size(); } + @SuppressWarnings("synthetic-access") CallableStatementParamInfo(java.sql.ResultSet paramTypesRs) throws SQLException { boolean hadRows = paramTypesRs.last(); @@ -167,8 +211,8 @@ if (hadRows) { this.numParameters = paramTypesRs.getRow(); - this.parameterList = new ArrayList(this.numParameters); - this.parameterMap = new HashMap(this.numParameters); + this.parameterList = new ArrayList(this.numParameters); + this.parameterMap = new HashMap(this.numParameters); paramTypesRs.beforeFirst(); @@ -179,8 +223,8 @@ if (isFunctionCall) { this.numParameters += 1; - } } + } private void addParametersFromDBMD(java.sql.ResultSet paramTypesRs) throws SQLException { @@ -230,7 +274,7 @@ throw SQLError.createSQLException( Messages.getString("CallableStatement.11") + paramIndex //$NON-NLS-1$ + Messages.getString("CallableStatement.12") + numParameters //$NON-NLS-1$ - + Messages.getString("CallableStatement.13"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + + Messages.getString("CallableStatement.13"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); //$NON-NLS-1$ } } @@ -240,16 +284,15 @@ * @see java.lang.Object#clone() */ protected Object clone() throws CloneNotSupportedException { - // TODO Auto-generated method stub return super.clone(); } CallableStatementParam getParameter(int index) { - return (CallableStatementParam) this.parameterList.get(index); + return this.parameterList.get(index); } CallableStatementParam getParameter(String name) { - return (CallableStatementParam) this.parameterMap.get(name); + return this.parameterMap.get(name); } public String getParameterClassName(int arg0) throws SQLException { @@ -266,15 +309,15 @@ mysqlTypeIfKnown = MysqlDefs.FIELD_TYPE_INT24; } - return ResultSetMetaData.getClassNameForJavaType(getParameterType(arg0), - isUnsigned, mysqlTypeIfKnown, isBinaryOrBlob, false); + return ResultSetMetaData.getClassNameForJavaType(getParameterType(arg0), isUnsigned, mysqlTypeIfKnown, + isBinaryOrBlob, false, connection.getYearIsDateType()); } public int getParameterCount() throws SQLException { if (this.parameterList == null) { return 0; } - + return this.parameterList.size(); } @@ -320,7 +363,7 @@ return false; } - Iterator iterator() { + Iterator iterator() { return this.parameterList.iterator(); } @@ -335,7 +378,7 @@ * quite a bit out there in the wild (Websphere, FreeBSD, anyone?) */ - class CallableStatementParamInfoJDBC3 extends CallableStatementParamInfo + protected class CallableStatementParamInfoJDBC3 extends CallableStatementParamInfo implements ParameterMetaData { CallableStatementParamInfoJDBC3(java.sql.ResultSet paramTypesRs) @@ -346,13 +389,62 @@ public CallableStatementParamInfoJDBC3(CallableStatementParamInfo paramInfo) { super(paramInfo); } + + /** + * Returns true if this either implements the interface argument or is directly or indirectly a wrapper + * for an object that does. Returns false otherwise. If this implements the interface then return true, + * else if this is a wrapper then return the result of recursively calling isWrapperFor on the wrapped + * object. If this does not implement the interface and is not a wrapper, return false. + * This method should be implemented as a low-cost operation compared to unwrap so that + * callers can use this method to avoid expensive unwrap calls that may fail. If this method + * returns true then calling unwrap with the same argument should succeed. + * + * @param interfaces a Class defining an interface. + * @return true if this implements the interface or directly or indirectly wraps an object that does. + * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper + * for an object with the given interface. + * @since 1.6 + */ + public boolean isWrapperFor(Class iface) throws SQLException { + checkClosed(); + + // This works for classes that aren't actually wrapping + // anything + return iface.isInstance(this); + } + + /** + * Returns an object that implements the given interface to allow access to non-standard methods, + * or standard methods not exposed by the proxy. + * The result may be either the object found to implement the interface or a proxy for that object. + * If the receiver implements the interface then that is the object. If the receiver is a wrapper + * and the wrapped object implements the interface then that is the object. Otherwise the object is + * the result of calling unwrap recursively on the wrapped object. If the receiver is not a + * wrapper and does not implement the interface, then an SQLException is thrown. + * + * @param iface A Class defining an interface that the result must implement. + * @return an object that implements the interface. May be a proxy for the actual implementing object. + * @throws java.sql.SQLException If no object found that implements the interface + * @since 1.6 + */ + public Object unwrap(Class iface) throws java.sql.SQLException { + try { + // This works for classes that aren't actually wrapping + // anything + return Util.cast(iface, this); + } catch (ClassCastException cce) { + throw SQLError.createSQLException("Unable to unwrap to " + iface.toString(), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + } } private final static int NOT_OUTPUT_PARAMETER_INDICATOR = Integer.MIN_VALUE; private final static String PARAMETER_NAMESPACE_PREFIX = "@com_mysql_jdbc_outparam_"; //$NON-NLS-1$ private static String mangleParameterName(String origParameterName) { + //Fixed for 5.5+ in callers if (origParameterName == null) { return null; } @@ -375,22 +467,22 @@ private boolean callingStoredFunction = false; - private ResultSet functionReturnValueResults; + private ResultSetInternalMethods functionReturnValueResults; private boolean hasOutputParams = false; // private List parameterList; // private Map parameterMap; - private ResultSet outputParameterResults; + private ResultSetInternalMethods outputParameterResults; - private boolean outputParamWasNull = false; + protected boolean outputParamWasNull = false; private int[] parameterIndexToRsIndex; protected CallableStatementParamInfo paramInfo; private CallableStatementParam returnValueParam; - + /** * Creates a new CallableStatement * @@ -402,7 +494,7 @@ * @throws SQLException * if an error occurs */ - public CallableStatement(Connection conn, + public CallableStatement(MySQLConnection conn, CallableStatementParamInfo paramInfo) throws SQLException { super(conn, paramInfo.nativeSql, paramInfo.catalogInUse); @@ -412,85 +504,105 @@ if (this.callingStoredFunction) { this.parameterCount += 1; } + + this.retrieveGeneratedKeys = true; // not provided for in the JDBC spec } /** - * Creates a new CallableStatement - * - * @param conn - * the connection creating this statement - * @param catalog - * catalog the current catalog - * - * @throws SQLException - * if an error occurs + * Creates a callable statement instance -- We need to provide factory-style methods + * so we can support both JDBC3 (and older) and JDBC4 runtimes, otherwise + * the class verifier complains when it tries to load JDBC4-only interface + * classes that are present in JDBC4 method signatures. */ - public CallableStatement(Connection conn, String catalog) - throws SQLException { - super(conn, catalog, null); - determineParameterTypes(); - generateParameterMap(); - - if (this.callingStoredFunction) { - this.parameterCount += 1; + protected static CallableStatement getInstance(MySQLConnection conn, String sql, + String catalog, boolean isFunctionCall) throws SQLException { + if (!Util.isJdbc4()) { + return new CallableStatement(conn, sql, catalog, isFunctionCall); } + + return (CallableStatement) Util.handleNewInstance( + JDBC_4_CSTMT_4_ARGS_CTOR, new Object[] { conn, sql, catalog, + Boolean.valueOf(isFunctionCall) }, conn.getExceptionInterceptor()); } + + /** + * Creates a callable statement instance -- We need to provide factory-style methods + * so we can support both JDBC3 (and older) and JDBC4 runtimes, otherwise + * the class verifier complains when it tries to load JDBC4-only interface + * classes that are present in JDBC4 method signatures. + */ + protected static CallableStatement getInstance(MySQLConnection conn, + CallableStatementParamInfo paramInfo) throws SQLException { + if (!Util.isJdbc4()) { + return new CallableStatement(conn, paramInfo); + } + + return (CallableStatement) Util.handleNewInstance( + JDBC_4_CSTMT_2_ARGS_CTOR, new Object[] { conn, paramInfo }, conn.getExceptionInterceptor()); + + } + private int[] placeholderToParameterIndexMap; - private void generateParameterMap() throws SQLException { - // if the user specified some parameters as literals, we need to - // provide a map from the specified placeholders to the actual - // parameter numbers - - int parameterCountFromMetaData = this.paramInfo.getParameterCount(); - - // Ignore the first ? if this is a stored function, it doesn't count - - if (this.callingStoredFunction) { - parameterCountFromMetaData--; - } - - if (this.paramInfo != null && - this.parameterCount != parameterCountFromMetaData) { - this.placeholderToParameterIndexMap = new int[this.parameterCount]; + synchronized (checkClosed().getConnectionMutex()) { + if (this.paramInfo == null) { + return; + } - int startPos = this.callingStoredFunction ? StringUtils.indexOfIgnoreCase(this.originalSql, - "SELECT") : StringUtils.indexOfIgnoreCase(this.originalSql, "CALL"); + // if the user specified some parameters as literals, we need to + // provide a map from the specified placeholders to the actual + // parameter numbers - if (startPos != -1) { - int parenOpenPos = this.originalSql.indexOf('(', startPos + 4); + int parameterCountFromMetaData = this.paramInfo.getParameterCount(); + + // Ignore the first ? if this is a stored function, it doesn't count + + if (this.callingStoredFunction) { + parameterCountFromMetaData--; + } + + if (this.paramInfo != null && + this.parameterCount != parameterCountFromMetaData) { + this.placeholderToParameterIndexMap = new int[this.parameterCount]; - if (parenOpenPos != -1) { - int parenClosePos = StringUtils.indexOfIgnoreCaseRespectQuotes(parenOpenPos, - this.originalSql, ")", '\'', true); + int startPos = this.callingStoredFunction ? StringUtils.indexOfIgnoreCase(this.originalSql, + "SELECT") : StringUtils.indexOfIgnoreCase(this.originalSql, "CALL"); + + if (startPos != -1) { + int parenOpenPos = this.originalSql.indexOf('(', startPos + 4); - if (parenClosePos != -1) { - List parsedParameters = StringUtils.split(this.originalSql.substring(parenOpenPos + 1, parenClosePos), ",", "'\"", "'\"", true); + if (parenOpenPos != -1) { + int parenClosePos = StringUtils.indexOfIgnoreCaseRespectQuotes(parenOpenPos, + this.originalSql, ")", '\'', true); - int numParsedParameters = parsedParameters.size(); - - // sanity check - - if (numParsedParameters != this.parameterCount) { - // bail? - } - - int placeholderCount = 0; - - for (int i = 0; i < numParsedParameters; i++) { - if (((String)parsedParameters.get(i)).equals("?")) { - this.placeholderToParameterIndexMap[placeholderCount++] = i; + if (parenClosePos != -1) { + List parsedParameters = StringUtils.split(this.originalSql.substring(parenOpenPos + 1, parenClosePos), ",", "'\"", "'\"", true); + + int numParsedParameters = parsedParameters.size(); + + // sanity check + + if (numParsedParameters != this.parameterCount) { + // bail? } + + int placeholderCount = 0; + + for (int i = 0; i < numParsedParameters; i++) { + if (((String)parsedParameters.get(i)).equals("?")) { + this.placeholderToParameterIndexMap[placeholderCount++] = i; + } + } } } } } } } - + /** * Creates a new CallableStatement * @@ -504,18 +616,29 @@ * @throws SQLException * if an error occurs */ - public CallableStatement(Connection conn, String sql, String catalog, + public CallableStatement(MySQLConnection conn, String sql, String catalog, boolean isFunctionCall) throws SQLException { super(conn, sql, catalog); this.callingStoredFunction = isFunctionCall; - determineParameterTypes(); - generateParameterMap(); - - if (this.callingStoredFunction) { + if (!this.callingStoredFunction) { + if (!StringUtils.startsWithIgnoreCaseAndWs(sql, "CALL")) { + // not really a stored procedure call + fakeParameterTypes(false); + } else { + determineParameterTypes(); + } + + generateParameterMap(); + } else { + determineParameterTypes(); + generateParameterMap(); + this.parameterCount += 1; } + + this.retrieveGeneratedKeys = true; // not provided for in the JDBC spec } /* @@ -532,51 +655,53 @@ private CallableStatementParam checkIsOutputParam(int paramIndex) throws SQLException { - if (this.callingStoredFunction) { - if (paramIndex == 1) { - - if (this.returnValueParam == null) { - this.returnValueParam = new CallableStatementParam("", 0, - false, true, Types.VARCHAR, "VARCHAR", 0, 0, - DatabaseMetaData.attributeNullableUnknown, - DatabaseMetaData.procedureColumnReturn); + synchronized (checkClosed().getConnectionMutex()) { + if (this.callingStoredFunction) { + if (paramIndex == 1) { + + if (this.returnValueParam == null) { + this.returnValueParam = new CallableStatementParam("", 0, + false, true, Types.VARCHAR, "VARCHAR", 0, 0, + DatabaseMetaData.attributeNullableUnknown, + DatabaseMetaData.procedureColumnReturn); + } + + return this.returnValueParam; } - - return this.returnValueParam; + + // Move to position in output result set + paramIndex--; } - - // Move to position in output result set - paramIndex--; + + checkParameterIndexBounds(paramIndex); + + int localParamIndex = paramIndex - 1; + + if (this.placeholderToParameterIndexMap != null) { + localParamIndex = this.placeholderToParameterIndexMap[localParamIndex]; + } + + CallableStatementParam paramDescriptor = this.paramInfo + .getParameter(localParamIndex); + + // We don't have reliable metadata in this case, trust + // the caller + + if (this.connection.getNoAccessToProcedureBodies()) { + paramDescriptor.isOut = true; + paramDescriptor.isIn = true; + paramDescriptor.inOutModifier = DatabaseMetaData.procedureColumnInOut; + } else if (!paramDescriptor.isOut) { + throw SQLError.createSQLException( + Messages.getString("CallableStatement.9") + paramIndex //$NON-NLS-1$ + + Messages.getString("CallableStatement.10"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + + this.hasOutputParams = true; + + return paramDescriptor; } - - checkParameterIndexBounds(paramIndex); - - int localParamIndex = paramIndex - 1; - - if (this.placeholderToParameterIndexMap != null) { - localParamIndex = this.placeholderToParameterIndexMap[localParamIndex]; - } - - CallableStatementParam paramDescriptor = this.paramInfo - .getParameter(localParamIndex); - - // We don't have reliable metadata in this case, trust - // the caller - - if (this.connection.getNoAccessToProcedureBodies()) { - paramDescriptor.isOut = true; - paramDescriptor.isIn = true; - paramDescriptor.inOutModifier = DatabaseMetaData.procedureColumnInOut; - } else if (!paramDescriptor.isOut) { - throw SQLError.createSQLException( - Messages.getString("CallableStatement.9") + paramIndex //$NON-NLS-1$ - + Messages.getString("CallableStatement.10"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - this.hasOutputParams = true; - - return paramDescriptor; } /** @@ -587,7 +712,9 @@ * @throws SQLException */ private void checkParameterIndexBounds(int paramIndex) throws SQLException { - this.paramInfo.checkBounds(paramIndex); + synchronized (checkClosed().getConnectionMutex()) { + this.paramInfo.checkBounds(paramIndex); + } } /** @@ -601,19 +728,21 @@ private void checkStreamability() throws SQLException { if (this.hasOutputParams && createStreamingResultSet()) { throw SQLError.createSQLException(Messages.getString("CallableStatement.14"), //$NON-NLS-1$ - SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); + SQLError.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor()); } } - public synchronized void clearParameters() throws SQLException { - super.clearParameters(); - - try { - if (this.outputParameterResults != null) { - this.outputParameterResults.close(); + public void clearParameters() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + super.clearParameters(); + + try { + if (this.outputParameterResults != null) { + this.outputParameterResults.close(); + } + } finally { + this.outputParameterResults = null; } - } finally { - this.outputParameterResults = null; } } @@ -623,120 +752,155 @@ * * @throws SQLException if we can't build the metadata. */ - private void fakeParameterTypes() throws SQLException { - Field[] fields = new Field[13]; - - fields[0] = new Field("", "PROCEDURE_CAT", Types.CHAR, 0); - fields[1] = new Field("", "PROCEDURE_SCHEM", Types.CHAR, 0); - fields[2] = new Field("", "PROCEDURE_NAME", Types.CHAR, 0); - fields[3] = new Field("", "COLUMN_NAME", Types.CHAR, 0); - fields[4] = new Field("", "COLUMN_TYPE", Types.CHAR, 0); - fields[5] = new Field("", "DATA_TYPE", Types.SMALLINT, 0); - fields[6] = new Field("", "TYPE_NAME", Types.CHAR, 0); - fields[7] = new Field("", "PRECISION", Types.INTEGER, 0); - fields[8] = new Field("", "LENGTH", Types.INTEGER, 0); - fields[9] = new Field("", "SCALE", Types.SMALLINT, 0); - fields[10] = new Field("", "RADIX", Types.SMALLINT, 0); - fields[11] = new Field("", "NULLABLE", Types.SMALLINT, 0); - fields[12] = new Field("", "REMARKS", Types.CHAR, 0); - - String procName = extractProcedureName(); - - byte[] procNameAsBytes = null; - - try { - procNameAsBytes = procName.getBytes("UTF-8"); - } catch (UnsupportedEncodingException ueEx) { - procNameAsBytes = StringUtils.s2b(procName, this.connection); + private void fakeParameterTypes(boolean isReallyProcedure) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + Field[] fields = new Field[13]; + + fields[0] = new Field("", "PROCEDURE_CAT", Types.CHAR, 0); + fields[1] = new Field("", "PROCEDURE_SCHEM", Types.CHAR, 0); + fields[2] = new Field("", "PROCEDURE_NAME", Types.CHAR, 0); + fields[3] = new Field("", "COLUMN_NAME", Types.CHAR, 0); + fields[4] = new Field("", "COLUMN_TYPE", Types.CHAR, 0); + fields[5] = new Field("", "DATA_TYPE", Types.SMALLINT, 0); + fields[6] = new Field("", "TYPE_NAME", Types.CHAR, 0); + fields[7] = new Field("", "PRECISION", Types.INTEGER, 0); + fields[8] = new Field("", "LENGTH", Types.INTEGER, 0); + fields[9] = new Field("", "SCALE", Types.SMALLINT, 0); + fields[10] = new Field("", "RADIX", Types.SMALLINT, 0); + fields[11] = new Field("", "NULLABLE", Types.SMALLINT, 0); + fields[12] = new Field("", "REMARKS", Types.CHAR, 0); + + String procName = isReallyProcedure ? extractProcedureName() : null; + + byte[] procNameAsBytes = null; + + try { + procNameAsBytes = procName == null ? null : StringUtils.getBytes(procName, "UTF-8"); + } catch (UnsupportedEncodingException ueEx) { + procNameAsBytes = StringUtils.s2b(procName, this.connection); + } + + ArrayList resultRows = new ArrayList(); + + for (int i = 0; i < this.parameterCount; i++) { + byte[][] row = new byte[13][]; + row[0] = null; // PROCEDURE_CAT + row[1] = null; // PROCEDURE_SCHEM + row[2] = procNameAsBytes; // PROCEDURE/NAME + row[3] = StringUtils.s2b(String.valueOf(i), this.connection); // COLUMN_NAME + + row[4] = StringUtils.s2b(String + .valueOf(DatabaseMetaData.procedureColumnIn), + this.connection); + + row[5] = StringUtils.s2b(String.valueOf(Types.VARCHAR), + this.connection); // DATA_TYPE + row[6] = StringUtils.s2b("VARCHAR", this.connection); // TYPE_NAME + row[7] = StringUtils.s2b(Integer.toString(65535), this.connection); // PRECISION + row[8] = StringUtils.s2b(Integer.toString(65535), this.connection); // LENGTH + row[9] = StringUtils.s2b(Integer.toString(0), this.connection); // SCALE + row[10] = StringUtils.s2b(Integer.toString(10), this.connection); // RADIX + + row[11] = StringUtils.s2b(Integer + .toString(DatabaseMetaData.procedureNullableUnknown), + this.connection); // nullable + + row[12] = null; + + resultRows.add(new ByteArrayRow(row, getExceptionInterceptor())); + } + + java.sql.ResultSet paramTypesRs = DatabaseMetaData.buildResultSet( + fields, resultRows, this.connection); + + convertGetProcedureColumnsToInternalDescriptors(paramTypesRs); } - - ArrayList resultRows = new ArrayList(); - - for (int i = 0; i < this.parameterCount; i++) { - byte[][] row = new byte[13][]; - row[0] = null; // PROCEDURE_CAT - row[1] = null; // PROCEDURE_SCHEM - row[2] = procNameAsBytes; // PROCEDURE/NAME - row[3] = StringUtils.s2b(String.valueOf(i), this.connection); // COLUMN_NAME - - row[4] = StringUtils.s2b(String - .valueOf(DatabaseMetaData.procedureColumnIn), - this.connection); - - row[5] = StringUtils.s2b(String.valueOf(Types.VARCHAR), - this.connection); // DATA_TYPE - row[6] = StringUtils.s2b("VARCHAR", this.connection); // TYPE_NAME - row[7] = StringUtils.s2b(Integer.toString(65535), this.connection); // PRECISION - row[8] = StringUtils.s2b(Integer.toString(65535), this.connection); // LENGTH - row[9] = StringUtils.s2b(Integer.toString(0), this.connection); // SCALE - row[10] = StringUtils.s2b(Integer.toString(10), this.connection); // RADIX - - row[11] = StringUtils.s2b(Integer - .toString(DatabaseMetaData.procedureNullableUnknown), - this.connection); // nullable - - row[12] = null; - - resultRows.add(row); - } - - java.sql.ResultSet paramTypesRs = DatabaseMetaData.buildResultSet( - fields, resultRows, this.connection); - - convertGetProcedureColumnsToInternalDescriptors(paramTypesRs); } private void determineParameterTypes() throws SQLException { - if (this.connection.getNoAccessToProcedureBodies()) { - fakeParameterTypes(); - - return; - } - - java.sql.ResultSet paramTypesRs = null; - - try { - String procName = extractProcedureName(); - - java.sql.DatabaseMetaData dbmd = this.connection.getMetaData(); - - boolean useCatalog = false; - - if (procName.indexOf(".") == -1) { - useCatalog = true; - } - - paramTypesRs = dbmd.getProcedureColumns(this.connection - .versionMeetsMinimum(5, 0, 2) - && useCatalog ? this.currentCatalog : null, null, procName, - "%"); //$NON-NLS-1$ - - convertGetProcedureColumnsToInternalDescriptors(paramTypesRs); - } finally { - SQLException sqlExRethrow = null; - - if (paramTypesRs != null) { + synchronized (checkClosed().getConnectionMutex()) { + java.sql.ResultSet paramTypesRs = null; + + try { + //Bug#57022, we need to check for db.SPname notation first + // and pass on only SPname + String procName = extractProcedureName(); + String quotedId = ""; try { - paramTypesRs.close(); + quotedId = this.connection.supportsQuotedIdentifiers() ? + this.connection.getMetaData().getIdentifierQuoteString() : ""; } catch (SQLException sqlEx) { - sqlExRethrow = sqlEx; + // Forced by API, never thrown from getIdentifierQuoteString() in + // this implementation. + AssertionFailedException.shouldNotHappen(sqlEx); } - - paramTypesRs = null; + + List parseList = StringUtils.splitDBdotName(procName, "", + quotedId , this.connection.isNoBackslashEscapesSet()); + String tmpCatalog = ""; + //There *should* be 2 rows, if any. + if (parseList.size() == 2) { + tmpCatalog = (String) parseList.get(0); + procName = (String) parseList.get(1); + } else { + //keep values as they are + } + + java.sql.DatabaseMetaData dbmd = this.connection.getMetaData(); + + boolean useCatalog = false; + + if (tmpCatalog.length() <= 0) { + useCatalog = true; + } + + paramTypesRs = dbmd.getProcedureColumns(this.connection + .versionMeetsMinimum(5, 0, 2) + && useCatalog ? this.currentCatalog : tmpCatalog/*null*/, null, procName, + "%"); //$NON-NLS-1$ + + boolean hasResults = false; + try { + if (paramTypesRs.next()) { + paramTypesRs.previous(); + hasResults = true; + } + } catch (Exception e) { + // paramTypesRs is empty, proceed with fake params. swallow, was expected + } + if (hasResults){ + convertGetProcedureColumnsToInternalDescriptors(paramTypesRs); + } else { + fakeParameterTypes(true); + } + } finally { + SQLException sqlExRethrow = null; + + if (paramTypesRs != null) { + try { + paramTypesRs.close(); + } catch (SQLException sqlEx) { + sqlExRethrow = sqlEx; + } + + paramTypesRs = null; + } + + if (sqlExRethrow != null) { + throw sqlExRethrow; + } } - - if (sqlExRethrow != null) { - throw sqlExRethrow; - } } } private void convertGetProcedureColumnsToInternalDescriptors(java.sql.ResultSet paramTypesRs) throws SQLException { - if (!this.connection.isRunningOnJDK13()) { - this.paramInfo = new CallableStatementParamInfoJDBC3( - paramTypesRs); - } else { - this.paramInfo = new CallableStatementParamInfo(paramTypesRs); + synchronized (checkClosed().getConnectionMutex()) { + if (!this.connection.isRunningOnJDK13()) { + this.paramInfo = new CallableStatementParamInfoJDBC3( + paramTypesRs); + } else { + this.paramInfo = new CallableStatementParamInfo(paramTypesRs); + } } } @@ -746,13 +910,11 @@ * @see java.sql.PreparedStatement#execute() */ public boolean execute() throws SQLException { - boolean returnVal = false; + synchronized (checkClosed().getConnectionMutex()) { + boolean returnVal = false; - checkClosed(); + checkStreamability(); - checkStreamability(); - - synchronized (this.connection.getMutex()) { setInOutParamsOnServer(); setOutParams(); @@ -765,14 +927,15 @@ } retrieveOutParams(); - } + - if (!this.callingStoredFunction) { - return returnVal; + if (!this.callingStoredFunction) { + return returnVal; + } + + // Functions can't return results + return false; } - - // Functions can't return results - return false; } /* @@ -781,22 +944,21 @@ * @see java.sql.PreparedStatement#executeQuery() */ public java.sql.ResultSet executeQuery() throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - checkStreamability(); + checkStreamability(); + + java.sql.ResultSet execResults = null; - java.sql.ResultSet execResults = null; - - synchronized (this.connection.getMutex()) { setInOutParamsOnServer(); setOutParams(); execResults = super.executeQuery(); retrieveOutParams(); + + return execResults; } - - return execResults; } /* @@ -805,28 +967,27 @@ * @see java.sql.PreparedStatement#executeUpdate() */ public int executeUpdate() throws SQLException { - int returnVal = -1; + synchronized (checkClosed().getConnectionMutex()) { + int returnVal = -1; + + + checkStreamability(); + + if (this.callingStoredFunction) { + execute(); + + return -1; + } - checkClosed(); - - checkStreamability(); - - if (this.callingStoredFunction) { - execute(); - - return -1; - } - - synchronized (this.connection.getMutex()) { setInOutParamsOnServer(); setOutParams(); returnVal = super.executeUpdate(); retrieveOutParams(); - } - return returnVal; + return returnVal; + } } private String extractProcedureName() throws SQLException { @@ -866,7 +1027,7 @@ } throw SQLError.createSQLException(Messages.getString("CallableStatement.1"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } /** @@ -880,70 +1041,76 @@ * @throws SQLException * if the parameter name is null or empty. */ - private String fixParameterName(String paramNameIn) throws SQLException { - if ((paramNameIn == null) || (paramNameIn.length() == 0)) { - throw SQLError.createSQLException( - ((Messages.getString("CallableStatement.0") + paramNameIn) == null) //$NON-NLS-1$ - ? Messages.getString("CallableStatement.15") : Messages.getString("CallableStatement.16"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$ + protected String fixParameterName(String paramNameIn) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + //Fixed for 5.5+ + if (((paramNameIn == null) || (paramNameIn.length() == 0)) && (!hasParametersView())) { + throw SQLError.createSQLException( + ((Messages.getString("CallableStatement.0") + paramNameIn) == null) //$NON-NLS-1$ + ? Messages.getString("CallableStatement.15") : Messages.getString("CallableStatement.16"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, + getExceptionInterceptor()); //$NON-NLS-1$ //$NON-NLS-2$ + } + + if ((paramNameIn == null) && (hasParametersView())) { + paramNameIn = "nullpn"; + }; + + if (this.connection.getNoAccessToProcedureBodies()) { + throw SQLError.createSQLException("No access to parameters by name when connection has been configured not to access procedure bodies", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + + return mangleParameterName(paramNameIn); } - - if (this.connection.getNoAccessToProcedureBodies()) { - throw SQLError.createSQLException("No access to parameters by name when connection has been configured not to access procedure bodies", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - return mangleParameterName(paramNameIn); - - /* - * if (paramNameIn.startsWith("@")) { return paramNameIn; } else { - * StringBuffer paramNameBuf = new StringBuffer("@"); - * paramNameBuf.append(paramNameIn); - * - * return paramNameBuf.toString(); } - */ } /** * @see java.sql.CallableStatement#getArray(int) */ - public synchronized Array getArray(int i) throws SQLException { - ResultSet rs = getOutputParameters(i); - - Array retValue = rs.getArray(mapOutputParameterIndexToRsIndex(i)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Array getArray(int i) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(i); + + Array retValue = rs.getArray(mapOutputParameterIndexToRsIndex(i)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getArray(java.lang.String) */ - public synchronized Array getArray(String parameterName) + public Array getArray(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Array retValue = rs.getArray(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Array retValue = rs.getArray(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getBigDecimal(int) */ - public synchronized BigDecimal getBigDecimal(int parameterIndex) + public BigDecimal getBigDecimal(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - BigDecimal retValue = rs - .getBigDecimal(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + BigDecimal retValue = rs + .getBigDecimal(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** @@ -962,456 +1129,543 @@ * @see java.sql.CallableStatement#getBigDecimal(int, int) * @deprecated */ - public synchronized BigDecimal getBigDecimal(int parameterIndex, int scale) + public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - BigDecimal retValue = rs.getBigDecimal( - mapOutputParameterIndexToRsIndex(parameterIndex), scale); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + BigDecimal retValue = rs.getBigDecimal( + mapOutputParameterIndexToRsIndex(parameterIndex), scale); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getBigDecimal(java.lang.String) */ - public synchronized BigDecimal getBigDecimal(String parameterName) + public BigDecimal getBigDecimal(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - BigDecimal retValue = rs.getBigDecimal(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + BigDecimal retValue = rs.getBigDecimal(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getBlob(int) */ - public synchronized Blob getBlob(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - Blob retValue = rs - .getBlob(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Blob getBlob(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Blob retValue = rs + .getBlob(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getBlob(java.lang.String) */ - public synchronized Blob getBlob(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Blob retValue = rs.getBlob(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Blob getBlob(String parameterName) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Blob retValue = rs.getBlob(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getBoolean(int) */ - public synchronized boolean getBoolean(int parameterIndex) + public boolean getBoolean(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - boolean retValue = rs - .getBoolean(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + boolean retValue = rs + .getBoolean(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getBoolean(java.lang.String) */ - public synchronized boolean getBoolean(String parameterName) + public boolean getBoolean(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - boolean retValue = rs.getBoolean(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + boolean retValue = rs.getBoolean(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getByte(int) */ - public synchronized byte getByte(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - byte retValue = rs - .getByte(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public byte getByte(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + byte retValue = rs + .getByte(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getByte(java.lang.String) */ - public synchronized byte getByte(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - byte retValue = rs.getByte(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public byte getByte(String parameterName) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + byte retValue = rs.getByte(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getBytes(int) */ - public synchronized byte[] getBytes(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - byte[] retValue = rs - .getBytes(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public byte[] getBytes(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + byte[] retValue = rs + .getBytes(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getBytes(java.lang.String) */ - public synchronized byte[] getBytes(String parameterName) + public byte[] getBytes(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - byte[] retValue = rs.getBytes(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + byte[] retValue = rs.getBytes(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getClob(int) */ - public synchronized Clob getClob(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - Clob retValue = rs - .getClob(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Clob getClob(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Clob retValue = rs + .getClob(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getClob(java.lang.String) */ - public synchronized Clob getClob(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Clob retValue = rs.getClob(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Clob getClob(String parameterName) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Clob retValue = rs.getClob(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getDate(int) */ - public synchronized Date getDate(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - Date retValue = rs - .getDate(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Date getDate(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Date retValue = rs + .getDate(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getDate(int, java.util.Calendar) */ - public synchronized Date getDate(int parameterIndex, Calendar cal) + public Date getDate(int parameterIndex, Calendar cal) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - Date retValue = rs.getDate( - mapOutputParameterIndexToRsIndex(parameterIndex), cal); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Date retValue = rs.getDate( + mapOutputParameterIndexToRsIndex(parameterIndex), cal); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getDate(java.lang.String) */ - public synchronized Date getDate(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Date retValue = rs.getDate(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Date getDate(String parameterName) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Date retValue = rs.getDate(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getDate(java.lang.String, * java.util.Calendar) */ - public synchronized Date getDate(String parameterName, Calendar cal) + public Date getDate(String parameterName, Calendar cal) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Date retValue = rs.getDate(fixParameterName(parameterName), cal); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Date retValue = rs.getDate(fixParameterName(parameterName), cal); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getDouble(int) */ - public synchronized double getDouble(int parameterIndex) + public double getDouble(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - double retValue = rs - .getDouble(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + double retValue = rs + .getDouble(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getDouble(java.lang.String) */ - public synchronized double getDouble(String parameterName) + public double getDouble(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - double retValue = rs.getDouble(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + double retValue = rs.getDouble(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getFloat(int) */ - public synchronized float getFloat(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - float retValue = rs - .getFloat(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public float getFloat(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + float retValue = rs + .getFloat(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getFloat(java.lang.String) */ - public synchronized float getFloat(String parameterName) + public float getFloat(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - float retValue = rs.getFloat(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + float retValue = rs.getFloat(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getInt(int) */ - public synchronized int getInt(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - int retValue = rs - .getInt(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public int getInt(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + int retValue = rs + .getInt(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getInt(java.lang.String) */ - public synchronized int getInt(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - int retValue = rs.getInt(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public int getInt(String parameterName) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + int retValue = rs.getInt(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getLong(int) */ - public synchronized long getLong(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - long retValue = rs - .getLong(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public long getLong(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + long retValue = rs + .getLong(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getLong(java.lang.String) */ - public synchronized long getLong(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - long retValue = rs.getLong(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public long getLong(String parameterName) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + long retValue = rs.getLong(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } - private int getNamedParamIndex(String paramName, boolean forOut) + protected int getNamedParamIndex(String paramName, boolean forOut) throws SQLException { - if (this.connection.getNoAccessToProcedureBodies()) { - throw SQLError.createSQLException("No access to parameters by name when connection has been configured not to access procedure bodies", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - if ((paramName == null) || (paramName.length() == 0)) { - throw SQLError.createSQLException(Messages.getString("CallableStatement.2"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - CallableStatementParam namedParamInfo = this.paramInfo - .getParameter(paramName); - - if (this.paramInfo == null) { - throw SQLError.createSQLException( - Messages.getString("CallableStatement.3") + paramName + Messages.getString("CallableStatement.4"), //$NON-NLS-1$ //$NON-NLS-2$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - if (forOut && !namedParamInfo.isOut) { - throw SQLError.createSQLException( - Messages.getString("CallableStatement.5") + paramName //$NON-NLS-1$ - + Messages.getString("CallableStatement.6"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - - if (this.placeholderToParameterIndexMap == null) { - return namedParamInfo.index + 1; // JDBC indices are 1-based - } - - for (int i = 0; i < this.placeholderToParameterIndexMap.length; i++) { - if (this.placeholderToParameterIndexMap[i] == namedParamInfo.index) { - return i + 1; + synchronized (checkClosed().getConnectionMutex()) { + if (this.connection.getNoAccessToProcedureBodies()) { + throw SQLError.createSQLException("No access to parameters by name when connection has been configured not to access procedure bodies", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } + + //Fixed for 5.5+ in callers + if ((paramName == null) || (paramName.length() == 0)) { + throw SQLError.createSQLException(Messages.getString("CallableStatement.2"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + + if (this.paramInfo == null) { + throw SQLError.createSQLException( + Messages.getString("CallableStatement.3") + paramName + Messages.getString("CallableStatement.4"), //$NON-NLS-1$ //$NON-NLS-2$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + + CallableStatementParam namedParamInfo = this.paramInfo + .getParameter(paramName); + + if (forOut && !namedParamInfo.isOut) { + throw SQLError.createSQLException( + Messages.getString("CallableStatement.5") + paramName //$NON-NLS-1$ + + Messages.getString("CallableStatement.6"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + + + if (this.placeholderToParameterIndexMap == null) { + return namedParamInfo.index + 1; // JDBC indices are 1-based + } + + for (int i = 0; i < this.placeholderToParameterIndexMap.length; i++) { + if (this.placeholderToParameterIndexMap[i] == namedParamInfo.index) { + return i + 1; + } + } + + throw SQLError.createSQLException("Can't find local placeholder mapping for parameter named \"" + + paramName + "\".", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } - - throw SQLError.createSQLException("Can't find local placeholder mapping for parameter named \"" + - paramName + "\".", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } /** * @see java.sql.CallableStatement#getObject(int) */ - public synchronized Object getObject(int parameterIndex) + public Object getObject(int parameterIndex) throws SQLException { - CallableStatementParam paramDescriptor = checkIsOutputParam(parameterIndex); - - ResultSet rs = getOutputParameters(parameterIndex); - - Object retVal = rs.getObjectStoredProc( - mapOutputParameterIndexToRsIndex(parameterIndex), - paramDescriptor.desiredJdbcType); - - this.outputParamWasNull = rs.wasNull(); - - return retVal; + synchronized (checkClosed().getConnectionMutex()) { + CallableStatementParam paramDescriptor = checkIsOutputParam(parameterIndex); + + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Object retVal = rs.getObjectStoredProc( + mapOutputParameterIndexToRsIndex(parameterIndex), + paramDescriptor.desiredJdbcType); + + this.outputParamWasNull = rs.wasNull(); + + return retVal; + } } /** * @see java.sql.CallableStatement#getObject(int, java.util.Map) */ - public synchronized Object getObject(int parameterIndex, Map map) + public Object getObject(int parameterIndex, Map> map) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - Object retVal = rs.getObject( - mapOutputParameterIndexToRsIndex(parameterIndex), map); - - this.outputParamWasNull = rs.wasNull(); - - return retVal; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Object retVal = rs.getObject( + mapOutputParameterIndexToRsIndex(parameterIndex), map); + + this.outputParamWasNull = rs.wasNull(); + + return retVal; + } } /** * @see java.sql.CallableStatement#getObject(java.lang.String) */ - public synchronized Object getObject(String parameterName) + public Object getObject(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Object retValue = rs.getObject(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Object retValue = rs.getObject(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getObject(java.lang.String, * java.util.Map) */ - public synchronized Object getObject(String parameterName, Map map) + public Object getObject(String parameterName, Map> map) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Object retValue = rs.getObject(fixParameterName(parameterName), map); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Object retValue = rs.getObject(fixParameterName(parameterName), map); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } + + // JDBC-4.1 + public T getObject(int parameterIndex, Class type) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + // remove cast once 1.5, 1.6 EOL'd + T retVal = ((ResultSetImpl)rs).getObject( + mapOutputParameterIndexToRsIndex(parameterIndex), type); + + this.outputParamWasNull = rs.wasNull(); + + return retVal; + } + } + + public T getObject(String parameterName, Class type) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + T retValue = ((ResultSetImpl)rs).getObject(fixParameterName(parameterName), type); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } + } /** * Returns the ResultSet that holds the output parameters, or throws an @@ -1423,298 +1677,335 @@ * if no output parameters were defined, or if no output * parameters were returned. */ - private ResultSet getOutputParameters(int paramIndex) throws SQLException { - this.outputParamWasNull = false; - - if (paramIndex == 1 && this.callingStoredFunction - && this.returnValueParam != null) { - return this.functionReturnValueResults; - } - - if (this.outputParameterResults == null) { - if (this.paramInfo.numberOfParameters() == 0) { - throw SQLError.createSQLException(Messages - .getString("CallableStatement.7"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + protected ResultSetInternalMethods getOutputParameters(int paramIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + this.outputParamWasNull = false; + + if (paramIndex == 1 && this.callingStoredFunction + && this.returnValueParam != null) { + return this.functionReturnValueResults; } - throw SQLError.createSQLException(Messages.getString("CallableStatement.8"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + + if (this.outputParameterResults == null) { + if (this.paramInfo.numberOfParameters() == 0) { + throw SQLError.createSQLException(Messages + .getString("CallableStatement.7"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + throw SQLError.createSQLException(Messages.getString("CallableStatement.8"), //$NON-NLS-1$ + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + } + + return this.outputParameterResults; } - - return this.outputParameterResults; - } - public synchronized ParameterMetaData getParameterMetaData() + public ParameterMetaData getParameterMetaData() throws SQLException { - if (this.placeholderToParameterIndexMap == null) { - return (CallableStatementParamInfoJDBC3) this.paramInfo; - } else { + synchronized (checkClosed().getConnectionMutex()) { + if (this.placeholderToParameterIndexMap == null) { + return (CallableStatementParamInfoJDBC3) this.paramInfo; + } + return new CallableStatementParamInfoJDBC3(this.paramInfo); } } /** * @see java.sql.CallableStatement#getRef(int) */ - public synchronized Ref getRef(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - Ref retValue = rs - .getRef(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Ref getRef(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Ref retValue = rs + .getRef(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getRef(java.lang.String) */ - public synchronized Ref getRef(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Ref retValue = rs.getRef(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Ref getRef(String parameterName) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Ref retValue = rs.getRef(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getShort(int) */ - public synchronized short getShort(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - short retValue = rs - .getShort(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public short getShort(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + short retValue = rs + .getShort(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getShort(java.lang.String) */ - public synchronized short getShort(String parameterName) + public short getShort(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - short retValue = rs.getShort(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + short retValue = rs.getShort(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getString(int) */ - public synchronized String getString(int parameterIndex) + public String getString(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - String retValue = rs - .getString(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + String retValue = rs + .getString(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getString(java.lang.String) */ - public synchronized String getString(String parameterName) + public String getString(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - String retValue = rs.getString(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + String retValue = rs.getString(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getTime(int) */ - public synchronized Time getTime(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - Time retValue = rs - .getTime(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Time getTime(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Time retValue = rs + .getTime(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getTime(int, java.util.Calendar) */ - public synchronized Time getTime(int parameterIndex, Calendar cal) + public Time getTime(int parameterIndex, Calendar cal) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - Time retValue = rs.getTime( - mapOutputParameterIndexToRsIndex(parameterIndex), cal); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Time retValue = rs.getTime( + mapOutputParameterIndexToRsIndex(parameterIndex), cal); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getTime(java.lang.String) */ - public synchronized Time getTime(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Time retValue = rs.getTime(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public Time getTime(String parameterName) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Time retValue = rs.getTime(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getTime(java.lang.String, * java.util.Calendar) */ - public synchronized Time getTime(String parameterName, Calendar cal) + public Time getTime(String parameterName, Calendar cal) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Time retValue = rs.getTime(fixParameterName(parameterName), cal); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Time retValue = rs.getTime(fixParameterName(parameterName), cal); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getTimestamp(int) */ - public synchronized Timestamp getTimestamp(int parameterIndex) + public Timestamp getTimestamp(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - Timestamp retValue = rs - .getTimestamp(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Timestamp retValue = rs + .getTimestamp(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getTimestamp(int, java.util.Calendar) */ - public synchronized Timestamp getTimestamp(int parameterIndex, Calendar cal) + public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - Timestamp retValue = rs.getTimestamp( - mapOutputParameterIndexToRsIndex(parameterIndex), cal); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + Timestamp retValue = rs.getTimestamp( + mapOutputParameterIndexToRsIndex(parameterIndex), cal); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getTimestamp(java.lang.String) */ - public synchronized Timestamp getTimestamp(String parameterName) + public Timestamp getTimestamp(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Timestamp retValue = rs.getTimestamp(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Timestamp retValue = rs.getTimestamp(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getTimestamp(java.lang.String, * java.util.Calendar) */ - public synchronized Timestamp getTimestamp(String parameterName, + public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - Timestamp retValue = rs.getTimestamp(fixParameterName(parameterName), - cal); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + Timestamp retValue = rs.getTimestamp(fixParameterName(parameterName), + cal); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getURL(int) */ - public synchronized URL getURL(int parameterIndex) throws SQLException { - ResultSet rs = getOutputParameters(parameterIndex); - - URL retValue = rs - .getURL(mapOutputParameterIndexToRsIndex(parameterIndex)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public URL getURL(int parameterIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(parameterIndex); + + URL retValue = rs + .getURL(mapOutputParameterIndexToRsIndex(parameterIndex)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } /** * @see java.sql.CallableStatement#getURL(java.lang.String) */ - public synchronized URL getURL(String parameterName) throws SQLException { - ResultSet rs = getOutputParameters(0); // definitely not going to be - // from ?= - - URL retValue = rs.getURL(fixParameterName(parameterName)); - - this.outputParamWasNull = rs.wasNull(); - - return retValue; + public URL getURL(String parameterName) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + ResultSetInternalMethods rs = getOutputParameters(0); // definitely not going to be + // from ?= + + URL retValue = rs.getURL(fixParameterName(parameterName)); + + this.outputParamWasNull = rs.wasNull(); + + return retValue; + } } - private int mapOutputParameterIndexToRsIndex(int paramIndex) + protected int mapOutputParameterIndexToRsIndex(int paramIndex) throws SQLException { - if (this.returnValueParam != null && paramIndex == 1) { - return 1; + synchronized (checkClosed().getConnectionMutex()) { + if (this.returnValueParam != null && paramIndex == 1) { + return 1; + } + + checkParameterIndexBounds(paramIndex); + + int localParamIndex = paramIndex - 1; + + if (this.placeholderToParameterIndexMap != null) { + localParamIndex = this.placeholderToParameterIndexMap[localParamIndex]; + } + + int rsIndex = this.parameterIndexToRsIndex[localParamIndex]; + + if (rsIndex == NOT_OUTPUT_PARAMETER_INDICATOR) { + throw SQLError.createSQLException( + Messages.getString("CallableStatement.21") + paramIndex //$NON-NLS-1$ + + Messages.getString("CallableStatement.22"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + + return rsIndex + 1; } - - checkParameterIndexBounds(paramIndex); - - int localParamIndex = paramIndex - 1; - - if (this.placeholderToParameterIndexMap != null) { - localParamIndex = this.placeholderToParameterIndexMap[localParamIndex]; - } - - int rsIndex = this.parameterIndexToRsIndex[localParamIndex]; - - if (rsIndex == NOT_OUTPUT_PARAMETER_INDICATOR) { - throw SQLError.createSQLException( - Messages.getString("CallableStatement.21") + paramIndex //$NON-NLS-1$ - + Messages.getString("CallableStatement.22"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - return rsIndex + 1; } /** @@ -1747,9 +2038,11 @@ * @see java.sql.CallableStatement#registerOutParameter(java.lang.String, * int) */ - public synchronized void registerOutParameter(String parameterName, + public void registerOutParameter(String parameterName, int sqlType) throws SQLException { - registerOutParameter(getNamedParamIndex(parameterName, true), sqlType); + synchronized (checkClosed().getConnectionMutex()) { + registerOutParameter(getNamedParamIndex(parameterName, true), sqlType); + } } /** @@ -1778,75 +2071,81 @@ * if an error occurs. */ private void retrieveOutParams() throws SQLException { - int numParameters = this.paramInfo.numberOfParameters(); - - this.parameterIndexToRsIndex = new int[numParameters]; - - for (int i = 0; i < numParameters; i++) { - this.parameterIndexToRsIndex[i] = NOT_OUTPUT_PARAMETER_INDICATOR; - } - - int localParamIndex = 0; - - if (numParameters > 0) { - StringBuffer outParameterQuery = new StringBuffer("SELECT "); //$NON-NLS-1$ - - boolean firstParam = true; - boolean hadOutputParams = false; - - for (Iterator paramIter = this.paramInfo.iterator(); paramIter - .hasNext();) { - CallableStatementParam retrParamInfo = (CallableStatementParam) paramIter - .next(); - - if (retrParamInfo.isOut) { - hadOutputParams = true; - - this.parameterIndexToRsIndex[retrParamInfo.index] = localParamIndex++; - - String outParameterName = mangleParameterName(retrParamInfo.paramName); - - if (!firstParam) { - outParameterQuery.append(","); //$NON-NLS-1$ - } else { - firstParam = false; + synchronized (checkClosed().getConnectionMutex()) { + int numParameters = this.paramInfo.numberOfParameters(); + + this.parameterIndexToRsIndex = new int[numParameters]; + + for (int i = 0; i < numParameters; i++) { + this.parameterIndexToRsIndex[i] = NOT_OUTPUT_PARAMETER_INDICATOR; + } + + int localParamIndex = 0; + + if (numParameters > 0) { + StringBuffer outParameterQuery = new StringBuffer("SELECT "); //$NON-NLS-1$ + + boolean firstParam = true; + boolean hadOutputParams = false; + + for (Iterator paramIter = this.paramInfo.iterator(); paramIter + .hasNext();) { + CallableStatementParam retrParamInfo = paramIter + .next(); + + if (retrParamInfo.isOut) { + hadOutputParams = true; + + this.parameterIndexToRsIndex[retrParamInfo.index] = localParamIndex++; + + if ((retrParamInfo.paramName == null) && (hasParametersView())) { + retrParamInfo.paramName = "nullnp" + retrParamInfo.index; + } + + String outParameterName = mangleParameterName(retrParamInfo.paramName); + + if (!firstParam) { + outParameterQuery.append(","); //$NON-NLS-1$ + } else { + firstParam = false; + } + + if (!outParameterName.startsWith("@")) { //$NON-NLS-1$ + outParameterQuery.append('@'); + } + + outParameterQuery.append(outParameterName); } - - if (!outParameterName.startsWith("@")) { //$NON-NLS-1$ - outParameterQuery.append('@'); - } - - outParameterQuery.append(outParameterName); } - } - - if (hadOutputParams) { - // We can't use 'ourself' to execute this query, or any - // pending result sets would be overwritten - java.sql.Statement outParameterStmt = null; - java.sql.ResultSet outParamRs = null; - - try { - outParameterStmt = this.connection.createStatement(); - outParamRs = outParameterStmt - .executeQuery(outParameterQuery.toString()); - this.outputParameterResults = ((com.mysql.jdbc.ResultSet) outParamRs) - .copy(); - - if (!this.outputParameterResults.next()) { - this.outputParameterResults.close(); - this.outputParameterResults = null; + + if (hadOutputParams) { + // We can't use 'ourself' to execute this query, or any + // pending result sets would be overwritten + java.sql.Statement outParameterStmt = null; + java.sql.ResultSet outParamRs = null; + + try { + outParameterStmt = this.connection.createStatement(); + outParamRs = outParameterStmt + .executeQuery(outParameterQuery.toString()); + this.outputParameterResults = ((com.mysql.jdbc.ResultSetInternalMethods) outParamRs) + .copy(); + + if (!this.outputParameterResults.next()) { + this.outputParameterResults.close(); + this.outputParameterResults = null; + } + } finally { + if (outParameterStmt != null) { + outParameterStmt.close(); + } } - } finally { - if (outParameterStmt != null) { - outParameterStmt.close(); - } + } else { + this.outputParameterResults = null; } } else { this.outputParameterResults = null; } - } else { - this.outputParameterResults = null; } } @@ -1942,75 +2241,83 @@ * */ private void setInOutParamsOnServer() throws SQLException { - if (this.paramInfo.numParameters > 0) { - int parameterIndex = 0; - - for (Iterator paramIter = this.paramInfo.iterator(); paramIter - .hasNext();) { - - CallableStatementParam inParamInfo = (CallableStatementParam) paramIter - .next(); - - if (inParamInfo.isOut && inParamInfo.isIn) { - String inOutParameterName = mangleParameterName(inParamInfo.paramName); - StringBuffer queryBuf = new StringBuffer( - 4 + inOutParameterName.length() + 1 + 1); - queryBuf.append("SET "); //$NON-NLS-1$ - queryBuf.append(inOutParameterName); - queryBuf.append("=?"); //$NON-NLS-1$ - - PreparedStatement setPstmt = null; - - try { - setPstmt = this.connection - .clientPrepareStatement(queryBuf.toString()); - - byte[] parameterAsBytes = getBytesRepresentation( - inParamInfo.index); - - if (parameterAsBytes != null) { - if (parameterAsBytes.length > 8 - && parameterAsBytes[0] == '_' - && parameterAsBytes[1] == 'b' - && parameterAsBytes[2] == 'i' - && parameterAsBytes[3] == 'n' - && parameterAsBytes[4] == 'a' - && parameterAsBytes[5] == 'r' - && parameterAsBytes[6] == 'y' - && parameterAsBytes[7] == '\'') { - setPstmt.setBytesNoEscapeNoQuotes(1, - parameterAsBytes); - } else { - int sqlType = inParamInfo.desiredJdbcType; + synchronized (checkClosed().getConnectionMutex()) { + if (this.paramInfo.numParameters > 0) { + for (Iterator paramIter = this.paramInfo.iterator(); paramIter + .hasNext();) { + + CallableStatementParam inParamInfo = paramIter + .next(); + + //Fix for 5.5+ + if (inParamInfo.isOut && inParamInfo.isIn) { + if ((inParamInfo.paramName == null) && (hasParametersView())) { + inParamInfo.paramName = "nullnp" + inParamInfo.index; + }; + + String inOutParameterName = mangleParameterName(inParamInfo.paramName); + StringBuffer queryBuf = new StringBuffer( + 4 + inOutParameterName.length() + 1 + 1); + queryBuf.append("SET "); //$NON-NLS-1$ + queryBuf.append(inOutParameterName); + queryBuf.append("=?"); //$NON-NLS-1$ + + PreparedStatement setPstmt = null; + + try { + setPstmt = (PreparedStatement) this.connection + .clientPrepareStatement(queryBuf.toString()); + + if (this.isNull[inParamInfo.index]) { + setPstmt.setBytesNoEscapeNoQuotes(1, "NULL".getBytes()); - switch (sqlType) { - case Types.BIT: - case Types.BINARY: - case Types.BLOB: - case Types.JAVA_OBJECT: - case Types.LONGVARBINARY: - case Types.VARBINARY: - setPstmt.setBytes(1, parameterAsBytes); - break; - default: - // the inherited PreparedStatement methods - // have already escaped and quoted these parameters - setPstmt.setBytesNoEscape(1, parameterAsBytes); + } else { + byte[] parameterAsBytes = getBytesRepresentation( + inParamInfo.index); + + if (parameterAsBytes != null) { + if (parameterAsBytes.length > 8 + && parameterAsBytes[0] == '_' + && parameterAsBytes[1] == 'b' + && parameterAsBytes[2] == 'i' + && parameterAsBytes[3] == 'n' + && parameterAsBytes[4] == 'a' + && parameterAsBytes[5] == 'r' + && parameterAsBytes[6] == 'y' + && parameterAsBytes[7] == '\'') { + setPstmt.setBytesNoEscapeNoQuotes(1, + parameterAsBytes); + } else { + int sqlType = inParamInfo.desiredJdbcType; + + switch (sqlType) { + case Types.BIT: + case Types.BINARY: + case Types.BLOB: + case Types.JAVA_OBJECT: + case Types.LONGVARBINARY: + case Types.VARBINARY: + setPstmt.setBytes(1, parameterAsBytes); + break; + default: + // the inherited PreparedStatement methods + // have already escaped and quoted these parameters + setPstmt.setBytesNoEscape(1, parameterAsBytes); + } + } + } else { + setPstmt.setNull(1, Types.NULL); } } - } else { - setPstmt.setNull(1, Types.NULL); + + setPstmt.executeUpdate(); + } finally { + if (setPstmt != null) { + setPstmt.close(); + } } - - setPstmt.executeUpdate(); - } finally { - if (setPstmt != null) { - setPstmt.close(); - } } } - - parameterIndex++; } } } @@ -2071,29 +2378,49 @@ } private void setOutParams() throws SQLException { - if (this.paramInfo.numParameters > 0) { - for (Iterator paramIter = this.paramInfo.iterator(); paramIter - .hasNext();) { - CallableStatementParam outParamInfo = (CallableStatementParam) paramIter - .next(); - - if (!this.callingStoredFunction && outParamInfo.isOut) { - String outParameterName = mangleParameterName(outParamInfo.paramName); - - int outParamIndex; - - if (this.placeholderToParameterIndexMap == null) { - outParamIndex = outParamInfo.index + 1; - } else { - outParamIndex = this.placeholderToParameterIndexMap[outParamInfo.index - 1 /* JDBC is 1-based */]; + synchronized (checkClosed().getConnectionMutex()) { + if (this.paramInfo.numParameters > 0) { + for (Iterator paramIter = this.paramInfo.iterator(); paramIter + .hasNext();) { + CallableStatementParam outParamInfo = paramIter + .next(); + + if (!this.callingStoredFunction && outParamInfo.isOut) { + + if ((outParamInfo.paramName == null) && (hasParametersView())) { + outParamInfo.paramName = "nullnp" + outParamInfo.index; + }; + + String outParameterName = mangleParameterName(outParamInfo.paramName); + + int outParamIndex = 0; + + if (this.placeholderToParameterIndexMap == null) { + outParamIndex = outParamInfo.index + 1; + } else { + // Find it, todo: remove this linear search + boolean found = false; + + for (int i = 0; i < this.placeholderToParameterIndexMap.length; i++) { + if (this.placeholderToParameterIndexMap[i] == outParamInfo.index) { + outParamIndex = i + 1; /* JDBC is 1-based */ + found = true; + break; + } + } + + if (!found) { + throw SQLError.createSQLException("boo!", "S1000", this.connection.getExceptionInterceptor()); + } + } + + this.setBytesNoEscapeNoQuotes(outParamIndex, + StringUtils.getBytes(outParameterName, + this.charConverter, this.charEncoding, + this.connection + .getServerCharacterEncoding(), + this.connection.parserKnowsUnicode(), getExceptionInterceptor())); } - - this.setBytesNoEscapeNoQuotes(outParamIndex, - StringUtils.getBytes(outParameterName, - this.charConverter, this.charEncoding, - this.connection - .getServerCharacterEncoding(), - this.connection.parserKnowsUnicode())); } } } @@ -2158,14 +2485,16 @@ /** * @see java.sql.CallableStatement#wasNull() */ - public synchronized boolean wasNull() throws SQLException { - return this.outputParamWasNull; + public boolean wasNull() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + return this.outputParamWasNull; + } } public int[] executeBatch() throws SQLException { if (this.hasOutputParams) { throw SQLError.createSQLException("Can't call executeBatch() on CallableStatement with OUTPUT parameters", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } return super.executeBatch(); @@ -2178,4 +2507,168 @@ return super.getParameterIndexOffset(); } + + public void setAsciiStream(String parameterName, InputStream x) throws SQLException { + setAsciiStream(getNamedParamIndex(parameterName, false), x); + + } + + public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException { + setAsciiStream(getNamedParamIndex(parameterName, false), x, length); + + } + + public void setBinaryStream(String parameterName, InputStream x) throws SQLException { + setBinaryStream(getNamedParamIndex(parameterName, false), x); + + } + + public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException { + setBinaryStream(getNamedParamIndex(parameterName, false), x, length); + + } + + public void setBlob(String parameterName, Blob x) throws SQLException { + setBlob(getNamedParamIndex(parameterName, false), x); + + } + + public void setBlob(String parameterName, InputStream inputStream) throws SQLException { + setBlob(getNamedParamIndex(parameterName, false), inputStream); + + } + + public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException { + setBlob(getNamedParamIndex(parameterName, false), inputStream, length); + + } + + public void setCharacterStream(String parameterName, Reader reader) throws SQLException { + setCharacterStream(getNamedParamIndex(parameterName, false), reader); + + } + + public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException { + setCharacterStream(getNamedParamIndex(parameterName, false), reader, length); + + } + + public void setClob(String parameterName, Clob x) throws SQLException { + setClob(getNamedParamIndex(parameterName, false), x); + + } + + public void setClob(String parameterName, Reader reader) throws SQLException { + setClob(getNamedParamIndex(parameterName, false), reader); + + } + + public void setClob(String parameterName, Reader reader, long length) throws SQLException { + setClob(getNamedParamIndex(parameterName, false), reader, length); + + } + + public void setNCharacterStream(String parameterName, Reader value) throws SQLException { + setNCharacterStream(getNamedParamIndex(parameterName, false), value); + + } + + public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException { + setNCharacterStream(getNamedParamIndex(parameterName, false), value, length); + + } + + /** + * Check whether the stored procedure alters any data or is safe for read-only usage. + * + * @return true if procedure does not alter data + * @throws SQLException + */ + private boolean checkReadOnlyProcedure() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (this.connection.getNoAccessToProcedureBodies()) { + return false; + } + + if (this.paramInfo.isReadOnlySafeChecked) { + return this.paramInfo.isReadOnlySafeProcedure; + } + + ResultSet rs = null; + java.sql.PreparedStatement ps = null; + + try { + String procName = extractProcedureName(); + + String catalog = this.currentCatalog; + + if (procName.indexOf(".") != -1) { + catalog = procName.substring(0, procName.indexOf(".")); + + if (StringUtils.startsWithIgnoreCaseAndWs(catalog, "`") && catalog.trim().endsWith("`")) { + catalog = catalog.substring(1, catalog.length() - 1); + } + + procName = procName.substring(procName.indexOf(".") + 1); + procName = StringUtils.toString(StringUtils.stripEnclosure( + StringUtils.getBytes(procName), "`", "`")); + } + ps = this.connection + .prepareStatement("SELECT SQL_DATA_ACCESS FROM " + + " information_schema.routines " + + " WHERE routine_schema = ? " + + " AND routine_name = ?"); + ps.setMaxRows(0); + ps.setFetchSize(0); + + ps.setString(1, catalog); + ps.setString(2, procName); + rs = ps.executeQuery(); + if (rs.next()) { + String sqlDataAccess = rs.getString(1); + if ("READS SQL DATA".equalsIgnoreCase(sqlDataAccess) + || "NO SQL".equalsIgnoreCase(sqlDataAccess)) { + synchronized (this.paramInfo) { + this.paramInfo.isReadOnlySafeChecked = true; + this.paramInfo.isReadOnlySafeProcedure = true; + } + return true; + } + } + } catch (SQLException e) { + // swallow the Exception + } finally { + if(rs != null){ + rs.close(); + } + if(ps != null){ + ps.close(); + } + + } + this.paramInfo.isReadOnlySafeChecked = false; + this.paramInfo.isReadOnlySafeProcedure = false; + } + return false; + + } + + protected boolean checkReadOnlySafeStatement() throws SQLException { + return (super.checkReadOnlySafeStatement() || this.checkReadOnlyProcedure()); + } + + private boolean hasParametersView() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + try { + if (this.connection.versionMeetsMinimum(5, 5, 0)) { + java.sql.DatabaseMetaData dbmd1 = new DatabaseMetaDataUsingInfoSchema(this.connection, this.connection.getCatalog()); + return ((DatabaseMetaDataUsingInfoSchema)dbmd1).gethasParametersView(); + } + + return false; + } catch (SQLException e) { + return false; + } + } + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/CharsetMapping.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/CharsetMapping.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/CharsetMapping.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/CharsetMapping.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2006 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.SQLException; @@ -51,71 +50,163 @@ * Map of MySQL-4.1 charset indexes to Java encoding names */ public static final String[] INDEX_TO_CHARSET; - + /** * Map of MySQL-4.1 collation index to collation names */ public static final String[] INDEX_TO_COLLATION; + /** + * Size of static maps INDEX_TO_JAVA_CHARSET, INDEX_TO_MYSQL_CHARSET, INDEX_TO_COLLATION + */ + public static final int MAP_SIZE = 255; + /** + * Map of MySQL-4.1 collation indexes to MySQL encoding names + */ + public static final Map STATIC_INDEX_TO_MYSQL_CHARSET_MAP; + /** + * Map of MySQL-4.1 charset names to mblen + */ + public static final Map STATIC_CHARSET_TO_NUM_BYTES_MAP; + /** + * Map of MySQL-4.0 charset names to mblen + */ + public static final Map STATIC_4_0_CHARSET_TO_NUM_BYTES_MAP; /** Mapping of Java charset names to MySQL charset names */ - private static final Map JAVA_TO_MYSQL_CHARSET_MAP; + private static final Map> JAVA_TO_MYSQL_CHARSET_MAP; - private static final Map JAVA_UC_TO_MYSQL_CHARSET_MAP; + private static final Map> JAVA_UC_TO_MYSQL_CHARSET_MAP; - private static final Map ERROR_MESSAGE_FILE_TO_MYSQL_CHARSET_MAP; + private static final Map ERROR_MESSAGE_FILE_TO_MYSQL_CHARSET_MAP; /** Map/List of multibyte character sets (using MySQL names) */ - private static final Map MULTIBYTE_CHARSETS; + private static final Map MULTIBYTE_CHARSETS; - private static final Map MYSQL_TO_JAVA_CHARSET_MAP; + public static final Map MYSQL_TO_JAVA_CHARSET_MAP; + private static final Map MYSQL_ENCODING_NAME_TO_CHARSET_INDEX_MAP; + + private static final String MYSQL_CHARSET_NAME_armscii8 = "armscii8"; + private static final String MYSQL_CHARSET_NAME_ascii = "ascii"; + private static final String MYSQL_CHARSET_NAME_big5 = "big5"; + private static final String MYSQL_CHARSET_NAME_binary = "binary"; + private static final String MYSQL_CHARSET_NAME_cp1250 = "cp1250"; + private static final String MYSQL_CHARSET_NAME_cp1251 = "cp1251"; + private static final String MYSQL_CHARSET_NAME_cp1256 = "cp1256"; + private static final String MYSQL_CHARSET_NAME_cp1257 = "cp1257"; + private static final String MYSQL_CHARSET_NAME_cp850 = "cp850"; + private static final String MYSQL_CHARSET_NAME_cp852 = "cp852"; + private static final String MYSQL_CHARSET_NAME_cp866 = "cp866"; + private static final String MYSQL_CHARSET_NAME_cp932 = "cp932"; + private static final String MYSQL_CHARSET_NAME_dec8 = "dec8"; + private static final String MYSQL_CHARSET_NAME_eucjpms = "eucjpms"; + private static final String MYSQL_CHARSET_NAME_euckr = "euckr"; + private static final String MYSQL_CHARSET_NAME_gb2312 = "gb2312"; + private static final String MYSQL_CHARSET_NAME_gbk = "gbk"; + private static final String MYSQL_CHARSET_NAME_geostd8 = "geostd8"; + private static final String MYSQL_CHARSET_NAME_greek = "greek"; + private static final String MYSQL_CHARSET_NAME_hebrew = "hebrew"; + private static final String MYSQL_CHARSET_NAME_hp8 = "hp8"; + private static final String MYSQL_CHARSET_NAME_keybcs2 = "keybcs2"; + private static final String MYSQL_CHARSET_NAME_koi8r = "koi8r"; + private static final String MYSQL_CHARSET_NAME_koi8u = "koi8u"; + private static final String MYSQL_CHARSET_NAME_latin1 = "latin1"; + private static final String MYSQL_CHARSET_NAME_latin2 = "latin2"; + private static final String MYSQL_CHARSET_NAME_latin5 = "latin5"; + private static final String MYSQL_CHARSET_NAME_latin7 = "latin7"; + private static final String MYSQL_CHARSET_NAME_macce = "macce"; + private static final String MYSQL_CHARSET_NAME_macroman = "macroman"; + private static final String MYSQL_CHARSET_NAME_sjis = "sjis"; + private static final String MYSQL_CHARSET_NAME_swe7 = "swe7"; + private static final String MYSQL_CHARSET_NAME_tis620 = "tis620"; + private static final String MYSQL_CHARSET_NAME_ucs2 = "ucs2"; + private static final String MYSQL_CHARSET_NAME_ujis = "ujis"; + private static final String MYSQL_CHARSET_NAME_utf16 = "utf16"; + private static final String MYSQL_CHARSET_NAME_utf16le = "utf16le"; + private static final String MYSQL_CHARSET_NAME_utf32 = "utf32"; + private static final String MYSQL_CHARSET_NAME_utf8 = "utf8"; + private static final String MYSQL_CHARSET_NAME_utf8mb4 = "utf8mb4"; + + private static final String MYSQL_4_0_CHARSET_NAME_croat = "croat"; // 4.1 => 27 latin2 latin2_croatian_ci + private static final String MYSQL_4_0_CHARSET_NAME_czech = "czech"; // 4.1 => 2 latin2 latin2_czech_ci + private static final String MYSQL_4_0_CHARSET_NAME_danish = "danish"; // 4.1 => 15 latin1 latin1_danish_ci + private static final String MYSQL_4_0_CHARSET_NAME_dos = "dos"; // 4.1 => 4 cp850 cp850_general_ci + private static final String MYSQL_4_0_CHARSET_NAME_estonia = "estonia"; // 4.1 => 20 latin7 latin7_estonian_ci + private static final String MYSQL_4_0_CHARSET_NAME_euc_kr = "euc_kr"; // 4.1 => 19 euckr euckr_korean_ci + private static final String MYSQL_4_0_CHARSET_NAME_german1 = "german1"; // 4.1 => 5 latin1 latin1_german1_ci + private static final String MYSQL_4_0_CHARSET_NAME_hungarian = "hungarian"; // 4.1 => 21 latin2 latin2_hungarian_ci + private static final String MYSQL_4_0_CHARSET_NAME_koi8_ru = "koi8_ru"; // 4.1 => 7 koi8r koi8r_general_ci + private static final String MYSQL_4_0_CHARSET_NAME_koi8_ukr = "koi8_ukr"; // 4.1 => 22 koi8u koi8u_ukrainian_ci + private static final String MYSQL_4_0_CHARSET_NAME_latin1_de = "latin1_de"; // 4.1 => 31 latin1 latin1_german2_ci + private static final String MYSQL_4_0_CHARSET_NAME_usa7 = "usa7"; // 4.1 => 11 ascii ascii_general_ci + private static final String MYSQL_4_0_CHARSET_NAME_win1250 = "win1250"; // 4.1 => 26 cp1250 cp1250_general_ci + 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 = "ISO8859_1"; // punting for not-used character sets - public static final Map STATIC_CHARSET_TO_NUM_BYTES_MAP; - - static { - HashMap tempNumBytesMap = new HashMap(); - - tempNumBytesMap.put("big5", new Integer(2)); - tempNumBytesMap.put("dec8" , new Integer(1)); - tempNumBytesMap.put("cp850", new Integer(1)); - tempNumBytesMap.put("hp8", new Integer(1)); - tempNumBytesMap.put("koi8r", new Integer(1)); - tempNumBytesMap.put("latin1", new Integer(1)); - tempNumBytesMap.put("latin2", new Integer(1)); - tempNumBytesMap.put("swe7", new Integer(1)); - tempNumBytesMap.put("ascii", new Integer(1)); - tempNumBytesMap.put("ujis", new Integer(3)); - tempNumBytesMap.put("sjis", new Integer(2)); - tempNumBytesMap.put("hebrew", new Integer(1)); - tempNumBytesMap.put("tis620", new Integer(1)); - tempNumBytesMap.put("euckr", new Integer(2)); - tempNumBytesMap.put("koi8u", new Integer(1)); - tempNumBytesMap.put("gb2312", new Integer(2)); - tempNumBytesMap.put("greek", new Integer(1)); - tempNumBytesMap.put("cp1250", new Integer(1)); - tempNumBytesMap.put("gbk", new Integer(2)); - tempNumBytesMap.put("latin5", new Integer(1)); - tempNumBytesMap.put("armscii8", new Integer(1)); - tempNumBytesMap.put("utf8", new Integer(3)); - tempNumBytesMap.put("ucs2", new Integer(2)); - tempNumBytesMap.put("cp866", new Integer(1)); - tempNumBytesMap.put("keybcs2", new Integer(1)); - tempNumBytesMap.put("macce", new Integer(1)); - tempNumBytesMap.put("macroman", new Integer(1)); - tempNumBytesMap.put("cp852" , new Integer(1)); - tempNumBytesMap.put("latin7", new Integer(1)); - tempNumBytesMap.put("cp1251", new Integer(1)); - tempNumBytesMap.put("cp1256" , new Integer(1)); - tempNumBytesMap.put("cp1257", new Integer(1)); - tempNumBytesMap.put("binary", new Integer(1)); - tempNumBytesMap.put("geostd8", new Integer(1)); - tempNumBytesMap.put("cp932", new Integer(2)); - tempNumBytesMap.put("eucjpms", new Integer(3)); - - STATIC_CHARSET_TO_NUM_BYTES_MAP = Collections.unmodifiableMap( - tempNumBytesMap); + static { + HashMap tempNumBytesMap = new HashMap(); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_armscii8, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_ascii, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_big5, 2); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_binary, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_cp1250, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_cp1251, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_cp1256, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_cp1257, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_cp850, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_cp852, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_cp866, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_cp932, 2); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_dec8, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_eucjpms, 3); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_euckr, 2); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_gb2312, 2); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_gbk, 2); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_geostd8, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_greek, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_hebrew, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_hp8, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_keybcs2, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_koi8r, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_koi8u, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_latin1, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_latin2, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_latin5, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_latin7, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_macce, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_macroman, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_sjis, 2); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_swe7, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_tis620, 1); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_ucs2, 2); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_ujis, 3); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_utf16, 4); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_utf16le, 4); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_utf32, 4); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_utf8, 3); + tempNumBytesMap.put(MYSQL_CHARSET_NAME_utf8mb4, 4); + STATIC_CHARSET_TO_NUM_BYTES_MAP = Collections.unmodifiableMap(tempNumBytesMap); + tempNumBytesMap = new HashMap(); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_croat, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_czech, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_danish, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_dos, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_estonia, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_euc_kr, 2); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_german1, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_hungarian, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_koi8_ru, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_koi8_ukr, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_latin1_de, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_usa7, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_win1250, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_win1251, 1); + tempNumBytesMap.put(MYSQL_4_0_CHARSET_NAME_win1251ukr, 1); + STATIC_4_0_CHARSET_TO_NUM_BYTES_MAP = Collections.unmodifiableMap(tempNumBytesMap); + CHARSET_CONFIG.setProperty("javaToMysqlMappings", // // Note: This used to be stored in Charsets.properties, @@ -172,6 +263,7 @@ + "MacRoman = macroman," + "MacCentralEurope = macce," + "UTF-8 = utf8," + + "UTF-8 = *> 5.5.2 utf8mb4," + "UnicodeBig = ucs2," + "US-ASCII = binary," + "Cp943 = sjis," @@ -189,37 +281,35 @@ + "GREEK = greek," + "EUCKR = euckr," + "GB2312 = gb2312," - + "LATIN2 = latin2"); + + "LATIN2 = latin2," + + "UTF-16 = >5.2.0 utf16," + + "UTF-16LE = >5.6.0 utf16le," + + "UTF-32 = >5.2.0 utf32"); - HashMap javaToMysqlMap = new HashMap(); + HashMap> javaToMysqlMap = new HashMap>(); - populateMapWithKeyValuePairs("javaToMysqlMappings", javaToMysqlMap, - true, false); + populateMapWithKeyValuePairsVersioned("javaToMysqlMappings", javaToMysqlMap, false); JAVA_TO_MYSQL_CHARSET_MAP = Collections.unmodifiableMap(javaToMysqlMap); - HashMap mysqlToJavaMap = new HashMap(); - Set keySet = JAVA_TO_MYSQL_CHARSET_MAP.keySet(); + HashMap mysqlToJavaMap = new HashMap(); - Iterator javaCharsets = keySet.iterator(); - + Set keySet = JAVA_TO_MYSQL_CHARSET_MAP.keySet(); + Iterator javaCharsets = keySet.iterator(); while (javaCharsets.hasNext()) { - Object javaEncodingName = javaCharsets.next(); - List mysqlEncodingList = (List) JAVA_TO_MYSQL_CHARSET_MAP - .get(javaEncodingName); + String javaEncodingName = javaCharsets.next(); + List mysqlEncodingList = JAVA_TO_MYSQL_CHARSET_MAP.get(javaEncodingName); - Iterator mysqlEncodings = mysqlEncodingList.iterator(); + Iterator mysqlEncodings = mysqlEncodingList.iterator(); String mysqlEncodingName = null; while (mysqlEncodings.hasNext()) { - VersionedStringProperty mysqlProp = (VersionedStringProperty) mysqlEncodings - .next(); + VersionedStringProperty mysqlProp = mysqlEncodings.next(); mysqlEncodingName = mysqlProp.toString(); mysqlToJavaMap.put(mysqlEncodingName, javaEncodingName); - mysqlToJavaMap.put(mysqlEncodingName - .toUpperCase(Locale.ENGLISH), javaEncodingName); + mysqlToJavaMap.put(mysqlEncodingName.toUpperCase(Locale.ENGLISH), javaEncodingName); } } @@ -229,24 +319,20 @@ MYSQL_TO_JAVA_CHARSET_MAP = Collections.unmodifiableMap(mysqlToJavaMap); - TreeMap ucMap = new TreeMap(String.CASE_INSENSITIVE_ORDER); - Iterator javaNamesKeys = JAVA_TO_MYSQL_CHARSET_MAP.keySet().iterator(); - + TreeMap> ucMap = new TreeMap>(String.CASE_INSENSITIVE_ORDER); + Iterator javaNamesKeys = JAVA_TO_MYSQL_CHARSET_MAP.keySet().iterator(); while (javaNamesKeys.hasNext()) { - String key = (String) javaNamesKeys.next(); - - ucMap.put(key.toUpperCase(Locale.ENGLISH), - JAVA_TO_MYSQL_CHARSET_MAP.get(key)); + String key = javaNamesKeys.next(); + ucMap.put(key.toUpperCase(Locale.ENGLISH), JAVA_TO_MYSQL_CHARSET_MAP.get(key)); } - JAVA_UC_TO_MYSQL_CHARSET_MAP = Collections.unmodifiableMap(ucMap); // // Character sets that we can't convert // ourselves. // - HashMap tempMapMulti = new HashMap(); + HashMap tempMapMulti = new HashMap(); CHARSET_CONFIG.setProperty("multibyteCharsets", // @@ -278,410 +364,296 @@ + "GB2312 = gb2312," + "UTF-8 = utf8," + "utf8 = utf8," - + "UnicodeBig = ucs2"); + + "UnicodeBig = ucs2," + + "UTF-16 = >5.2.0 utf16," + + "UTF-16LE = >5.6.0 utf16le," + + "UTF-32 = >5.2.0 utf32"); - populateMapWithKeyValuePairs("multibyteCharsets", tempMapMulti, false, - true); + populateMapWithKeyValuePairsUnversioned("multibyteCharsets", tempMapMulti, true); MULTIBYTE_CHARSETS = Collections.unmodifiableMap(tempMapMulti); - INDEX_TO_CHARSET = new String[211]; + Collation[] collation = new Collation[MAP_SIZE]; + collation[1] = new Collation(1, "big5_chinese_ci", MYSQL_CHARSET_NAME_big5); + collation[2] = new Collation(2, "latin2_czech_cs", MYSQL_CHARSET_NAME_latin2); + collation[3] = new Collation(3, "dec8_swedish_ci", MYSQL_CHARSET_NAME_dec8, "ISO8859_1"); // punting for "dec8" + collation[4] = new Collation(4, "cp850_general_ci", MYSQL_CHARSET_NAME_cp850, "ISO8859_1"); // punting for "dos" + collation[5] = new Collation(5, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1); + collation[6] = new Collation(6, "hp8_english_ci", MYSQL_CHARSET_NAME_hp8, "ISO8859_1"); // punting for "hp8" + collation[7] = new Collation(7, "koi8r_general_ci", MYSQL_CHARSET_NAME_koi8r); + collation[8] = new Collation(8, "latin1_swedish_ci", MYSQL_CHARSET_NAME_latin1 );//"Cp1252" + collation[9] = new Collation(9, "latin2_general_ci", MYSQL_CHARSET_NAME_latin2); + collation[10] = new Collation(10, "swe7_swedish_ci", MYSQL_CHARSET_NAME_swe7, "ISO8859_1"); // punting for "swe7" + collation[11] = new Collation(11, "ascii_general_ci", MYSQL_CHARSET_NAME_ascii); + collation[12] = new Collation(12, "ujis_japanese_ci", MYSQL_CHARSET_NAME_ujis); + collation[13] = new Collation(13, "sjis_japanese_ci", MYSQL_CHARSET_NAME_sjis); + collation[14] = new Collation(14, "cp1251_bulgarian_ci", MYSQL_CHARSET_NAME_cp1251); + collation[15] = new Collation(15, "latin1_danish_ci", MYSQL_CHARSET_NAME_latin1); + collation[16] = new Collation(16, "hebrew_general_ci", MYSQL_CHARSET_NAME_hebrew); + collation[17] = new Collation(17, "latin1_german1_ci", MYSQL_4_0_CHARSET_NAME_win1251); // removed since 4.1 + collation[18] = new Collation(18, "tis620_thai_ci", MYSQL_CHARSET_NAME_tis620); + collation[19] = new Collation(19, "euckr_korean_ci", MYSQL_CHARSET_NAME_euckr); + collation[20] = new Collation(20, "latin7_estonian_cs", MYSQL_CHARSET_NAME_latin7, "ISO8859_13"); // punting for "estonia"; + collation[21] = new Collation(21, "latin2_hungarian_ci", MYSQL_CHARSET_NAME_latin2); + collation[22] = new Collation(22, "koi8u_general_ci", MYSQL_CHARSET_NAME_koi8u, "KOI8_R"); // punting for "koi8_ukr" + collation[23] = new Collation(23, "cp1251_ukrainian_ci", MYSQL_CHARSET_NAME_cp1251); + collation[24] = new Collation(24, "gb2312_chinese_ci", MYSQL_CHARSET_NAME_gb2312); + collation[25] = new Collation(25, "greek_general_ci", MYSQL_CHARSET_NAME_greek); + collation[26] = new Collation(26, "cp1250_general_ci", MYSQL_CHARSET_NAME_cp1250); + collation[27] = new Collation(27, "latin2_croatian_ci", MYSQL_CHARSET_NAME_latin2); + collation[28] = new Collation(28, "gbk_chinese_ci", MYSQL_CHARSET_NAME_gbk); + collation[29] = new Collation(29, "cp1257_lithuanian_ci", MYSQL_CHARSET_NAME_cp1257); + collation[30] = new Collation(30, "latin5_turkish_ci", MYSQL_CHARSET_NAME_latin5); + collation[31] = new Collation(31, "latin1_german2_ci", MYSQL_CHARSET_NAME_latin1); + collation[32] = new Collation(32, "armscii8_general_ci", MYSQL_CHARSET_NAME_armscii8,"ISO8859_1"); + collation[33] = new Collation(33, "utf8_general_ci", MYSQL_CHARSET_NAME_utf8); + collation[34] = new Collation(34, "cp1250_czech_cs", MYSQL_CHARSET_NAME_cp1250); + collation[35] = new Collation(35, "ucs2_general_ci", MYSQL_CHARSET_NAME_ucs2); + collation[36] = new Collation(36, "cp866_general_ci", MYSQL_CHARSET_NAME_cp866); + collation[37] = new Collation(37, "keybcs2_general_ci", MYSQL_CHARSET_NAME_keybcs2, "Cp895"); + collation[38] = new Collation(38, "macce_general_ci", MYSQL_CHARSET_NAME_macce); + collation[39] = new Collation(39, "macroman_general_ci", MYSQL_CHARSET_NAME_macroman); + collation[40] = new Collation(40, "cp852_general_ci", MYSQL_CHARSET_NAME_cp852, "LATIN2"); // punting for "pclatin2" + collation[41] = new Collation(41, "latin7_general_ci", MYSQL_CHARSET_NAME_latin7, "ISO8859_13"); // punting for "latvian"; + collation[42] = new Collation(42, "latin7_general_cs", MYSQL_CHARSET_NAME_latin7, "ISO8859_13"); // punting for "latvian1"; + collation[43] = new Collation(43, "macce_bin", MYSQL_CHARSET_NAME_macce); + collation[44] = new Collation(44, "cp1250_croatian_ci", MYSQL_CHARSET_NAME_cp1250); + collation[45] = new Collation(45, "utf8mb4_general_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[46] = new Collation(46, "utf8mb4_bin", MYSQL_CHARSET_NAME_utf8mb4); + collation[47] = new Collation(47, "latin1_bin", MYSQL_CHARSET_NAME_latin1); + collation[48] = new Collation(48, "latin1_general_ci", MYSQL_CHARSET_NAME_latin1); + collation[49] = new Collation(49, "latin1_general_cs", MYSQL_CHARSET_NAME_latin1); + collation[50] = new Collation(50, "cp1251_bin", MYSQL_CHARSET_NAME_cp1251); + collation[51] = new Collation(51, "cp1251_general_ci", MYSQL_CHARSET_NAME_cp1251); + collation[52] = new Collation(52, "cp1251_general_cs", MYSQL_CHARSET_NAME_cp1251); + collation[53] = new Collation(53, "macroman_bin", MYSQL_CHARSET_NAME_macroman); + collation[54] = new Collation(54, "utf16_general_ci", MYSQL_CHARSET_NAME_utf16); + collation[55] = new Collation(55, "utf16_bin", MYSQL_CHARSET_NAME_utf16); + collation[56] = new Collation(56, "utf16le_general_ci", MYSQL_CHARSET_NAME_utf16le); + collation[57] = new Collation(57, "cp1256_general_ci", MYSQL_CHARSET_NAME_cp1256); + collation[58] = new Collation(58, "cp1257_bin", MYSQL_CHARSET_NAME_cp1257); + collation[59] = new Collation(59, "cp1257_general_ci", MYSQL_CHARSET_NAME_cp1257); + collation[60] = new Collation(60, "utf32_general_ci", MYSQL_CHARSET_NAME_utf32); + collation[61] = new Collation(61, "utf32_bin", MYSQL_CHARSET_NAME_utf32); + collation[62] = new Collation(62, "utf16le_bin", MYSQL_CHARSET_NAME_utf16le); + collation[63] = new Collation(63, "binary", MYSQL_CHARSET_NAME_binary); + collation[64] = new Collation(64, "armscii8_bin", MYSQL_CHARSET_NAME_armscii8,"ISO8859_2"); // punting "armscii" + collation[65] = new Collation(65, "ascii_bin", MYSQL_CHARSET_NAME_ascii); + collation[66] = new Collation(66, "cp1250_bin", MYSQL_CHARSET_NAME_cp1250); + collation[67] = new Collation(67, "cp1256_bin", MYSQL_CHARSET_NAME_cp1256); + collation[68] = new Collation(68, "cp866_bin", MYSQL_CHARSET_NAME_cp866); + collation[69] = new Collation(69, "dec8_bin", MYSQL_CHARSET_NAME_dec8, "US-ASCII"); // punting for "dec8" + collation[70] = new Collation(70, "greek_bin", MYSQL_CHARSET_NAME_greek); + collation[71] = new Collation(71, "hebrew_bin", MYSQL_CHARSET_NAME_hebrew); + collation[72] = new Collation(72, "hp8_bin", MYSQL_CHARSET_NAME_hp8, "US-ASCII"); // punting for "hp8" + collation[73] = new Collation(73, "keybcs2_bin", MYSQL_CHARSET_NAME_keybcs2, "Cp895"); // punting for "keybcs2" + collation[74] = new Collation(74, "koi8r_bin", MYSQL_CHARSET_NAME_koi8r); + collation[75] = new Collation(75, "koi8u_bin", MYSQL_CHARSET_NAME_koi8u, "KOI8_R"); // punting for koi8ukr" + collation[76] = new Collation(76, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[77] = new Collation(77, "latin2_bin", MYSQL_CHARSET_NAME_latin2); + collation[78] = new Collation(78, "latin5_bin", MYSQL_CHARSET_NAME_latin5); + collation[79] = new Collation(79, "latin7_bin", MYSQL_CHARSET_NAME_latin7); + collation[80] = new Collation(80, "cp850_bin", MYSQL_CHARSET_NAME_cp850); + collation[81] = new Collation(81, "cp852_bin", MYSQL_CHARSET_NAME_cp852); + collation[82] = new Collation(82, "swe7_bin", MYSQL_CHARSET_NAME_swe7, "ISO8859_1"); //"ISO8859_1"; // punting for "swe7" + collation[83] = new Collation(83, "utf8_bin", MYSQL_CHARSET_NAME_utf8); + collation[84] = new Collation(84, "big5_bin", MYSQL_CHARSET_NAME_big5); + collation[85] = new Collation(85, "euckr_bin", MYSQL_CHARSET_NAME_euckr); + collation[86] = new Collation(86, "gb2312_bin", MYSQL_CHARSET_NAME_gb2312); + collation[87] = new Collation(87, "gbk_bin", MYSQL_CHARSET_NAME_gbk); + collation[88] = new Collation(88, "sjis_bin", MYSQL_CHARSET_NAME_sjis); + collation[89] = new Collation(89, "tis620_bin", MYSQL_CHARSET_NAME_tis620); + collation[90] = new Collation(90, "ucs2_bin", MYSQL_CHARSET_NAME_ucs2); + collation[91] = new Collation(91, "ujis_bin", MYSQL_CHARSET_NAME_ujis); + collation[92] = new Collation(92, "geostd8_general_ci", MYSQL_CHARSET_NAME_geostd8, "US-ASCII"); //"US-ASCII"; //punting for "geostd8" + collation[93] = new Collation(93, "geostd8_bin", MYSQL_CHARSET_NAME_geostd8, "US-ASCII"); //"US-ASCII"; // punting for "geostd8" + collation[94] = new Collation(94, "latin1_spanish_ci", MYSQL_CHARSET_NAME_latin1); + collation[95] = new Collation(95, "cp932_japanese_ci", MYSQL_CHARSET_NAME_cp932); + collation[96] = new Collation(96, "cp932_bin", MYSQL_CHARSET_NAME_cp932); + collation[97] = new Collation(97, "eucjpms_japanese_ci", MYSQL_CHARSET_NAME_eucjpms); + collation[98] = new Collation(98, "eucjpms_bin", MYSQL_CHARSET_NAME_eucjpms); + collation[99] = new Collation(99, "cp1250_polish_ci", MYSQL_CHARSET_NAME_cp1250); + collation[100] = new Collation(100, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[101] = new Collation(101, "utf16_unicode_ci", MYSQL_CHARSET_NAME_utf16); + collation[102] = new Collation(102, "utf16_icelandic_ci", MYSQL_CHARSET_NAME_utf16); + collation[103] = new Collation(103, "utf16_latvian_ci", MYSQL_CHARSET_NAME_utf16); + collation[104] = new Collation(104, "utf16_romanian_ci", MYSQL_CHARSET_NAME_utf16); + collation[105] = new Collation(105, "utf16_slovenian_ci", MYSQL_CHARSET_NAME_utf16); + collation[106] = new Collation(106, "utf16_polish_ci", MYSQL_CHARSET_NAME_utf16); + collation[107] = new Collation(107, "utf16_estonian_ci", MYSQL_CHARSET_NAME_utf16); + collation[108] = new Collation(108, "utf16_spanish_ci", MYSQL_CHARSET_NAME_utf16); + collation[109] = new Collation(109, "utf16_swedish_ci", MYSQL_CHARSET_NAME_utf16); + collation[110] = new Collation(110, "utf16_turkish_ci", MYSQL_CHARSET_NAME_utf16); + collation[111] = new Collation(111, "utf16_czech_ci", MYSQL_CHARSET_NAME_utf16); + collation[112] = new Collation(112, "utf16_danish_ci", MYSQL_CHARSET_NAME_utf16); + collation[113] = new Collation(113, "utf16_lithuanian_ci", MYSQL_CHARSET_NAME_utf16); + collation[114] = new Collation(114, "utf16_slovak_ci", MYSQL_CHARSET_NAME_utf16); + collation[115] = new Collation(115, "utf16_spanish2_ci", MYSQL_CHARSET_NAME_utf16); + collation[116] = new Collation(116, "utf16_roman_ci", MYSQL_CHARSET_NAME_utf16); + collation[117] = new Collation(117, "utf16_persian_ci", MYSQL_CHARSET_NAME_utf16); + collation[118] = new Collation(118, "utf16_esperanto_ci", MYSQL_CHARSET_NAME_utf16); + collation[119] = new Collation(119, "utf16_hungarian_ci", MYSQL_CHARSET_NAME_utf16); + collation[120] = new Collation(120, "utf16_sinhala_ci", MYSQL_CHARSET_NAME_utf16); + collation[121] = new Collation(121, "utf16_german2_ci", MYSQL_CHARSET_NAME_utf16); + collation[122] = new Collation(122, "utf16_croatian_ci", MYSQL_CHARSET_NAME_utf16); + collation[123] = new Collation(123, "utf16_unicode_520_ci", MYSQL_CHARSET_NAME_utf16); + collation[124] = new Collation(124, "utf16_vietnamese_ci", MYSQL_CHARSET_NAME_utf16); + collation[125] = new Collation(125, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[126] = new Collation(126, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[127] = new Collation(127, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[128] = new Collation(128, "ucs2_unicode_ci", MYSQL_CHARSET_NAME_ucs2); + collation[129] = new Collation(129, "ucs2_icelandic_ci", MYSQL_CHARSET_NAME_ucs2); + collation[130] = new Collation(130, "ucs2_latvian_ci", MYSQL_CHARSET_NAME_ucs2); + collation[131] = new Collation(131, "ucs2_romanian_ci", MYSQL_CHARSET_NAME_ucs2); + collation[132] = new Collation(132, "ucs2_slovenian_ci", MYSQL_CHARSET_NAME_ucs2); + collation[133] = new Collation(133, "ucs2_polish_ci", MYSQL_CHARSET_NAME_ucs2); + collation[134] = new Collation(134, "ucs2_estonian_ci", MYSQL_CHARSET_NAME_ucs2); + collation[135] = new Collation(135, "ucs2_spanish_ci", MYSQL_CHARSET_NAME_ucs2); + collation[136] = new Collation(136, "ucs2_swedish_ci", MYSQL_CHARSET_NAME_ucs2); + collation[137] = new Collation(137, "ucs2_turkish_ci", MYSQL_CHARSET_NAME_ucs2); + collation[138] = new Collation(138, "ucs2_czech_ci", MYSQL_CHARSET_NAME_ucs2); + collation[139] = new Collation(139, "ucs2_danish_ci", MYSQL_CHARSET_NAME_ucs2); + collation[140] = new Collation(140, "ucs2_lithuanian_ci", MYSQL_CHARSET_NAME_ucs2); + collation[141] = new Collation(141, "ucs2_slovak_ci", MYSQL_CHARSET_NAME_ucs2); + collation[142] = new Collation(142, "ucs2_spanish2_ci", MYSQL_CHARSET_NAME_ucs2); + collation[143] = new Collation(143, "ucs2_roman_ci", MYSQL_CHARSET_NAME_ucs2); + collation[144] = new Collation(144, "ucs2_persian_ci", MYSQL_CHARSET_NAME_ucs2); + collation[145] = new Collation(145, "ucs2_esperanto_ci", MYSQL_CHARSET_NAME_ucs2); + collation[146] = new Collation(146, "ucs2_hungarian_ci", MYSQL_CHARSET_NAME_ucs2); + collation[147] = new Collation(147, "ucs2_sinhala_ci", MYSQL_CHARSET_NAME_ucs2); + collation[148] = new Collation(148, "ucs2_german2_ci", MYSQL_CHARSET_NAME_ucs2); + collation[149] = new Collation(149, "ucs2_croatian_ci", MYSQL_CHARSET_NAME_ucs2); + collation[150] = new Collation(150, "ucs2_unicode_520_ci", MYSQL_CHARSET_NAME_ucs2); + collation[151] = new Collation(151, "ucs2_vietnamese_ci", MYSQL_CHARSET_NAME_ucs2); + collation[152] = new Collation(152, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[153] = new Collation(153, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[154] = new Collation(154, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[155] = new Collation(155, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[156] = new Collation(156, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[157] = new Collation(157, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[158] = new Collation(158, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[159] = new Collation(159, "ucs2_general_mysql500_ci", MYSQL_CHARSET_NAME_ucs2); + collation[160] = new Collation(160, "utf32_unicode_ci", MYSQL_CHARSET_NAME_utf32); + collation[161] = new Collation(161, "utf32_icelandic_ci", MYSQL_CHARSET_NAME_utf32); + collation[162] = new Collation(162, "utf32_latvian_ci", MYSQL_CHARSET_NAME_utf32); + collation[163] = new Collation(163, "utf32_romanian_ci", MYSQL_CHARSET_NAME_utf32); + collation[164] = new Collation(164, "utf32_slovenian_ci", MYSQL_CHARSET_NAME_utf32); + collation[165] = new Collation(165, "utf32_polish_ci", MYSQL_CHARSET_NAME_utf32); + collation[166] = new Collation(166, "utf32_estonian_ci", MYSQL_CHARSET_NAME_utf32); + collation[167] = new Collation(167, "utf32_spanish_ci", MYSQL_CHARSET_NAME_utf32); + collation[168] = new Collation(168, "utf32_swedish_ci", MYSQL_CHARSET_NAME_utf32); + collation[169] = new Collation(169, "utf32_turkish_ci", MYSQL_CHARSET_NAME_utf32); + collation[170] = new Collation(170, "utf32_czech_ci", MYSQL_CHARSET_NAME_utf32); + collation[171] = new Collation(171, "utf32_danish_ci", MYSQL_CHARSET_NAME_utf32); + collation[172] = new Collation(172, "utf32_lithuanian_ci", MYSQL_CHARSET_NAME_utf32); + collation[173] = new Collation(173, "utf32_slovak_ci", MYSQL_CHARSET_NAME_utf32); + collation[174] = new Collation(174, "utf32_spanish2_ci", MYSQL_CHARSET_NAME_utf32); + collation[175] = new Collation(175, "utf32_roman_ci", MYSQL_CHARSET_NAME_utf32); + collation[176] = new Collation(176, "utf32_persian_ci", MYSQL_CHARSET_NAME_utf32); + collation[177] = new Collation(177, "utf32_esperanto_ci", MYSQL_CHARSET_NAME_utf32); + collation[178] = new Collation(178, "utf32_hungarian_ci", MYSQL_CHARSET_NAME_utf32); + collation[179] = new Collation(179, "utf32_sinhala_ci", MYSQL_CHARSET_NAME_utf32); + collation[180] = new Collation(180, "utf32_german2_ci", MYSQL_CHARSET_NAME_utf32); + collation[181] = new Collation(181, "utf32_croatian_ci", MYSQL_CHARSET_NAME_utf32); + collation[182] = new Collation(182, "utf32_unicode_520_ci", MYSQL_CHARSET_NAME_utf32); + collation[183] = new Collation(183, "utf32_vietnamese_ci", MYSQL_CHARSET_NAME_utf32); + collation[184] = new Collation(184, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[185] = new Collation(185, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[186] = new Collation(186, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[187] = new Collation(187, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[188] = new Collation(188, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[189] = new Collation(189, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[190] = new Collation(190, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[191] = new Collation(191, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[192] = new Collation(192, "utf8_unicode_ci", MYSQL_CHARSET_NAME_utf8); + collation[193] = new Collation(193, "utf8_icelandic_ci", MYSQL_CHARSET_NAME_utf8); + collation[194] = new Collation(194, "utf8_latvian_ci", MYSQL_CHARSET_NAME_utf8); + collation[195] = new Collation(195, "utf8_romanian_ci", MYSQL_CHARSET_NAME_utf8); + collation[196] = new Collation(196, "utf8_slovenian_ci", MYSQL_CHARSET_NAME_utf8); + collation[197] = new Collation(197, "utf8_polish_ci", MYSQL_CHARSET_NAME_utf8); + collation[198] = new Collation(198, "utf8_estonian_ci", MYSQL_CHARSET_NAME_utf8); + collation[199] = new Collation(199, "utf8_spanish_ci", MYSQL_CHARSET_NAME_utf8); + collation[200] = new Collation(200, "utf8_swedish_ci", MYSQL_CHARSET_NAME_utf8); + collation[201] = new Collation(201, "utf8_turkish_ci", MYSQL_CHARSET_NAME_utf8); + collation[202] = new Collation(202, "utf8_czech_ci", MYSQL_CHARSET_NAME_utf8); + collation[203] = new Collation(203, "utf8_danish_ci", MYSQL_CHARSET_NAME_utf8); + collation[204] = new Collation(204, "utf8_lithuanian_ci", MYSQL_CHARSET_NAME_utf8); + collation[205] = new Collation(205, "utf8_slovak_ci", MYSQL_CHARSET_NAME_utf8); + collation[206] = new Collation(206, "utf8_spanish2_ci", MYSQL_CHARSET_NAME_utf8); + collation[207] = new Collation(207, "utf8_roman_ci", MYSQL_CHARSET_NAME_utf8); + collation[208] = new Collation(208, "utf8_persian_ci", MYSQL_CHARSET_NAME_utf8); + collation[209] = new Collation(209, "utf8_esperanto_ci", MYSQL_CHARSET_NAME_utf8); + collation[210] = new Collation(210, "utf8_hungarian_ci", MYSQL_CHARSET_NAME_utf8); + collation[211] = new Collation(211, "utf8_sinhala_ci", MYSQL_CHARSET_NAME_utf8); + collation[212] = new Collation(212, "utf8_german2_ci", MYSQL_CHARSET_NAME_utf8); + collation[213] = new Collation(213, "utf8_croatian_ci", MYSQL_CHARSET_NAME_utf8); + collation[214] = new Collation(214, "utf8_unicode_520_ci", MYSQL_CHARSET_NAME_utf8); + collation[215] = new Collation(215, "utf8_vietnamese_ci", MYSQL_CHARSET_NAME_utf8); + collation[216] = new Collation(216, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[217] = new Collation(217, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[218] = new Collation(218, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[219] = new Collation(219, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[220] = new Collation(220, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[221] = new Collation(221, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[222] = new Collation(222, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[223] = new Collation(223, "utf8_general_mysql500_ci", MYSQL_CHARSET_NAME_utf8); + collation[224] = new Collation(224, "utf8mb4_unicode_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[225] = new Collation(225, "utf8mb4_icelandic_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[226] = new Collation(226, "utf8mb4_latvian_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[227] = new Collation(227, "utf8mb4_romanian_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[228] = new Collation(228, "utf8mb4_slovenian_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[229] = new Collation(229, "utf8mb4_polish_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[230] = new Collation(230, "utf8mb4_estonian_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[231] = new Collation(231, "utf8mb4_spanish_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[232] = new Collation(232, "utf8mb4_swedish_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[233] = new Collation(233, "utf8mb4_turkish_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[234] = new Collation(234, "utf8mb4_czech_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[235] = new Collation(235, "utf8mb4_danish_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[236] = new Collation(236, "utf8mb4_lithuanian_ci",MYSQL_CHARSET_NAME_utf8mb4); + collation[237] = new Collation(237, "utf8mb4_slovak_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[238] = new Collation(238, "utf8mb4_spanish2_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[239] = new Collation(239, "utf8mb4_roman_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[240] = new Collation(240, "utf8mb4_persian_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[241] = new Collation(241, "utf8mb4_esperanto_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[242] = new Collation(242, "utf8mb4_hungarian_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[243] = new Collation(243, "utf8mb4_sinhala_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[244] = new Collation(244, "utf8mb4_german2_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[245] = new Collation(245, "utf8mb4_croatian_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[246] = new Collation(246, "utf8mb4_unicode_520_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[247] = new Collation(247, "utf8mb4_vietnamese_ci", MYSQL_CHARSET_NAME_utf8mb4); + collation[248] = new Collation(248, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[249] = new Collation(249, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[250] = new Collation(250, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[251] = new Collation(251, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[252] = new Collation(252, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[253] = new Collation(253, "latin1_german1_ci", MYSQL_CHARSET_NAME_latin1, NOT_USED); + collation[254] = new Collation(254, "utf8mb3_general_cs", MYSQL_CHARSET_NAME_utf8); + + INDEX_TO_COLLATION = new String[MAP_SIZE]; + INDEX_TO_CHARSET = new String[MAP_SIZE]; + Map indexToMysqlCharset = new HashMap(); + Map indexMap = new TreeMap(String.CASE_INSENSITIVE_ORDER); - try { - INDEX_TO_CHARSET[1] = getJavaEncodingForMysqlEncoding("big5", null); - INDEX_TO_CHARSET[2] = getJavaEncodingForMysqlEncoding("czech", null); - INDEX_TO_CHARSET[3] = "ISO8859_1"; // punting for "dec8" - INDEX_TO_CHARSET[4] = "ISO8859_1"; // punting for "dos" - INDEX_TO_CHARSET[5] = getJavaEncodingForMysqlEncoding("german1", - null); - INDEX_TO_CHARSET[6] = "ISO8859_1"; // punting for "hp8" - INDEX_TO_CHARSET[7] = getJavaEncodingForMysqlEncoding("koi8_ru", - null); - INDEX_TO_CHARSET[8] = getJavaEncodingForMysqlEncoding("latin1", - null); - INDEX_TO_CHARSET[9] = getJavaEncodingForMysqlEncoding("latin2", - null); - INDEX_TO_CHARSET[10] = "ISO8859_1"; // punting for "swe7" - INDEX_TO_CHARSET[11] = getJavaEncodingForMysqlEncoding("usa7", null); - INDEX_TO_CHARSET[12] = getJavaEncodingForMysqlEncoding("ujis", null); - INDEX_TO_CHARSET[13] = getJavaEncodingForMysqlEncoding("sjis", null); - INDEX_TO_CHARSET[14] = getJavaEncodingForMysqlEncoding("cp1251", - null); - INDEX_TO_CHARSET[15] = getJavaEncodingForMysqlEncoding("danish", - null); - INDEX_TO_CHARSET[16] = getJavaEncodingForMysqlEncoding("hebrew", - null); + for (int i = 1; i < MAP_SIZE; i++) { + INDEX_TO_COLLATION[i] = collation[i].collationName; + indexToMysqlCharset.put(i, collation[i].charsetName); + INDEX_TO_CHARSET[i] = collation[i].javaCharsetName; - INDEX_TO_CHARSET[17] = NOT_USED; // not used in the server - - INDEX_TO_CHARSET[18] = getJavaEncodingForMysqlEncoding("tis620", - null); - INDEX_TO_CHARSET[19] = getJavaEncodingForMysqlEncoding("euc_kr", - null); - INDEX_TO_CHARSET[20] = getJavaEncodingForMysqlEncoding("estonia", - null); - INDEX_TO_CHARSET[21] = getJavaEncodingForMysqlEncoding("hungarian", - null); - INDEX_TO_CHARSET[22] = "KOI8_R"; //punting for "koi8_ukr" - INDEX_TO_CHARSET[23] = getJavaEncodingForMysqlEncoding( - "win1251ukr", null); - INDEX_TO_CHARSET[24] = getJavaEncodingForMysqlEncoding("gb2312", - null); - INDEX_TO_CHARSET[25] = getJavaEncodingForMysqlEncoding("greek", - null); - INDEX_TO_CHARSET[26] = getJavaEncodingForMysqlEncoding("win1250", - null); - INDEX_TO_CHARSET[27] = getJavaEncodingForMysqlEncoding("croat", - null); - INDEX_TO_CHARSET[28] = getJavaEncodingForMysqlEncoding("gbk", null); - INDEX_TO_CHARSET[29] = getJavaEncodingForMysqlEncoding("cp1257", - null); - INDEX_TO_CHARSET[30] = getJavaEncodingForMysqlEncoding("latin5", - null); - INDEX_TO_CHARSET[31] = getJavaEncodingForMysqlEncoding("latin1_de", - null); - INDEX_TO_CHARSET[32] = "ISO8859_1"; // punting "armscii8" - INDEX_TO_CHARSET[33] = getJavaEncodingForMysqlEncoding("utf8", null); - INDEX_TO_CHARSET[34] = "Cp1250"; // punting "win1250ch" - INDEX_TO_CHARSET[35] = getJavaEncodingForMysqlEncoding("ucs2", null); - INDEX_TO_CHARSET[36] = getJavaEncodingForMysqlEncoding("cp866", - null); - INDEX_TO_CHARSET[37] = "Cp895"; // punting "keybcs2" - INDEX_TO_CHARSET[38] = getJavaEncodingForMysqlEncoding("macce", - null); - INDEX_TO_CHARSET[39] = getJavaEncodingForMysqlEncoding("macroman", - null); - INDEX_TO_CHARSET[40] = "latin2"; // punting "pclatin2" - INDEX_TO_CHARSET[41] = getJavaEncodingForMysqlEncoding("latvian", - null); - INDEX_TO_CHARSET[42] = getJavaEncodingForMysqlEncoding("latvian1", - null); - INDEX_TO_CHARSET[43] = getJavaEncodingForMysqlEncoding("macce", - null); - INDEX_TO_CHARSET[44] = getJavaEncodingForMysqlEncoding("macce", - null); - INDEX_TO_CHARSET[45] = getJavaEncodingForMysqlEncoding("macce", - null); - INDEX_TO_CHARSET[46] = getJavaEncodingForMysqlEncoding("macce", - null); - INDEX_TO_CHARSET[47] = getJavaEncodingForMysqlEncoding("latin1", - null); - INDEX_TO_CHARSET[48] = getJavaEncodingForMysqlEncoding( - "latin1", null); - INDEX_TO_CHARSET[49] = getJavaEncodingForMysqlEncoding( - "latin1", null); - INDEX_TO_CHARSET[50] = getJavaEncodingForMysqlEncoding("cp1251", - null); - INDEX_TO_CHARSET[51] = getJavaEncodingForMysqlEncoding( - "cp1251", null); - INDEX_TO_CHARSET[52] = getJavaEncodingForMysqlEncoding( - "cp1251", null); - INDEX_TO_CHARSET[53] = getJavaEncodingForMysqlEncoding( - "macroman", null); - INDEX_TO_CHARSET[54] = getJavaEncodingForMysqlEncoding( - "macroman", null); - INDEX_TO_CHARSET[55] = getJavaEncodingForMysqlEncoding( - "macroman", null); - INDEX_TO_CHARSET[56] = getJavaEncodingForMysqlEncoding( - "macroman", null); - INDEX_TO_CHARSET[57] = getJavaEncodingForMysqlEncoding("cp1256", - null); - - INDEX_TO_CHARSET[58] = NOT_USED; // not used - INDEX_TO_CHARSET[59] = NOT_USED; // not used - INDEX_TO_CHARSET[60] = NOT_USED; // not used - INDEX_TO_CHARSET[61] = NOT_USED; // not used - INDEX_TO_CHARSET[62] = NOT_USED; // not used - - INDEX_TO_CHARSET[63] = getJavaEncodingForMysqlEncoding("binary", - null); - INDEX_TO_CHARSET[64] = "ISO8859_2"; // punting "armscii" - INDEX_TO_CHARSET[65] = getJavaEncodingForMysqlEncoding("ascii", - null); - INDEX_TO_CHARSET[66] = getJavaEncodingForMysqlEncoding("cp1250", - null); - INDEX_TO_CHARSET[67] = getJavaEncodingForMysqlEncoding("cp1256", - null); - INDEX_TO_CHARSET[68] = getJavaEncodingForMysqlEncoding("cp866", - null); - INDEX_TO_CHARSET[69] = "US-ASCII"; // punting for "dec8" - INDEX_TO_CHARSET[70] = getJavaEncodingForMysqlEncoding("greek", - null); - INDEX_TO_CHARSET[71] = getJavaEncodingForMysqlEncoding("hebrew", - null); - INDEX_TO_CHARSET[72] = "US-ASCII"; // punting for "hp8" - INDEX_TO_CHARSET[73] = "Cp895"; // punting for "keybcs2" - INDEX_TO_CHARSET[74] = getJavaEncodingForMysqlEncoding("koi8r", - null); - INDEX_TO_CHARSET[75] = "KOI8_r"; // punting for koi8ukr" - - INDEX_TO_CHARSET[76] = NOT_USED; // not used - - INDEX_TO_CHARSET[77] = getJavaEncodingForMysqlEncoding("latin2", - null); - INDEX_TO_CHARSET[78] = getJavaEncodingForMysqlEncoding("latin5", - null); - INDEX_TO_CHARSET[79] = getJavaEncodingForMysqlEncoding("latin7", - null); - INDEX_TO_CHARSET[80] = getJavaEncodingForMysqlEncoding("cp850", - null); - INDEX_TO_CHARSET[81] = getJavaEncodingForMysqlEncoding("cp852", - null); - INDEX_TO_CHARSET[82] = "ISO8859_1"; // punting for "swe7" - INDEX_TO_CHARSET[83] = getJavaEncodingForMysqlEncoding("utf8", null); - INDEX_TO_CHARSET[84] = getJavaEncodingForMysqlEncoding("big5", null); - INDEX_TO_CHARSET[85] = getJavaEncodingForMysqlEncoding("euckr", - null); - INDEX_TO_CHARSET[86] = getJavaEncodingForMysqlEncoding("gb2312", - null); - INDEX_TO_CHARSET[87] = getJavaEncodingForMysqlEncoding("gbk", null); - INDEX_TO_CHARSET[88] = getJavaEncodingForMysqlEncoding("sjis", null); - INDEX_TO_CHARSET[89] = getJavaEncodingForMysqlEncoding("tis620", - null); - INDEX_TO_CHARSET[90] = getJavaEncodingForMysqlEncoding("ucs2", null); - INDEX_TO_CHARSET[91] = getJavaEncodingForMysqlEncoding("ujis", null); - INDEX_TO_CHARSET[92] = "US-ASCII"; //punting for "geostd8" - INDEX_TO_CHARSET[93] = "US-ASCII"; // punting for "geostd8" - INDEX_TO_CHARSET[94] = getJavaEncodingForMysqlEncoding("latin1", - null); - INDEX_TO_CHARSET[95] = getJavaEncodingForMysqlEncoding("cp932", - null); - INDEX_TO_CHARSET[96] = getJavaEncodingForMysqlEncoding("cp932", - null); - INDEX_TO_CHARSET[97] = getJavaEncodingForMysqlEncoding("eucjpms", - null); - INDEX_TO_CHARSET[98] = getJavaEncodingForMysqlEncoding("eucjpms", - null); - - for (int i = 99; i < 128; i++) { - INDEX_TO_CHARSET[i] = NOT_USED; // not used - } - - INDEX_TO_CHARSET[128] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[129] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[130] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[131] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[132] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[133] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[134] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[135] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[136] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[137] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[138] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[139] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[140] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[141] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[142] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[143] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[144] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[145] = getJavaEncodingForMysqlEncoding("ucs2", - null); - INDEX_TO_CHARSET[146] = getJavaEncodingForMysqlEncoding("ucs2", - null); + if (INDEX_TO_CHARSET[i] != null) indexMap.put(INDEX_TO_CHARSET[i], i); + } - for (int i = 147; i < 192; i++) { - INDEX_TO_CHARSET[i] = NOT_USED; // not used - } - - INDEX_TO_CHARSET[192] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[193] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[194] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[195] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[196] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[197] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[198] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[199] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[200] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[201] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[202] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[203] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[204] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[205] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[206] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[207] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[208] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[209] = getJavaEncodingForMysqlEncoding("utf8", - null); - INDEX_TO_CHARSET[210] = getJavaEncodingForMysqlEncoding("utf8", - null); - - // Sanity check - - for (int i = 1; i < INDEX_TO_CHARSET.length; i++) { - if (INDEX_TO_CHARSET[i] == null) { - throw new RuntimeException("Assertion failure: No mapping from charset index " + i + " to a Java character set"); - } - } - } catch (SQLException sqlEx) { - // ignore, it won't happen in this case + // Sanity check + for (int i = 1; i < MAP_SIZE; i++) { + if (INDEX_TO_COLLATION[i] == null) throw new RuntimeException("Assertion failure: No mapping from charset index " + i + " to a mysql collation"); + if (indexToMysqlCharset.get(i) == null) throw new RuntimeException("Assertion failure: No mapping from charset index " + i + " to a mysql character set"); + if (INDEX_TO_CHARSET[i] == null) throw new RuntimeException("Assertion failure: No mapping from charset index " + i + " to a Java character set"); } + + MYSQL_ENCODING_NAME_TO_CHARSET_INDEX_MAP = Collections.unmodifiableMap(indexMap); + STATIC_INDEX_TO_MYSQL_CHARSET_MAP = Collections.unmodifiableMap(indexToMysqlCharset); - INDEX_TO_COLLATION = new String[211]; + Map tempMap = new HashMap(); - INDEX_TO_COLLATION[1] = "big5_chinese_ci"; - INDEX_TO_COLLATION[2] = "latin2_czech_cs"; - INDEX_TO_COLLATION[3] = "dec8_swedish_ci"; - INDEX_TO_COLLATION[4] = "cp850_general_ci"; - INDEX_TO_COLLATION[5] = "latin1_german1_ci"; - INDEX_TO_COLLATION[6] = "hp8_english_ci"; - INDEX_TO_COLLATION[7] = "koi8r_general_ci"; - INDEX_TO_COLLATION[8] = "latin1_swedish_ci"; - INDEX_TO_COLLATION[9] = "latin2_general_ci"; - INDEX_TO_COLLATION[10] = "swe7_swedish_ci"; - INDEX_TO_COLLATION[11] = "ascii_general_ci"; - INDEX_TO_COLLATION[12] = "ujis_japanese_ci"; - INDEX_TO_COLLATION[13] = "sjis_japanese_ci"; - INDEX_TO_COLLATION[14] = "cp1251_bulgarian_ci"; - INDEX_TO_COLLATION[15] = "latin1_danish_ci"; - INDEX_TO_COLLATION[16] = "hebrew_general_ci"; - INDEX_TO_COLLATION[18] = "tis620_thai_ci"; - INDEX_TO_COLLATION[19] = "euckr_korean_ci"; - INDEX_TO_COLLATION[20] = "latin7_estonian_cs"; - INDEX_TO_COLLATION[21] = "latin2_hungarian_ci"; - INDEX_TO_COLLATION[22] = "koi8u_general_ci"; - INDEX_TO_COLLATION[23] = "cp1251_ukrainian_ci"; - INDEX_TO_COLLATION[24] = "gb2312_chinese_ci"; - INDEX_TO_COLLATION[25] = "greek_general_ci"; - INDEX_TO_COLLATION[26] = "cp1250_general_ci"; - INDEX_TO_COLLATION[27] = "latin2_croatian_ci"; - INDEX_TO_COLLATION[28] = "gbk_chinese_ci"; - INDEX_TO_COLLATION[29] = "cp1257_lithuanian_ci"; - INDEX_TO_COLLATION[30] = "latin5_turkish_ci"; - INDEX_TO_COLLATION[31] = "latin1_german2_ci"; - INDEX_TO_COLLATION[32] = "armscii8_general_ci"; - INDEX_TO_COLLATION[33] = "utf8_general_ci"; - INDEX_TO_COLLATION[34] = "cp1250_czech_cs"; - INDEX_TO_COLLATION[35] = "ucs2_general_ci"; - INDEX_TO_COLLATION[36] = "cp866_general_ci"; - INDEX_TO_COLLATION[37] = "keybcs2_general_ci"; - INDEX_TO_COLLATION[38] = "macce_general_ci"; - INDEX_TO_COLLATION[39] = "macroman_general_ci"; - INDEX_TO_COLLATION[40] = "cp852_general_ci"; - INDEX_TO_COLLATION[41] = "latin7_general_ci"; - INDEX_TO_COLLATION[42] = "latin7_general_cs"; - INDEX_TO_COLLATION[43] = "macce_bin"; - INDEX_TO_COLLATION[44] = "cp1250_croatian_ci"; - INDEX_TO_COLLATION[47] = "latin1_bin"; - INDEX_TO_COLLATION[48] = "latin1_general_ci"; - INDEX_TO_COLLATION[49] = "latin1_general_cs"; - INDEX_TO_COLLATION[50] = "cp1251_bin"; - INDEX_TO_COLLATION[51] = "cp1251_general_ci"; - INDEX_TO_COLLATION[52] = "cp1251_general_cs"; - INDEX_TO_COLLATION[53] = "macroman_bin"; - INDEX_TO_COLLATION[57] = "cp1256_general_ci"; - INDEX_TO_COLLATION[58] = "cp1257_bin"; - INDEX_TO_COLLATION[59] = "cp1257_general_ci"; - INDEX_TO_COLLATION[63] = "binary"; - INDEX_TO_COLLATION[64] = "armscii8_bin"; - INDEX_TO_COLLATION[65] = "ascii_bin"; - INDEX_TO_COLLATION[66] = "cp1250_bin"; - INDEX_TO_COLLATION[67] = "cp1256_bin"; - INDEX_TO_COLLATION[68] = "cp866_bin"; - INDEX_TO_COLLATION[69] = "dec8_bin"; - INDEX_TO_COLLATION[70] = "greek_bin"; - INDEX_TO_COLLATION[71] = "hebrew_bin"; - INDEX_TO_COLLATION[72] = "hp8_bin"; - INDEX_TO_COLLATION[73] = "keybcs2_bin"; - INDEX_TO_COLLATION[74] = "koi8r_bin"; - INDEX_TO_COLLATION[75] = "koi8u_bin"; - INDEX_TO_COLLATION[77] = "latin2_bin"; - INDEX_TO_COLLATION[78] = "latin5_bin"; - INDEX_TO_COLLATION[79] = "latin7_bin"; - INDEX_TO_COLLATION[80] = "cp850_bin"; - INDEX_TO_COLLATION[81] = "cp852_bin"; - INDEX_TO_COLLATION[82] = "swe7_bin"; - INDEX_TO_COLLATION[83] = "utf8_bin"; - INDEX_TO_COLLATION[84] = "big5_bin"; - INDEX_TO_COLLATION[85] = "euckr_bin"; - INDEX_TO_COLLATION[86] = "gb2312_bin"; - INDEX_TO_COLLATION[87] = "gbk_bin"; - INDEX_TO_COLLATION[88] = "sjis_bin"; - INDEX_TO_COLLATION[89] = "tis620_bin"; - INDEX_TO_COLLATION[90] = "ucs2_bin"; - INDEX_TO_COLLATION[91] = "ujis_bin"; - INDEX_TO_COLLATION[92] = "geostd8_general_ci"; - INDEX_TO_COLLATION[93] = "geostd8_bin"; - INDEX_TO_COLLATION[94] = "latin1_spanish_ci"; - INDEX_TO_COLLATION[95] = "cp932_japanese_ci"; - INDEX_TO_COLLATION[96] = "cp932_bin"; - INDEX_TO_COLLATION[97] = "eucjpms_japanese_ci"; - INDEX_TO_COLLATION[98] = "eucjpms_bin"; - INDEX_TO_COLLATION[99] = "cp1250_polish_ci"; - INDEX_TO_COLLATION[128] = "ucs2_unicode_ci"; - INDEX_TO_COLLATION[129] = "ucs2_icelandic_ci"; - INDEX_TO_COLLATION[130] = "ucs2_latvian_ci"; - INDEX_TO_COLLATION[131] = "ucs2_romanian_ci"; - INDEX_TO_COLLATION[132] = "ucs2_slovenian_ci"; - INDEX_TO_COLLATION[133] = "ucs2_polish_ci"; - INDEX_TO_COLLATION[134] = "ucs2_estonian_ci"; - INDEX_TO_COLLATION[135] = "ucs2_spanish_ci"; - INDEX_TO_COLLATION[136] = "ucs2_swedish_ci"; - INDEX_TO_COLLATION[137] = "ucs2_turkish_ci"; - INDEX_TO_COLLATION[138] = "ucs2_czech_ci"; - INDEX_TO_COLLATION[139] = "ucs2_danish_ci"; - INDEX_TO_COLLATION[140] = "ucs2_lithuanian_ci "; - INDEX_TO_COLLATION[141] = "ucs2_slovak_ci"; - INDEX_TO_COLLATION[142] = "ucs2_spanish2_ci"; - INDEX_TO_COLLATION[143] = "ucs2_roman_ci"; - INDEX_TO_COLLATION[144] = "ucs2_persian_ci"; - INDEX_TO_COLLATION[145] = "ucs2_esperanto_ci"; - INDEX_TO_COLLATION[146] = "ucs2_hungarian_ci"; - INDEX_TO_COLLATION[192] = "utf8_unicode_ci"; - INDEX_TO_COLLATION[193] = "utf8_icelandic_ci"; - INDEX_TO_COLLATION[194] = "utf8_latvian_ci"; - INDEX_TO_COLLATION[195] = "utf8_romanian_ci"; - INDEX_TO_COLLATION[196] = "utf8_slovenian_ci"; - INDEX_TO_COLLATION[197] = "utf8_polish_ci"; - INDEX_TO_COLLATION[198] = "utf8_estonian_ci"; - INDEX_TO_COLLATION[199] = "utf8_spanish_ci"; - INDEX_TO_COLLATION[200] = "utf8_swedish_ci"; - INDEX_TO_COLLATION[201] = "utf8_turkish_ci"; - INDEX_TO_COLLATION[202] = "utf8_czech_ci"; - INDEX_TO_COLLATION[203] = "utf8_danish_ci"; - INDEX_TO_COLLATION[204] = "utf8_lithuanian_ci "; - INDEX_TO_COLLATION[205] = "utf8_slovak_ci"; - INDEX_TO_COLLATION[206] = "utf8_spanish2_ci"; - INDEX_TO_COLLATION[207] = "utf8_roman_ci"; - INDEX_TO_COLLATION[208] = "utf8_persian_ci"; - INDEX_TO_COLLATION[209] = "utf8_esperanto_ci"; - INDEX_TO_COLLATION[210] = "utf8_hungarian_ci"; - - Map tempMap = new HashMap(); - tempMap.put("czech", "latin2"); tempMap.put("danish", "latin1"); tempMap.put("dutch", "latin1"); @@ -711,63 +683,59 @@ Collections.unmodifiableMap(tempMap); } - public final static String getJavaEncodingForMysqlEncoding(String mysqlEncoding, + public final static String getMysqlEncodingForJavaEncoding(String javaEncodingUC, Connection conn) throws SQLException { - if (conn != null && conn.versionMeetsMinimum(4, 1, 0) && - "latin1".equalsIgnoreCase(mysqlEncoding)) { - return "Cp1252"; - } - - return (String) MYSQL_TO_JAVA_CHARSET_MAP.get(mysqlEncoding); - } + try { + List mysqlEncodings = CharsetMapping.JAVA_UC_TO_MYSQL_CHARSET_MAP.get(javaEncodingUC); - public final static String getMysqlEncodingForJavaEncoding(String javaEncodingUC, - Connection conn) throws SQLException { - List mysqlEncodings = (List) CharsetMapping.JAVA_UC_TO_MYSQL_CHARSET_MAP - .get(javaEncodingUC); - ; + if (mysqlEncodings != null) { + Iterator iter = mysqlEncodings.iterator(); - if (mysqlEncodings != null) { - Iterator iter = mysqlEncodings.iterator(); + VersionedStringProperty versionedProp = null; - VersionedStringProperty versionedProp = null; + while (iter.hasNext()) { + VersionedStringProperty propToCheck = iter.next(); - while (iter.hasNext()) { - VersionedStringProperty propToCheck = (VersionedStringProperty) iter - .next(); + if (conn == null) { + // Take the first one we get - if (conn == null) { - // Take the first one we get + return propToCheck.toString(); + } - return propToCheck.toString(); - } + if (versionedProp != null && !versionedProp.preferredValue) { + if (versionedProp.majorVersion == propToCheck.majorVersion + && versionedProp.minorVersion == propToCheck.minorVersion + && versionedProp.subminorVersion == propToCheck.subminorVersion) { + return versionedProp.toString(); + } + } - if (versionedProp != null && !versionedProp.preferredValue) { - if (versionedProp.majorVersion == propToCheck.majorVersion - && versionedProp.minorVersion == propToCheck.minorVersion - && versionedProp.subminorVersion == propToCheck.subminorVersion) { - return versionedProp.toString(); + if (propToCheck.isOkayForVersion(conn)) { + if (propToCheck.preferredValue) { + return propToCheck.toString(); + } + + versionedProp = propToCheck; + } else { + break; } } - if (propToCheck.isOkayForVersion(conn)) { - if (propToCheck.preferredValue) { - return propToCheck.toString(); - } - - versionedProp = propToCheck; - } else { - break; + if (versionedProp != null) { + return versionedProp.toString(); } } - if (versionedProp != null) { - return versionedProp.toString(); - } + return null; + } 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; } - return null; } final static int getNumberOfCharsetsConfigured() { @@ -786,7 +754,23 @@ * @return the Java encoding name that error messages use * @throws SQLException if determination of the character encoding fails */ - final static String getCharacterEncodingForErrorMessages(Connection conn) throws SQLException { + final static String getCharacterEncodingForErrorMessages(ConnectionImpl conn) throws SQLException { + + // As of MySQL 5.5, the server constructs error messages using UTF-8 + // and returns them to clients in the character set specified by the + // character_set_results system variable. + if (conn.versionMeetsMinimum(5, 5, 0)) { + String errorMessageEncodingMysql = conn.getServerVariable("character_set_results"); + if (errorMessageEncodingMysql != null) { + String javaEncoding = conn.getJavaEncodingForMysqlEncoding(errorMessageEncodingMysql); + if (javaEncoding != null) { + return javaEncoding; + } + } + + return "UTF-8"; + } + String errorMessageFile = conn.getServerVariable("language"); if (errorMessageFile == null || errorMessageFile.length() == 0) { @@ -817,14 +801,14 @@ errorMessageFile = errorMessageFile.substring(lastSlashIndex + 1, endWithoutSlash); - String errorMessageEncodingMysql = (String)ERROR_MESSAGE_FILE_TO_MYSQL_CHARSET_MAP.get(errorMessageFile); + String errorMessageEncodingMysql = ERROR_MESSAGE_FILE_TO_MYSQL_CHARSET_MAP.get(errorMessageFile); if (errorMessageEncodingMysql == null) { // punt return "Cp1252"; } - String javaEncoding = getJavaEncodingForMysqlEncoding(errorMessageEncodingMysql, conn); + String javaEncoding = conn.getJavaEncodingForMysqlEncoding(errorMessageEncodingMysql); if (javaEncoding == null) { // punt @@ -850,77 +834,80 @@ return MULTIBYTE_CHARSETS.containsKey(javaEncodingNameUC); } - private static void populateMapWithKeyValuePairs(String configKey, - Map mapToPopulate, boolean addVersionedProperties, - boolean addUppercaseKeys) { + private static void populateMapWithKeyValuePairsUnversioned(String configKey, Map mapToPopulate, boolean addUppercaseKeys) { String javaToMysqlConfig = CHARSET_CONFIG.getProperty(configKey); + if (javaToMysqlConfig == null) throw new RuntimeException("Could not find configuration value " + "\"" + configKey + "\" in Charsets.properties resource"); + + List mappings = StringUtils.split(javaToMysqlConfig, ",", true); + if (mappings == null) throw new RuntimeException("Missing/corrupt entry for \"" + configKey + "\" in Charsets.properties."); - if (javaToMysqlConfig != null) { - List mappings = StringUtils.split(javaToMysqlConfig, ",", true); + Iterator mappingsIter = mappings.iterator(); + while (mappingsIter.hasNext()) { + String aMapping = mappingsIter.next(); + List parsedPair = StringUtils.split(aMapping, "=", true); + if (parsedPair.size() != 2) throw new RuntimeException("Syntax error in Charsets.properties " + "resource for token \"" + aMapping + "\"."); - if (mappings != null) { - Iterator mappingsIter = mappings.iterator(); + String key = parsedPair.get(0).toString(); + String value = parsedPair.get(1).toString(); + mapToPopulate.put(key, value); - while (mappingsIter.hasNext()) { - String aMapping = (String) mappingsIter.next(); + if (addUppercaseKeys) mapToPopulate.put(key.toUpperCase(Locale.ENGLISH), value); + } + } - List parsedPair = StringUtils.split(aMapping, "=", true); + private static void populateMapWithKeyValuePairsVersioned(String configKey, Map> mapToPopulate, boolean addUppercaseKeys) { + String javaToMysqlConfig = CHARSET_CONFIG.getProperty(configKey); + if (javaToMysqlConfig == null) throw new RuntimeException("Could not find configuration value " + "\"" + configKey + "\" in Charsets.properties resource"); - if (parsedPair.size() == 2) { - String key = parsedPair.get(0).toString(); - String value = parsedPair.get(1).toString(); + List mappings = StringUtils.split(javaToMysqlConfig, ",", true); + if (mappings == null) throw new RuntimeException("Missing/corrupt entry for \"" + configKey + "\" in Charsets.properties."); - if (addVersionedProperties) { - List versionedProperties = (List) mapToPopulate - .get(key); + Iterator mappingsIter = mappings.iterator(); + while (mappingsIter.hasNext()) { + String aMapping = mappingsIter.next(); + List parsedPair = StringUtils.split(aMapping, "=", true); + if (parsedPair.size() != 2) throw new RuntimeException("Syntax error in Charsets.properties " + "resource for token \"" + aMapping + "\"."); - if (versionedProperties == null) { - versionedProperties = new ArrayList(); - mapToPopulate.put(key, versionedProperties); - } + String key = parsedPair.get(0).toString(); + String value = parsedPair.get(1).toString(); - VersionedStringProperty verProp = new VersionedStringProperty( - value); - versionedProperties.add(verProp); + List versionedProperties = mapToPopulate.get(key); - if (addUppercaseKeys) { - String keyUc = key.toUpperCase(Locale.ENGLISH); + if (versionedProperties == null) { + versionedProperties = new ArrayList(); + mapToPopulate.put(key, versionedProperties); + } - versionedProperties = (List) mapToPopulate - .get(keyUc); + VersionedStringProperty verProp = new VersionedStringProperty(value); + versionedProperties.add(verProp); - if (versionedProperties == null) { - versionedProperties = new ArrayList(); - mapToPopulate.put(keyUc, - versionedProperties); - } + if (addUppercaseKeys) { + String keyUc = key.toUpperCase(Locale.ENGLISH); + versionedProperties = mapToPopulate.get(keyUc); - versionedProperties.add(verProp); - } - } else { - mapToPopulate.put(key, value); - - if (addUppercaseKeys) { - mapToPopulate.put(key - .toUpperCase(Locale.ENGLISH), value); - } - } - } else { - throw new RuntimeException( - "Syntax error in Charsets.properties " - + "resource for token \"" + aMapping - + "\"."); - } + if (versionedProperties == null) { + versionedProperties = new ArrayList(); + mapToPopulate.put(keyUc, versionedProperties); } - } else { - throw new RuntimeException("Missing/corrupt entry for \"" - + configKey + "\" in Charsets.properties."); + + versionedProperties.add(verProp); } - } else { - throw new RuntimeException("Could not find configuration value " - + "\"" + configKey + "\" in Charsets.properties resource"); } } + + public static int getCharsetIndexForMysqlEncodingName(String name) { + if (name == null) { + return 0; + } + + Integer asInt = MYSQL_ENCODING_NAME_TO_CHARSET_INDEX_MAP.get(name); + + if (asInt == null) { + return 0; + } + + return asInt.intValue(); + } } class VersionedStringProperty { @@ -953,7 +940,7 @@ } String versionInfo = property.substring(0, charPos); - List versionParts = StringUtils.split(versionInfo, ".", true); + List versionParts = StringUtils.split(versionInfo, ".", true); majorVersion = Integer.parseInt(versionParts.get(0).toString()); @@ -989,7 +976,44 @@ subminorVersion); } + public String toString() { return propertyInfo; } } + +class Collation { + public int index; + public String collationName; + public String charsetName; + public String javaCharsetName; + + public Collation(int index, String collationName, String charsetName) { + this.index = index; + this.collationName = collationName; + this.charsetName = charsetName; + this.javaCharsetName = CharsetMapping.MYSQL_TO_JAVA_CHARSET_MAP.get(charsetName); + } + + public Collation(int index, String collationName, String charsetName, String javaCharsetName) { + this.index = index; + this.collationName = collationName; + this.charsetName = charsetName; + this.javaCharsetName = javaCharsetName; + } + + public String toString() { + StringBuffer asString = new StringBuffer(); + asString.append("["); + asString.append("index="); + asString.append(this.index); + asString.append(",collationName="); + asString.append(this.collationName); + asString.append(",charsetName="); + asString.append(this.charsetName); + asString.append(",javaCharsetName="); + asString.append(this.javaCharsetName); + asString.append("]"); + return asString.toString(); + } +} Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Clob.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Clob.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Clob.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Clob.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.ByteArrayInputStream; @@ -30,7 +29,6 @@ import java.io.Reader; import java.io.StringReader; import java.io.Writer; - import java.sql.SQLException; /** @@ -41,17 +39,24 @@ */ public class Clob implements java.sql.Clob, OutputStreamWatcher, WriterWatcher { private String charData; - - Clob(String charDataInit) { + private ExceptionInterceptor exceptionInterceptor; + + Clob(ExceptionInterceptor exceptionInterceptor) { + this.charData = ""; + this.exceptionInterceptor = exceptionInterceptor; + } + + Clob(String charDataInit, ExceptionInterceptor exceptionInterceptor) { this.charData = charDataInit; + this.exceptionInterceptor = exceptionInterceptor; } /** * @see java.sql.Clob#getAsciiStream() */ public InputStream getAsciiStream() throws SQLException { if (this.charData != null) { - return new ByteArrayInputStream(this.charData.getBytes()); + return new ByteArrayInputStream(StringUtils.getBytes(this.charData)); } return null; @@ -74,7 +79,7 @@ public String getSubString(long startPos, int length) throws SQLException { if (startPos < 1) { throw SQLError.createSQLException(Messages.getString("Clob.6"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } int adjustedStartPos = (int)startPos - 1; @@ -83,7 +88,7 @@ if (this.charData != null) { if (adjustedEndIndex > this.charData.length()) { throw SQLError.createSQLException(Messages.getString("Clob.7"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } return this.charData.substring(adjustedStartPos, @@ -119,13 +124,13 @@ if (startPos < 1) { throw SQLError.createSQLException( Messages.getString("Clob.8") //$NON-NLS-1$ - + startPos + Messages.getString("Clob.9"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + + startPos + Messages.getString("Clob.9"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); //$NON-NLS-1$ } if (this.charData != null) { if ((startPos - 1) > this.charData.length()) { throw SQLError.createSQLException(Messages.getString("Clob.10"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } int pos = this.charData.indexOf(stringToFind, (int) (startPos - 1)); @@ -142,14 +147,14 @@ public OutputStream setAsciiStream(long indexToWriteAt) throws SQLException { if (indexToWriteAt < 1) { throw SQLError.createSQLException(Messages.getString("Clob.0"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } WatchableOutputStream bytesOut = new WatchableOutputStream(); bytesOut.setWatcher(this); if (indexToWriteAt > 0) { - bytesOut.write(this.charData.getBytes(), 0, + bytesOut.write(StringUtils.getBytes(this.charData), 0, (int) (indexToWriteAt - 1)); } @@ -162,7 +167,7 @@ public Writer setCharacterStream(long indexToWriteAt) throws SQLException { if (indexToWriteAt < 1) { throw SQLError.createSQLException(Messages.getString("Clob.1"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } WatchableWriter writer = new WatchableWriter(); @@ -184,12 +189,12 @@ public int setString(long pos, String str) throws SQLException { if (pos < 1) { throw SQLError.createSQLException(Messages.getString("Clob.2"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } if (str == null) { throw SQLError.createSQLException(Messages.getString("Clob.3"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } StringBuffer charBuf = new StringBuffer(this.charData); @@ -212,12 +217,12 @@ throws SQLException { if (pos < 1) { throw SQLError.createSQLException(Messages.getString("Clob.4"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } if (str == null) { throw SQLError.createSQLException(Messages.getString("Clob.5"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } StringBuffer charBuf = new StringBuffer(this.charData); @@ -243,7 +248,7 @@ if (streamSize < this.charData.length()) { try { out.write(StringUtils - .getBytes(this.charData, null, null, false, null), + .getBytes(this.charData, null, null, false, null, this.exceptionInterceptor), streamSize, this.charData.length() - streamSize); } catch (SQLException ex) { // @@ -261,7 +266,7 @@ throw SQLError.createSQLException( Messages.getString("Clob.11") //$NON-NLS-1$ + this.charData.length() - + Messages.getString("Clob.12") + length + Messages.getString("Clob.13")); //$NON-NLS-1$ //$NON-NLS-2$ + + Messages.getString("Clob.12") + length + Messages.getString("Clob.13"), this.exceptionInterceptor); //$NON-NLS-1$ //$NON-NLS-2$ } this.charData = this.charData.substring(0, (int) length); @@ -287,4 +292,12 @@ this.charData = out.toString(); } + + public void free() throws SQLException { + this.charData = null; + } + + public Reader getCharacterStream(long pos, long length) throws SQLException { + return new StringReader(getSubString(pos, (int)length)); + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/CommunicationsException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/CommunicationsException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/CommunicationsException.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/CommunicationsException.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,31 +1,28 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; -import java.net.BindException; - import java.sql.SQLException; /** @@ -40,177 +37,50 @@ * @version $Id: CommunicationsException.java,v 1.1.2.1 2005/05/13 18:58:37 * mmatthews Exp $ */ -public class CommunicationsException extends SQLException { +public class CommunicationsException extends SQLException implements StreamingNotifiable { - private static final long DEFAULT_WAIT_TIMEOUT_SECONDS = 28800; + static final long serialVersionUID = 3193864990663398317L; - private static final int DUE_TO_TIMEOUT_FALSE = 0; + private String exceptionMessage = null; - private static final int DUE_TO_TIMEOUT_MAYBE = 2; - - private static final int DUE_TO_TIMEOUT_TRUE = 1; - - private String exceptionMessage; - private boolean streamingResultSetInPlay = false; - public CommunicationsException(Connection conn, long lastPacketSentTimeMs, - Exception underlyingException) { + private MySQLConnection conn; + private long lastPacketSentTimeMs; + private long lastPacketReceivedTimeMs; + private Exception underlyingException; - long serverTimeoutSeconds = 0; - boolean isInteractiveClient = false; - - if (conn != null) { - isInteractiveClient = conn.getInteractiveClient(); - - String serverTimeoutSecondsStr = null; - - if (isInteractiveClient) { - serverTimeoutSecondsStr = conn - .getServerVariable("interactive_timeout"); //$NON-NLS-1$ - } else { - serverTimeoutSecondsStr = conn - .getServerVariable("wait_timeout"); //$NON-NLS-1$ - } - - if (serverTimeoutSecondsStr != null) { - try { - serverTimeoutSeconds = Long - .parseLong(serverTimeoutSecondsStr); - } catch (NumberFormatException nfe) { - serverTimeoutSeconds = 0; - } - } - } - - StringBuffer exceptionMessageBuf = new StringBuffer(); - - if (lastPacketSentTimeMs == 0) { - lastPacketSentTimeMs = System.currentTimeMillis(); - } - - long timeSinceLastPacket = (System.currentTimeMillis() - lastPacketSentTimeMs) / 1000; - - int dueToTimeout = DUE_TO_TIMEOUT_FALSE; - - StringBuffer timeoutMessageBuf = null; - - if (this.streamingResultSetInPlay) { - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.ClientWasStreaming")); //$NON-NLS-1$ - } else { - if (serverTimeoutSeconds != 0) { - if (timeSinceLastPacket > serverTimeoutSeconds) { - dueToTimeout = DUE_TO_TIMEOUT_TRUE; - - timeoutMessageBuf = new StringBuffer(); - - timeoutMessageBuf.append(Messages - .getString("CommunicationsException.2")); //$NON-NLS-1$ - - if (!isInteractiveClient) { - timeoutMessageBuf.append(Messages - .getString("CommunicationsException.3")); //$NON-NLS-1$ - } else { - timeoutMessageBuf.append(Messages - .getString("CommunicationsException.4")); //$NON-NLS-1$ - } - - } - } else if (timeSinceLastPacket > DEFAULT_WAIT_TIMEOUT_SECONDS) { - dueToTimeout = DUE_TO_TIMEOUT_MAYBE; - - timeoutMessageBuf = new StringBuffer(); - - timeoutMessageBuf.append(Messages - .getString("CommunicationsException.5")); //$NON-NLS-1$ - timeoutMessageBuf.append(Messages - .getString("CommunicationsException.6")); //$NON-NLS-1$ - timeoutMessageBuf.append(Messages - .getString("CommunicationsException.7")); //$NON-NLS-1$ - timeoutMessageBuf.append(Messages - .getString("CommunicationsException.8")); //$NON-NLS-1$ - } - - if (dueToTimeout == DUE_TO_TIMEOUT_TRUE - || dueToTimeout == DUE_TO_TIMEOUT_MAYBE) { - - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.9")); //$NON-NLS-1$ - exceptionMessageBuf.append(timeSinceLastPacket); - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.10")); //$NON-NLS-1$ - - if (timeoutMessageBuf != null) { - exceptionMessageBuf.append(timeoutMessageBuf); - } - - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.11")); //$NON-NLS-1$ - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.12")); //$NON-NLS-1$ - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.13")); //$NON-NLS-1$ - - } else { - // - // Attempt to determine the reason for the underlying exception - // (we can only make a best-guess here) - // - - if (underlyingException instanceof BindException) { - if (conn.getLocalSocketAddress() != null && - !Util.interfaceExists(conn.getLocalSocketAddress())) { - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.19a")); //$NON-NLS-1$ - } else { - // too many client connections??? - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.14")); //$NON-NLS-1$ - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.15")); //$NON-NLS-1$ - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.16")); //$NON-NLS-1$ - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.17")); //$NON-NLS-1$ - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.18")); //$NON-NLS-1$ - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.19")); //$NON-NLS-1$ - } - } - } - } + public CommunicationsException(MySQLConnection conn, long lastPacketSentTimeMs, + long lastPacketReceivedTimeMs, Exception underlyingException) { - if (exceptionMessageBuf.length() == 0) { - // We haven't figured out a good reason, so copy it. - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.20")); //$NON-NLS-1$ - - if (underlyingException != null) { - exceptionMessageBuf.append(Messages - .getString("CommunicationsException.21")); //$NON-NLS-1$ - exceptionMessageBuf.append(Util - .stackTraceToString(underlyingException)); - } - - if (conn != null && conn.getMaintainTimeStats() && - !conn.getParanoid()) { - exceptionMessageBuf.append("\n\nLast packet sent to the server was "); - exceptionMessageBuf.append(System.currentTimeMillis() - lastPacketSentTimeMs); - exceptionMessageBuf.append(" ms ago."); - } + // store this information for later generation of message + this.conn = conn; + this.lastPacketReceivedTimeMs = lastPacketReceivedTimeMs; + this.lastPacketSentTimeMs = lastPacketSentTimeMs; + this.underlyingException = underlyingException; + + if (underlyingException != null) { + initCause(underlyingException); } - - this.exceptionMessage = exceptionMessageBuf.toString(); } + + /* * (non-Javadoc) * * @see java.lang.Throwable#getMessage() */ public String getMessage() { + // Get the message at last possible moment, but cache it + // and drop references to conn, underlyingException + if(this.exceptionMessage == null){ + this.exceptionMessage = SQLError.createLinkFailureMessageBasedOnHeuristics(this.conn, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, this.underlyingException, + this.streamingResultSetInPlay); + this.conn = null; + this.underlyingException = null; + } return this.exceptionMessage; } @@ -222,8 +92,11 @@ public String getSQLState() { return SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE; } - - protected void setWasStreamingResults() { + + /* (non-Javadoc) + * @see com.mysql.jdbc.StreamingNotifiable#setWasStreamingResults() + */ + public void setWasStreamingResults() { this.streamingResultSetInPlay = true; } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/CompressedInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/CompressedInputStream.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/CompressedInputStream.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/CompressedInputStream.java 30 Jul 2014 08:37:25 -0000 1.1.2.1 @@ -1,37 +1,36 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; - import java.sql.SQLException; - import java.util.zip.DataFormatException; import java.util.zip.Inflater; +import com.mysql.jdbc.log.Log; +import com.mysql.jdbc.log.NullLogger; /** * Used to de-compress packets from the MySQL server when protocol-level @@ -46,15 +45,18 @@ /** The packet data after it has been un-compressed */ private byte[] buffer; - /** The connection that is using us (used to read config values) */ - private Connection connection; - /** The stream we are reading from the server */ private InputStream in; /** The ZIP inflater used to un-compress packets */ private Inflater inflater; + /** Connection property reference */ + private ConnectionPropertiesImpl.BooleanConnectionProperty traceProtocol; + + /** Connection logger */ + private Log log; + /** * The buffer to read packet headers into */ @@ -72,7 +74,13 @@ * @param streamFromServer */ public CompressedInputStream(Connection conn, InputStream streamFromServer) { - this.connection = conn; + this.traceProtocol = ((ConnectionPropertiesImpl)conn).traceProtocol; + try { + this.log = conn.getLog(); + } catch (SQLException e) { + this.log = new NullLogger(null); + } + this.in = streamFromServer; this.inflater = new Inflater(); } @@ -94,7 +102,10 @@ public void close() throws IOException { this.in.close(); this.buffer = null; + this.inflater.end(); this.inflater = null; + this.traceProtocol = null; + this.log = null; } /** @@ -121,16 +132,13 @@ + (((this.packetHeaderBuffer[5] & 0xff)) << 8) + (((this.packetHeaderBuffer[6] & 0xff)) << 16); - if (this.connection.getTraceProtocol()) { - try { - this.connection.getLog().logTrace( - "Reading compressed packet of length " - + compressedPacketLength + " uncompressed to " - + uncompressedLength); - } catch (SQLException sqlEx) { - throw new IOException(sqlEx.toString()); // should never - // happen - } + boolean doTrace = this.traceProtocol.getValueAsBoolean(); + + if (doTrace) { + this.log.logTrace( + "Reading compressed packet of length " + + compressedPacketLength + " uncompressed to " + + uncompressedLength); } if (uncompressedLength > 0) { @@ -157,16 +165,9 @@ this.inflater.end(); } else { - if (this.connection.getTraceProtocol()) { - try { - this.connection - .getLog() - .logTrace( - "Packet didn't meet compression threshold, not uncompressing..."); - } catch (SQLException sqlEx) { - throw new IOException(sqlEx.toString()); // should never - // happen - } + if (doTrace) { + this.log.logTrace( + "Packet didn't meet compression threshold, not uncompressing..."); } // @@ -177,27 +178,17 @@ readFully(uncompressedData, 0, compressedPacketLength); } - if (this.connection.getTraceProtocol()) { - try { - this.connection.getLog().logTrace( + if (doTrace) { + this.log.logTrace( "Uncompressed packet: \n" + StringUtils.dumpAsHex(uncompressedData, compressedPacketLength)); - } catch (SQLException sqlEx) { - throw new IOException(sqlEx.toString()); // should never - // happen - } } if ((this.buffer != null) && (this.pos < this.buffer.length)) { - if (this.connection.getTraceProtocol()) { - try { - this.connection.getLog().logTrace( - "Combining remaining packet with new: "); - } catch (SQLException sqlEx) { - throw new IOException(sqlEx.toString()); // should never - // happen - } + if (doTrace) { + this.log.logTrace( + "Combining remaining packet with new: "); } int remaining = this.buffer.length - this.pos; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Connection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Connection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Connection.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Connection.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,1851 +1,50 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; -import com.mysql.jdbc.log.Log; -import com.mysql.jdbc.log.LogFactory; -import com.mysql.jdbc.log.NullLogger; -import com.mysql.jdbc.profiler.ProfileEventSink; -import com.mysql.jdbc.profiler.ProfilerEvent; -import com.mysql.jdbc.util.LRUCache; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.io.UnsupportedEncodingException; - -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.math.BigDecimal; - -import java.net.URL; - -import java.sql.Blob; -import java.sql.Clob; -import java.sql.Date; -import java.sql.ParameterMetaData; -import java.sql.Ref; import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Savepoint; -import java.sql.Time; -import java.sql.Timestamp; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; import java.util.Properties; -import java.util.Stack; -import java.util.StringTokenizer; import java.util.TimeZone; -import java.util.Timer; -import java.util.TreeMap; +import java.util.concurrent.Executor; +import com.mysql.jdbc.log.Log; + /** - * A Connection represents a session with a specific database. Within the - * context of a Connection, SQL statements are executed and results are - * returned. - *

- * A Connection's database is able to provide information describing its tables, - * its supported SQL grammar, its stored procedures, the capabilities of this - * connection, etc. This information is obtained with the getMetaData method. - *

+ * This interface contains methods that are considered the "vendor extension" + * to the JDBC API for MySQL's implementation of java.sql.Connection. * - * @author Mark Matthews + * For those looking further into the driver implementation, it is not + * an API that is used for plugability of implementations inside our driver + * (which is why there are still references to ConnectionImpl throughout the + * code). + * * @version $Id$ - * @see java.sql.Connection + * */ -public class Connection extends ConnectionProperties implements - java.sql.Connection { - private static final String JDBC_LOCAL_CHARACTER_SET_RESULTS = "jdbc.local.character_set_results"; +public interface Connection extends java.sql.Connection, ConnectionProperties { /** - * Used as a key for caching callable statements which (may) depend on - * current catalog...In 5.0.x, they don't (currently), but stored procedure - * names soon will, so current catalog is a (hidden) component of the name. - */ - class CompoundCacheKey { - String componentOne; - - String componentTwo; - - int hashCode; - - CompoundCacheKey(String partOne, String partTwo) { - this.componentOne = partOne; - this.componentTwo = partTwo; - - // Handle first component (in most cases, currentCatalog) - // being NULL.... - this.hashCode = (((this.componentOne != null) ? this.componentOne - : "") + this.componentTwo).hashCode(); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object obj) { - if (obj instanceof CompoundCacheKey) { - CompoundCacheKey another = (CompoundCacheKey) obj; - - boolean firstPartEqual = false; - - if (this.componentOne == null) { - firstPartEqual = (another.componentOne == null); - } else { - firstPartEqual = this.componentOne - .equals(another.componentOne); - } - - return (firstPartEqual && this.componentTwo - .equals(another.componentTwo)); - } - - return false; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return this.hashCode; - } - } - - /** - * Wrapper class for UltraDev CallableStatements that are really - * PreparedStatments. Nice going, UltraDev developers. - */ - class UltraDevWorkAround implements java.sql.CallableStatement { - private java.sql.PreparedStatement delegate = null; - - UltraDevWorkAround(java.sql.PreparedStatement pstmt) { - this.delegate = pstmt; - } - - public void addBatch() throws SQLException { - this.delegate.addBatch(); - } - - public void addBatch(java.lang.String p1) throws SQLException { - this.delegate.addBatch(p1); - } - - public void cancel() throws SQLException { - this.delegate.cancel(); - } - - public void clearBatch() throws SQLException { - this.delegate.clearBatch(); - } - - public void clearParameters() throws SQLException { - this.delegate.clearParameters(); - } - - public void clearWarnings() throws SQLException { - this.delegate.clearWarnings(); - } - - public void close() throws SQLException { - this.delegate.close(); - } - - public boolean execute() throws SQLException { - return this.delegate.execute(); - } - - public boolean execute(java.lang.String p1) throws SQLException { - return this.delegate.execute(p1); - } - - /** - * @see Statement#execute(String, int) - */ - public boolean execute(String arg0, int arg1) throws SQLException { - return this.delegate.execute(arg0, arg1); - } - - /** - * @see Statement#execute(String, int[]) - */ - public boolean execute(String arg0, int[] arg1) throws SQLException { - return this.delegate.execute(arg0, arg1); - } - - /** - * @see Statement#execute(String, String[]) - */ - public boolean execute(String arg0, String[] arg1) throws SQLException { - return this.delegate.execute(arg0, arg1); - } - - public int[] executeBatch() throws SQLException { - return this.delegate.executeBatch(); - } - - public java.sql.ResultSet executeQuery() throws SQLException { - return this.delegate.executeQuery(); - } - - public java.sql.ResultSet executeQuery(java.lang.String p1) - throws SQLException { - return this.delegate.executeQuery(p1); - } - - public int executeUpdate() throws SQLException { - return this.delegate.executeUpdate(); - } - - public int executeUpdate(java.lang.String p1) throws SQLException { - return this.delegate.executeUpdate(p1); - } - - /** - * @see Statement#executeUpdate(String, int) - */ - public int executeUpdate(String arg0, int arg1) throws SQLException { - return this.delegate.executeUpdate(arg0, arg1); - } - - /** - * @see Statement#executeUpdate(String, int[]) - */ - public int executeUpdate(String arg0, int[] arg1) throws SQLException { - return this.delegate.executeUpdate(arg0, arg1); - } - - /** - * @see Statement#executeUpdate(String, String[]) - */ - public int executeUpdate(String arg0, String[] arg1) - throws SQLException { - return this.delegate.executeUpdate(arg0, arg1); - } - - public java.sql.Array getArray(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getArray(String) - */ - public java.sql.Array getArray(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public java.math.BigDecimal getBigDecimal(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * DOCUMENT ME! - * - * @param p1 - * DOCUMENT ME! - * @param p2 - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws SQLException - * DOCUMENT ME! - * @deprecated - */ - public java.math.BigDecimal getBigDecimal(int p1, int p2) - throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getBigDecimal(String) - */ - public BigDecimal getBigDecimal(String arg0) throws SQLException { - return null; - } - - public java.sql.Blob getBlob(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getBlob(String) - */ - public java.sql.Blob getBlob(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public boolean getBoolean(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getBoolean(String) - */ - public boolean getBoolean(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public byte getByte(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getByte(String) - */ - public byte getByte(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public byte[] getBytes(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getBytes(String) - */ - public byte[] getBytes(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public java.sql.Clob getClob(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getClob(String) - */ - public Clob getClob(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public java.sql.Connection getConnection() throws SQLException { - return this.delegate.getConnection(); - } - - public java.sql.Date getDate(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - public java.sql.Date getDate(int p1, final Calendar p2) - throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getDate(String) - */ - public Date getDate(String arg0) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#getDate(String, Calendar) - */ - public Date getDate(String arg0, Calendar arg1) throws SQLException { - throw new NotImplemented(); - } - - public double getDouble(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getDouble(String) - */ - public double getDouble(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public int getFetchDirection() throws SQLException { - return this.delegate.getFetchDirection(); - } - - public int getFetchSize() throws java.sql.SQLException { - return this.delegate.getFetchSize(); - } - - public float getFloat(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getFloat(String) - */ - public float getFloat(String arg0) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see Statement#getGeneratedKeys() - */ - public java.sql.ResultSet getGeneratedKeys() throws SQLException { - return this.delegate.getGeneratedKeys(); - } - - public int getInt(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getInt(String) - */ - public int getInt(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public long getLong(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getLong(String) - */ - public long getLong(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public int getMaxFieldSize() throws SQLException { - return this.delegate.getMaxFieldSize(); - } - - public int getMaxRows() throws SQLException { - return this.delegate.getMaxRows(); - } - - public java.sql.ResultSetMetaData getMetaData() throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - public boolean getMoreResults() throws SQLException { - return this.delegate.getMoreResults(); - } - - /** - * @see Statement#getMoreResults(int) - */ - public boolean getMoreResults(int arg0) throws SQLException { - return this.delegate.getMoreResults(); - } - - public java.lang.Object getObject(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - public java.lang.Object getObject(int p1, final java.util.Map p2) - throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getObject(String) - */ - public Object getObject(String arg0) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#getObject(String, Map) - */ - public Object getObject(String arg0, Map arg1) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see PreparedStatement#getParameterMetaData() - */ - public ParameterMetaData getParameterMetaData() throws SQLException { - return this.delegate.getParameterMetaData(); - } - - public int getQueryTimeout() throws SQLException { - return this.delegate.getQueryTimeout(); - } - - public java.sql.Ref getRef(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getRef(String) - */ - public Ref getRef(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public java.sql.ResultSet getResultSet() throws SQLException { - return this.delegate.getResultSet(); - } - - public int getResultSetConcurrency() throws SQLException { - return this.delegate.getResultSetConcurrency(); - } - - /** - * @see Statement#getResultSetHoldability() - */ - public int getResultSetHoldability() throws SQLException { - return this.delegate.getResultSetHoldability(); - } - - public int getResultSetType() throws SQLException { - return this.delegate.getResultSetType(); - } - - public short getShort(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getShort(String) - */ - public short getShort(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public java.lang.String getString(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getString(String) - */ - public String getString(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public java.sql.Time getTime(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - public java.sql.Time getTime(int p1, final java.util.Calendar p2) - throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getTime(String) - */ - public Time getTime(String arg0) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#getTime(String, Calendar) - */ - public Time getTime(String arg0, Calendar arg1) throws SQLException { - throw new NotImplemented(); - } - - public java.sql.Timestamp getTimestamp(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - public java.sql.Timestamp getTimestamp(int p1, - final java.util.Calendar p2) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#getTimestamp(String) - */ - public Timestamp getTimestamp(String arg0) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#getTimestamp(String, Calendar) - */ - public Timestamp getTimestamp(String arg0, Calendar arg1) - throws SQLException { - throw new NotImplemented(); - } - - public int getUpdateCount() throws SQLException { - return this.delegate.getUpdateCount(); - } - - /** - * @see CallableStatement#getURL(int) - */ - public URL getURL(int arg0) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#getURL(String) - */ - public URL getURL(String arg0) throws SQLException { - throw new NotImplemented(); - } - - public java.sql.SQLWarning getWarnings() throws SQLException { - return this.delegate.getWarnings(); - } - - public void registerOutParameter(int p1, int p2) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - public void registerOutParameter(int p1, int p2, int p3) - throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - public void registerOutParameter(int p1, int p2, java.lang.String p3) - throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - /** - * @see CallableStatement#registerOutParameter(String, int) - */ - public void registerOutParameter(String arg0, int arg1) - throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#registerOutParameter(String, int, int) - */ - public void registerOutParameter(String arg0, int arg1, int arg2) - throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#registerOutParameter(String, int, String) - */ - public void registerOutParameter(String arg0, int arg1, String arg2) - throws SQLException { - throw new NotImplemented(); - } - - public void setArray(int p1, final java.sql.Array p2) - throws SQLException { - this.delegate.setArray(p1, p2); - } - - public void setAsciiStream(int p1, final java.io.InputStream p2, int p3) - throws SQLException { - this.delegate.setAsciiStream(p1, p2, p3); - } - - /** - * @see CallableStatement#setAsciiStream(String, InputStream, int) - */ - public void setAsciiStream(String arg0, InputStream arg1, int arg2) - throws SQLException { - throw new NotImplemented(); - } - - public void setBigDecimal(int p1, final java.math.BigDecimal p2) - throws SQLException { - this.delegate.setBigDecimal(p1, p2); - } - - /** - * @see CallableStatement#setBigDecimal(String, BigDecimal) - */ - public void setBigDecimal(String arg0, BigDecimal arg1) - throws SQLException { - throw new NotImplemented(); - } - - public void setBinaryStream(int p1, final java.io.InputStream p2, int p3) - throws SQLException { - this.delegate.setBinaryStream(p1, p2, p3); - } - - /** - * @see CallableStatement#setBinaryStream(String, InputStream, int) - */ - public void setBinaryStream(String arg0, InputStream arg1, int arg2) - throws SQLException { - throw new NotImplemented(); - } - - public void setBlob(int p1, final java.sql.Blob p2) throws SQLException { - this.delegate.setBlob(p1, p2); - } - - public void setBoolean(int p1, boolean p2) throws SQLException { - this.delegate.setBoolean(p1, p2); - } - - /** - * @see CallableStatement#setBoolean(String, boolean) - */ - public void setBoolean(String arg0, boolean arg1) throws SQLException { - throw new NotImplemented(); - } - - public void setByte(int p1, byte p2) throws SQLException { - this.delegate.setByte(p1, p2); - } - - /** - * @see CallableStatement#setByte(String, byte) - */ - public void setByte(String arg0, byte arg1) throws SQLException { - throw new NotImplemented(); - } - - public void setBytes(int p1, byte[] p2) throws SQLException { - this.delegate.setBytes(p1, p2); - } - - /** - * @see CallableStatement#setBytes(String, byte[]) - */ - public void setBytes(String arg0, byte[] arg1) throws SQLException { - throw new NotImplemented(); - } - - public void setCharacterStream(int p1, final java.io.Reader p2, int p3) - throws SQLException { - this.delegate.setCharacterStream(p1, p2, p3); - } - - /** - * @see CallableStatement#setCharacterStream(String, Reader, int) - */ - public void setCharacterStream(String arg0, Reader arg1, int arg2) - throws SQLException { - throw new NotImplemented(); - } - - public void setClob(int p1, final java.sql.Clob p2) throws SQLException { - this.delegate.setClob(p1, p2); - } - - public void setCursorName(java.lang.String p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - public void setDate(int p1, final java.sql.Date p2) throws SQLException { - this.delegate.setDate(p1, p2); - } - - public void setDate(int p1, final java.sql.Date p2, - final java.util.Calendar p3) throws SQLException { - this.delegate.setDate(p1, p2, p3); - } - - /** - * @see CallableStatement#setDate(String, Date) - */ - public void setDate(String arg0, Date arg1) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#setDate(String, Date, Calendar) - */ - public void setDate(String arg0, Date arg1, Calendar arg2) - throws SQLException { - throw new NotImplemented(); - } - - public void setDouble(int p1, double p2) throws SQLException { - this.delegate.setDouble(p1, p2); - } - - /** - * @see CallableStatement#setDouble(String, double) - */ - public void setDouble(String arg0, double arg1) throws SQLException { - throw new NotImplemented(); - } - - public void setEscapeProcessing(boolean p1) throws SQLException { - this.delegate.setEscapeProcessing(p1); - } - - public void setFetchDirection(int p1) throws SQLException { - this.delegate.setFetchDirection(p1); - } - - public void setFetchSize(int p1) throws SQLException { - this.delegate.setFetchSize(p1); - } - - public void setFloat(int p1, float p2) throws SQLException { - this.delegate.setFloat(p1, p2); - } - - /** - * @see CallableStatement#setFloat(String, float) - */ - public void setFloat(String arg0, float arg1) throws SQLException { - throw new NotImplemented(); - } - - public void setInt(int p1, int p2) throws SQLException { - this.delegate.setInt(p1, p2); - } - - /** - * @see CallableStatement#setInt(String, int) - */ - public void setInt(String arg0, int arg1) throws SQLException { - throw new NotImplemented(); - } - - public void setLong(int p1, long p2) throws SQLException { - this.delegate.setLong(p1, p2); - } - - /** - * @see CallableStatement#setLong(String, long) - */ - public void setLong(String arg0, long arg1) throws SQLException { - throw new NotImplemented(); - } - - public void setMaxFieldSize(int p1) throws SQLException { - this.delegate.setMaxFieldSize(p1); - } - - public void setMaxRows(int p1) throws SQLException { - this.delegate.setMaxRows(p1); - } - - public void setNull(int p1, int p2) throws SQLException { - this.delegate.setNull(p1, p2); - } - - public void setNull(int p1, int p2, java.lang.String p3) - throws SQLException { - this.delegate.setNull(p1, p2, p3); - } - - /** - * @see CallableStatement#setNull(String, int) - */ - public void setNull(String arg0, int arg1) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#setNull(String, int, String) - */ - public void setNull(String arg0, int arg1, String arg2) - throws SQLException { - throw new NotImplemented(); - } - - public void setObject(int p1, final java.lang.Object p2) - throws SQLException { - this.delegate.setObject(p1, p2); - } - - public void setObject(int p1, final java.lang.Object p2, int p3) - throws SQLException { - this.delegate.setObject(p1, p2, p3); - } - - public void setObject(int p1, final java.lang.Object p2, int p3, int p4) - throws SQLException { - this.delegate.setObject(p1, p2, p3, p4); - } - - /** - * @see CallableStatement#setObject(String, Object) - */ - public void setObject(String arg0, Object arg1) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#setObject(String, Object, int) - */ - public void setObject(String arg0, Object arg1, int arg2) - throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#setObject(String, Object, int, int) - */ - public void setObject(String arg0, Object arg1, int arg2, int arg3) - throws SQLException { - throw new NotImplemented(); - } - - public void setQueryTimeout(int p1) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - public void setRef(int p1, final Ref p2) throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - - public void setShort(int p1, short p2) throws SQLException { - this.delegate.setShort(p1, p2); - } - - /** - * @see CallableStatement#setShort(String, short) - */ - public void setShort(String arg0, short arg1) throws SQLException { - throw new NotImplemented(); - } - - public void setString(int p1, java.lang.String p2) - throws java.sql.SQLException { - this.delegate.setString(p1, p2); - } - - /** - * @see CallableStatement#setString(String, String) - */ - public void setString(String arg0, String arg1) throws SQLException { - throw new NotImplemented(); - } - - public void setTime(int p1, final java.sql.Time p2) throws SQLException { - this.delegate.setTime(p1, p2); - } - - public void setTime(int p1, final java.sql.Time p2, - final java.util.Calendar p3) throws SQLException { - this.delegate.setTime(p1, p2, p3); - } - - /** - * @see CallableStatement#setTime(String, Time) - */ - public void setTime(String arg0, Time arg1) throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#setTime(String, Time, Calendar) - */ - public void setTime(String arg0, Time arg1, Calendar arg2) - throws SQLException { - throw new NotImplemented(); - } - - public void setTimestamp(int p1, final java.sql.Timestamp p2) - throws SQLException { - this.delegate.setTimestamp(p1, p2); - } - - public void setTimestamp(int p1, final java.sql.Timestamp p2, - final java.util.Calendar p3) throws SQLException { - this.delegate.setTimestamp(p1, p2, p3); - } - - /** - * @see CallableStatement#setTimestamp(String, Timestamp) - */ - public void setTimestamp(String arg0, Timestamp arg1) - throws SQLException { - throw new NotImplemented(); - } - - /** - * @see CallableStatement#setTimestamp(String, Timestamp, Calendar) - */ - public void setTimestamp(String arg0, Timestamp arg1, Calendar arg2) - throws SQLException { - throw new NotImplemented(); - } - - /** - * DOCUMENT ME! - * - * @param p1 - * DOCUMENT ME! - * @param p2 - * DOCUMENT ME! - * @param p3 - * DOCUMENT ME! - * @throws SQLException - * DOCUMENT ME! - * @deprecated - */ - public void setUnicodeStream(int p1, final java.io.InputStream p2, - int p3) throws SQLException { - this.delegate.setUnicodeStream(p1, p2, p3); - } - - /** - * @see PreparedStatement#setURL(int, URL) - */ - public void setURL(int arg0, URL arg1) throws SQLException { - this.delegate.setURL(arg0, arg1); - } - - /** - * @see CallableStatement#setURL(String, URL) - */ - public void setURL(String arg0, URL arg1) throws SQLException { - throw new NotImplemented(); - } - - public boolean wasNull() throws SQLException { - throw SQLError.createSQLException("Not supported"); - } - } - - /** - * Marker for character set converter not being available (not written, - * multibyte, etc) Used to prevent multiple instantiation requests. - */ - private static final Object CHARSET_CONVERTER_NOT_AVAILABLE_MARKER = new Object(); - - /** - * The mapping between MySQL charset names and Java charset names. - * Initialized by loadCharacterSetMapping() - */ - public static Map charsetMap; - - /** Default logger class name */ - protected static final String DEFAULT_LOGGER_CLASS = "com.mysql.jdbc.log.StandardLogger"; - - private final static int HISTOGRAM_BUCKETS = 20; - - /** Logger instance name */ - private static final String LOGGER_INSTANCE_NAME = "MySQL"; - - /** - * Map mysql transaction isolation level name to - * java.sql.Connection.TRANSACTION_XXX - */ - private static Map mapTransIsolationNameToValue = null; - - /** Null logger shared by all connections at startup */ - private static final Log NULL_LOGGER = new NullLogger(LOGGER_INSTANCE_NAME); - - private static Map roundRobinStatsMap; - - private static final Map serverCollationByUrl = new HashMap(); - - private static final Map serverConfigByUrl = new HashMap(); - - private static Timer cancelTimer; - - static { - mapTransIsolationNameToValue = new HashMap(8); - mapTransIsolationNameToValue.put("READ-UNCOMMITED", new Integer( - TRANSACTION_READ_UNCOMMITTED)); - mapTransIsolationNameToValue.put("READ-UNCOMMITTED", new Integer( - TRANSACTION_READ_UNCOMMITTED)); - mapTransIsolationNameToValue.put("READ-COMMITTED", new Integer( - TRANSACTION_READ_COMMITTED)); - mapTransIsolationNameToValue.put("REPEATABLE-READ", new Integer( - TRANSACTION_REPEATABLE_READ)); - mapTransIsolationNameToValue.put("SERIALIZABLE", new Integer( - TRANSACTION_SERIALIZABLE)); - - 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}); - - cancelTimer = (Timer)ctr.newInstance(new Object[] { "MySQL Statement Cancellation Timer", Boolean.TRUE}); - createdNamedTimer = true; - } catch (Throwable t) { - createdNamedTimer = false; - } - - if (!createdNamedTimer) { - cancelTimer = new Timer(true); - } - } - - protected static SQLException appendMessageToException(SQLException sqlEx, - String messageToAppend) { - String origMessage = sqlEx.getMessage(); - String sqlState = sqlEx.getSQLState(); - int vendorErrorCode = sqlEx.getErrorCode(); - - StringBuffer messageBuf = new StringBuffer(origMessage.length() - + messageToAppend.length()); - messageBuf.append(origMessage); - messageBuf.append(messageToAppend); - - SQLException sqlExceptionWithNewMessage = SQLError.createSQLException(messageBuf - .toString(), sqlState, vendorErrorCode); - - // - // Try and maintain the original stack trace, - // only works on JDK-1.4 and newer - // - - try { - // Have to do this with reflection, otherwise older JVMs croak - Method getStackTraceMethod = null; - Method setStackTraceMethod = null; - Object theStackTraceAsObject = null; - - Class stackTraceElementClass = Class - .forName("java.lang.StackTraceElement"); - Class stackTraceElementArrayClass = Array.newInstance( - stackTraceElementClass, new int[] { 0 }).getClass(); - - getStackTraceMethod = Throwable.class.getMethod("getStackTrace", - new Class[] {}); - - setStackTraceMethod = Throwable.class.getMethod("setStackTrace", - new Class[] { stackTraceElementArrayClass }); - - if (getStackTraceMethod != null && setStackTraceMethod != null) { - theStackTraceAsObject = getStackTraceMethod.invoke(sqlEx, - new Object[0]); - setStackTraceMethod.invoke(sqlExceptionWithNewMessage, - new Object[] { theStackTraceAsObject }); - } - } catch (NoClassDefFoundError noClassDefFound) { - - } catch (NoSuchMethodException noSuchMethodEx) { - - } catch (Throwable catchAll) { - - } - - return sqlExceptionWithNewMessage; - } - - protected static Timer getCancelTimer() { - return cancelTimer; - } - - private static synchronized int getNextRoundRobinHostIndex(String url, - List hostList) { - if (roundRobinStatsMap == null) { - roundRobinStatsMap = new HashMap(); - } - - int[] index = (int[]) roundRobinStatsMap.get(url); - - if (index == null) { - index = new int[1]; - index[0] = -1; - - roundRobinStatsMap.put(url, index); - } - - index[0]++; - - if (index[0] >= hostList.size()) { - index[0] = 0; - } - - return index[0]; - } - - private static boolean nullSafeCompare(String s1, String s2) { - if (s1 == null && s2 == null) { - return true; - } - - if (s1 == null && s2 != null) { - return false; - } - - return s1.equals(s2); - } - - /** Are we in autoCommit mode? */ - private boolean autoCommit = true; - - /** A map of SQL to parsed prepared statement parameters. */ - private Map cachedPreparedStatementParams; - - /** - * For servers > 4.1.0, what character set is the metadata returned in? - */ - private String characterSetMetadata = null; - - /** - * The character set we want results and result metadata returned in (null == - * results in any charset, metadata in UTF-8). - */ - private String characterSetResultsOnServer = null; - - /** - * Holds cached mappings to charset converters to avoid static - * synchronization and at the same time save memory (each charset converter - * takes approx 65K of static data). - */ - private Map charsetConverterMap = new HashMap(CharsetMapping - .getNumberOfCharsetsConfigured()); - - /** - * The mapping between MySQL charset names and the max number of chars in - * them. Lazily instantiated via getMaxBytesPerChar(). - */ - private Map charsetToNumBytesMap; - - /** The point in time when this connection was created */ - private long connectionCreationTimeMillis = 0; - - /** ID used when profiling */ - private long connectionId; - - /** The database we're currently using (called Catalog in JDBC terms). */ - private String database = null; - - /** Internal DBMD to use for various database-version specific features */ - private DatabaseMetaData dbmd = null; - - private TimeZone defaultTimeZone; - - /** The event sink to use for profiling */ - private ProfileEventSink eventSink; - - private boolean executingFailoverReconnect = false; - - /** Are we failed-over to a non-master host */ - private boolean failedOver = false; - - /** Why was this connection implicitly closed, if known? (for diagnostics) */ - private Throwable forceClosedReason; - - /** Where was this connection implicitly closed? (for diagnostics) */ - private Throwable forcedClosedLocation; - - /** Does the server suuport isolation levels? */ - private boolean hasIsolationLevels = false; - - /** Does this version of MySQL support quoted identifiers? */ - private boolean hasQuotedIdentifiers = false; - - /** The hostname we're connected to */ - private String host = null; - - /** The list of host(s) to try and connect to */ - private List hostList = null; - - /** How many hosts are in the host list? */ - private int hostListSize = 0; - - /** - * We need this 'bootstrapped', because 4.1 and newer will send fields back - * with this even before we fill this dynamically from the server. - */ - private String[] indexToCharsetMapping = CharsetMapping.INDEX_TO_CHARSET; - - /** The I/O abstraction interface (network conn to MySQL server */ - private MysqlIO io = null; - - private boolean isClientTzUTC = false; - - /** Has this connection been closed? */ - private boolean isClosed = true; - - /** Is this connection associated with a global tx? */ - private boolean isInGlobalTx = false; - - /** Is this connection running inside a JDK-1.3 VM? */ - private boolean isRunningOnJDK13 = false; - - /** isolation level */ - private int isolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED; - - private boolean isServerTzUTC = false; - - /** When did the last query finish? */ - private long lastQueryFinishedTime = 0; - - /** The logger we're going to use */ - private Log log = NULL_LOGGER; - - /** - * If gathering metrics, what was the execution time of the longest query so - * far ? - */ - private long longestQueryTimeMs = 0; - - /** Is the server configured to use lower-case table names only? */ - private boolean lowerCaseTableNames = false; - - /** When did the master fail? */ - private long masterFailTimeMillis = 0L; - - /** - * The largest packet we can send (changed once we know what the server - * supports, we get this at connection init). - */ - private int maxAllowedPacket = 65536; - - private long maximumNumberTablesAccessed = 0; - - /** Has the max-rows setting been changed from the default? */ - private boolean maxRowsChanged = false; - - /** When was the last time we reported metrics? */ - private long metricsLastReportedMs; - - private long minimumNumberTablesAccessed = Long.MAX_VALUE; - - /** Mutex */ - private final Object mutex = new Object(); - - /** The JDBC URL we're using */ - private String myURL = null; - - /** Does this connection need to be tested? */ - private boolean needsPing = false; - - private int netBufferLength = 16384; - - private boolean noBackslashEscapes = false; - - private long numberOfPreparedExecutes = 0; - - private long numberOfPrepares = 0; - - private long numberOfQueriesIssued = 0; - - private long numberOfResultSetsCreated = 0; - - private long[] numTablesMetricsHistBreakpoints; - - private int[] numTablesMetricsHistCounts; - - private long[] oldHistBreakpoints = null; - - private int[] oldHistCounts = null; - - /** A map of currently open statements */ - private Map openStatements; - - private LRUCache parsedCallableStatementCache; - - private boolean parserKnowsUnicode = false; - - /** The password we used */ - private String password = null; - - private long[] perfMetricsHistBreakpoints; - - private int[] perfMetricsHistCounts; - - /** Point of origin where this Connection was created */ - private Throwable pointOfOrigin; - - /** The port number we're connected to (defaults to 3306) */ - private int port = 3306; - - /** - * Used only when testing failover functionality for regressions, causes the - * failover code to not retry the master first - */ - private boolean preferSlaveDuringFailover = false; - - /** Properties for this connection specified by user */ - private Properties props = null; - - /** Number of queries we've issued since the master failed */ - private long queriesIssuedFailedOver = 0; - - /** Should we retrieve 'info' messages from the server? */ - private boolean readInfoMsg = false; - - /** Are we in read-only mode? */ - private boolean readOnly = false; - - /** Cache of ResultSet metadata */ - protected LRUCache resultSetMetadataCache; - - /** The timezone of the server */ - private TimeZone serverTimezoneTZ = null; - - /** The map of server variables that we retrieve at connection init. */ - private Map serverVariables = null; - - private long shortestQueryTimeMs = Long.MAX_VALUE; - - /** A map of statements that have had setMaxRows() called on them */ - private Map statementsUsingMaxRows; - - private double totalQueryTimeMs = 0; - - /** Are transactions supported by the MySQL server we are connected to? */ - private boolean transactionsSupported = false; - - /** - * The type map for UDTs (not implemented, but used by some third-party - * vendors, most notably IBM WebSphere) - */ - private Map typeMap; - - /** Has ANSI_QUOTES been enabled on the server? */ - private boolean useAnsiQuotes = false; - - /** The user we're connected as */ - private String user = null; - - /** - * Should we use server-side prepared statements? (auto-detected, but can be - * disabled by user) - */ - private boolean useServerPreparedStmts = false; - - private LRUCache serverSideStatementCheckCache; - - private LRUCache serverSideStatementCache; - private Calendar sessionCalendar; - private Calendar utcCalendar; - - private String origHostToConnectTo; - - private int origPortToConnectTo; - - // we don't want to be able to publicly clone this... - - private String origDatabaseToConnectTo; - - private String errorMessageEncoding = "Cp1252"; // to begin with, changes after we talk to the server - - private boolean usePlatformCharsetConverters; - - - /** - * Creates a connection to a MySQL Server. - * - * @param hostToConnectTo - * the hostname of the database server - * @param portToConnectTo - * the port number the server is listening on - * @param info - * a Properties[] list holding the user and password - * @param databaseToConnectTo - * the database to connect to - * @param url - * the URL of the connection - * @param d - * the Driver instantation of the connection - * @exception SQLException - * if a database access error occurs - */ - Connection(String hostToConnectTo, int portToConnectTo, Properties info, - String databaseToConnectTo, String url) - throws SQLException { - this.charsetToNumBytesMap = new HashMap(); - - this.connectionCreationTimeMillis = System.currentTimeMillis(); - this.pointOfOrigin = new Throwable(); - - // Stash away for later, used to clone this connection for Statement.cancel - // and Statement.setQueryTimeout(). - // - - this.origHostToConnectTo = hostToConnectTo; - this.origPortToConnectTo = portToConnectTo; - this.origDatabaseToConnectTo = databaseToConnectTo; - - try { - Blob.class.getMethod("truncate", new Class[] {Long.TYPE}); - - this.isRunningOnJDK13 = false; - } catch (NoSuchMethodException nsme) { - this.isRunningOnJDK13 = true; - } - - this.sessionCalendar = new GregorianCalendar(); - this.utcCalendar = new GregorianCalendar(); - this.utcCalendar.setTimeZone(TimeZone.getTimeZone("GMT")); - - // - // Normally, this code would be in initializeDriverProperties, - // but we need to do this as early as possible, so we can start - // logging to the 'correct' place as early as possible...this.log - // points to 'NullLogger' for every connection at startup to avoid - // NPEs and the overhead of checking for NULL at every logging call. - // - // We will reset this to the configured logger during properties - // initialization. - // - this.log = LogFactory.getLogger(getLogger(), LOGGER_INSTANCE_NAME); - - // We store this per-connection, due to static synchronization - // issues in Java's built-in TimeZone class... - this.defaultTimeZone = Util.getDefaultTimeZone(); - - if ("GMT".equalsIgnoreCase(this.defaultTimeZone.getID())) { - this.isClientTzUTC = true; - } else { - this.isClientTzUTC = false; - } - - this.openStatements = new HashMap(); - this.serverVariables = new HashMap(); - this.hostList = new ArrayList(); - - if (hostToConnectTo == null) { - this.host = "localhost"; - this.hostList.add(this.host); - } else if (hostToConnectTo.indexOf(",") != -1) { - // multiple hosts separated by commas (failover) - StringTokenizer hostTokenizer = new StringTokenizer( - hostToConnectTo, ",", false); - - while (hostTokenizer.hasMoreTokens()) { - this.hostList.add(hostTokenizer.nextToken().trim()); - } - } else { - this.host = hostToConnectTo; - this.hostList.add(this.host); - } - - this.hostListSize = this.hostList.size(); - this.port = portToConnectTo; - - if (databaseToConnectTo == null) { - databaseToConnectTo = ""; - } - - this.database = databaseToConnectTo; - this.myURL = url; - this.user = info.getProperty(NonRegisteringDriver.USER_PROPERTY_KEY); - this.password = info - .getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY); - - if ((this.user == null) || this.user.equals("")) { - this.user = ""; - } - - if (this.password == null) { - this.password = ""; - } - - this.props = info; - initializeDriverProperties(info); - - try { - createNewIO(false); - this.dbmd = new DatabaseMetaData(this, this.database); - } catch (SQLException ex) { - cleanup(ex); - - // don't clobber SQL exceptions - throw ex; - } catch (Exception ex) { - cleanup(ex); - - StringBuffer mesg = new StringBuffer(); - - if (getParanoid()) { - mesg.append("Cannot connect to MySQL server on "); - mesg.append(this.host); - mesg.append(":"); - mesg.append(this.port); - mesg.append(".\n\n"); - mesg.append("Make sure that there is a MySQL server "); - mesg.append("running on the machine/port you are trying "); - mesg - .append("to connect to and that the machine this software is " - + "running on "); - mesg.append("is able to connect to this host/port " - + "(i.e. not firewalled). "); - mesg - .append("Also make sure that the server has not been started " - + "with the --skip-networking "); - mesg.append("flag.\n\n"); - } else { - mesg.append("Unable to connect to database."); - } - - mesg.append("Underlying exception: \n\n"); - mesg.append(ex.getClass().getName()); - - if (!getParanoid()) { - mesg.append(Util.stackTraceToString(ex)); - } - - throw SQLError.createSQLException(mesg.toString(), - SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE); - } - } - - private void addToHistogram(int[] histogramCounts, - long[] histogramBreakpoints, long value, int numberOfTimes, - long currentLowerBound, long currentUpperBound) { - if (histogramCounts == null) { - createInitialHistogram(histogramBreakpoints, - currentLowerBound, currentUpperBound); - } - - for (int i = 0; i < HISTOGRAM_BUCKETS; i++) { - if (histogramBreakpoints[i] >= value) { - histogramCounts[i] += numberOfTimes; - - break; - } - } - } - - private void addToPerformanceHistogram(long value, int numberOfTimes) { - checkAndCreatePerformanceHistogram(); - - addToHistogram(this.perfMetricsHistCounts, - this.perfMetricsHistBreakpoints, value, numberOfTimes, - this.shortestQueryTimeMs == Long.MAX_VALUE ? 0 - : this.shortestQueryTimeMs, this.longestQueryTimeMs); - } - - private void addToTablesAccessedHistogram(long value, int numberOfTimes) { - checkAndCreateTablesAccessedHistogram(); - - addToHistogram(this.numTablesMetricsHistCounts, - this.numTablesMetricsHistBreakpoints, value, numberOfTimes, - this.minimumNumberTablesAccessed == Long.MAX_VALUE ? 0 - : this.minimumNumberTablesAccessed, - this.maximumNumberTablesAccessed); - } - - /** - * Builds the map needed for 4.1.0 and newer servers that maps field-level - * charset/collation info to a java character encoding name. - * - * @throws SQLException - * DOCUMENT ME! - */ - private void buildCollationMapping() throws SQLException { - if (versionMeetsMinimum(4, 1, 0)) { - - TreeMap sortedCollationMap = null; - - if (getCacheServerConfiguration()) { - synchronized (serverConfigByUrl) { - sortedCollationMap = (TreeMap) serverCollationByUrl - .get(getURL()); - } - } - - com.mysql.jdbc.Statement stmt = null; - com.mysql.jdbc.ResultSet results = null; - - try { - if (sortedCollationMap == null) { - sortedCollationMap = new TreeMap(); - - stmt = (com.mysql.jdbc.Statement) createStatement(); - - if (stmt.getMaxRows() != 0) { - stmt.setMaxRows(0); - } - - results = (com.mysql.jdbc.ResultSet) stmt - .executeQuery("SHOW COLLATION"); - - while (results.next()) { - String charsetName = results.getString(2); - Integer charsetIndex = new Integer(results.getInt(3)); - - sortedCollationMap.put(charsetIndex, charsetName); - } - - if (getCacheServerConfiguration()) { - synchronized (serverConfigByUrl) { - serverCollationByUrl.put(getURL(), - sortedCollationMap); - } - } - - } - - // Now, merge with what we already know - int highestIndex = ((Integer) sortedCollationMap.lastKey()) - .intValue(); - - if (CharsetMapping.INDEX_TO_CHARSET.length > highestIndex) { - highestIndex = CharsetMapping.INDEX_TO_CHARSET.length; - } - - this.indexToCharsetMapping = new String[highestIndex + 1]; - - for (int i = 0; i < CharsetMapping.INDEX_TO_CHARSET.length; i++) { - this.indexToCharsetMapping[i] = CharsetMapping.INDEX_TO_CHARSET[i]; - } - - for (Iterator indexIter = sortedCollationMap.entrySet() - .iterator(); indexIter.hasNext();) { - Map.Entry indexEntry = (Map.Entry) indexIter.next(); - - String mysqlCharsetName = (String) indexEntry.getValue(); - - this.indexToCharsetMapping[((Integer) indexEntry.getKey()) - .intValue()] = CharsetMapping - .getJavaEncodingForMysqlEncoding(mysqlCharsetName, - this); - } - } catch (java.sql.SQLException e) { - throw e; - } finally { - if (results != null) { - try { - results.close(); - } catch (java.sql.SQLException sqlE) { - ; - } - } - - if (stmt != null) { - try { - stmt.close(); - } catch (java.sql.SQLException sqlE) { - ; - } - } - } - } else { - // Safety, we already do this as an initializer, but this makes - // the intent more clear - this.indexToCharsetMapping = CharsetMapping.INDEX_TO_CHARSET; - } - } - - private boolean canHandleAsServerPreparedStatement(String sql) - throws SQLException { - if (sql == null || sql.length() == 0) { - return true; - } - - if (getCachePreparedStatements()) { - synchronized (this.serverSideStatementCheckCache) { - Boolean flag = (Boolean)this.serverSideStatementCheckCache.get(sql); - - if (flag != null) { - return flag.booleanValue(); - } - - boolean canHandle = canHandleAsServerPreparedStatementNoCache(sql); - - if (sql.length() < getPreparedStatementCacheSqlLimit()) { - this.serverSideStatementCheckCache.put(sql, - canHandle ? Boolean.TRUE : Boolean.FALSE); - } - - return canHandle; - } - } - - return canHandleAsServerPreparedStatementNoCache(sql); - } - - private boolean canHandleAsServerPreparedStatementNoCache(String sql) - throws SQLException { - - // Can't use server-side prepare for CALL - if (StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql, "CALL")) { - return false; - } - - boolean canHandleAsStatement = true; - - if (!versionMeetsMinimum(5, 0, 7) && - (StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql, "SELECT") - || StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql, - "DELETE") - || StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql, - "INSERT") - || StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql, - "UPDATE") - || StringUtils.startsWithIgnoreCaseAndNonAlphaNumeric(sql, - "REPLACE"))) { - - // check for limit ?[,?] - - /* - * The grammar for this (from the server) is: ULONG_NUM | ULONG_NUM - * ',' ULONG_NUM | ULONG_NUM OFFSET_SYM ULONG_NUM - */ - - int currentPos = 0; - int statementLength = sql.length(); - int lastPosToLook = statementLength - 7; // "LIMIT ".length() - boolean allowBackslashEscapes = !this.noBackslashEscapes; - char quoteChar = this.useAnsiQuotes ? '"' : '\''; - boolean foundLimitWithPlaceholder = false; - - while (currentPos < lastPosToLook) { - int limitStart = StringUtils.indexOfIgnoreCaseRespectQuotes( - currentPos, sql, "LIMIT ", quoteChar, - allowBackslashEscapes); - - if (limitStart == -1) { - break; - } - - currentPos = limitStart + 7; - - while (currentPos < statementLength) { - char c = sql.charAt(currentPos); - - // - // Have we reached the end - // of what can be in a LIMIT clause? - // - - if (!Character.isDigit(c) && !Character.isWhitespace(c) - && c != ',' && c != '?') { - break; - } - - if (c == '?') { - foundLimitWithPlaceholder = true; - break; - } - - currentPos++; - } - } - - canHandleAsStatement = !foundLimitWithPlaceholder; - } else if (StringUtils.startsWithIgnoreCaseAndWs(sql, "CREATE TABLE")) { - canHandleAsStatement = false; - } else if (StringUtils.startsWithIgnoreCaseAndWs(sql, "DO")) { - canHandleAsStatement = false; - } else if (StringUtils.startsWithIgnoreCaseAndWs(sql, "SET")) { - canHandleAsStatement = false; - } - - - - return canHandleAsStatement; - } - - /** * Changes the user on this connection by performing a re-authentication. If * authentication fails, the connection will remain under the context of the * current user. @@ -1858,4137 +57,382 @@ * if authentication fails, or some other error occurs while * performing the command. */ - public void changeUser(String userName, String newPassword) - throws SQLException { - if ((userName == null) || userName.equals("")) { - userName = ""; - } + public abstract void changeUser(String userName, String newPassword) + throws SQLException; - if (newPassword == null) { - newPassword = ""; - } + public abstract void clearHasTriedMaster(); - this.io.changeUser(userName, newPassword, this.database); - this.user = userName; - this.password = newPassword; - - if (versionMeetsMinimum(4, 1, 0)) { - configureClientCharacterSet(); - } - - setupServerForTruncationChecks(); - } - - private void checkAndCreatePerformanceHistogram() { - if (this.perfMetricsHistCounts == null) { - this.perfMetricsHistCounts = new int[HISTOGRAM_BUCKETS]; - } - - if (this.perfMetricsHistBreakpoints == null) { - this.perfMetricsHistBreakpoints = new long[HISTOGRAM_BUCKETS]; - } - } - - private void checkAndCreateTablesAccessedHistogram() { - if (this.numTablesMetricsHistCounts == null) { - this.numTablesMetricsHistCounts = new int[HISTOGRAM_BUCKETS]; - } - - if (this.numTablesMetricsHistBreakpoints == null) { - this.numTablesMetricsHistBreakpoints = new long[HISTOGRAM_BUCKETS]; - } - } - - private void checkClosed() throws SQLException { - if (this.isClosed) { - StringBuffer messageBuf = new StringBuffer( - "No operations allowed after connection closed."); - - if (this.forcedClosedLocation != null || this.forceClosedReason != null) { - messageBuf - .append("Connection was implicitly closed "); - } - - if (this.forcedClosedLocation != null) { - messageBuf.append("\n\n"); - messageBuf - .append(" at (stack trace):\n"); - messageBuf.append(Util - .stackTraceToString(this.forcedClosedLocation)); - } - - if (this.forceClosedReason != null) { - if (this.forcedClosedLocation != null) { - messageBuf.append("\n\nDue "); - } else { - messageBuf.append("due "); - } - - messageBuf.append("to underlying exception/error:\n"); - messageBuf.append(Util - .stackTraceToString(this.forceClosedReason)); - } - - throw SQLError.createSQLException(messageBuf.toString(), - SQLError.SQL_STATE_CONNECTION_NOT_OPEN); - } - } - /** - * If useUnicode flag is set and explicit client character encoding isn't - * specified then assign encoding from server if any. + * Prepares a statement on the client, using client-side emulation + * (irregardless of the configuration property 'useServerPrepStmts') + * with the same semantics as the java.sql.Connection.prepareStatement() + * method with the same argument types. * - * @throws SQLException - * DOCUMENT ME! + * @see java.sql.Connection#prepareStatement(String) */ - private void checkServerEncoding() throws SQLException { - if (getUseUnicode() && (getEncoding() != null)) { - // spec'd by client, don't map - return; - } + public abstract java.sql.PreparedStatement clientPrepareStatement(String sql) + throws SQLException; - String serverEncoding = (String) this.serverVariables - .get("character_set"); - - if (serverEncoding == null) { - // must be 4.1.1 or newer? - serverEncoding = (String) this.serverVariables - .get("character_set_server"); - } - - String mappedServerEncoding = null; - - if (serverEncoding != null) { - mappedServerEncoding = CharsetMapping - .getJavaEncodingForMysqlEncoding(serverEncoding - .toUpperCase(Locale.ENGLISH), this); - } - - // - // First check if we can do the encoding ourselves - // - if (!getUseUnicode() && (mappedServerEncoding != null)) { - SingleByteCharsetConverter converter = getCharsetConverter(mappedServerEncoding); - - if (converter != null) { // we know how to convert this ourselves - setUseUnicode(true); // force the issue - setEncoding(mappedServerEncoding); - - return; - } - } - - // - // Now, try and find a Java I/O converter that can do - // the encoding for us - // - if (serverEncoding != null) { - if (mappedServerEncoding == null) { - // We don't have a mapping for it, so try - // and canonicalize the name.... - if (Character.isLowerCase(serverEncoding.charAt(0))) { - char[] ach = serverEncoding.toCharArray(); - ach[0] = Character.toUpperCase(serverEncoding.charAt(0)); - setEncoding(new String(ach)); - } - } - - if (mappedServerEncoding == null) { - throw SQLError.createSQLException("Unknown character encoding on server '" - + serverEncoding - + "', use 'characterEncoding=' property " - + " to provide correct mapping", - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); - } - - // - // Attempt to use the encoding, and bail out if it - // can't be used - // - try { - "abc".getBytes(mappedServerEncoding); - setEncoding(mappedServerEncoding); - setUseUnicode(true); - } catch (UnsupportedEncodingException UE) { - throw SQLError.createSQLException( - "The driver can not map the character encoding '" - + getEncoding() - + "' that your server is using " - + "to a character encoding your JVM understands. You " - + "can specify this mapping manually by adding \"useUnicode=true\" " - + "as well as \"characterEncoding=[an_encoding_your_jvm_understands]\" " - + "to your JDBC URL.", "0S100"); - } - } - } - /** - * Set transaction isolation level to the value received from server if any. - * Is called by connectionInit(...) + * Prepares a statement on the client, using client-side emulation + * (irregardless of the configuration property 'useServerPrepStmts') + * with the same semantics as the java.sql.Connection.prepareStatement() + * method with the same argument types. * - * @throws SQLException - * DOCUMENT ME! + * @see java.sql.Connection#prepareStatement(String, int) */ - private void checkTransactionIsolationLevel() throws SQLException { - String txIsolationName = null; + public abstract java.sql.PreparedStatement clientPrepareStatement(String sql, + int autoGenKeyIndex) throws SQLException; - if (versionMeetsMinimum(4, 0, 3)) { - txIsolationName = "tx_isolation"; - } else { - txIsolationName = "transaction_isolation"; - } - - String s = (String) this.serverVariables.get(txIsolationName); - - if (s != null) { - Integer intTI = (Integer) mapTransIsolationNameToValue.get(s); - - if (intTI != null) { - this.isolationLevel = intTI.intValue(); - } - } - } - /** - * Destroys this connection and any underlying resources + * Prepares a statement on the client, using client-side emulation + * (irregardless of the configuration property 'useServerPrepStmts') + * with the same semantics as the java.sql.Connection.prepareStatement() + * method with the same argument types. * - * @param fromWhere - * DOCUMENT ME! - * @param whyCleanedUp - * DOCUMENT ME! + * @see java.sql.Connection#prepareStatement(String, int, int) */ - private void cleanup(Throwable whyCleanedUp) { - try { - if ((this.io != null) && !isClosed()) { - realClose(false, false, false, whyCleanedUp); - } else if (this.io != null) { - this.io.forceClose(); - } - } catch (SQLException sqlEx) { - // ignore, we're going away. - ; - } + public abstract java.sql.PreparedStatement clientPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency) throws SQLException; - this.isClosed = true; - } - /** - * After this call, getWarnings returns null until a new warning is reported - * for this connection. + * Prepares a statement on the client, using client-side emulation + * (irregardless of the configuration property 'useServerPrepStmts') + * with the same semantics as the java.sql.Connection.prepareStatement() + * method with the same argument types. * - * @exception SQLException - * if a database access error occurs + * @see java.sql.Connection#prepareStatement(String, int[]) */ - public void clearWarnings() throws SQLException { - // firstWarning = null; - } + public abstract java.sql.PreparedStatement clientPrepareStatement(String sql, + int[] autoGenKeyIndexes) throws SQLException; /** - * DOCUMENT ME! + * Prepares a statement on the client, using client-side emulation + * (irregardless of the configuration property 'useServerPrepStmts') + * with the same semantics as the java.sql.Connection.prepareStatement() + * method with the same argument types. * - * @param sql - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws SQLException - * DOCUMENT ME! + * @see java.sql.Connection#prepareStatement(String, int, int, int) */ - public PreparedStatement clientPrepareStatement(String sql) - throws SQLException { - return clientPrepareStatement(sql, - java.sql.ResultSet.TYPE_SCROLL_SENSITIVE, - java.sql.ResultSet.CONCUR_READ_ONLY); - } + public abstract java.sql.PreparedStatement clientPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException; /** - * @see Connection#prepareStatement(String, int) - */ - public java.sql.PreparedStatement clientPrepareStatement(String sql, - int autoGenKeyIndex) throws SQLException { - java.sql.PreparedStatement pStmt = clientPrepareStatement(sql); - - ((com.mysql.jdbc.PreparedStatement) pStmt) - .setRetrieveGeneratedKeys(autoGenKeyIndex == java.sql.Statement.RETURN_GENERATED_KEYS); - - return pStmt; - } - - /** - * DOCUMENT ME! + * Prepares a statement on the client, using client-side emulation + * (irregardless of the configuration property 'useServerPrepStmts') + * with the same semantics as the java.sql.Connection.prepareStatement() + * method with the same argument types. * - * @param sql - * DOCUMENT ME! - * @param resultSetType - * DOCUMENT ME! - * @param resultSetConcurrency - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws SQLException - * DOCUMENT ME! + * @see java.sql.Connection#prepareStatement(String, String[]) */ - public PreparedStatement clientPrepareStatement(String sql, - int resultSetType, int resultSetConcurrency) throws SQLException { - return clientPrepareStatement(sql, resultSetType, resultSetConcurrency, true); - } - - protected PreparedStatement clientPrepareStatement(String sql, - int resultSetType, int resultSetConcurrency, - boolean processEscapeCodesIfNeeded) throws SQLException { - checkClosed(); + public abstract java.sql.PreparedStatement clientPrepareStatement(String sql, + String[] autoGenKeyColNames) throws SQLException; - String nativeSql = processEscapeCodesIfNeeded && getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql): sql; - - PreparedStatement pStmt = null; - - if (getCachePreparedStatements()) { - synchronized (this.cachedPreparedStatementParams) { - PreparedStatement.ParseInfo pStmtInfo = (PreparedStatement.ParseInfo) this.cachedPreparedStatementParams - .get(nativeSql); - - if (pStmtInfo == null) { - pStmt = new com.mysql.jdbc.PreparedStatement(this, nativeSql, - this.database); - - PreparedStatement.ParseInfo parseInfo = pStmt.getParseInfo(); - - if (parseInfo.statementLength < getPreparedStatementCacheSqlLimit()) { - if (this.cachedPreparedStatementParams.size() >= getPreparedStatementCacheSize()) { - Iterator oldestIter = this.cachedPreparedStatementParams - .keySet().iterator(); - long lruTime = Long.MAX_VALUE; - String oldestSql = null; - - while (oldestIter.hasNext()) { - String sqlKey = (String) oldestIter.next(); - PreparedStatement.ParseInfo lruInfo = (PreparedStatement.ParseInfo) this.cachedPreparedStatementParams - .get(sqlKey); - - if (lruInfo.lastUsed < lruTime) { - lruTime = lruInfo.lastUsed; - oldestSql = sqlKey; - } - } - - if (oldestSql != null) { - this.cachedPreparedStatementParams - .remove(oldestSql); - } - } - - this.cachedPreparedStatementParams.put(nativeSql, pStmt - .getParseInfo()); - } - } else { - pStmtInfo.lastUsed = System.currentTimeMillis(); - pStmt = new com.mysql.jdbc.PreparedStatement(this, nativeSql, - this.database, pStmtInfo); - } - } - } else { - pStmt = new com.mysql.jdbc.PreparedStatement(this, nativeSql, - this.database); - } - - pStmt.setResultSetType(resultSetType); - pStmt.setResultSetConcurrency(resultSetConcurrency); - - return pStmt; - } - - - public void close() throws SQLException { - realClose(true, true, false, null); - } - /** - * Closes all currently open statements. - * - * @throws SQLException - * DOCUMENT ME! + * Returns the number of statements active on this connection, which + * haven't been .close()d. */ - private void closeAllOpenStatements() throws SQLException { - SQLException postponedException = null; + public abstract int getActiveStatementCount(); - 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()); - } - - int numStmts = currentlyOpenStatements.size(); - - for (int i = 0; i < numStmts; i++) { - Statement stmt = (Statement) 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; - } - } - } - - private void closeStatement(java.sql.Statement stmt) { - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException sqlEx) { - ; // ignore - } - - stmt = null; - } - } - - // --------------------------JDBC 2.0----------------------------- - /** - * The method commit() makes all changes made since the previous - * commit/rollback permanent and releases any database locks currently held - * by the Connection. This method should only be used when auto-commit has - * been disabled. - *

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

+ * Reports how long this connection has been idle. + * This time (reported in milliseconds) is updated once a query has + * completed. * - * @exception SQLException - * if a database access error occurs - * @see setAutoCommit - */ - public void commit() throws SQLException { - synchronized (getMutex()) { - checkClosed(); - - try { - // no-op if _relaxAutoCommit == true - if (this.autoCommit && !getRelaxAutoCommit()) { - throw SQLError.createSQLException("Can't call commit when autocommit=true"); - } else if (this.transactionsSupported) { - if (getUseLocalSessionState() && versionMeetsMinimum(5, 0, 0)) { - if (!this.io.inTransactionOnServer()) { - return; // effectively a no-op - } - } - - execSQL(null, "commit", -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.database, true, - false); - } - } catch (SQLException sqlException) { - if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE - .equals(sqlException.getSQLState())) { - throw SQLError.createSQLException( - "Communications link failure during commit(). Transaction resolution unknown.", - SQLError.SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN); - } - - throw sqlException; - } finally { - this.needsPing = this.getReconnectAtTxEnd(); - } - - return; - } - } - - /** - * Configures client-side properties for character set information. - * - * @throws SQLException - * if unable to configure the specified character set. - */ - private void configureCharsetProperties() throws SQLException { - if (getEncoding() != null) { - // Attempt to use the encoding, and bail out if it - // can't be used - try { - String testString = "abc"; - testString.getBytes(getEncoding()); - } catch (UnsupportedEncodingException UE) { - // Try the MySQL character encoding, then.... - String oldEncoding = getEncoding(); - - setEncoding(CharsetMapping.getJavaEncodingForMysqlEncoding( - oldEncoding, this)); - - if (getEncoding() == null) { - throw SQLError.createSQLException( - "Java does not support the MySQL character encoding " - + " " + "encoding '" + oldEncoding + "'.", - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); - } - - try { - String testString = "abc"; - testString.getBytes(getEncoding()); - } catch (UnsupportedEncodingException encodingEx) { - throw SQLError.createSQLException("Unsupported character " - + "encoding '" + getEncoding() + "'.", - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); - } - } - } - } - - /** - * Sets up client character set for MySQL-4.1 and newer if the user This - * must be done before any further communication with the server! - * - * @return true if this routine actually configured the client character - * set, or false if the driver needs to use 'older' methods to - * detect the character set, as it is connected to a MySQL server - * older than 4.1.0 - * @throws SQLException - * if an exception happens while sending 'SET NAMES' to the - * server, or the server sends character set information that - * the client doesn't know about. - */ - private boolean configureClientCharacterSet() throws SQLException { - String realJavaEncoding = getEncoding(); - boolean characterSetAlreadyConfigured = false; - - try { - if (versionMeetsMinimum(4, 1, 0)) { - characterSetAlreadyConfigured = true; - - setUseUnicode(true); - - configureCharsetProperties(); - realJavaEncoding = getEncoding(); // we need to do this again - // to grab this for - // versions > 4.1.0 - - try { - - // Fault injection for testing server character set indices - - if (props != null && props.getProperty("com.mysql.jdbc.faultInjection.serverCharsetIndex") != null) { - this.io.serverCharsetIndex = Integer.parseInt( - props.getProperty( - "com.mysql.jdbc.faultInjection.serverCharsetIndex")); - } - - String serverEncodingToSet = - CharsetMapping.INDEX_TO_CHARSET[this.io.serverCharsetIndex]; - - if (serverEncodingToSet == null || serverEncodingToSet.length() == 0) { - if (realJavaEncoding != null) { - // user knows best, try it - setEncoding(realJavaEncoding); - } else { - throw SQLError.createSQLException( - "Unknown initial character set index '" - + this.io.serverCharsetIndex - + "' received from server. Initial client character set can be forced via the 'characterEncoding' property.", - SQLError.SQL_STATE_GENERAL_ERROR); - } - } - - // "latin1" on MySQL-4.1.0+ is actually CP1252, not ISO8859_1 - if (versionMeetsMinimum(4, 1, 0) && - "ISO8859_1".equalsIgnoreCase(serverEncodingToSet)) { - serverEncodingToSet = "Cp1252"; - } - - setEncoding(serverEncodingToSet); - - } catch (ArrayIndexOutOfBoundsException outOfBoundsEx) { - if (realJavaEncoding != null) { - // user knows best, try it - setEncoding(realJavaEncoding); - } else { - throw SQLError.createSQLException( - "Unknown initial character set index '" - + this.io.serverCharsetIndex - + "' received from server. Initial client character set can be forced via the 'characterEncoding' property.", - SQLError.SQL_STATE_GENERAL_ERROR); - } - } - - if (getEncoding() == null) { - // punt? - setEncoding("ISO8859_1"); - } - - // - // Has the user has 'forced' the character encoding via - // driver properties? - // - if (getUseUnicode()) { - if (realJavaEncoding != null) { - - // - // Now, inform the server what character set we - // will be using from now-on... - // - if (realJavaEncoding.equalsIgnoreCase("UTF-8") - || realJavaEncoding.equalsIgnoreCase("UTF8")) { - // charset names are case-sensitive - - if (!getUseOldUTF8Behavior()) { - if (!characterSetNamesMatches("utf8")) { - execSQL(null, "SET NAMES utf8", -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, - false, this.database, true, false); - } - } - - setEncoding(realJavaEncoding); - } /* not utf-8 */else { - String mysqlEncodingName = CharsetMapping - .getMysqlEncodingForJavaEncoding( - realJavaEncoding - .toUpperCase(Locale.ENGLISH), - this); - - /* - * if ("koi8_ru".equals(mysqlEncodingName)) { // - * This has a _different_ name in 4.1... - * mysqlEncodingName = "ko18r"; } else if - * ("euc_kr".equals(mysqlEncodingName)) { // - * Different name in 4.1 mysqlEncodingName = - * "euckr"; } - */ - - if (mysqlEncodingName != null) { - - if (!characterSetNamesMatches(mysqlEncodingName)) { - execSQL(null, "SET NAMES " + mysqlEncodingName, - -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, - false, this.database, true, false); - } - } - - // Switch driver's encoding now, since the server - // knows what we're sending... - // - setEncoding(realJavaEncoding); - } - } else if (getEncoding() != null) { - // Tell the server we'll use the server default charset - // to send our - // queries from now on.... - String mysqlEncodingName = CharsetMapping - .getMysqlEncodingForJavaEncoding(getEncoding() - .toUpperCase(Locale.ENGLISH), this); - - if (!characterSetNamesMatches(mysqlEncodingName)) { - execSQL(null, "SET NAMES " + mysqlEncodingName, -1, - null, java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.database, true, false); - } - - realJavaEncoding = getEncoding(); - } - - } - - // - // We know how to deal with any charset coming back from - // the database, so tell the server not to do conversion - // if the user hasn't 'forced' a result-set character set - // - - String onServer = null; - boolean isNullOnServer = false; - - if (this.serverVariables != null) { - onServer = (String)this.serverVariables.get("character_set_results"); - - isNullOnServer = onServer == null || "NULL".equalsIgnoreCase(onServer) || onServer.length() == 0; - } - - if (getCharacterSetResults() == null) { - - // - // Only send if needed, if we're caching server variables - // we -have- to send, because we don't know what it was - // before we cached them. - // - if (!isNullOnServer) { - execSQL(null, "SET character_set_results = NULL", -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.database, true, - false); - if (!this.usingCachedConfig) { - this.serverVariables.put(JDBC_LOCAL_CHARACTER_SET_RESULTS, null); - } - } else { - if (!this.usingCachedConfig) { - this.serverVariables.put(JDBC_LOCAL_CHARACTER_SET_RESULTS, onServer); - } - } - } else { - String charsetResults = getCharacterSetResults(); - String mysqlEncodingName = null; - - if ("UTF-8".equalsIgnoreCase(charsetResults) - || "UTF8".equalsIgnoreCase(charsetResults)) { - mysqlEncodingName = "utf8"; - } else { - mysqlEncodingName = CharsetMapping - .getMysqlEncodingForJavaEncoding(charsetResults - .toUpperCase(Locale.ENGLISH), this); - } - - // - // Only change the value if needed - // - - if (!mysqlEncodingName.equalsIgnoreCase( - (String)this.serverVariables.get("character_set_results"))) { - StringBuffer setBuf = new StringBuffer( - "SET character_set_results = ".length() - + mysqlEncodingName.length()); - setBuf.append("SET character_set_results = ").append( - mysqlEncodingName); - - execSQL(null, setBuf.toString(), -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.database, true, false); - - if (!this.usingCachedConfig) { - this.serverVariables.put(JDBC_LOCAL_CHARACTER_SET_RESULTS, - mysqlEncodingName); - } - } else { - if (!this.usingCachedConfig) { - this.serverVariables.put(JDBC_LOCAL_CHARACTER_SET_RESULTS, onServer); - } - } - } - - if (getConnectionCollation() != null) { - StringBuffer setBuf = new StringBuffer( - "SET collation_connection = ".length() - + getConnectionCollation().length()); - setBuf.append("SET collation_connection = ").append( - getConnectionCollation()); - - execSQL(null, setBuf.toString(), -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.database, true, false); - } - } else { - // Use what the server has specified - realJavaEncoding = getEncoding(); // so we don't get - // swapped out in the finally - // block.... - } - } finally { - // Failsafe, make sure that the driver's notion of character - // encoding matches what the user has specified. - // - setEncoding(realJavaEncoding); - } - - return characterSetAlreadyConfigured; - } - - private boolean characterSetNamesMatches(String mysqlEncodingName) { - // set names is equivalent to character_set_client ..._results and ..._connection, - // but we set _results later, so don't check it here. - - return (mysqlEncodingName != null && - mysqlEncodingName.equalsIgnoreCase((String)this.serverVariables.get("character_set_client")) && - mysqlEncodingName.equalsIgnoreCase((String)this.serverVariables.get("character_set_connection"))); - } - - /** - * Configures the client's timezone if required. - * - * @throws SQLException - * if the timezone the server is configured to use can't be - * mapped to a Java timezone. - */ - private void configureTimezone() throws SQLException { - String configuredTimeZoneOnServer = (String) this.serverVariables - .get("timezone"); - - if (configuredTimeZoneOnServer == null) { - configuredTimeZoneOnServer = (String) this.serverVariables - .get("time_zone"); - - if ("SYSTEM".equalsIgnoreCase(configuredTimeZoneOnServer)) { - configuredTimeZoneOnServer = (String) this.serverVariables - .get("system_time_zone"); - } - } - - if (getUseTimezone() && configuredTimeZoneOnServer != null) { - // user can specify/override as property - String canoncicalTimezone = getServerTimezone(); - - if ((canoncicalTimezone == null) - || (canoncicalTimezone.length() == 0)) { - String serverTimezoneStr = configuredTimeZoneOnServer; - - try { - canoncicalTimezone = TimeUtil - .getCanoncialTimezone(serverTimezoneStr); - - if (canoncicalTimezone == null) { - throw SQLError.createSQLException("Can't map timezone '" - + serverTimezoneStr + "' to " - + " canonical timezone.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } catch (IllegalArgumentException iae) { - throw SQLError.createSQLException(iae.getMessage(), - SQLError.SQL_STATE_GENERAL_ERROR); - } - } - - this.serverTimezoneTZ = TimeZone.getTimeZone(canoncicalTimezone); - - // - // The Calendar class has the behavior of mapping - // unknown timezones to 'GMT' instead of throwing an - // exception, so we must check for this... - // - if (!canoncicalTimezone.equalsIgnoreCase("GMT") - && this.serverTimezoneTZ.getID().equals("GMT")) { - throw SQLError.createSQLException("No timezone mapping entry for '" - + canoncicalTimezone + "'", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - if ("GMT".equalsIgnoreCase(this.serverTimezoneTZ.getID())) { - this.isServerTzUTC = true; - } else { - this.isServerTzUTC = false; - } - } - } - - private void createInitialHistogram(long[] breakpoints, - long lowerBound, long upperBound) { - - double bucketSize = (((double) upperBound - (double) lowerBound) / HISTOGRAM_BUCKETS) * 1.25; - - if (bucketSize < 1) { - bucketSize = 1; - } - - for (int i = 0; i < HISTOGRAM_BUCKETS; i++) { - breakpoints[i] = lowerBound; - lowerBound += bucketSize; - } - } - - /** - * Creates an IO channel to the server - * - * @param isForReconnect - * is this request for a re-connect - * @return a new MysqlIO instance connected to a server - * @throws SQLException - * if a database access error occurs - * @throws CommunicationsException - * DOCUMENT ME! - */ - protected com.mysql.jdbc.MysqlIO createNewIO(boolean isForReconnect) - throws SQLException { - MysqlIO newIo = null; - - Properties mergedProps = new Properties(); - - mergedProps = exposeAsProperties(this.props); - - long queriesIssuedFailedOverCopy = this.queriesIssuedFailedOver; - this.queriesIssuedFailedOver = 0; - - try { - if (!getHighAvailability() && !this.failedOver) { - boolean connectionGood = false; - Exception connectionNotEstablishedBecause = null; - - int hostIndex = 0; - - // - // TODO: Eventually, when there's enough metadata - // on the server to support it, we should come up - // with a smarter way to pick what server to connect - // to...perhaps even making it 'pluggable' - // - if (getRoundRobinLoadBalance()) { - hostIndex = getNextRoundRobinHostIndex(getURL(), - this.hostList); - } - - for (; hostIndex < this.hostListSize; hostIndex++) { - - if (hostIndex == 0) { - this.hasTriedMasterFlag = true; - } - - try { - String newHostPortPair = (String) this.hostList - .get(hostIndex); - - int newPort = 3306; - - String[] hostPortPair = NonRegisteringDriver - .parseHostPortPair(newHostPortPair); - String newHost = hostPortPair[NonRegisteringDriver.HOST_NAME_INDEX]; - - if (newHost == null || newHost.trim().length() == 0) { - newHost = "localhost"; - } - - if (hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX] != null) { - try { - newPort = Integer - .parseInt(hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX]); - } catch (NumberFormatException nfe) { - throw SQLError.createSQLException( - "Illegal connection port value '" - + hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX] - + "'", - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); - } - } - - this.io = new MysqlIO(newHost, newPort, mergedProps, - getSocketFactoryClassName(), this, - getSocketTimeout()); - - this.io.doHandshake(this.user, this.password, - this.database); - this.connectionId = this.io.getThreadId(); - this.isClosed = false; - - // save state from old connection - boolean oldAutoCommit = getAutoCommit(); - int oldIsolationLevel = this.isolationLevel; - boolean oldReadOnly = isReadOnly(); - String oldCatalog = getCatalog(); - - // Server properties might be different - // from previous connection, so initialize - // again... - initializePropsFromServer(); - - if (isForReconnect) { - // Restore state from old connection - setAutoCommit(oldAutoCommit); - - if (this.hasIsolationLevels) { - setTransactionIsolation(oldIsolationLevel); - } - - setCatalog(oldCatalog); - } - - if (hostIndex != 0) { - setFailedOverState(); - queriesIssuedFailedOverCopy = 0; - } else { - this.failedOver = false; - queriesIssuedFailedOverCopy = 0; - - if (this.hostListSize > 1) { - setReadOnlyInternal(false); - } else { - setReadOnlyInternal(oldReadOnly); - } - } - - connectionGood = true; - - break; // low-level connection succeeded - } catch (Exception EEE) { - if (this.io != null) { - this.io.forceClose(); - } - - connectionNotEstablishedBecause = EEE; - - connectionGood = false; - - if (EEE instanceof SQLException) { - SQLException sqlEx = (SQLException)EEE; - - String sqlState = sqlEx.getSQLState(); - - // If this isn't a communications failure, it will probably never succeed, so - // give up right here and now .... - if ((sqlState == null) - || !sqlState - .equals(SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE)) { - throw sqlEx; - } - } - - // Check next host, it might be up... - if (getRoundRobinLoadBalance()) { - hostIndex = getNextRoundRobinHostIndex(getURL(), - this.hostList) - 1 /* incremented by for loop next time around */; - } else if ((this.hostListSize - 1) == hostIndex) { - throw new CommunicationsException(this, - (this.io != null) ? this.io - .getLastPacketSentTimeMs() : 0, - EEE); - } - } - } - - if (!connectionGood) { - // We've really failed! - throw SQLError.createSQLException( - "Could not create connection to database server due to underlying exception: '" - + connectionNotEstablishedBecause - + "'." - + (getParanoid() ? "" - : Util - .stackTraceToString(connectionNotEstablishedBecause)), - SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE); - } - } else { - double timeout = getInitialTimeout(); - boolean connectionGood = false; - - Exception connectionException = null; - - int hostIndex = 0; - - if (getRoundRobinLoadBalance()) { - hostIndex = getNextRoundRobinHostIndex(getURL(), - this.hostList); - } - - for (; (hostIndex < this.hostListSize) && !connectionGood; hostIndex++) { - if (hostIndex == 0) { - this.hasTriedMasterFlag = true; - } - - if (this.preferSlaveDuringFailover && hostIndex == 0) { - hostIndex++; - } - - for (int attemptCount = 0; (attemptCount < getMaxReconnects()) - && !connectionGood; attemptCount++) { - try { - if (this.io != null) { - this.io.forceClose(); - } - - String newHostPortPair = (String) this.hostList - .get(hostIndex); - - int newPort = 3306; - - String[] hostPortPair = NonRegisteringDriver - .parseHostPortPair(newHostPortPair); - String newHost = hostPortPair[NonRegisteringDriver.HOST_NAME_INDEX]; - - if (newHost == null || newHost.trim().length() == 0) { - newHost = "localhost"; - } - - if (hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX] != null) { - try { - newPort = Integer - .parseInt(hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX]); - } catch (NumberFormatException nfe) { - throw SQLError.createSQLException( - "Illegal connection port value '" - + hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX] - + "'", - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); - } - } - - this.io = new MysqlIO(newHost, newPort, - mergedProps, getSocketFactoryClassName(), - this, getSocketTimeout()); - this.io.doHandshake(this.user, this.password, - this.database); - - pingInternal(false); - this.connectionId = this.io.getThreadId(); - this.isClosed = false; - - // save state from old connection - boolean oldAutoCommit = getAutoCommit(); - int oldIsolationLevel = this.isolationLevel; - boolean oldReadOnly = isReadOnly(); - String oldCatalog = getCatalog(); - - // Server properties might be different - // from previous connection, so initialize - // again... - initializePropsFromServer(); - - if (isForReconnect) { - // Restore state from old connection - setAutoCommit(oldAutoCommit); - - if (this.hasIsolationLevels) { - setTransactionIsolation(oldIsolationLevel); - } - - setCatalog(oldCatalog); - } - - connectionGood = true; - - if (hostIndex != 0) { - setFailedOverState(); - queriesIssuedFailedOverCopy = 0; - } else { - this.failedOver = false; - queriesIssuedFailedOverCopy = 0; - - if (this.hostListSize > 1) { - setReadOnlyInternal(false); - } else { - setReadOnlyInternal(oldReadOnly); - } - } - - break; - } catch (Exception EEE) { - connectionException = EEE; - connectionGood = false; - - // Check next host, it might be up... - if (getRoundRobinLoadBalance()) { - hostIndex = getNextRoundRobinHostIndex(getURL(), - this.hostList) - 1 /* incremented by for loop next time around */; - } - } - - if (connectionGood) { - break; - } - - if (attemptCount > 0) { - try { - Thread.sleep((long) timeout * 1000); - } catch (InterruptedException IE) { - ; - } - } - } // end attempts for a single host - } // end iterator for list of hosts - - if (!connectionGood) { - // We've really failed! - throw SQLError.createSQLException( - "Server connection failure during transaction. Due to underlying exception: '" - + connectionException - + "'." - + (getParanoid() ? "" - : Util - .stackTraceToString(connectionException)) - + "\nAttempted reconnect " - + getMaxReconnects() + " times. Giving up.", - SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE); - } - } - - if (getParanoid() && !getHighAvailability() - && (this.hostListSize <= 1)) { - this.password = null; - this.user = null; - } - - if (isForReconnect) { - // - // Retrieve any 'lost' prepared statements if re-connecting - // - Iterator statementIter = this.openStatements.values() - .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 statement, thus removing it from the map, and - // generating - // a ConcurrentModificationException - // - Stack serverPreparedStatements = null; - - while (statementIter.hasNext()) { - Object statementObj = statementIter.next(); - - if (statementObj instanceof ServerPreparedStatement) { - if (serverPreparedStatements == null) { - serverPreparedStatements = new Stack(); - } - - serverPreparedStatements.add(statementObj); - } - } - - if (serverPreparedStatements != null) { - while (!serverPreparedStatements.isEmpty()) { - ((ServerPreparedStatement) serverPreparedStatements - .pop()).rePrepare(); - } - } - } - - return newIo; - } finally { - this.queriesIssuedFailedOver = queriesIssuedFailedOverCopy; - } - } - - private void createPreparedStatementCaches() { - int cacheSize = getPreparedStatementCacheSize(); - - this.cachedPreparedStatementParams = new HashMap(cacheSize); - - this.serverSideStatementCheckCache = new LRUCache(cacheSize); - - this.serverSideStatementCache = new LRUCache(cacheSize) { - protected boolean removeEldestEntry(java.util.Map.Entry eldest) { - if (this.maxElements <= 1) { - return false; - } - - boolean removeIt = super.removeEldestEntry(eldest); - - if (removeIt) { - ServerPreparedStatement ps = - (ServerPreparedStatement)eldest.getValue(); - ps.isCached = false; - ps.setClosed(false); - - try { - ps.close(); - } catch (SQLException sqlEx) { - // punt - } - } - - return removeIt; - } - }; - } - - /** - * SQL statements without parameters are normally executed using Statement - * objects. If the same SQL statement is executed many times, it is more - * efficient to use a PreparedStatement - * - * @return a new Statement object - * @throws SQLException - * passed through from the constructor - */ - public java.sql.Statement createStatement() throws SQLException { - return createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY); - } - - /** - * JDBC 2.0 Same as createStatement() above, but allows the default result - * set type and result set concurrency type to be overridden. - * - * @param resultSetType - * a result set type, see ResultSet.TYPE_XXX - * @param resultSetConcurrency - * a concurrency type, see ResultSet.CONCUR_XXX - * @return a new Statement object - * @exception SQLException - * if a database-access error occurs. - */ - public java.sql.Statement createStatement(int resultSetType, - int resultSetConcurrency) throws SQLException { - checkClosed(); - - Statement stmt = new com.mysql.jdbc.Statement(this, this.database); - stmt.setResultSetType(resultSetType); - stmt.setResultSetConcurrency(resultSetConcurrency); - - return stmt; - } - - /** - * @see Connection#createStatement(int, int, int) - */ - public java.sql.Statement createStatement(int resultSetType, - int resultSetConcurrency, int resultSetHoldability) - throws SQLException { - if (getPedantic()) { - if (resultSetHoldability != java.sql.ResultSet.HOLD_CURSORS_OVER_COMMIT) { - throw SQLError.createSQLException( - "HOLD_CUSRORS_OVER_COMMIT is only supported holdability level", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } - - return createStatement(resultSetType, resultSetConcurrency); - } - - protected void dumpTestcaseQuery(String query) { - System.err.println(query); - } - - protected Connection duplicate() throws SQLException { - return new Connection( this.origHostToConnectTo, - this.origPortToConnectTo, - this.props, - this.origDatabaseToConnectTo, - this.myURL); - } - - /** - * Send a query to the server. Returns one of the ResultSet objects. This is - * synchronized, so Statement's queries will be serialized. - * - * @param callingStatement - * DOCUMENT ME! - * @param sql - * the SQL statement to be executed - * @param maxRows - * DOCUMENT ME! - * @param packet - * DOCUMENT ME! - * @param resultSetType - * DOCUMENT ME! - * @param resultSetConcurrency - * DOCUMENT ME! - * @param streamResults - * DOCUMENT ME! - * @param queryIsSelectOnly - * DOCUMENT ME! - * @param catalog - * DOCUMENT ME! - * @param unpackFields - * DOCUMENT ME! - * @return a ResultSet holding the results - * @exception SQLException - * if a database error occurs - */ - - // ResultSet execSQL(Statement callingStatement, String sql, - // int maxRowsToRetreive, String catalog) throws SQLException { - // return execSQL(callingStatement, sql, maxRowsToRetreive, null, - // java.sql.ResultSet.TYPE_FORWARD_ONLY, - // java.sql.ResultSet.CONCUR_READ_ONLY, catalog); - // } - // ResultSet execSQL(Statement callingStatement, String sql, int maxRows, - // int resultSetType, int resultSetConcurrency, boolean streamResults, - // boolean queryIsSelectOnly, String catalog, boolean unpackFields) throws - // SQLException { - // return execSQL(callingStatement, sql, maxRows, null, resultSetType, - // resultSetConcurrency, streamResults, queryIsSelectOnly, catalog, - // unpackFields); - // } - ResultSet execSQL(Statement callingStatement, String sql, int maxRows, - Buffer packet, int resultSetType, int resultSetConcurrency, - boolean streamResults, String catalog, - boolean unpackFields) throws SQLException { - return execSQL(callingStatement, sql, maxRows, packet, resultSetType, - resultSetConcurrency, streamResults, - catalog, unpackFields, false); - } - - ResultSet execSQL(Statement callingStatement, String sql, int maxRows, - Buffer packet, int resultSetType, int resultSetConcurrency, - boolean streamResults, String catalog, - boolean unpackFields, - boolean isBatch) throws SQLException { - // - // Fall-back if the master is back online if we've - // issued queriesBeforeRetryMaster queries since - // we failed over - // - synchronized (this.mutex) { - long queryStartTime = 0; - - int endOfQueryPacketPosition = 0; - - if (packet != null) { - endOfQueryPacketPosition = packet.getPosition(); - } - - if (getGatherPerformanceMetrics()) { - queryStartTime = System.currentTimeMillis(); - } - - this.lastQueryFinishedTime = 0; // we're busy! - - if (this.failedOver && this.autoCommit && !isBatch) { - if (shouldFallBack() && !this.executingFailoverReconnect) { - try { - this.executingFailoverReconnect = true; - - createNewIO(true); - - String connectedHost = this.io.getHost(); - - if ((connectedHost != null) - && this.hostList.get(0).equals(connectedHost)) { - this.failedOver = false; - this.queriesIssuedFailedOver = 0; - setReadOnlyInternal(false); - } - } finally { - this.executingFailoverReconnect = false; - } - } - } - - if ((getHighAvailability() || this.failedOver) - && (this.autoCommit || getAutoReconnectForPools()) - && this.needsPing && !isBatch) { - try { - pingInternal(false); - - this.needsPing = false; - } catch (Exception Ex) { - createNewIO(true); - } - } - - try { - if (packet == null) { - String encoding = null; - - if (getUseUnicode()) { - encoding = getEncoding(); - } - - return this.io.sqlQueryDirect(callingStatement, sql, - encoding, null, maxRows, this, resultSetType, - resultSetConcurrency, streamResults, catalog, - unpackFields); - } - - return this.io.sqlQueryDirect(callingStatement, null, null, - packet, maxRows, this, resultSetType, - resultSetConcurrency, streamResults, catalog, - unpackFields); - } catch (java.sql.SQLException sqlE) { - // don't clobber SQL exceptions - - if (getDumpQueriesOnException()) { - String extractedSql = extractSqlFromPacket(sql, packet, - endOfQueryPacketPosition); - StringBuffer messageBuf = new StringBuffer(extractedSql - .length() + 32); - messageBuf - .append("\n\nQuery being executed when exception was thrown:\n\n"); - messageBuf.append(extractedSql); - - sqlE = appendMessageToException(sqlE, messageBuf.toString()); - } - - if ((getHighAvailability() || this.failedOver)) { - this.needsPing = true; - } else { - String sqlState = sqlE.getSQLState(); - - if ((sqlState != null) - && sqlState - .equals(SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE)) { - cleanup(sqlE); - } - } - - throw sqlE; - } catch (Exception ex) { - if ((getHighAvailability() || this.failedOver)) { - this.needsPing = true; - } else if (ex instanceof IOException) { - cleanup(ex); - } - - String exceptionType = ex.getClass().getName(); - String exceptionMessage = ex.getMessage(); - - if (!getParanoid()) { - exceptionMessage += "\n\nNested Stack Trace:\n"; - exceptionMessage += Util.stackTraceToString(ex); - } - - throw new java.sql.SQLException( - "Error during query: Unexpected Exception: " - + exceptionType + " message given: " - + exceptionMessage, - SQLError.SQL_STATE_GENERAL_ERROR); - } finally { - if (getMaintainTimeStats()) { - this.lastQueryFinishedTime = System.currentTimeMillis(); - } - - if (this.failedOver) { - this.queriesIssuedFailedOver++; - } - - if (getGatherPerformanceMetrics()) { - long queryTime = System.currentTimeMillis() - - queryStartTime; - - registerQueryExecutionTime(queryTime); - } - } - } - } - - protected String extractSqlFromPacket(String possibleSqlQuery, - Buffer queryPacket, int endOfQueryPacketPosition) - throws SQLException { - - String extractedSql = null; - - if (possibleSqlQuery != null) { - if (possibleSqlQuery.length() > getMaxQuerySizeToLog()) { - StringBuffer truncatedQueryBuf = new StringBuffer( - possibleSqlQuery.substring(0, getMaxQuerySizeToLog())); - truncatedQueryBuf.append(Messages.getString("MysqlIO.25")); - extractedSql = truncatedQueryBuf.toString(); - } else { - extractedSql = possibleSqlQuery; - } - } - - if (extractedSql == null) { - // This is probably from a client-side prepared - // statement - - int extractPosition = endOfQueryPacketPosition; - - boolean truncated = false; - - if (endOfQueryPacketPosition > getMaxQuerySizeToLog()) { - extractPosition = getMaxQuerySizeToLog(); - truncated = true; - } - - extractedSql = new String(queryPacket.getByteBuffer(), 5, - (extractPosition - 5)); - - if (truncated) { - extractedSql += Messages.getString("MysqlIO.25"); //$NON-NLS-1$ - } - } - - return extractedSql; - - } - - /** - * DOCUMENT ME! - * - * @throws Throwable - * DOCUMENT ME! - */ - protected void finalize() throws Throwable { - cleanup(null); - } - - protected StringBuffer generateConnectionCommentBlock(StringBuffer buf) { - buf.append("/* conn id "); - buf.append(getId()); - buf.append(" */ "); - - return buf; - } - - 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; - } - - /** - * Gets the current auto-commit state - * - * @return Current state of auto-commit - * @exception SQLException - * if an error occurs - * @see setAutoCommit - */ - public boolean getAutoCommit() throws SQLException { - return this.autoCommit; - } - - /** - * Optimization to only use one calendar per-session, or calculate it for - * each call, depending on user configuration - */ - protected Calendar getCalendarInstanceForSessionOrNew() { - if (getDynamicCalendars()) { - return Calendar.getInstance(); - } - - return getSessionLockedCalendar(); - } - - /** - * Return the connections current catalog name, or null if no catalog name - * is set, or we dont support catalogs. - *

- * Note: MySQL's notion of catalogs are individual databases. - *

- * - * @return the current catalog name or null - * @exception SQLException - * if a database access error occurs - */ - public String getCatalog() throws SQLException { - return this.database; - } - - /** - * @return Returns the characterSetMetadata. - */ - protected String getCharacterSetMetadata() { - return characterSetMetadata; - } - - /** - * Returns the locally mapped instance of a charset converter (to avoid - * overhead of static synchronization). - * - * @param javaEncodingName - * the encoding name to retrieve - * @return a character converter, or null if one couldn't be mapped. - */ - SingleByteCharsetConverter getCharsetConverter( - String javaEncodingName) throws SQLException { - if (javaEncodingName == null) { - return null; - } - - if (this.usePlatformCharsetConverters) { - return null; // we'll use Java's built-in routines for this - // they're finally fast enough - } - - SingleByteCharsetConverter converter = null; - - synchronized (this.charsetConverterMap) { - Object asObject = this.charsetConverterMap - .get(javaEncodingName); - - if (asObject == CHARSET_CONVERTER_NOT_AVAILABLE_MARKER) { - return null; - } - - converter = (SingleByteCharsetConverter)asObject; - - if (converter == null) { - try { - converter = SingleByteCharsetConverter.getInstance( - javaEncodingName, this); - - if (converter == null) { - this.charsetConverterMap.put(javaEncodingName, - CHARSET_CONVERTER_NOT_AVAILABLE_MARKER); - } else { - this.charsetConverterMap.put(javaEncodingName, converter); - } - } catch (UnsupportedEncodingException unsupEncEx) { - this.charsetConverterMap.put(javaEncodingName, - CHARSET_CONVERTER_NOT_AVAILABLE_MARKER); - - converter = null; - } - } - } - - return converter; - } - - /** - * Returns the Java character encoding name for the given MySQL server - * charset index - * - * @param charsetIndex - * @return the Java character encoding name for the given MySQL server - * charset index - * @throws SQLException - * if the character set index isn't known by the driver - */ - protected String getCharsetNameForIndex(int charsetIndex) - throws SQLException { - String charsetName = null; - - if (getUseOldUTF8Behavior()) { - return getEncoding(); - } - - if (charsetIndex != MysqlDefs.NO_CHARSET_INFO) { - try { - charsetName = this.indexToCharsetMapping[charsetIndex]; - - if ("sjis".equalsIgnoreCase(charsetName) || - "MS932".equalsIgnoreCase(charsetName) /* for JDK6 */) { - // Use our encoding so that code pages like Cp932 work - if (CharsetMapping.isAliasForSjis(getEncoding())) { - charsetName = getEncoding(); - } - } - } catch (ArrayIndexOutOfBoundsException outOfBoundsEx) { - throw SQLError.createSQLException( - "Unknown character set index for field '" - + charsetIndex + "' received from server.", - SQLError.SQL_STATE_GENERAL_ERROR); - } - - // Punt - if (charsetName == null) { - charsetName = getEncoding(); - } - } else { - charsetName = getEncoding(); - } - - return charsetName; - } - - /** - * DOCUMENT ME! - * - * @return Returns the defaultTimeZone. - */ - protected TimeZone getDefaultTimeZone() { - return this.defaultTimeZone; - } - - /** - * @see Connection#getHoldability() - */ - public int getHoldability() throws SQLException { - return java.sql.ResultSet.CLOSE_CURSORS_AT_COMMIT; - } - - long getId() { - return this.connectionId; - } - - /** - * NOT JDBC-Compliant, but clients can use this method to determine how long - * this connection has been idle. This time (reported in milliseconds) is - * updated once a query has completed. - * * @return number of ms that this connection has been idle, 0 if the driver * is busy retrieving results. */ - public long getIdleFor() { - if (this.lastQueryFinishedTime == 0) { - return 0; - } + public abstract long getIdleFor(); - long now = System.currentTimeMillis(); - long idleTime = now - this.lastQueryFinishedTime; - - return idleTime; - } - /** - * Returns the IO channel to the server - * - * @return the IO channel to the server - * @throws SQLException - * if the connection is closed. - */ - protected MysqlIO getIO() throws SQLException { - if ((this.io == null) || this.isClosed) { - throw SQLError.createSQLException( - "Operation not allowed on closed connection", - SQLError.SQL_STATE_CONNECTION_NOT_OPEN); - } - - return this.io; - } - - /** * Returns the log mechanism that should be used to log information from/for * this Connection. * * @return the Log instance to use for logging messages. * @throws SQLException * if an error occurs */ - public Log getLog() throws SQLException { - return this.log; - } + public abstract Log getLog() throws SQLException; /** - * Returns the maximum packet size the MySQL server will accept - * - * @return DOCUMENT ME! - */ - int getMaxAllowedPacket() { - return this.maxAllowedPacket; - } - - protected int getMaxBytesPerChar(String javaCharsetName) - throws SQLException { - // TODO: Check if we can actually run this query at this point in time - String charset = CharsetMapping.getMysqlEncodingForJavaEncoding( - javaCharsetName, this); - - if (versionMeetsMinimum(4, 1, 0)) { - Map mapToCheck = null; - - if (!getUseDynamicCharsetInfo()) { - mapToCheck = CharsetMapping.STATIC_CHARSET_TO_NUM_BYTES_MAP; - } else { - mapToCheck = this.charsetToNumBytesMap; - - synchronized (this.charsetToNumBytesMap) { - if (this.charsetToNumBytesMap.isEmpty()) { - - java.sql.Statement stmt = null; - java.sql.ResultSet rs = null; - - try { - stmt = getMetadataSafeStatement(); - - rs = stmt.executeQuery("SHOW CHARACTER SET"); - - while (rs.next()) { - this.charsetToNumBytesMap.put(rs.getString("Charset"), - new Integer(rs.getInt("Maxlen"))); - } - - rs.close(); - rs = null; - - stmt.close(); - - stmt = null; - } finally { - if (rs != null) { - rs.close(); - rs = null; - } - - if (stmt != null) { - stmt.close(); - stmt = null; - } - } - } - } - } - - Integer mbPerChar = (Integer) mapToCheck.get(charset); - - if (mbPerChar != null) { - return mbPerChar.intValue(); - } - - return 1; // we don't know - } - - return 1; // we don't know - } - - /** - * A connection's database is able to provide information describing its - * tables, its supported SQL grammar, its stored procedures, the - * capabilities of this connection, etc. This information is made available - * through a DatabaseMetaData object. - * - * @return a DatabaseMetaData object for this connection - * @exception SQLException - * if a database access error occurs - */ - public java.sql.DatabaseMetaData getMetaData() throws SQLException { - checkClosed(); - - if (getUseInformationSchema() && - this.versionMeetsMinimum(5, 0, 7)) { - return new DatabaseMetaDataUsingInfoSchema(this, this.database); - } - - return new DatabaseMetaData(this, this.database); - } - - protected java.sql.Statement getMetadataSafeStatement() throws SQLException { - java.sql.Statement stmt = createStatement(); - - if (stmt.getMaxRows() != 0) { - stmt.setMaxRows(0); - } - - stmt.setEscapeProcessing(false); - - return stmt; - } - - /** - * Returns the Mutex all queries are locked against - * - * @return DOCUMENT ME! - * @throws SQLException - * DOCUMENT ME! - */ - Object getMutex() throws SQLException { - if (this.io == null) { - throw SQLError.createSQLException( - "Connection.close() has already been called. Invalid operation in this state.", - SQLError.SQL_STATE_CONNECTION_NOT_OPEN); - } - - reportMetricsIfNeeded(); - - return this.mutex; - } - - /** - * Returns the packet buffer size the MySQL server reported upon connection - * - * @return DOCUMENT ME! - */ - int getNetBufferLength() { - return this.netBufferLength; - } - - /** * Returns the server's character set * * @return the server's character set. */ - protected String getServerCharacterEncoding() { - if (this.io.versionMeetsMinimum(4, 1, 0)) { - return (String) this.serverVariables.get("character_set_server"); - } else { - return (String) this.serverVariables.get("character_set"); - } - } + public abstract String getServerCharacterEncoding(); - int getServerMajorVersion() { - return this.io.getServerMajorVersion(); - } - - int getServerMinorVersion() { - return this.io.getServerMinorVersion(); - } - - int getServerSubMinorVersion() { - return this.io.getServerSubMinorVersion(); - } - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! + * Returns the TimeZone that represents the configured + * timezone for the server. */ - public TimeZone getServerTimezoneTZ() { - return this.serverTimezoneTZ; - } + public abstract TimeZone getServerTimezoneTZ(); - String getServerVariable(String variableName) { - if (this.serverVariables != null) { - return (String) this.serverVariables.get(variableName); - } - - return null; - } - - String getServerVersion() { - return this.io.getServerVersion(); - } - - protected Calendar getSessionLockedCalendar() { - - return this.sessionCalendar; - } - - /** - * Get this Connection's current transaction isolation mode. + * Returns the comment that will be prepended to all statements + * sent to the server. * - * @return the current TRANSACTION_ mode value - * @exception SQLException - * if a database access error occurs + * @return the comment that will be prepended to all statements + * sent to the server. */ - public int getTransactionIsolation() throws SQLException { + public abstract String getStatementComment(); - if (this.hasIsolationLevels && !getUseLocalSessionState()) { - java.sql.Statement stmt = null; - java.sql.ResultSet rs = null; - - try { - stmt = getMetadataSafeStatement(); - - String query = null; - - int offset = 0; - - if (versionMeetsMinimum(4, 0, 3)) { - query = "SELECT @@session.tx_isolation"; - offset = 1; - } else { - query = "SHOW VARIABLES LIKE 'transaction_isolation'"; - offset = 2; - } - - rs = stmt.executeQuery(query); - - if (rs.next()) { - String s = rs.getString(offset); - - if (s != null) { - Integer intTI = (Integer) mapTransIsolationNameToValue - .get(s); - - if (intTI != null) { - return intTI.intValue(); - } - } - - throw SQLError.createSQLException( - "Could not map transaction isolation '" + s - + " to a valid JDBC level.", - SQLError.SQL_STATE_GENERAL_ERROR); - } - - throw SQLError.createSQLException( - "Could not retrieve transaction isolation level from server", - SQLError.SQL_STATE_GENERAL_ERROR); - - } finally { - if (rs != null) { - try { - rs.close(); - } catch (Exception ex) { - // ignore - ; - } - - rs = null; - } - - if (stmt != null) { - try { - stmt.close(); - } catch (Exception ex) { - // ignore - ; - } - - stmt = null; - } - } - } - - return this.isolationLevel; - } - /** - * JDBC 2.0 Get the type-map object associated with this connection. By - * default, the map returned is empty. - * - * @return the type map - * @throws SQLException - * if a database error occurs + * Has this connection tried to execute a query on the "master" + * server (first host in a multiple host list). */ - public synchronized java.util.Map getTypeMap() throws SQLException { - if (this.typeMap == null) { - this.typeMap = new HashMap(); - } + public abstract boolean hasTriedMaster(); - return this.typeMap; - } - - String getURL() { - return this.myURL; - } - - String getUser() { - return this.user; - } - - protected Calendar getUtcCalendar() { - return this.utcCalendar; - } - /** - * The first warning reported by calls on this Connection is returned. - * Note: Sebsequent warnings will be changed to this - * java.sql.SQLWarning - * - * @return the first java.sql.SQLWarning or null - * @exception SQLException - * if a database access error occurs + * Is this connection currently a participant in an XA transaction? */ - public SQLWarning getWarnings() throws SQLException { - return null; - } - - public boolean hasSameProperties(Connection c) { - return this.props.equals(c.props); - } - - protected void incrementNumberOfPreparedExecutes() { - if (getGatherPerformanceMetrics()) { - this.numberOfPreparedExecutes++; - - // We need to increment this, because - // server-side prepared statements bypass - // any execution by the connection itself... - this.numberOfQueriesIssued++; - } - } + public abstract boolean isInGlobalTx(); - protected void incrementNumberOfPrepares() { - if (getGatherPerformanceMetrics()) { - this.numberOfPrepares++; - } - } - - protected void incrementNumberOfResultSetsCreated() { - if (getGatherPerformanceMetrics()) { - this.numberOfResultSetsCreated++; - } - } - /** - * Initializes driver properties that come from URL or properties passed to - * the driver manager. - * - * @param info - * DOCUMENT ME! - * @throws SQLException - * DOCUMENT ME! + * Set the state of being in a global (XA) transaction. + * @param flag */ - private void initializeDriverProperties(Properties info) - throws SQLException { - initializeProperties(info); - - this.usePlatformCharsetConverters = getUseJvmCharsetConverters(); + public void setInGlobalTx(boolean flag); - this.log = LogFactory.getLogger(getLogger(), LOGGER_INSTANCE_NAME); - - if (getProfileSql() || getUseUsageAdvisor()) { - this.eventSink = ProfileEventSink.getInstance(this); - } - - if (getCachePreparedStatements()) { - createPreparedStatementCaches(); - } - - if (getNoDatetimeStringSync() && getUseTimezone()) { - throw SQLError.createSQLException( - "Can't enable noDatetimeSync and useTimezone configuration " - + "properties at the same time", - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); - } - - if (getCacheCallableStatements()) { - this.parsedCallableStatementCache = new LRUCache( - getCallableStatementCacheSize()); - } - - if (getAllowMultiQueries()) { - setCacheResultSetMetadata(false); // we don't handle this yet - } - - if (getCacheResultSetMetadata()) { - this.resultSetMetadataCache = new LRUCache( - getMetadataCacheSize()); - } - } - /** - * Sets varying properties that depend on server information. Called once we - * have connected to the server. - * - * @param info - * DOCUMENT ME! - * @throws SQLException - * DOCUMENT ME! - */ - private void initializePropsFromServer() throws SQLException { - setSessionVariables(); - - // - // the "boolean" type didn't come along until MySQL-4.1 - // - - if (!versionMeetsMinimum(4, 1, 0)) { - setTransformedBitIsBoolean(false); - } - - this.parserKnowsUnicode = versionMeetsMinimum(4, 1, 0); - - // - // Users can turn off detection of server-side prepared statements - // - if (getUseServerPreparedStmts() && versionMeetsMinimum(4, 1, 0)) { - this.useServerPreparedStmts = true; - - if (versionMeetsMinimum(5, 0, 0) && !versionMeetsMinimum(5, 0, 3)) { - this.useServerPreparedStmts = false; // 4.1.2+ style prepared - // statements - // don't work on these versions - } - } - - this.serverVariables.clear(); - - // - // If version is greater than 3.21.22 get the server - // variables. - if (versionMeetsMinimum(3, 21, 22)) { - loadServerVariables(); - - buildCollationMapping(); - - LicenseConfiguration.checkLicenseType(this.serverVariables); - - String lowerCaseTables = (String) this.serverVariables - .get("lower_case_table_names"); - - this.lowerCaseTableNames = "on".equalsIgnoreCase(lowerCaseTables) - || "1".equalsIgnoreCase(lowerCaseTables) - || "2".equalsIgnoreCase(lowerCaseTables); - - configureTimezone(); - - if (this.serverVariables.containsKey("max_allowed_packet")) { - this.maxAllowedPacket = getServerVariableAsInt("max_allowed_packet", 1024 * 1024); - - int preferredBlobSendChunkSize = getBlobSendChunkSize(); - - int allowedBlobSendChunkSize = Math.min(preferredBlobSendChunkSize, - this.maxAllowedPacket) - - ServerPreparedStatement.BLOB_STREAM_READ_BUF_SIZE - - 11 /* LONG_DATA and MySQLIO packet header size */; - - setBlobSendChunkSize(String.valueOf(allowedBlobSendChunkSize)); - } - - if (this.serverVariables.containsKey("net_buffer_length")) { - this.netBufferLength = getServerVariableAsInt("net_buffer_length", 16 * 1024); - } - - checkTransactionIsolationLevel(); - - if (!versionMeetsMinimum(4, 1, 0)) { - checkServerEncoding(); - } - - this.io.checkForCharsetMismatch(); - - if (this.serverVariables.containsKey("sql_mode")) { - int sqlMode = 0; - - String sqlModeAsString = (String) 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 ((sqlMode & 4) > 0) { - this.useAnsiQuotes = true; - } else { - this.useAnsiQuotes = false; - } - } - } - - this.errorMessageEncoding = - CharsetMapping.getCharacterEncodingForErrorMessages(this); - - - boolean overrideDefaultAutocommit = isAutoCommitNonDefaultOnServer(); - - configureClientCharacterSet(); - - if (versionMeetsMinimum(3, 23, 15)) { - this.transactionsSupported = true; - - if (!overrideDefaultAutocommit) { - setAutoCommit(true); // to override anything - // the server is set to...reqd - // by JDBC spec. - } - } else { - this.transactionsSupported = false; - } - - - if (versionMeetsMinimum(3, 23, 36)) { - this.hasIsolationLevels = true; - } else { - this.hasIsolationLevels = false; - } - - this.hasQuotedIdentifiers = versionMeetsMinimum(3, 23, 6); - - this.io.resetMaxBuf(); - - // - // If we're using MySQL 4.1.0 or newer, we need to figure - // out what character set metadata will be returned in, - // and then map that to a Java encoding name. - // - // We've already set it, and it might be different than what - // was originally on the server, which is why we use the - // "special" key to retrieve it - if (this.io.versionMeetsMinimum(4, 1, 0)) { - String characterSetResultsOnServerMysql = (String) this.serverVariables - .get(JDBC_LOCAL_CHARACTER_SET_RESULTS); - - if (characterSetResultsOnServerMysql == null - || StringUtils.startsWithIgnoreCaseAndWs( - characterSetResultsOnServerMysql, "NULL") - || characterSetResultsOnServerMysql.length() == 0) { - String defaultMetadataCharsetMysql = (String) this.serverVariables - .get("character_set_system"); - String defaultMetadataCharset = null; - - if (defaultMetadataCharsetMysql != null) { - defaultMetadataCharset = CharsetMapping - .getJavaEncodingForMysqlEncoding( - defaultMetadataCharsetMysql, this); - } else { - defaultMetadataCharset = "UTF-8"; - } - - this.characterSetMetadata = defaultMetadataCharset; - } else { - this.characterSetResultsOnServer = CharsetMapping - .getJavaEncodingForMysqlEncoding( - characterSetResultsOnServerMysql, this); - this.characterSetMetadata = this.characterSetResultsOnServer; - } - } - - // - // Query cache is broken wrt. multi-statements before MySQL-4.1.10 - // - - if (this.versionMeetsMinimum(4, 1, 0) - && !this.versionMeetsMinimum(4, 1, 10) - && getAllowMultiQueries()) { - if ("ON".equalsIgnoreCase((String) this.serverVariables - .get("query_cache_type")) - && !"0".equalsIgnoreCase((String) this.serverVariables - .get("query_cache_size"))) { - setAllowMultiQueries(false); - } - } - - // - // Server can do this more efficiently for us - // - - setupServerForTruncationChecks(); - } - - private int getServerVariableAsInt(String variableName, int fallbackValue) - throws SQLException { - try { - return Integer.parseInt((String) this.serverVariables - .get(variableName)); - } catch (NumberFormatException nfe) { - getLog().logWarn(Messages.getString("Connection.BadValueInServerVariables", new Object[] {variableName, - this.serverVariables.get(variableName), new Integer(fallbackValue)})); - - return fallbackValue; - } - } - - /** - * 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 - */ - private boolean isAutoCommitNonDefaultOnServer() throws SQLException { - boolean overrideDefaultAutocommit = false; - - String initConnectValue = (String) this.serverVariables - .get("init_connect"); - - if (versionMeetsMinimum(4, 1, 2) && initConnectValue != null - && initConnectValue.length() > 0) { - if (!getElideSetAutoCommits()) { - // 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; - } - } - - } finally { - if (rs != null) { - try { - rs.close(); - } catch (SQLException sqlEx) { - // do nothing - } - } - - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException sqlEx) { - // do nothing - } - } - } - } else { - if (this.getIO().isSetNeededForAutoCommitMode(true)) { - // we're not in standard autocommit=true mode - this.autoCommit = false; - overrideDefaultAutocommit = true; - } - } - } - - return overrideDefaultAutocommit; - } - - private void setupServerForTruncationChecks() throws SQLException { - if (getJdbcCompliantTruncation()) { - if (versionMeetsMinimum(5, 0, 2)) { - - String currentSqlMode = - (String)this.serverVariables.get("sql_mode"); - - boolean strictTransTablesIsSet = StringUtils.indexOfIgnoreCase(currentSqlMode, "STRICT_TRANS_TABLES") != -1; - - if (currentSqlMode == null || - currentSqlMode.length() == 0 || !strictTransTablesIsSet) { - StringBuffer commandBuf = new StringBuffer("SET sql_mode='"); - - if (currentSqlMode != null && currentSqlMode.length() > 0) { - commandBuf.append(currentSqlMode); - commandBuf.append(","); - } - - commandBuf.append("STRICT_TRANS_TABLES'"); - - execSQL(null, commandBuf.toString(), -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.database, true, false); - - setJdbcCompliantTruncation(false); // server's handling this for us now - } else if (strictTransTablesIsSet) { - // We didn't set it, but someone did, so we piggy back on it - setJdbcCompliantTruncation(false); // server's handling this for us now - } - - } - } - } - - protected boolean isClientTzUTC() { - return this.isClientTzUTC; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean isClosed() { - return this.isClosed; - } - - protected boolean isCursorFetchEnabled() throws SQLException { - return (versionMeetsMinimum(5, 0, 2) && getUseCursorFetch()); - } - - public boolean isInGlobalTx() { - return this.isInGlobalTx; - } - - /** * Is this connection connected to the first host in the list if * there is a list of servers in the URL? * * @return true if this connection is connected to the first in * the list. */ - public synchronized boolean isMasterConnection() { - return !this.failedOver; - } + public abstract boolean isMasterConnection(); /** * Is the server in a sql_mode that doesn't allow us to use \\ to escape * things? * * @return Returns the noBackslashEscapes. */ - public boolean isNoBackslashEscapesSet() { - return this.noBackslashEscapes; - } + public abstract boolean isNoBackslashEscapesSet(); - boolean isReadInfoMsgEnabled() { - return this.readInfoMsg; - } - /** - * Tests to see if the connection is in Read Only Mode. Note that we cannot - * really put the database in read only mode, but we pretend we can by - * returning the value of the readOnly flag + * Does this connection have the same resource name as the given + * connection (for XA)? * - * @return true if the connection is read only - * @exception SQLException - * if a database access error occurs + * @param c + * @return */ - public boolean isReadOnly() throws SQLException { - return this.readOnly; - } - - protected boolean isRunningOnJDK13() { - return this.isRunningOnJDK13; - } - - public synchronized boolean isSameResource(Connection otherConnection) { - if (otherConnection == null) { - return false; - } - - boolean directCompare = true; - - String otherHost = otherConnection.origHostToConnectTo; - String otherOrigDatabase = otherConnection.origDatabaseToConnectTo; - String otherCurrentCatalog = otherConnection.database; - - if (!nullSafeCompare(otherHost, this.origHostToConnectTo)) { - directCompare = false; - } else if (otherHost != null && otherHost.indexOf(",") == -1 && - otherHost.indexOf(":") == -1) { - // need to check port numbers - directCompare = (otherConnection.origPortToConnectTo == - this.origPortToConnectTo); - } - - if (directCompare) { - if (!nullSafeCompare(otherOrigDatabase, this.origDatabaseToConnectTo)) { directCompare = false; - directCompare = false; - } else if (!nullSafeCompare(otherCurrentCatalog, this.database)) { - directCompare = false; - } - } - - if (directCompare) { - return true; - } - - // Has the user explicitly set a resourceId? - String otherResourceId = otherConnection.getResourceId(); - String myResourceId = getResourceId(); - - if (otherResourceId != null || myResourceId != null) { - directCompare = nullSafeCompare(otherResourceId, myResourceId); - - if (directCompare) { - return true; - } - } - - return false; - } - - protected boolean isServerTzUTC() { - return this.isServerTzUTC; - } - - private boolean usingCachedConfig = false; + public abstract boolean isSameResource(Connection c); /** - * Loads the result of 'SHOW VARIABLES' into the serverVariables field so - * that the driver can configure itself. - * - * @throws SQLException - * if the 'SHOW VARIABLES' query fails for any reason. - */ - private void loadServerVariables() throws SQLException { - - if (getCacheServerConfiguration()) { - synchronized (serverConfigByUrl) { - Map cachedVariableMap = (Map) serverConfigByUrl.get(getURL()); - - if (cachedVariableMap != null) { - this.serverVariables = cachedVariableMap; - this.usingCachedConfig = true; - - return; - } - } - } - - com.mysql.jdbc.Statement stmt = null; - com.mysql.jdbc.ResultSet results = null; - - try { - stmt = (com.mysql.jdbc.Statement) createStatement(); - stmt.setEscapeProcessing(false); - - results = (com.mysql.jdbc.ResultSet) stmt - .executeQuery("SHOW SESSION VARIABLES"); - - while (results.next()) { - this.serverVariables.put(results.getString(1), results - .getString(2)); - } - - if (getCacheServerConfiguration()) { - synchronized (serverConfigByUrl) { - serverConfigByUrl.put(getURL(), this.serverVariables); - } - } - } catch (SQLException e) { - throw e; - } finally { - if (results != null) { - try { - results.close(); - } catch (SQLException sqlE) { - ; - } - } - - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException sqlE) { - ; - } - } - } - } - - /** * Is the server configured to use lower-case table names only? * * @return true if lower_case_table_names is 'on' */ - public boolean lowerCaseTableNames() { - return this.lowerCaseTableNames; - } + public abstract boolean lowerCaseTableNames(); /** - * Has the maxRows value changed? - * - * @param stmt - * DOCUMENT ME! + * Does the server this connection is connected to + * support unicode? */ - void maxRowsChanged(Statement stmt) { - synchronized (this.mutex) { - if (this.statementsUsingMaxRows == null) { - this.statementsUsingMaxRows = new HashMap(); - } + public abstract boolean parserKnowsUnicode(); - this.statementsUsingMaxRows.put(stmt, stmt); - - this.maxRowsChanged = true; - } - } - /** - * A driver may convert the JDBC sql grammar into its system's native SQL - * grammar prior to sending it; nativeSQL returns the native form of the - * statement that the driver would have sent. + * Detect if the connection is still good by sending a ping command + * to the server. * - * @param sql - * a SQL statement that may contain one or more '?' parameter - * placeholders - * @return the native form of this statement - * @exception SQLException - * if a database access error occurs - */ - public String nativeSQL(String sql) throws SQLException { - if (sql == null) { - return null; - } - - Object escapedSqlResult = EscapeProcessor.escapeSQL(sql, - serverSupportsConvertFn(), - this); - - if (escapedSqlResult instanceof String) { - return (String) escapedSqlResult; - } - - return ((EscapeProcessorResult) escapedSqlResult).escapedSql; - } - - private CallableStatement parseCallableStatement(String sql) - throws SQLException { - Object escapedSqlResult = EscapeProcessor.escapeSQL(sql, - serverSupportsConvertFn(), this); - - boolean isFunctionCall = false; - String parsedSql = null; - - if (escapedSqlResult instanceof EscapeProcessorResult) { - parsedSql = ((EscapeProcessorResult) escapedSqlResult).escapedSql; - isFunctionCall = ((EscapeProcessorResult) escapedSqlResult).callingStoredFunction; - } else { - parsedSql = (String) escapedSqlResult; - isFunctionCall = false; - } - - return new CallableStatement(this, parsedSql, this.database, - isFunctionCall); - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean parserKnowsUnicode() { - return this.parserKnowsUnicode; - } - - /** - * Detect if the connection is still good - * * @throws SQLException * if the ping fails */ - public void ping() throws SQLException { - pingInternal(true); - } + public abstract void ping() throws SQLException; - private void pingInternal(boolean checkForClosedConnection) - throws SQLException { - if (checkForClosedConnection) { - checkClosed(); - } - - // Need MySQL-3.22.1, but who uses anything older!? - this.io.sendCommand(MysqlDefs.PING, null, null, false, null); - } - /** - * DOCUMENT ME! - * - * @param sql - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws SQLException - * DOCUMENT ME! - */ - public java.sql.CallableStatement prepareCall(String sql) - throws SQLException { - if (this.getUseUltraDevWorkAround()) { - return new UltraDevWorkAround(prepareStatement(sql)); - } - - return prepareCall(sql, java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY); - } - - /** - * JDBC 2.0 Same as prepareCall() above, but allows the default result set - * type and result set concurrency type to be overridden. - * - * @param sql - * the SQL representing the callable statement - * @param resultSetType - * a result set type, see ResultSet.TYPE_XXX - * @param resultSetConcurrency - * a concurrency type, see ResultSet.CONCUR_XXX - * @return a new CallableStatement object containing the pre-compiled SQL - * statement - * @exception SQLException - * if a database-access error occurs. - */ - public java.sql.CallableStatement prepareCall(String sql, - int resultSetType, int resultSetConcurrency) throws SQLException { - if (versionMeetsMinimum(5, 0, 0)) { - CallableStatement cStmt = null; - - if (!getCacheCallableStatements()) { - - cStmt = parseCallableStatement(sql); - } else { - synchronized (this.parsedCallableStatementCache) { - CompoundCacheKey key = new CompoundCacheKey(getCatalog(), sql); - - CallableStatement.CallableStatementParamInfo cachedParamInfo = (CallableStatement.CallableStatementParamInfo) this.parsedCallableStatementCache - .get(key); - - if (cachedParamInfo != null) { - cStmt = new CallableStatement(this, cachedParamInfo); - } else { - cStmt = parseCallableStatement(sql); - - cachedParamInfo = cStmt.paramInfo; - - this.parsedCallableStatementCache.put(key, cachedParamInfo); - } - } - } - - cStmt.setResultSetType(resultSetType); - cStmt.setResultSetConcurrency(resultSetConcurrency); - - return cStmt; - } - - throw SQLError.createSQLException("Callable statements not " + "supported.", - SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); - } - - /** - * @see Connection#prepareCall(String, int, int, int) - */ - public java.sql.CallableStatement prepareCall(String sql, - int resultSetType, int resultSetConcurrency, - int resultSetHoldability) throws SQLException { - if (getPedantic()) { - if (resultSetHoldability != java.sql.ResultSet.HOLD_CURSORS_OVER_COMMIT) { - throw SQLError.createSQLException( - "HOLD_CUSRORS_OVER_COMMIT is only supported holdability level", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } - - CallableStatement cStmt = (com.mysql.jdbc.CallableStatement) prepareCall( - sql, resultSetType, resultSetConcurrency); - - return cStmt; - } - - /** - * A SQL statement with or without IN parameters can be pre-compiled and - * stored in a PreparedStatement object. This object can then be used to - * efficiently execute this statement multiple times. - *

- * Note: This method is optimized for handling parametric SQL - * statements that benefit from precompilation if the driver supports - * precompilation. In this case, the statement is not sent to the database - * until the PreparedStatement is executed. This has no direct effect on - * users; however it does affect which method throws certain - * java.sql.SQLExceptions - *

- *

- * MySQL does not support precompilation of statements, so they are handled - * by the driver. - *

- * - * @param sql - * a SQL statement that may contain one or more '?' IN parameter - * placeholders - * @return a new PreparedStatement object containing the pre-compiled - * statement. - * @exception SQLException - * if a database access error occurs. - */ - public java.sql.PreparedStatement prepareStatement(String sql) - throws SQLException { - return prepareStatement(sql, java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY); - } - - /** - * @see Connection#prepareStatement(String, int) - */ - public java.sql.PreparedStatement prepareStatement(String sql, - int autoGenKeyIndex) throws SQLException { - java.sql.PreparedStatement pStmt = prepareStatement(sql); - - ((com.mysql.jdbc.PreparedStatement) pStmt) - .setRetrieveGeneratedKeys(autoGenKeyIndex == java.sql.Statement.RETURN_GENERATED_KEYS); - - return pStmt; - } - - /** - * JDBC 2.0 Same as prepareStatement() above, but allows the default result - * set type and result set concurrency type to be overridden. - * - * @param sql - * the SQL query containing place holders - * @param resultSetType - * a result set type, see ResultSet.TYPE_XXX - * @param resultSetConcurrency - * a concurrency type, see ResultSet.CONCUR_XXX - * @return a new PreparedStatement object containing the pre-compiled SQL - * statement - * @exception SQLException - * if a database-access error occurs. - */ - public java.sql.PreparedStatement prepareStatement(String sql, - int resultSetType, int resultSetConcurrency) throws SQLException { - checkClosed(); - - // - // FIXME: Create warnings if can't create results of the given - // type or concurrency - // - PreparedStatement pStmt = null; - - boolean canServerPrepare = true; - - String nativeSql = getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql): sql; - - if (getEmulateUnsupportedPstmts()) { - canServerPrepare = canHandleAsServerPreparedStatement(nativeSql); - } - - if (this.useServerPreparedStmts && canServerPrepare) { - if (this.getCachePreparedStatements()) { - synchronized (this.serverSideStatementCache) { - pStmt = (com.mysql.jdbc.ServerPreparedStatement)this.serverSideStatementCache.remove(sql); - - if (pStmt != null) { - ((com.mysql.jdbc.ServerPreparedStatement)pStmt).setClosed(false); - pStmt.clearParameters(); - } - - if (pStmt == null) { - try { - pStmt = new com.mysql.jdbc.ServerPreparedStatement(this, nativeSql, - this.database, resultSetType, resultSetConcurrency); - if (sql.length() < getPreparedStatementCacheSqlLimit()) { - ((com.mysql.jdbc.ServerPreparedStatement)pStmt).isCached = true; - } - } catch (SQLException sqlEx) { - // Punt, if necessary - if (getEmulateUnsupportedPstmts()) { - pStmt = clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false); - - if (sql.length() < getPreparedStatementCacheSqlLimit()) { - this.serverSideStatementCheckCache.put(sql, Boolean.FALSE); - } - } else { - throw sqlEx; - } - } - } - } - } else { - try { - pStmt = new com.mysql.jdbc.ServerPreparedStatement(this, nativeSql, - this.database, resultSetType, resultSetConcurrency); - } catch (SQLException sqlEx) { - // Punt, if necessary - if (getEmulateUnsupportedPstmts()) { - pStmt = clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false); - } else { - throw sqlEx; - } - } - } - } else { - pStmt = clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false); - } - - return pStmt; - } - - /** - * @see Connection#prepareStatement(String, int, int, int) - */ - public java.sql.PreparedStatement prepareStatement(String sql, - int resultSetType, int resultSetConcurrency, - int resultSetHoldability) throws SQLException { - if (getPedantic()) { - if (resultSetHoldability != java.sql.ResultSet.HOLD_CURSORS_OVER_COMMIT) { - throw SQLError.createSQLException( - "HOLD_CUSRORS_OVER_COMMIT is only supported holdability level", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } - - return prepareStatement(sql, resultSetType, resultSetConcurrency); - } - - /** - * @see Connection#prepareStatement(String, int[]) - */ - public java.sql.PreparedStatement prepareStatement(String sql, - int[] autoGenKeyIndexes) throws SQLException { - java.sql.PreparedStatement pStmt = prepareStatement(sql); - - ((com.mysql.jdbc.PreparedStatement) pStmt) - .setRetrieveGeneratedKeys((autoGenKeyIndexes != null) - && (autoGenKeyIndexes.length > 0)); - - return pStmt; - } - - /** - * @see Connection#prepareStatement(String, String[]) - */ - public java.sql.PreparedStatement prepareStatement(String sql, - String[] autoGenKeyColNames) throws SQLException { - java.sql.PreparedStatement pStmt = prepareStatement(sql); - - ((com.mysql.jdbc.PreparedStatement) pStmt) - .setRetrieveGeneratedKeys((autoGenKeyColNames != null) - && (autoGenKeyColNames.length > 0)); - - return pStmt; - } - - /** - * Closes connection and frees resources. - * - * @param calledExplicitly - * is this being called from close() - * @param issueRollback - * should a rollback() be issued? - * @throws SQLException - * if an error occurs - */ - protected void realClose(boolean calledExplicitly, boolean issueRollback, - boolean skipLocalTeardown, Throwable reason) throws SQLException { - SQLException sqlEx = null; - - if (this.isClosed()) { - return; - } - - this.forceClosedReason = reason; - - try { - if (!skipLocalTeardown) { - if (!getAutoCommit() && issueRollback) { - try { - rollback(); - } catch (SQLException ex) { - sqlEx = ex; - } - } - - reportMetrics(); - - if (getUseUsageAdvisor()) { - if (!calledExplicitly) { - String message = "Connection implicitly closed by Driver. You should call Connection.close() from your code to free resources more efficiently and avoid resource leaks."; - - this.eventSink.consumeEvent(new ProfilerEvent( - ProfilerEvent.TYPE_WARN, "", //$NON-NLS-1$ - this.getCatalog(), this.getId(), -1, -1, System - .currentTimeMillis(), 0, Constants.MILLIS_I18N, - null, - this.pointOfOrigin, message)); - } - - long connectionLifeTime = System.currentTimeMillis() - - this.connectionCreationTimeMillis; - - if (connectionLifeTime < 500) { - String message = "Connection lifetime of < .5 seconds. You might be un-necessarily creating short-lived connections and should investigate connection pooling to be more efficient."; - - this.eventSink.consumeEvent(new ProfilerEvent( - ProfilerEvent.TYPE_WARN, "", //$NON-NLS-1$ - this.getCatalog(), this.getId(), -1, -1, System - .currentTimeMillis(), 0, Constants.MILLIS_I18N, - null, - this.pointOfOrigin, message)); - } - } - - try { - closeAllOpenStatements(); - } catch (SQLException ex) { - sqlEx = ex; - } - - if (this.io != null) { - try { - this.io.quit(); - } catch (Exception e) { - ; - } - - } - } else { - this.io.forceClose(); - } - } finally { - this.openStatements = null; - this.io = null; - ProfileEventSink.removeInstance(this); - this.isClosed = true; - } - - if (sqlEx != null) { - throw sqlEx; - } - - } - - protected void recachePreparedStatement(ServerPreparedStatement pstmt) { - synchronized (this.serverSideStatementCache) { - this.serverSideStatementCache.put(pstmt.originalSql, pstmt); - } - } - - /** - * DOCUMENT ME! - * - * @param queryTimeMs - */ - protected void registerQueryExecutionTime(long queryTimeMs) { - if (queryTimeMs > this.longestQueryTimeMs) { - this.longestQueryTimeMs = queryTimeMs; - - repartitionPerformanceHistogram(); - } - - addToPerformanceHistogram(queryTimeMs, 1); - - if (queryTimeMs < this.shortestQueryTimeMs) { - this.shortestQueryTimeMs = (queryTimeMs == 0) ? 1 : queryTimeMs; - } - - this.numberOfQueriesIssued++; - - this.totalQueryTimeMs += queryTimeMs; - } - - /** - * Register a Statement instance as open. - * - * @param stmt - * the Statement instance to remove - */ - void registerStatement(Statement stmt) { - synchronized (this.openStatements) { - this.openStatements.put(stmt, stmt); - } - } - - /** - * @see Connection#releaseSavepoint(Savepoint) - */ - public void releaseSavepoint(Savepoint arg0) throws SQLException { - // this is a no-op - } - - private void repartitionHistogram(int[] histCounts, long[] histBreakpoints, - long currentLowerBound, long currentUpperBound) { - - if (oldHistCounts == null) { - oldHistCounts = new int[histCounts.length]; - oldHistBreakpoints = new long[histBreakpoints.length]; - } - - for (int i = 0; i < histCounts.length; i++) { - oldHistCounts[i] = histCounts[i]; - } - - for (int i = 0; i < oldHistBreakpoints.length; i++) { - oldHistBreakpoints[i] = histBreakpoints[i]; - } - - createInitialHistogram(histBreakpoints, currentLowerBound, - currentUpperBound); - - for (int i = 0; i < HISTOGRAM_BUCKETS; i++) { - addToHistogram(histCounts, histBreakpoints, oldHistBreakpoints[i], - oldHistCounts[i], currentLowerBound, currentUpperBound); - } - } - - private void repartitionPerformanceHistogram() { - checkAndCreatePerformanceHistogram(); - - repartitionHistogram(this.perfMetricsHistCounts, - this.perfMetricsHistBreakpoints, - this.shortestQueryTimeMs == Long.MAX_VALUE ? 0 - : this.shortestQueryTimeMs, this.longestQueryTimeMs); - } - - private void repartitionTablesAccessedHistogram() { - checkAndCreateTablesAccessedHistogram(); - - repartitionHistogram(this.numTablesMetricsHistCounts, - this.numTablesMetricsHistBreakpoints, - this.minimumNumberTablesAccessed == Long.MAX_VALUE ? 0 - : this.minimumNumberTablesAccessed, - this.maximumNumberTablesAccessed); - } - - private void reportMetrics() { - if (getGatherPerformanceMetrics()) { - StringBuffer logMessage = new StringBuffer(256); - - logMessage.append("** Performance Metrics Report **\n"); - logMessage.append("\nLongest reported query: " - + this.longestQueryTimeMs + " ms"); - logMessage.append("\nShortest reported query: " - + this.shortestQueryTimeMs + " ms"); - logMessage - .append("\nAverage query execution time: " - + (this.totalQueryTimeMs / this.numberOfQueriesIssued) - + " ms"); - logMessage.append("\nNumber of statements executed: " - + this.numberOfQueriesIssued); - logMessage.append("\nNumber of result sets created: " - + this.numberOfResultSetsCreated); - logMessage.append("\nNumber of statements prepared: " - + this.numberOfPrepares); - logMessage.append("\nNumber of prepared statement executions: " - + this.numberOfPreparedExecutes); - - if (this.perfMetricsHistBreakpoints != null) { - logMessage.append("\n\n\tTiming Histogram:\n"); - int maxNumPoints = 20; - int highestCount = Integer.MIN_VALUE; - - for (int i = 0; i < (HISTOGRAM_BUCKETS); i++) { - if (this.perfMetricsHistCounts[i] > highestCount) { - highestCount = this.perfMetricsHistCounts[i]; - } - } - - if (highestCount == 0) { - highestCount = 1; // avoid DIV/0 - } - - for (int i = 0; i < (HISTOGRAM_BUCKETS - 1); i++) { - - if (i == 0) { - logMessage.append("\n\tless than " - + this.perfMetricsHistBreakpoints[i + 1] - + " ms: \t" + this.perfMetricsHistCounts[i]); - } else { - logMessage.append("\n\tbetween " - + this.perfMetricsHistBreakpoints[i] + " and " - + this.perfMetricsHistBreakpoints[i + 1] - + " ms: \t" + this.perfMetricsHistCounts[i]); - } - - logMessage.append("\t"); - - int numPointsToGraph = (int) (maxNumPoints * ((double) this.perfMetricsHistCounts[i] / (double) highestCount)); - - for (int j = 0; j < numPointsToGraph; j++) { - logMessage.append("*"); - } - - if (this.longestQueryTimeMs < this.perfMetricsHistCounts[i + 1]) { - break; - } - } - - if (this.perfMetricsHistBreakpoints[HISTOGRAM_BUCKETS - 2] < this.longestQueryTimeMs) { - logMessage.append("\n\tbetween "); - logMessage - .append(this.perfMetricsHistBreakpoints[HISTOGRAM_BUCKETS - 2]); - logMessage.append(" and "); - logMessage - .append(this.perfMetricsHistBreakpoints[HISTOGRAM_BUCKETS - 1]); - logMessage.append(" ms: \t"); - logMessage - .append(this.perfMetricsHistCounts[HISTOGRAM_BUCKETS - 1]); - } - } - - if (this.numTablesMetricsHistBreakpoints != null) { - logMessage.append("\n\n\tTable Join Histogram:\n"); - int maxNumPoints = 20; - int highestCount = Integer.MIN_VALUE; - - for (int i = 0; i < (HISTOGRAM_BUCKETS); i++) { - if (this.numTablesMetricsHistCounts[i] > highestCount) { - highestCount = this.numTablesMetricsHistCounts[i]; - } - } - - if (highestCount == 0) { - highestCount = 1; // avoid DIV/0 - } - - for (int i = 0; i < (HISTOGRAM_BUCKETS - 1); i++) { - - if (i == 0) { - logMessage.append("\n\t" - + this.numTablesMetricsHistBreakpoints[i + 1] - + " tables or less: \t\t" - + this.numTablesMetricsHistCounts[i]); - } else { - logMessage.append("\n\tbetween " - + this.numTablesMetricsHistBreakpoints[i] - + " and " - + this.numTablesMetricsHistBreakpoints[i + 1] - + " tables: \t" - + this.numTablesMetricsHistCounts[i]); - } - - logMessage.append("\t"); - - int numPointsToGraph = (int) (maxNumPoints * ((double) this.numTablesMetricsHistCounts[i] / (double) highestCount)); - - for (int j = 0; j < numPointsToGraph; j++) { - logMessage.append("*"); - } - - if (this.maximumNumberTablesAccessed < this.numTablesMetricsHistBreakpoints[i + 1]) { - break; - } - } - - if (this.numTablesMetricsHistBreakpoints[HISTOGRAM_BUCKETS - 2] < this.maximumNumberTablesAccessed) { - logMessage.append("\n\tbetween "); - logMessage - .append(this.numTablesMetricsHistBreakpoints[HISTOGRAM_BUCKETS - 2]); - logMessage.append(" and "); - logMessage - .append(this.numTablesMetricsHistBreakpoints[HISTOGRAM_BUCKETS - 1]); - logMessage.append(" tables: "); - logMessage - .append(this.numTablesMetricsHistCounts[HISTOGRAM_BUCKETS - 1]); - } - } - - this.log.logInfo(logMessage); - - this.metricsLastReportedMs = System.currentTimeMillis(); - } - } - - /** - * Reports currently collected metrics if this feature is enabled and the - * timeout has passed. - */ - private void reportMetricsIfNeeded() { - if (getGatherPerformanceMetrics()) { - if ((System.currentTimeMillis() - this.metricsLastReportedMs) > getReportMetricsIntervalMillis()) { - reportMetrics(); - } - } - } - - protected void reportNumberOfTablesAccessed(int numTablesAccessed) { - if (numTablesAccessed < this.minimumNumberTablesAccessed) { - this.minimumNumberTablesAccessed = numTablesAccessed; - } - - if (numTablesAccessed > this.maximumNumberTablesAccessed) { - this.maximumNumberTablesAccessed = numTablesAccessed; - - repartitionTablesAccessedHistogram(); - } - - addToTablesAccessedHistogram(numTablesAccessed, 1); - } - - /** * Resets the server-side state of this connection. Doesn't work for MySQL * versions older than 4.0.6 or if isParanoid() is set (it will become a * no-op in these cases). Usually only used from connection pooling code. * * @throws SQLException * if the operation fails while resetting server state. */ - public void resetServerState() throws SQLException { - if (!getParanoid() - && ((this.io != null) && versionMeetsMinimum(4, 0, 6))) { - changeUser(this.user, this.password); - } - } + public abstract void resetServerState() throws SQLException; /** - * The method rollback() drops all changes made since the previous - * commit/rollback and releases any database locks currently held by the - * Connection. + * Prepares a statement on the server (irregardless of the + * configuration property 'useServerPrepStmts') with the same semantics + * as the java.sql.Connection.prepareStatement() method with the + * same argument types. * - * @exception SQLException - * if a database access error occurs - * @see commit + * @see java.sql.Connection#prepareStatement(String) */ - public void rollback() throws SQLException { - synchronized (getMutex()) { - checkClosed(); - - try { - // no-op if _relaxAutoCommit == true - if (this.autoCommit && !getRelaxAutoCommit()) { - throw SQLError.createSQLException( - "Can't call rollback when autocommit=true", - SQLError.SQL_STATE_CONNECTION_NOT_OPEN); - } else if (this.transactionsSupported) { - try { - rollbackNoChecks(); - } catch (SQLException sqlEx) { - // We ignore non-transactional tables if told to do so - if (getIgnoreNonTxTables() - && (sqlEx.getErrorCode() != SQLError.ER_WARNING_NOT_COMPLETE_ROLLBACK)) { - throw sqlEx; - } - } - } - } catch (SQLException sqlException) { - if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE - .equals(sqlException.getSQLState())) { - throw SQLError.createSQLException( - "Communications link failure during rollback(). Transaction resolution unknown.", - SQLError.SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN); - } - - throw sqlException; - } finally { - this.needsPing = this.getReconnectAtTxEnd(); - } - } - } + public abstract java.sql.PreparedStatement serverPrepareStatement(String sql) + throws SQLException; /** - * @see Connection#rollback(Savepoint) + * Prepares a statement on the server (irregardless of the + * configuration property 'useServerPrepStmts') with the same semantics + * as the java.sql.Connection.prepareStatement() method with the + * same argument types. + * + * @see java.sql.Connection#prepareStatement(String, int) */ - public void rollback(Savepoint savepoint) throws SQLException { + public abstract java.sql.PreparedStatement serverPrepareStatement(String sql, + int autoGenKeyIndex) throws SQLException; - if (versionMeetsMinimum(4, 0, 14) || versionMeetsMinimum(4, 1, 1)) { - synchronized (getMutex()) { - checkClosed(); - - try { - StringBuffer rollbackQuery = new StringBuffer( - "ROLLBACK TO SAVEPOINT "); - rollbackQuery.append('`'); - rollbackQuery.append(savepoint.getSavepointName()); - rollbackQuery.append('`'); - - java.sql.Statement stmt = null; - - try { - stmt = createStatement(); - - stmt.executeUpdate(rollbackQuery.toString()); - } catch (SQLException sqlEx) { - int errno = sqlEx.getErrorCode(); - - if (errno == 1181) { - String msg = sqlEx.getMessage(); - - if (msg != null) { - int indexOfError153 = msg.indexOf("153"); - - if (indexOfError153 != -1) { - throw SQLError.createSQLException("Savepoint '" - + savepoint.getSavepointName() - + "' does not exist", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT, - errno); - } - } - } - - // We ignore non-transactional tables if told to do so - if (getIgnoreNonTxTables() - && (sqlEx.getErrorCode() != SQLError.ER_WARNING_NOT_COMPLETE_ROLLBACK)) { - throw sqlEx; - } - - if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE - .equals(sqlEx.getSQLState())) { - throw SQLError.createSQLException( - "Communications link failure during rollback(). Transaction resolution unknown.", - SQLError.SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN); - } - - throw sqlEx; - } finally { - closeStatement(stmt); - } - } finally { - this.needsPing = this.getReconnectAtTxEnd(); - } - } - } else { - throw new NotImplemented(); - } - } - - private void rollbackNoChecks() throws SQLException { - if (getUseLocalSessionState() && versionMeetsMinimum(5, 0, 0)) { - if (!this.io.inTransactionOnServer()) { - return; // effectively a no-op - } - } - - execSQL(null, "rollback", -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.database, true, false); - } - /** - * DOCUMENT ME! + * Prepares a statement on the server (irregardless of the + * configuration property 'useServerPrepStmts') with the same semantics + * as the java.sql.Connection.prepareStatement() method with the + * same argument types. * - * @param sql - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws SQLException - * DOCUMENT ME! + * @see java.sql.Connection#prepareStatement(String, int, int) */ - public ServerPreparedStatement serverPrepare(String sql) - throws SQLException { - - String nativeSql = getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql): sql; - - return new ServerPreparedStatement(this, nativeSql, this.getCatalog(), - java.sql.ResultSet.TYPE_SCROLL_SENSITIVE, - java.sql.ResultSet.CONCUR_READ_ONLY); - } - - protected boolean serverSupportsConvertFn() throws SQLException { - return versionMeetsMinimum(4, 0, 2); - } - + public abstract java.sql.PreparedStatement serverPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency) throws SQLException; /** - * 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 - * 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. - *

+ * Prepares a statement on the server (irregardless of the + * configuration property 'useServerPrepStmts') with the same semantics + * as the java.sql.Connection.prepareStatement() method with the + * same argument types. * - * @param autoCommitFlag - - * true enables auto-commit; false disables it - * @exception SQLException - * if a database access error occurs + * @see java.sql.Connection#prepareStatement(String, int, int, int) */ - public void setAutoCommit(boolean autoCommitFlag) throws SQLException { - synchronized (getMutex()) { - checkClosed(); + public abstract java.sql.PreparedStatement serverPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException; - if (getAutoReconnectForPools()) { - setHighAvailability(true); - } - - try { - if (this.transactionsSupported) { - - boolean needsSetOnServer = true; - - if (this.getUseLocalSessionState() - && this.autoCommit == autoCommitFlag) { - needsSetOnServer = false; - } else if (!this.getHighAvailability()) { - needsSetOnServer = this.getIO() - .isSetNeededForAutoCommitMode(autoCommitFlag); - } - - // this internal value must be set first as failover depends on - // it - // being set to true to fail over (which is done by most - // app servers and connection pools at the end of - // a transaction), and the driver issues an implicit set - // based on this value when it (re)-connects to a server - // so the value holds across connections - this.autoCommit = autoCommitFlag; - - if (needsSetOnServer) { - execSQL(null, autoCommitFlag ? "SET autocommit=1" - : "SET autocommit=0", -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.database, true, false); - } - - } else { - if ((autoCommitFlag == false) && !getRelaxAutoCommit()) { - throw SQLError.createSQLException("MySQL Versions Older than 3.23.15 " - + "do not support transactions", - SQLError.SQL_STATE_CONNECTION_NOT_OPEN); - } - - this.autoCommit = autoCommitFlag; - } - } finally { - if (this.getAutoReconnectForPools()) { - setHighAvailability(false); - } - } - - return; - } - } - /** - * A sub-space of this Connection's database may be selected by setting a - * catalog name. If the driver does not support catalogs, it will silently - * ignore this request - *

- * Note: MySQL's notion of catalogs are individual databases. - *

+ * Prepares a statement on the server (irregardless of the + * configuration property 'useServerPrepStmts') with the same semantics + * as the java.sql.Connection.prepareStatement() method with the + * same argument types. * - * @param catalog - * the database for this connection to use - * @throws SQLException - * if a database access error occurs + * @see java.sql.Connection#prepareStatement(String, int[]) */ - public void setCatalog(String catalog) throws SQLException { - synchronized (getMutex()) { - checkClosed(); + public abstract java.sql.PreparedStatement serverPrepareStatement(String sql, + int[] autoGenKeyIndexes) throws SQLException; - if (catalog == null) { - throw SQLError.createSQLException("Catalog can not be null", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - if (getUseLocalSessionState()) { - if (this.lowerCaseTableNames) { - if (this.database.equalsIgnoreCase(catalog)) { - return; - } - } else { - if (this.database.equals(catalog)) { - return; - } - } - } - - String quotedId = this.dbmd.getIdentifierQuoteString(); - - if ((quotedId == null) || quotedId.equals(" ")) { - quotedId = ""; - } - - StringBuffer query = new StringBuffer("USE "); - query.append(quotedId); - query.append(catalog); - query.append(quotedId); - - execSQL(null, query.toString(), -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.database, true, false); - - this.database = catalog; - } - } - /** - * @param failedOver - * The failedOver to set. - */ - public synchronized void setFailedOver(boolean flag) { - this.failedOver = flag; - } - - /** - * Sets state for a failed-over connection + * Prepares a statement on the server (irregardless of the + * configuration property 'useServerPrepStmts') with the same semantics + * as the java.sql.Connection.prepareStatement() method with the + * same argument types. * - * @throws SQLException - * DOCUMENT ME! + * @see java.sql.Connection#prepareStatement(String, String[]) */ - private void setFailedOverState() throws SQLException { - if (getFailOverReadOnly()) { - setReadOnlyInternal(true); - } + public abstract java.sql.PreparedStatement serverPrepareStatement(String sql, + String[] autoGenKeyColNames) throws SQLException; - this.queriesIssuedFailedOver = 0; - this.failedOver = true; - this.masterFailTimeMillis = System.currentTimeMillis(); - } - /** - * @see Connection#setHoldability(int) + * @param failedOver + * The failedOver to set. */ - public void setHoldability(int arg0) throws SQLException { - // do nothing - } + public abstract void setFailedOver(boolean flag); - public void setInGlobalTx(boolean flag) { - this.isInGlobalTx = flag; - } - - // exposed for testing /** * @param preferSlaveDuringFailover * The preferSlaveDuringFailover to set. */ - public void setPreferSlaveDuringFailover(boolean flag) { - this.preferSlaveDuringFailover = flag; - } + public abstract void setPreferSlaveDuringFailover(boolean flag); - void setReadInfoMsgEnabled(boolean flag) { - this.readInfoMsg = flag; - } - /** - * You can put a connection in read-only mode as a hint to enable database - * optimizations Note: setReadOnly cannot be called while in the - * middle of a transaction + * Sets the comment that will be prepended to all statements + * sent to the server. Do not use slash-star or star-slash tokens + * in the comment as these will be added by the driver itself. * - * @param readOnlyFlag - - * true enables read-only mode; false disables it - * @exception SQLException - * if a database access error occurs + * @param comment the comment that will be prepended to all statements + * sent to the server. */ - public void setReadOnly(boolean readOnlyFlag) throws SQLException { - checkClosed(); - - // Ignore calls to this method if we're failed over and - // we're configured to fail over read-only. - if (this.failedOver && getFailOverReadOnly() && !readOnlyFlag) { - return; - } - - setReadOnlyInternal(readOnlyFlag); - } - - protected void setReadOnlyInternal(boolean readOnlyFlag) throws SQLException { - this.readOnly = readOnlyFlag; - } + public abstract void setStatementComment(String comment); /** - * @see Connection#setSavepoint() + * Used by MiniAdmin to shutdown a MySQL server + * + * @throws SQLException + * if the command can not be issued. */ - public java.sql.Savepoint setSavepoint() throws SQLException { - MysqlSavepoint savepoint = new MysqlSavepoint(); + public abstract void shutdownServer() throws SQLException; - setSavepoint(savepoint); - - return savepoint; - } - - private void setSavepoint(MysqlSavepoint savepoint) throws SQLException { - - if (versionMeetsMinimum(4, 0, 14) || versionMeetsMinimum(4, 1, 1)) { - synchronized (getMutex()) { - checkClosed(); - - StringBuffer savePointQuery = new StringBuffer("SAVEPOINT "); - savePointQuery.append('`'); - savePointQuery.append(savepoint.getSavepointName()); - savePointQuery.append('`'); - - java.sql.Statement stmt = null; - - try { - stmt = createStatement(); - - stmt.executeUpdate(savePointQuery.toString()); - } finally { - closeStatement(stmt); - } - } - } else { - throw new NotImplemented(); - } - } - /** - * @see Connection#setSavepoint(String) + * Does the server this connection is connected to + * support quoted isolation levels? */ - public synchronized java.sql.Savepoint setSavepoint(String name) throws SQLException { - MysqlSavepoint savepoint = new MysqlSavepoint(name); + public abstract boolean supportsIsolationLevel(); - setSavepoint(savepoint); - - return savepoint; - } - /** - * + * Does the server this connection is connected to + * support quoted identifiers? */ - private void setSessionVariables() throws SQLException { - if (this.versionMeetsMinimum(4, 0, 0) && getSessionVariables() != null) { - List variablesToSet = StringUtils.split(getSessionVariables(), ",", "\"'", "\"'", - false); + public abstract boolean supportsQuotedIdentifiers(); - int numVariablesToSet = variablesToSet.size(); - - java.sql.Statement stmt = null; - - try { - stmt = getMetadataSafeStatement(); - - for (int i = 0; i < numVariablesToSet; i++) { - String variableValuePair = (String) variablesToSet.get(i); - - if (variableValuePair.startsWith("@")) { - stmt.executeUpdate("SET " + variableValuePair); - } else { - stmt.executeUpdate("SET SESSION " + variableValuePair); - } - } - } finally { - if (stmt != null) { - stmt.close(); - } - } - } - - } - /** - * Attempts to change the transaction isolation level for this - * Connection object to the one given. - * The constants defined in the interface Connection - * are the possible transaction isolation levels. - *

- * Note: If this method is called during a transaction, the result - * is implementation-defined. - * - * @param level one of the following Connection constants: - * Connection.TRANSACTION_READ_UNCOMMITTED, - * Connection.TRANSACTION_READ_COMMITTED, - * Connection.TRANSACTION_REPEATABLE_READ, or - * Connection.TRANSACTION_SERIALIZABLE. - * (Note that Connection.TRANSACTION_NONE cannot be used - * because it specifies that transactions are not supported.) - * @exception SQLException if a database access error occurs - * or the given parameter is not one of the Connection - * constants - * @see DatabaseMetaData#supportsTransactionIsolationLevel - * @see #getTransactionIsolation - */ - public synchronized void setTransactionIsolation(int level) throws SQLException { - checkClosed(); + * Does the server this connection is connected to + * support quoted identifiers? + */ + public abstract boolean supportsTransactions(); - if (this.hasIsolationLevels) { - String sql = null; - - boolean shouldSendSet = false; - - if (getAlwaysSendSetIsolation()) { - shouldSendSet = true; - } else { - if (level != this.isolationLevel) { - shouldSendSet = true; - } - } - - if (getUseLocalSessionState()) { - shouldSendSet = this.isolationLevel != level; - } - - if (shouldSendSet) { - switch (level) { - case java.sql.Connection.TRANSACTION_NONE: - throw SQLError.createSQLException("Transaction isolation level " - + "NONE not supported by MySQL"); - - case java.sql.Connection.TRANSACTION_READ_COMMITTED: - sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"; - - break; - - case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED: - sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"; - - break; - - case java.sql.Connection.TRANSACTION_REPEATABLE_READ: - sql = "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"; - - break; - - case java.sql.Connection.TRANSACTION_SERIALIZABLE: - sql = "SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE"; - - break; - - default: - throw SQLError.createSQLException("Unsupported transaction " - + "isolation level '" + level + "'", - SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); - } - - execSQL(null, sql, -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY,false, - this.database, true, false); - - this.isolationLevel = level; - } - } else { - throw SQLError.createSQLException("Transaction Isolation Levels are " - + "not supported on MySQL versions older than 3.23.36.", - SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); - } - } - /** - * JDBC 2.0 Install a type-map object as the default type-map for this - * connection - * - * @param map - * the type mapping - * @throws SQLException - * if a database error occurs. + * Does the server this connection is connected to + * meet or exceed the given version? */ - public synchronized void setTypeMap(java.util.Map map) throws SQLException { - this.typeMap = map; - } + public abstract boolean versionMeetsMinimum(int major, int minor, + int subminor) throws SQLException; - /** - * Should we try to connect back to the master? We try when we've been - * failed over >= this.secondsBeforeRetryMaster _or_ we've issued > - * this.queriesIssuedFailedOver - * - * @return DOCUMENT ME! - */ - private boolean shouldFallBack() { - long secondsSinceFailedOver = (System.currentTimeMillis() - this.masterFailTimeMillis) / 1000; + public abstract void reportQueryTime(long millisOrNanos); + + public abstract boolean isAbonormallyLongQuery(long millisOrNanos); - // Done this way so we can set a condition in the debugger - boolean tryFallback = ((secondsSinceFailedOver >= getSecondsBeforeRetryMaster()) || (this.queriesIssuedFailedOver >= getQueriesBeforeRetryMaster())); - - return tryFallback; - } + public abstract void initializeExtension(Extension ex) throws SQLException; /** - * Used by MiniAdmin to shutdown a MySQL server - * - * @throws SQLException - * if the command can not be issued. + * Returns the -session- value of 'auto_increment_increment' from the server if it exists, + * or '1' if not. */ - public void shutdownServer() throws SQLException { - try { - this.io.sendCommand(MysqlDefs.SHUTDOWN, null, null, false, null); - } catch (Exception ex) { - throw SQLError.createSQLException("Unhandled exception '" + ex.toString() - + "'", SQLError.SQL_STATE_GENERAL_ERROR); - } - } - + public abstract int getAutoIncrementIncrement(); + /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! + * Does this connection have the same properties as another? */ - public boolean supportsIsolationLevel() { - return this.hasIsolationLevels; - } + public boolean hasSameProperties(Connection c); /** - * DOCUMENT ME! + * Returns the parsed and passed in properties for this connection. * - * @return DOCUMENT ME! + * @return */ - public boolean supportsQuotedIdentifiers() { - return this.hasQuotedIdentifiers; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean supportsTransactions() { - return this.transactionsSupported; - } - - /** - * Remove the given statement from the list of open statements - * - * @param stmt - * the Statement instance to remove - */ - void unregisterStatement(Statement stmt) { - if (this.openStatements != null) { - synchronized (this.openStatements) { - this.openStatements.remove(stmt); - } - } - } + public Properties getProperties(); - /** - * Called by statements on their .close() to let the connection know when it - * is safe to set the connection back to 'default' row limits. - * - * @param stmt - * the statement releasing it's max-rows requirement - * @throws SQLException - * if a database error occurs issuing the statement that sets - * the limit default. - */ - void unsetMaxRows(Statement stmt) throws SQLException { - synchronized (this.mutex) { - if (this.statementsUsingMaxRows != null) { - Object found = this.statementsUsingMaxRows.remove(stmt); + public String getHost(); - if ((found != null) - && (this.statementsUsingMaxRows.size() == 0)) { - execSQL(null, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, - null, java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.database, true, false); + public void setProxy(MySQLConnection proxy); - this.maxRowsChanged = false; - } - } - } - } - - boolean useAnsiQuotedIdentifiers() { - return this.useAnsiQuotes; - } - /** - * Has maxRows() been set? + * Is the server this connection is connected to "local" (i.e. same host) as the application? * - * @return DOCUMENT ME! + * @return */ - boolean useMaxRows() { - synchronized (this.mutex) { - return this.maxRowsChanged; - } - } + public boolean isServerLocal() throws SQLException; - public boolean versionMeetsMinimum(int major, int minor, int subminor) - throws SQLException { - checkClosed(); + int getSessionMaxRows(); - return this.io.versionMeetsMinimum(major, minor, subminor); - } + void setSessionMaxRows(int max) throws SQLException; - protected String getErrorMessageEncoding() { - return errorMessageEncoding; - } + // JDBC-4.1 + // until we flip catalog/schema, this is a no-op + void setSchema(String schema) throws SQLException; - /* - * For testing failover scenarios - */ - private boolean hasTriedMasterFlag = false; + String getSchema() throws SQLException; - public void clearHasTriedMaster() { - this.hasTriedMasterFlag = false; - } + // JDBC-4.1 + void abort(Executor executor) throws SQLException; - public boolean hasTriedMaster() { - return this.hasTriedMasterFlag; - } + // JDBC-4.1 + void setNetworkTimeout(Executor executor, final int milliseconds) throws SQLException; - /** - * Returns cached metadata (or null if not cached) for the given query, - * which must match _exactly_. - * - * This method is synchronized by the caller on getMutex(), so if - * calling this method from internal code in the driver, make sure it's - * synchronized on the mutex that guards communication with the server. - * - * @param sql - * the query that is the key to the cache - * - * @return metadata cached for the given SQL, or none if it doesn't - * exist. - */ - protected CachedResultSetMetaData getCachedMetaData(String sql) { - if (this.resultSetMetadataCache != null) { - synchronized (this.resultSetMetadataCache) { - return (CachedResultSetMetaData) this.resultSetMetadataCache - .get(sql); - } - } + int getNetworkTimeout() throws SQLException; - return null; // no cache exists - } + // ************************** + // moved from MySQLConnection + // ************************** - /** - * Caches CachedResultSetMetaData that has been placed in the cache using - * the given SQL as a key. - * - * This method is synchronized by the caller on getMutex(), so if - * calling this method from internal code in the driver, make sure it's - * synchronized on the mutex that guards communication with the server. - * - * @param sql the query that the metadata pertains too. - * @param cachedMetaData metadata (if it exists) to populate the cache. - * @param resultSet the result set to retreive metadata from, or apply to. - * - * @throws SQLException - */ - protected void initializeResultsMetadataFromCache(String sql, - CachedResultSetMetaData cachedMetaData, ResultSet resultSet) - throws SQLException { + void abortInternal() throws SQLException; - if (cachedMetaData == null) { - - // read from results - cachedMetaData = new CachedResultSetMetaData(); - cachedMetaData.fields = resultSet.fields; + void checkClosed() throws SQLException; - // assume that users will use named-based - // lookups - resultSet.buildIndexMapping(); - resultSet.initializeWithMetadata(); - - if (resultSet instanceof UpdatableResultSet) { - ((UpdatableResultSet)resultSet).checkUpdatability(); - } - - cachedMetaData.columnNameToIndex = resultSet.columnNameToIndex; - cachedMetaData.fullColumnNameToIndex = resultSet.fullColumnNameToIndex; - - cachedMetaData.metadata = resultSet.getMetaData(); - - this.resultSetMetadataCache.put(sql, cachedMetaData); - } else { - // initialize results from cached data - resultSet.fields = cachedMetaData.fields; - resultSet.columnNameToIndex = cachedMetaData.columnNameToIndex; - resultSet.fullColumnNameToIndex = cachedMetaData.fullColumnNameToIndex; - resultSet.hasBuiltIndexMapping = true; - resultSet.initializeWithMetadata(); - - if (resultSet instanceof UpdatableResultSet) { - ((UpdatableResultSet)resultSet).checkUpdatability(); - } - } - } -} \ No newline at end of file + Object getConnectionMutex(); +} Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionFeatureNotAvailableException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionFeatureNotAvailableException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionFeatureNotAvailableException.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionFeatureNotAvailableException.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; /** @@ -37,14 +36,16 @@ public class ConnectionFeatureNotAvailableException extends CommunicationsException { + static final long serialVersionUID = -5065030488729238287L; + /** * @param conn * @param lastPacketSentTimeMs * @param underlyingException */ - public ConnectionFeatureNotAvailableException(Connection conn, + public ConnectionFeatureNotAvailableException(MySQLConnection conn, long lastPacketSentTimeMs, Exception underlyingException) { - super(conn, lastPacketSentTimeMs, underlyingException); + super(conn, lastPacketSentTimeMs, 0, underlyingException); } /* Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionGroup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionGroupManager.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionLifecycleInterceptor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionProperties.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionProperties.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionProperties.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionProperties.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,4184 +1,1750 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; -import com.mysql.jdbc.log.Jdk14Logger; -import com.mysql.jdbc.log.Log; -import com.mysql.jdbc.log.StandardLogger; - -import java.io.Serializable; -import java.io.UnsupportedEncodingException; - -import java.sql.DriverPropertyInfo; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.util.TreeMap; +public interface ConnectionProperties { -import javax.naming.RefAddr; -import javax.naming.Reference; -import javax.naming.StringRefAddr; - -/** - * Represents configurable properties for Connections and DataSources. Can also - * expose properties as JDBC DriverPropertyInfo if required as well. - * - * @author Mark Matthews - * @version $Id: ConnectionProperties.java,v 1.1.2.2 2005/05/17 14:58:56 - * mmatthews Exp $ - */ -public class ConnectionProperties implements Serializable { - - private static final long serialVersionUID = 4257801713007640580L; - - class BooleanConnectionProperty extends ConnectionProperty implements Serializable { - - private static final long serialVersionUID = 2540132501709159404L; - - /** - * DOCUMENT ME! - * - * @param propertyNameToSet - * @param defaultValueToSet - * @param descriptionToSet - * DOCUMENT ME! - * @param sinceVersionToSet - * DOCUMENT ME! - */ - BooleanConnectionProperty(String propertyNameToSet, - boolean defaultValueToSet, String descriptionToSet, - String sinceVersionToSet, String category, int orderInCategory) { - super(propertyNameToSet, new Boolean(defaultValueToSet), null, 0, - 0, descriptionToSet, sinceVersionToSet, category, - orderInCategory); - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#getAllowableValues() - */ - String[] getAllowableValues() { - return new String[] { "true", "false", "yes", "no" }; - } - - boolean getValueAsBoolean() { - return ((Boolean) this.valueAsObject).booleanValue(); - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#hasValueConstraints() - */ - boolean hasValueConstraints() { - return true; - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#initializeFrom(java.util.Properties) - */ - void initializeFrom(String extractedValue) throws SQLException { - if (extractedValue != null) { - validateStringValues(extractedValue); - - this.valueAsObject = new Boolean(extractedValue - .equalsIgnoreCase("TRUE") - || extractedValue.equalsIgnoreCase("YES")); - } else { - this.valueAsObject = this.defaultValue; - } - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#isRangeBased() - */ - boolean isRangeBased() { - return false; - } - - void setValue(boolean valueFlag) { - this.valueAsObject = new Boolean(valueFlag); - } - } - - abstract class ConnectionProperty implements Serializable { - String[] allowableValues; - - String categoryName; - - Object defaultValue; - - int lowerBound; - - int order; - - String propertyName; - - String sinceVersion; - - int upperBound; - - Object valueAsObject; - - boolean required; - - String description; - - public ConnectionProperty() {} - - ConnectionProperty(String propertyNameToSet, Object defaultValueToSet, - String[] allowableValuesToSet, int lowerBoundToSet, - int upperBoundToSet, String descriptionToSet, - String sinceVersionToSet, String category, int orderInCategory) { - - this.description = descriptionToSet; - this.propertyName = propertyNameToSet; - this.defaultValue = defaultValueToSet; - this.valueAsObject = defaultValueToSet; - this.allowableValues = allowableValuesToSet; - this.lowerBound = lowerBoundToSet; - this.upperBound = upperBoundToSet; - this.required = false; - this.sinceVersion = sinceVersionToSet; - this.categoryName = category; - this.order = orderInCategory; - } - - String[] getAllowableValues() { - return this.allowableValues; - } - - /** - * @return Returns the categoryName. - */ - String getCategoryName() { - return this.categoryName; - } - - Object getDefaultValue() { - return this.defaultValue; - } - - int getLowerBound() { - return this.lowerBound; - } - - /** - * @return Returns the order. - */ - int getOrder() { - return this.order; - } - - String getPropertyName() { - return this.propertyName; - } - - int getUpperBound() { - return this.upperBound; - } - - Object getValueAsObject() { - return this.valueAsObject; - } - - abstract boolean hasValueConstraints(); - - void initializeFrom(Properties extractFrom) throws SQLException { - String extractedValue = extractFrom.getProperty(getPropertyName()); - extractFrom.remove(getPropertyName()); - initializeFrom(extractedValue); - } - - void initializeFrom(Reference ref) throws SQLException { - RefAddr refAddr = ref.get(getPropertyName()); - - if (refAddr != null) { - String refContentAsString = (String) refAddr.getContent(); - - initializeFrom(refContentAsString); - } - } - - abstract void initializeFrom(String extractedValue) throws SQLException; - - abstract boolean isRangeBased(); - - /** - * @param categoryName - * The categoryName to set. - */ - void setCategoryName(String categoryName) { - this.categoryName = categoryName; - } - - /** - * @param order - * The order to set. - */ - void setOrder(int order) { - this.order = order; - } - - void setValueAsObject(Object obj) { - this.valueAsObject = obj; - } - - void storeTo(Reference ref) { - if (getValueAsObject() != null) { - ref.add(new StringRefAddr(getPropertyName(), getValueAsObject() - .toString())); - } - } - - DriverPropertyInfo getAsDriverPropertyInfo() { - DriverPropertyInfo dpi = new DriverPropertyInfo(this.propertyName, null); - dpi.choices = getAllowableValues(); - dpi.value = (this.valueAsObject != null) ? this.valueAsObject.toString() : null; - dpi.required = this.required; - dpi.description = this.description; - - return dpi; - } - - - void validateStringValues(String valueToValidate) throws SQLException { - String[] validateAgainst = getAllowableValues(); - - if (valueToValidate == null) { - return; - } - - if ((validateAgainst == null) || (validateAgainst.length == 0)) { - return; - } - - for (int i = 0; i < validateAgainst.length; i++) { - if ((validateAgainst[i] != null) - && validateAgainst[i].equalsIgnoreCase(valueToValidate)) { - return; - } - } - - StringBuffer errorMessageBuf = new StringBuffer(); - - errorMessageBuf.append("The connection property '"); - errorMessageBuf.append(getPropertyName()); - errorMessageBuf.append("' only accepts values of the form: "); - - if (validateAgainst.length != 0) { - errorMessageBuf.append("'"); - errorMessageBuf.append(validateAgainst[0]); - errorMessageBuf.append("'"); - - for (int i = 1; i < (validateAgainst.length - 1); i++) { - errorMessageBuf.append(", "); - errorMessageBuf.append("'"); - errorMessageBuf.append(validateAgainst[i]); - errorMessageBuf.append("'"); - } - - errorMessageBuf.append(" or '"); - errorMessageBuf - .append(validateAgainst[validateAgainst.length - 1]); - errorMessageBuf.append("'"); - } - - errorMessageBuf.append(". The value '"); - errorMessageBuf.append(valueToValidate); - errorMessageBuf.append("' is not in this set."); - - throw SQLError.createSQLException(errorMessageBuf.toString(), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } - - class IntegerConnectionProperty extends ConnectionProperty implements Serializable { - - private static final long serialVersionUID = -3004305481796850832L; - - public IntegerConnectionProperty(String propertyNameToSet, - Object defaultValueToSet, String[] allowableValuesToSet, - int lowerBoundToSet, int upperBoundToSet, - String descriptionToSet, String sinceVersionToSet, - String category, int orderInCategory) { - super(propertyNameToSet, defaultValueToSet, allowableValuesToSet, - lowerBoundToSet, upperBoundToSet, descriptionToSet, sinceVersionToSet, - category, orderInCategory); - } - - int multiplier = 1; - - IntegerConnectionProperty(String propertyNameToSet, - int defaultValueToSet, int lowerBoundToSet, - int upperBoundToSet, String descriptionToSet, - String sinceVersionToSet, String category, int orderInCategory) { - super(propertyNameToSet, new Integer(defaultValueToSet), null, - lowerBoundToSet, upperBoundToSet, descriptionToSet, - sinceVersionToSet, category, orderInCategory); - } - - /** - * DOCUMENT ME! - * - * @param propertyNameToSet - * @param defaultValueToSet - * @param descriptionToSet - * @param sinceVersionToSet - * DOCUMENT ME! - */ - - IntegerConnectionProperty(String propertyNameToSet, - int defaultValueToSet, String descriptionToSet, - String sinceVersionToSet, String category, int orderInCategory) { - this(propertyNameToSet, defaultValueToSet, 0, 0, descriptionToSet, - sinceVersionToSet, category, orderInCategory); - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#getAllowableValues() - */ - String[] getAllowableValues() { - return null; - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#getLowerBound() - */ - int getLowerBound() { - return this.lowerBound; - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#getUpperBound() - */ - int getUpperBound() { - return this.upperBound; - } - - int getValueAsInt() { - return ((Integer) this.valueAsObject).intValue(); - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#hasValueConstraints() - */ - boolean hasValueConstraints() { - return false; - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#initializeFrom(java.lang.String) - */ - void initializeFrom(String extractedValue) throws SQLException { - if (extractedValue != null) { - try { - // Parse decimals, too - int intValue = Double.valueOf(extractedValue).intValue(); - - /* - * if (isRangeBased()) { if ((intValue < getLowerBound()) || - * (intValue > getUpperBound())) { throw new - * SQLException("The connection property '" + - * getPropertyName() + "' only accepts integer values in the - * range of " + getLowerBound() + " - " + getUpperBound() + ", - * the value '" + extractedValue + "' exceeds this range.", - * SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } } - */ - this.valueAsObject = new Integer(intValue * multiplier); - } catch (NumberFormatException nfe) { - throw SQLError.createSQLException("The connection property '" - + getPropertyName() - + "' only accepts integer values. The value '" - + extractedValue - + "' can not be converted to an integer.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } else { - this.valueAsObject = this.defaultValue; - } - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#isRangeBased() - */ - boolean isRangeBased() { - return getUpperBound() != getLowerBound(); - } - - void setValue(int valueFlag) { - this.valueAsObject = new Integer(valueFlag); - } - } - - public class LongConnectionProperty extends IntegerConnectionProperty { - - private static final long serialVersionUID = 6068572984340480895L; - - LongConnectionProperty(String propertyNameToSet, - long defaultValueToSet, long lowerBoundToSet, - long upperBoundToSet, String descriptionToSet, - String sinceVersionToSet, String category, int orderInCategory) { - super(propertyNameToSet, new Long(defaultValueToSet), null, - (int)lowerBoundToSet, (int)upperBoundToSet, descriptionToSet, - sinceVersionToSet, category, orderInCategory); - } - - - LongConnectionProperty(String propertyNameToSet, - long defaultValueToSet, String descriptionToSet, - String sinceVersionToSet, String category, int orderInCategory) { - this(propertyNameToSet, - defaultValueToSet, 0, - 0, descriptionToSet, - sinceVersionToSet, category, orderInCategory); - } - - void setValue(long value) { - this.valueAsObject = new Long(value); - } - - long getValueAsLong() { - return ((Long) this.valueAsObject).longValue(); - } - - void initializeFrom(String extractedValue) throws SQLException { - if (extractedValue != null) { - try { - // Parse decimals, too - long longValue = Double.valueOf(extractedValue).longValue(); - - this.valueAsObject = new Long(longValue); - } catch (NumberFormatException nfe) { - throw SQLError.createSQLException("The connection property '" - + getPropertyName() - + "' only accepts long integer values. The value '" - + extractedValue - + "' can not be converted to a long integer.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } else { - this.valueAsObject = this.defaultValue; - } - } - } - - class MemorySizeConnectionProperty extends IntegerConnectionProperty implements Serializable { - - private static final long serialVersionUID = 7351065128998572656L; - - MemorySizeConnectionProperty(String propertyNameToSet, - int defaultValueToSet, int lowerBoundToSet, - int upperBoundToSet, String descriptionToSet, - String sinceVersionToSet, String category, int orderInCategory) { - super(propertyNameToSet, defaultValueToSet, lowerBoundToSet, - upperBoundToSet, descriptionToSet, sinceVersionToSet, - category, orderInCategory); - // TODO Auto-generated constructor stub - } - - void initializeFrom(String extractedValue) throws SQLException { - if (extractedValue != null) { - if (extractedValue.endsWith("k") - || extractedValue.endsWith("K") - || extractedValue.endsWith("kb") - || extractedValue.endsWith("Kb") - || extractedValue.endsWith("kB")) { - multiplier = 1024; - int indexOfK = StringUtils.indexOfIgnoreCase( - extractedValue, "k"); - extractedValue = extractedValue.substring(0, indexOfK); - } else if (extractedValue.endsWith("m") - || extractedValue.endsWith("M") - || extractedValue.endsWith("G") - || extractedValue.endsWith("mb") - || extractedValue.endsWith("Mb") - || extractedValue.endsWith("mB")) { - multiplier = 1024 * 1024; - int indexOfM = StringUtils.indexOfIgnoreCase( - extractedValue, "m"); - extractedValue = extractedValue.substring(0, indexOfM); - } else if (extractedValue.endsWith("g") - || extractedValue.endsWith("G") - || extractedValue.endsWith("gb") - || extractedValue.endsWith("Gb") - || extractedValue.endsWith("gB")) { - multiplier = 1024 * 1024 * 1024; - int indexOfG = StringUtils.indexOfIgnoreCase( - extractedValue, "g"); - extractedValue = extractedValue.substring(0, indexOfG); - } - } - - super.initializeFrom(extractedValue); - } - - void setValue(String value) throws SQLException { - initializeFrom(value); - } - } - - class StringConnectionProperty extends ConnectionProperty implements Serializable { - - private static final long serialVersionUID = 5432127962785948272L; - - StringConnectionProperty(String propertyNameToSet, - String defaultValueToSet, String descriptionToSet, - String sinceVersionToSet, String category, int orderInCategory) { - this(propertyNameToSet, defaultValueToSet, null, descriptionToSet, - sinceVersionToSet, category, orderInCategory); - } - - /** - * DOCUMENT ME! - * - * @param propertyNameToSet - * @param defaultValueToSet - * @param allowableValuesToSet - * @param descriptionToSet - * @param sinceVersionToSet - * DOCUMENT ME! - */ - StringConnectionProperty(String propertyNameToSet, - String defaultValueToSet, String[] allowableValuesToSet, - String descriptionToSet, String sinceVersionToSet, - String category, int orderInCategory) { - super(propertyNameToSet, defaultValueToSet, allowableValuesToSet, - 0, 0, descriptionToSet, sinceVersionToSet, category, - orderInCategory); - } - - String getValueAsString() { - return (String) this.valueAsObject; - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#hasValueConstraints() - */ - boolean hasValueConstraints() { - return (this.allowableValues != null) - && (this.allowableValues.length > 0); - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#initializeFrom(java.util.Properties) - */ - void initializeFrom(String extractedValue) throws SQLException { - if (extractedValue != null) { - validateStringValues(extractedValue); - - this.valueAsObject = extractedValue; - } else { - this.valueAsObject = this.defaultValue; - } - } - - /** - * @see com.mysql.jdbc.ConnectionProperties.ConnectionProperty#isRangeBased() - */ - boolean isRangeBased() { - return false; - } - - void setValue(String valueFlag) { - this.valueAsObject = valueFlag; - } - } - - private static final String CONNECTION_AND_AUTH_CATEGORY = "Connection/Authentication"; - - private static final String NETWORK_CATEGORY = "Networking"; - - private static final String DEBUGING_PROFILING_CATEGORY = "Debuging/Profiling"; - - private static final String HA_CATEGORY = "High Availability and Clustering"; - - private static final String MISC_CATEGORY = "Miscellaneous"; - - private static final String PERFORMANCE_CATEGORY = "Performance Extensions"; - - private static final String SECURITY_CATEGORY = "Security"; - - private static final String[] PROPERTY_CATEGORIES = new String[] { - CONNECTION_AND_AUTH_CATEGORY, NETWORK_CATEGORY, - HA_CATEGORY, SECURITY_CATEGORY, - PERFORMANCE_CATEGORY, DEBUGING_PROFILING_CATEGORY, MISC_CATEGORY }; - - private static final ArrayList PROPERTY_LIST = new ArrayList(); - - private static final String STANDARD_LOGGER_NAME = StandardLogger.class.getName(); - - protected static final String ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL = "convertToNull"; - - protected static final String ZERO_DATETIME_BEHAVIOR_EXCEPTION = "exception"; - - protected static final String ZERO_DATETIME_BEHAVIOR_ROUND = "round"; - - static { - try { - java.lang.reflect.Field[] declaredFields = ConnectionProperties.class - .getDeclaredFields(); - - for (int i = 0; i < declaredFields.length; i++) { - if (ConnectionProperties.ConnectionProperty.class - .isAssignableFrom(declaredFields[i].getType())) { - PROPERTY_LIST.add(declaredFields[i]); - } - } - } catch (Exception ex) { - throw new RuntimeException(ex.toString()); - } - } - /** - * Exposes all ConnectionPropertyInfo instances as DriverPropertyInfo - * - * @param info - * the properties to load into these ConnectionPropertyInfo - * instances - * @param slotsToReserve - * the number of DPI slots to reserve for 'standard' DPI - * properties (user, host, password, etc) - * @return a list of all ConnectionPropertyInfo instances, as - * DriverPropertyInfo - * @throws SQLException - * if an error occurs - */ - protected static DriverPropertyInfo[] exposeAsDriverPropertyInfo( - Properties info, int slotsToReserve) throws SQLException { - return (new ConnectionProperties() { - }).exposeAsDriverPropertyInfoInternal(info, slotsToReserve); - } - - private BooleanConnectionProperty allowLoadLocalInfile = new BooleanConnectionProperty( - "allowLoadLocalInfile", - true, - "Should the driver allow use of 'LOAD DATA LOCAL INFILE...' (defaults to 'true').", - "3.0.3", SECURITY_CATEGORY, Integer.MAX_VALUE); - - private BooleanConnectionProperty allowMultiQueries = new BooleanConnectionProperty( - "allowMultiQueries", - false, - "Allow the use of ';' to delimit multiple queries during one statement (true/false), defaults to 'false'", - "3.1.1", SECURITY_CATEGORY, 1); - - private BooleanConnectionProperty allowNanAndInf = new BooleanConnectionProperty( - "allowNanAndInf", - false, - "Should the driver allow NaN or +/- INF values in PreparedStatement.setDouble()?", - "3.1.5", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty allowUrlInLocalInfile = new BooleanConnectionProperty( - "allowUrlInLocalInfile", - false, - "Should the driver allow URLs in 'LOAD DATA LOCAL INFILE' statements?", - "3.1.4", SECURITY_CATEGORY, Integer.MAX_VALUE); - - private BooleanConnectionProperty alwaysSendSetIsolation = new BooleanConnectionProperty( - "alwaysSendSetIsolation", - true, - "Should the driver always communicate with the database when " - + " Connection.setTransactionIsolation() is called? " - + "If set to false, the driver will only communicate with the " - + "database when the requested transaction isolation is different " - + "than the whichever is newer, the last value that was set via " - + "Connection.setTransactionIsolation(), or the value that was read from " - + "the server when the connection was established.", - "3.1.7", PERFORMANCE_CATEGORY, Integer.MAX_VALUE); - - private BooleanConnectionProperty autoClosePStmtStreams = new BooleanConnectionProperty( - "autoClosePStmtStreams", - false, - "Should the driver automatically call .close() on streams/readers passed as " - + "arguments via set*() methods?", - "3.1.12", - MISC_CATEGORY, - Integer.MIN_VALUE); - - private BooleanConnectionProperty autoDeserialize = new BooleanConnectionProperty( - "autoDeserialize", - false, - "Should the driver automatically detect and de-serialize objects stored in BLOB fields?", - "3.1.5", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty autoGenerateTestcaseScript = new BooleanConnectionProperty( - "autoGenerateTestcaseScript", false, - "Should the driver dump the SQL it is executing, including server-side " - + "prepared statements to STDERR?", "3.1.9", - DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - private boolean autoGenerateTestcaseScriptAsBoolean = false; - - private BooleanConnectionProperty autoReconnect = new BooleanConnectionProperty( - "autoReconnect", - false, - "Should the driver try to re-establish stale and/or dead connections? " - + " If enabled the driver will throw an exception for a queries issued on a stale or dead connection, " - + " which belong to the current transaction, but will attempt reconnect before the next query issued on the " - + "connection in a new transaction. The use of this feature " - + "is not recommended, because it has side effects related to session state and data consistency when applications don't" - + "handle SQLExceptions properly, and is only designed to be used " - + "when you are unable to configure your application to handle SQLExceptions resulting from dead and" - + "stale connections properly. Alternatively, investigate setting the MySQL server variable \"wait_timeout\"" - + "to some high value rather than the default of 8 hours.", - "1.1", HA_CATEGORY, 0); - - private BooleanConnectionProperty autoReconnectForPools = new BooleanConnectionProperty( - "autoReconnectForPools", - false, - "Use a reconnection strategy appropriate for connection pools (defaults to 'false')", - "3.1.3", HA_CATEGORY, 1); - - private boolean autoReconnectForPoolsAsBoolean = false; - - private MemorySizeConnectionProperty blobSendChunkSize = new MemorySizeConnectionProperty( - "blobSendChunkSize", - 1024 * 1024, - 1, - Integer.MAX_VALUE, - "Chunk to use when sending BLOB/CLOBs via ServerPreparedStatements", - "3.1.9", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty blobsAreStrings = new BooleanConnectionProperty( - "blobsAreStrings", false, - "Should the driver always treat 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); - - 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); - - private BooleanConnectionProperty cacheCallableStatements = new BooleanConnectionProperty( - "cacheCallableStmts", false, - "Should the driver cache the parsing stage of CallableStatements", - "3.1.2", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty cachePreparedStatements = new BooleanConnectionProperty( - "cachePrepStmts", - false, - "Should the driver cache the parsing stage of PreparedStatements of client-side " - + "prepared statements, the \"check\" for suitability of server-side prepared " - + " and server-side prepared statements themselves?", - "3.0.10", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty cacheResultSetMetadata = new BooleanConnectionProperty( - "cacheResultSetMetadata", - false, - "Should the driver cache ResultSetMetaData for Statements and PreparedStatements? (Req. JDK-1.4+, true/false, default 'false')", - "3.1.1", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private boolean cacheResultSetMetaDataAsBoolean; - - private BooleanConnectionProperty cacheServerConfiguration = new BooleanConnectionProperty( - "cacheServerConfiguration", - false, - "Should the driver cache the results of " - + "'SHOW VARIABLES' and 'SHOW COLLATION' on a per-URL basis?", - "3.1.5", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private IntegerConnectionProperty callableStatementCacheSize = new IntegerConnectionProperty( - "callableStmtCacheSize", - 100, - 0, - Integer.MAX_VALUE, - "If 'cacheCallableStmts' is enabled, how many callable statements should be cached?", - "3.1.2", PERFORMANCE_CATEGORY, 5); - - private BooleanConnectionProperty capitalizeTypeNames = new BooleanConnectionProperty( - "capitalizeTypeNames", - true, - "Capitalize type names in DatabaseMetaData? (usually only useful when using WebObjects, true/false, defaults to 'false')", - "2.0.7", MISC_CATEGORY, Integer.MIN_VALUE); - - private StringConnectionProperty characterEncoding = new StringConnectionProperty( - "characterEncoding", - null, - "If 'useUnicode' is set to true, what character encoding should the driver use when dealing with strings? (defaults is to 'autodetect')", - "1.1g", MISC_CATEGORY, 5); - - private String characterEncodingAsString = null; - - private StringConnectionProperty characterSetResults = new StringConnectionProperty( - "characterSetResults", null, - "Character set to tell the server to return results as.", "3.0.13", - MISC_CATEGORY, 6); - - private BooleanConnectionProperty clobberStreamingResults = new BooleanConnectionProperty( - "clobberStreamingResults", - false, - "This will cause a 'streaming' ResultSet to be automatically closed, " - + "and any outstanding data still streaming from the server to be discarded if another query is executed " - + "before all the data has been read from the server.", - "3.0.9", MISC_CATEGORY, Integer.MIN_VALUE); - - private StringConnectionProperty clobCharacterEncoding = new StringConnectionProperty( - "clobCharacterEncoding", - null, - "The character encoding to use for sending and retrieving TEXT, MEDIUMTEXT " + - "and LONGTEXT values instead of the configured connection characterEncoding", - "5.0.0", MISC_CATEGORY, Integer.MIN_VALUE); - - private StringConnectionProperty connectionCollation = new StringConnectionProperty( - "connectionCollation", - null, - "If set, tells the server to use this collation via 'set collation_connection'", - "3.0.13", MISC_CATEGORY, 7); - - private IntegerConnectionProperty connectTimeout = new IntegerConnectionProperty( - "connectTimeout", 0, 0, Integer.MAX_VALUE, - "Timeout for socket connect (in milliseconds), with 0 being no timeout. " - + "Only works on JDK-1.4 or newer. Defaults to '0'.", - "3.0.1", CONNECTION_AND_AUTH_CATEGORY, 9); - - private BooleanConnectionProperty continueBatchOnError = new BooleanConnectionProperty( - "continueBatchOnError", - true, - "Should the driver continue processing batch commands if " - + "one statement fails. The JDBC spec allows either way (defaults to 'true').", - "3.0.3", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty createDatabaseIfNotExist = new BooleanConnectionProperty( - "createDatabaseIfNotExist", - false, - "Creates the database given in the URL if it doesn't yet exist. Assumes " - + " the configured user has permissions to create databases.", - "3.1.9", MISC_CATEGORY, Integer.MIN_VALUE); - - private IntegerConnectionProperty defaultFetchSize = new IntegerConnectionProperty("defaultFetchSize", 0, "The driver will call setFetchSize(n) with this value on all newly-created Statements", "3.1.9", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty detectServerPreparedStmts = new BooleanConnectionProperty( - "useServerPrepStmts", - false, - "Use server-side prepared statements if the server supports them?", - "3.1.0", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty dontTrackOpenResources = new BooleanConnectionProperty( - "dontTrackOpenResources", - false, - "The JDBC specification requires the driver to automatically track and close resources, " - + "however if your application doesn't do a good job of " - + "explicitly calling close() on statements or result sets, " - + "this can cause memory leakage. Setting this property to true " - + "relaxes this constraint, and can be more memory efficient for " - + "some applications.", "3.1.7", PERFORMANCE_CATEGORY, - Integer.MIN_VALUE); - - private BooleanConnectionProperty dumpQueriesOnException = new BooleanConnectionProperty( - "dumpQueriesOnException", - false, - "Should the driver dump the contents of the query sent to the server in the message for SQLExceptions?", - "3.1.3", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty dynamicCalendars = new BooleanConnectionProperty( - "dynamicCalendars", - false, - "Should the driver retrieve the default" - + " calendar when required, or cache it per connection/session?", - "3.1.5", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty elideSetAutoCommits = new BooleanConnectionProperty( - "elideSetAutoCommits", - false, - "If using MySQL-4.1 or newer, should the driver only issue 'set autocommit=n' queries when the server's state doesn't match the requested state by Connection.setAutoCommit(boolean)?", - "3.1.3", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty emptyStringsConvertToZero = new BooleanConnectionProperty( - "emptyStringsConvertToZero", true, - "Should the driver allow conversions from empty string " - + "fields to numeric values of '0'?", "3.1.8", - MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty emulateLocators = new BooleanConnectionProperty( - "emulateLocators", false, "N/A", "3.1.0", MISC_CATEGORY, - Integer.MIN_VALUE); - - private BooleanConnectionProperty emulateUnsupportedPstmts = new BooleanConnectionProperty( - "emulateUnsupportedPstmts", - true, - "Should the driver detect prepared statements that are not supported by the server, and " - + "replace them with client-side emulated versions?", - "3.1.7", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty enablePacketDebug = new BooleanConnectionProperty( - "enablePacketDebug", - false, - "When enabled, a ring-buffer of 'packetDebugBufferSize' packets will be kept, and dumped when exceptions are thrown in key areas in the driver's code", - "3.1.3", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty enableQueryTimeouts = new BooleanConnectionProperty( - "enableQueryTimeouts", - true, - "When enabled, query timeouts set via Statement.setQueryTimeout() use a shared " - + "java.util.Timer instance for scheduling. Even if the timeout doesn't expire before the query is processed, there will be " - + "memory used by the TimerTask for the given timeout which won't be reclaimed until " - + "the time the timeout would have expired if it hadn't been cancelled by the driver. High-load environments " - + "might want to consider disabling this functionality.", - "5.0.6", - PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty explainSlowQueries = new BooleanConnectionProperty( - "explainSlowQueries", - false, - "If 'logSlowQueries' is enabled, should the driver automatically issue an 'EXPLAIN' on the" - + " server and send the results to the configured log at a WARN level?", - "3.1.2", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - /** When failed-over, set connection to read-only? */ - private BooleanConnectionProperty failOverReadOnly = new BooleanConnectionProperty( - "failOverReadOnly", - true, - "When failing over in autoReconnect mode, should the connection be set to 'read-only'?", - "3.0.12", HA_CATEGORY, 2); - - private BooleanConnectionProperty gatherPerformanceMetrics = new BooleanConnectionProperty( - "gatherPerfMetrics", - false, - "Should the driver gather performance metrics, and report them via the configured logger every 'reportMetricsIntervalMillis' milliseconds?", - "3.1.2", DEBUGING_PROFILING_CATEGORY, 1); - - private BooleanConnectionProperty generateSimpleParameterMetadata = new BooleanConnectionProperty( - "generateSimpleParameterMetadata", false, "Should the driver generate simplified parameter metadata for PreparedStatements when " - + "no metadata is available either because the server couldn't support preparing the statement, or server-side prepared statements" + - " are disabled?" - , "5.0.5", MISC_CATEGORY, Integer.MIN_VALUE); - - private boolean highAvailabilityAsBoolean = false; - - private BooleanConnectionProperty holdResultsOpenOverStatementClose = new BooleanConnectionProperty( - "holdResultsOpenOverStatementClose", - false, - "Should the driver close result sets on Statement.close() as required by the JDBC specification?", - "3.1.7", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty includeInnodbStatusInDeadlockExceptions = new BooleanConnectionProperty( - "includeInnodbStatusInDeadlockExceptions", - false, - "Include the output of \"SHOW ENGINE INNODB STATUS\" in exception messages when deadlock exceptions are detected?", - "5.0.7", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty ignoreNonTxTables = new BooleanConnectionProperty( - "ignoreNonTxTables", - false, - "Ignore non-transactional table warning for rollback? (defaults to 'false').", - "3.0.9", MISC_CATEGORY, Integer.MIN_VALUE); - - private IntegerConnectionProperty initialTimeout = new IntegerConnectionProperty( - "initialTimeout", 2, 1, Integer.MAX_VALUE, - "If autoReconnect is enabled, the" - + " initial time to wait between" - + " re-connect attempts (in seconds, defaults to '2').", - "1.1", HA_CATEGORY, 5); - - private BooleanConnectionProperty isInteractiveClient = new BooleanConnectionProperty( - "interactiveClient", - false, - "Set the CLIENT_INTERACTIVE flag, which tells MySQL " - + "to timeout connections based on INTERACTIVE_TIMEOUT instead of WAIT_TIMEOUT", - "3.1.0", CONNECTION_AND_AUTH_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty jdbcCompliantTruncation = new BooleanConnectionProperty( - "jdbcCompliantTruncation", - true, - "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)?", "3.1.2", MISC_CATEGORY, - Integer.MIN_VALUE); - - private boolean jdbcCompliantTruncationForReads = - this.jdbcCompliantTruncation.getValueAsBoolean(); - - private StringConnectionProperty loadBalanceStrategy = new StringConnectionProperty( - "loadBalanceStrategy", - "random", - new String[] {"random", "bestResponseTime"}, - "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 balancin 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.", - "5.0.6", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private StringConnectionProperty localSocketAddress = new StringConnectionProperty("localSocketAddress", - null, "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.", - "5.0.5", CONNECTION_AND_AUTH_CATEGORY, Integer.MIN_VALUE); - - private MemorySizeConnectionProperty locatorFetchBufferSize = new MemorySizeConnectionProperty( - "locatorFetchBufferSize", - 1024 * 1024, - 0, - Integer.MAX_VALUE, - "If 'emulateLocators' is configured to 'true', what size " - + " buffer should be used when fetching BLOB data for getBinaryInputStream?", - "3.2.1", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private StringConnectionProperty loggerClassName = new StringConnectionProperty( - "logger", STANDARD_LOGGER_NAME, - "The name of a class that implements '" + Log.class.getName() - + "' that will be used to log messages to." - + "(default is '" + STANDARD_LOGGER_NAME + "', which " - + "logs to STDERR)", "3.1.1", DEBUGING_PROFILING_CATEGORY, - 0); - - private BooleanConnectionProperty logSlowQueries = new BooleanConnectionProperty( - "logSlowQueries", - false, - "Should queries that take longer than 'slowQueryThresholdMillis' be logged?", - "3.1.2", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty logXaCommands = new BooleanConnectionProperty( - "logXaCommands", - false, - "Should the driver log XA commands sent by MysqlXaConnection to the server," + - " at the DEBUG level of logging?", - "5.0.5", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty maintainTimeStats = new BooleanConnectionProperty( - "maintainTimeStats", - true, - "Should the driver maintain various internal timers to enable " - + "idle time calculations as well as more verbose error messages when " - + "the connection to the server fails? Setting this property to " - + "false removes at least two calls to System.getCurrentTimeMillis() " - + "per query.", "3.1.9", PERFORMANCE_CATEGORY, - Integer.MAX_VALUE); - - private boolean maintainTimeStatsAsBoolean = true; - - private IntegerConnectionProperty maxQuerySizeToLog = new IntegerConnectionProperty( - "maxQuerySizeToLog", - 2048, - 0, - Integer.MAX_VALUE, - "Controls the maximum length/size of a query that will get logged when profiling or tracing", - "3.1.3", DEBUGING_PROFILING_CATEGORY, 4); - - private IntegerConnectionProperty maxReconnects = new IntegerConnectionProperty( - "maxReconnects", - 3, - 1, - Integer.MAX_VALUE, - "Maximum number of reconnects to attempt if autoReconnect is true, default is '3'.", - "1.1", HA_CATEGORY, 4); - - private IntegerConnectionProperty maxRows = new IntegerConnectionProperty( - "maxRows", -1, -1, Integer.MAX_VALUE, - "The maximum number of rows to return " - + " (0, the default means return all rows).", - "all versions", MISC_CATEGORY, Integer.MIN_VALUE); - - private int maxRowsAsInt = -1; - - private IntegerConnectionProperty metadataCacheSize = new IntegerConnectionProperty( - "metadataCacheSize", - 50, - 1, - Integer.MAX_VALUE, - "The number of queries to cache" - + "ResultSetMetadata for if cacheResultSetMetaData is set to 'true' (default 50)", - "3.1.1", PERFORMANCE_CATEGORY, 5); - - private BooleanConnectionProperty noAccessToProcedureBodies = new BooleanConnectionProperty( - "noAccessToProcedureBodies", - false, - "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); - - private BooleanConnectionProperty noDatetimeStringSync = new BooleanConnectionProperty( - "noDatetimeStringSync", - false, - "Don't ensure that ResultSet.getDatetimeType().toString().equals(ResultSet.getString())", - "3.1.7", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty noTimezoneConversionForTimeType = new BooleanConnectionProperty( - "noTimezoneConversionForTimeType", - false, - "Don't convert TIME values using the server timezone if 'useTimezone'='true'", - "5.0.0", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty nullCatalogMeansCurrent = new BooleanConnectionProperty( - "nullCatalogMeansCurrent", - true, - "When DatabaseMetadataMethods ask for a 'catalog' parameter, does the value null mean use the current catalog? " - + "(this is not JDBC-compliant, but follows legacy behavior from earlier versions of the driver)", - "3.1.8", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty nullNamePatternMatchesAll = new BooleanConnectionProperty( - "nullNamePatternMatchesAll", - true, - "Should DatabaseMetaData methods that accept *pattern parameters treat null the same as '%' " - + " (this is not JDBC-compliant, however older versions of the driver accepted this departure from the specification)", - "3.1.8", MISC_CATEGORY, Integer.MIN_VALUE); - - private IntegerConnectionProperty packetDebugBufferSize = new IntegerConnectionProperty( - "packetDebugBufferSize", - 20, - 0, - Integer.MAX_VALUE, - "The maximum number of packets to retain when 'enablePacketDebug' is true", - "3.1.3", DEBUGING_PROFILING_CATEGORY, 7); - - private BooleanConnectionProperty padCharsWithSpace = new BooleanConnectionProperty( - "padCharsWithSpace", - false, - "If a result set column has the CHAR type and the value does not fill the " - + "amount of characters specified in the DDL for the column, should the driver " - + "pad the remaining characters with space (for ANSI compliance)?", - "5.0.6", - MISC_CATEGORY, - Integer.MIN_VALUE); - - private BooleanConnectionProperty paranoid = new BooleanConnectionProperty( - "paranoid", - false, - "Take measures to prevent exposure sensitive information in error messages and clear " - + "data structures holding sensitive data when possible? (defaults to 'false')", - "3.0.1", SECURITY_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty pedantic = new BooleanConnectionProperty( - "pedantic", false, "Follow the JDBC spec to the letter.", "3.0.0", - MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty pinGlobalTxToPhysicalConnection = new BooleanConnectionProperty( - "pinGlobalTxToPhysicalConnection", false, "When using XAConnections, should the driver ensure that " - + " operations on a given XID are always routed to the same physical connection? This allows the XAConnection" - + " to support \"XA START ... JOIN\" after \"XA END\" has been called", - "5.0.1", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty populateInsertRowWithDefaultValues = new BooleanConnectionProperty( - "populateInsertRowWithDefaultValues", false, - "When using ResultSets that are CONCUR_UPDATABLE, should the driver pre-poulate " + - "the \"insert\" row with default values from the DDL for the table used in the query " + - " so those values are immediately available for ResultSet accessors? This functionality requires a " + - " call to the database for metadata each time a result set of this type is created. " + - " If disabled (the default), the default values will be populated by the an internal" + - " call to refreshRow() which pulls back default values and/or values changed by triggers.", - "5.0.5", MISC_CATEGORY, Integer.MIN_VALUE); - - private IntegerConnectionProperty preparedStatementCacheSize = new IntegerConnectionProperty( - "prepStmtCacheSize", 25, 0, Integer.MAX_VALUE, - "If prepared statement caching is enabled, " - + "how many prepared statements should be cached?", - "3.0.10", PERFORMANCE_CATEGORY, 10); - - private IntegerConnectionProperty preparedStatementCacheSqlLimit = new IntegerConnectionProperty( - "prepStmtCacheSqlLimit", - 256, - 1, - Integer.MAX_VALUE, - "If prepared statement caching is enabled, " - + "what's the largest SQL the driver will cache the parsing for?", - "3.0.10", PERFORMANCE_CATEGORY, 11); - - private BooleanConnectionProperty processEscapeCodesForPrepStmts = - new BooleanConnectionProperty("processEscapeCodesForPrepStmts", - true, - "Should the driver process escape codes in queries that are prepared?", - "3.1.12", - MISC_CATEGORY, Integer.MIN_VALUE); - - private StringConnectionProperty profileSql = new StringConnectionProperty( - "profileSql", - null, - "Deprecated, use 'profileSQL' instead. Trace queries and their execution/fetch times on STDERR (true/false) defaults to 'false'", - "2.0.14", DEBUGING_PROFILING_CATEGORY, 3); - - private BooleanConnectionProperty profileSQL = new BooleanConnectionProperty( - "profileSQL", - false, - "Trace queries and their execution/fetch times to the configured logger (true/false) defaults to 'false'", - "3.1.0", DEBUGING_PROFILING_CATEGORY, 1); - - private boolean profileSQLAsBoolean = false; - - private StringConnectionProperty propertiesTransform = new StringConnectionProperty( - NonRegisteringDriver.PROPERTIES_TRANSFORM_KEY, - null, - "An implementation of com.mysql.jdbc.ConnectionPropertiesTransform that the driver will use to modify URL properties passed to the driver before attempting a connection", - "3.1.4", CONNECTION_AND_AUTH_CATEGORY, Integer.MIN_VALUE); - - private IntegerConnectionProperty queriesBeforeRetryMaster = new IntegerConnectionProperty( - "queriesBeforeRetryMaster", - 50, - 1, - Integer.MAX_VALUE, - "Number of queries to issue before falling back to master when failed over " - + "(when using multi-host failover). Whichever condition is met first, " - + "'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an " - + "attempt to be made to reconnect to the master. Defaults to 50.", - "3.0.2", HA_CATEGORY, 7); - - private BooleanConnectionProperty reconnectAtTxEnd = new BooleanConnectionProperty( - "reconnectAtTxEnd", false, - "If autoReconnect is set to true, should the driver attempt reconnections" - + "at the end of every transaction?", "3.0.10", - HA_CATEGORY, 4); - - private boolean reconnectTxAtEndAsBoolean = false; - - private BooleanConnectionProperty relaxAutoCommit = new BooleanConnectionProperty( - "relaxAutoCommit", - false, - "If the version of MySQL the driver connects to does not support transactions, still allow calls to commit(), rollback() and setAutoCommit() (true/false, defaults to 'false')?", - "2.0.13", MISC_CATEGORY, Integer.MIN_VALUE); - - private IntegerConnectionProperty reportMetricsIntervalMillis = new IntegerConnectionProperty( - "reportMetricsIntervalMillis", - 30000, - 0, - Integer.MAX_VALUE, - "If 'gatherPerfMetrics' is enabled, how often should they be logged (in ms)?", - "3.1.2", DEBUGING_PROFILING_CATEGORY, 3); - - private BooleanConnectionProperty requireSSL = new BooleanConnectionProperty( - "requireSSL", false, - "Require SSL connection if useSSL=true? (defaults to 'false').", - "3.1.0", SECURITY_CATEGORY, 3); - - private StringConnectionProperty resourceId = new StringConnectionProperty( - "resourceId", - null, "A globally unique name that identifies the resource that this datasource or connection is " + - "connected to, used for XAResource.isSameRM() when the driver can't determine this value based on " + - "hostnames used in the URL", - "5.0.1", - HA_CATEGORY, - Integer.MIN_VALUE); - - private IntegerConnectionProperty resultSetSizeThreshold = new IntegerConnectionProperty("resultSetSizeThreshold", 100, - "If the usage advisor is enabled, how many rows should a result set contain before the driver warns that it " - + " is suspiciously large?", "5.0.5", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty retainStatementAfterResultSetClose = new BooleanConnectionProperty( - "retainStatementAfterResultSetClose", - false, - "Should the driver retain the Statement reference in a ResultSet after ResultSet.close()" - + " has been called. This is not JDBC-compliant after JDBC-4.0.", - "3.1.11", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty rewriteBatchedStatements = new BooleanConnectionProperty( - "rewriteBatchedStatements", - false, - "Should the driver use multiqueries (irregardless of the setting of \"allowMultiQueries\") as well as " - + "rewriting of prepared statements for INSERT and REPLACE into multi-value inserts/replaces when executeBatch() is called? Notice that this has the potential " - + "for SQL injection if using plain java.sql.Statements and your code doesn't sanitize input correctly.\n\n" - + "Notice that if you don't specify stream lengths when using PreparedStatement.set*Stream()," - + "the driver won't be able to determine the optimium number of parameters per batch and you might receive " - + "an error from the driver that the resultant packet is too large.\n\n" - + "Statement.getGeneratedKeys() for these rewritten statements only works when the entire " - + "batch includes INSERT statements.", - "3.1.13", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty rollbackOnPooledClose = new BooleanConnectionProperty( - "rollbackOnPooledClose", - true, - "Should the driver issue a rollback() when the logical connection in a pool is closed?", - "3.0.15", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty roundRobinLoadBalance = new BooleanConnectionProperty( - "roundRobinLoadBalance", - false, - "When autoReconnect is enabled, and failoverReadonly is false, should we pick hosts to connect to on a round-robin basis?", - "3.1.2", HA_CATEGORY, 5); - - private BooleanConnectionProperty runningCTS13 = new BooleanConnectionProperty( - "runningCTS13", - false, - "Enables workarounds for bugs in Sun's JDBC compliance testsuite version 1.3", - "3.1.7", MISC_CATEGORY, Integer.MIN_VALUE); - - private IntegerConnectionProperty secondsBeforeRetryMaster = new IntegerConnectionProperty( - "secondsBeforeRetryMaster", - 30, - 1, - Integer.MAX_VALUE, - "How long should the driver wait, when failed over, before attempting " - + "to reconnect to the master server? Whichever condition is met first, " - + "'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an " - + "attempt to be made to reconnect to the master. Time in seconds, defaults to 30", - "3.0.2", HA_CATEGORY, 8); - - private StringConnectionProperty serverTimezone = new StringConnectionProperty( - "serverTimezone", - null, - "Override detection/mapping of timezone. Used when timezone from server doesn't map to Java timezone", - "3.0.2", MISC_CATEGORY, Integer.MIN_VALUE); - - private StringConnectionProperty sessionVariables = new StringConnectionProperty( - "sessionVariables", null, - "A comma-separated list of name/value pairs to be sent as SET SESSION ... to " - + " the server when the driver connects.", "3.1.8", - MISC_CATEGORY, Integer.MAX_VALUE); - - private IntegerConnectionProperty slowQueryThresholdMillis = new IntegerConnectionProperty( - "slowQueryThresholdMillis", - 2000, - 0, - Integer.MAX_VALUE, - "If 'logSlowQueries' is enabled, how long should a query (in ms) before it is logged as 'slow'?", - "3.1.2", DEBUGING_PROFILING_CATEGORY, 9); - - private LongConnectionProperty slowQueryThresholdNanos = new LongConnectionProperty( - "slowQueryThresholdNanos", - 0, - "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.", - "5.0.7", - DEBUGING_PROFILING_CATEGORY, - 10); - - private StringConnectionProperty socketFactoryClassName = new StringConnectionProperty( - "socketFactory", - StandardSocketFactory.class.getName(), - "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.", - "3.0.3", CONNECTION_AND_AUTH_CATEGORY, 4); - - private IntegerConnectionProperty socketTimeout = new IntegerConnectionProperty( - "socketTimeout", - 0, - 0, - Integer.MAX_VALUE, - "Timeout on network socket operations (0, the default means no timeout).", - "3.0.1", CONNECTION_AND_AUTH_CATEGORY, 10); - - private BooleanConnectionProperty strictFloatingPoint = new BooleanConnectionProperty( - "strictFloatingPoint", false, - "Used only in older versions of compliance test", "3.0.0", - MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty strictUpdates = new BooleanConnectionProperty( - "strictUpdates", - true, - "Should the driver do strict checking (all primary keys selected) of updatable result sets (true, false, defaults to 'true')?", - "3.0.4", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty overrideSupportsIntegrityEnhancementFacility = - new BooleanConnectionProperty("overrideSupportsIntegrityEnhancementFacility", - false, - "Should the driver return \"true\" for DatabaseMetaData.supportsIntegrityEnhancementFacility() " - + "even if the database doesn't support it to workaround applications that require this method to return " - + "\"true\" to signal support of foreign keys, even though the SQL specification states that this facility " - + "contains much more than just foreign key support (one such application being OpenOffice)?", - "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(), - "If connecting using TCP/IP, should the driver set SO_TCP_NODELAY (disabling the Nagle Algorithm)?", - "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(), - "If connecting using TCP/IP, should the driver set SO_KEEPALIVE?", - "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, - "If connecting using TCP/IP, should the driver set SO_RCV_BUF to the given value? " - + "The default value of '0', means use the platform default value for this property)", - "5.0.7", NETWORK_CATEGORY, Integer.MIN_VALUE); - - private IntegerConnectionProperty tcpSndBuf = new IntegerConnectionProperty( - StandardSocketFactory.TCP_SND_BUF_PROPERTY_NAME, - Integer.parseInt(StandardSocketFactory.TCP_SND_BUF_DEFAULT_VALUE), - 0, Integer.MAX_VALUE, - "If connecting using TCP/IP, shuold the driver set SO_SND_BUF to the given value? " - + "The default value of '0', means use the platform default value for this property)", - "5.0.7", NETWORK_CATEGORY, Integer.MIN_VALUE); - - private IntegerConnectionProperty tcpTrafficClass = new IntegerConnectionProperty( - StandardSocketFactory.TCP_TRAFFIC_CLASS_PROPERTY_NAME, - Integer.parseInt(StandardSocketFactory.TCP_TRAFFIC_CLASS_DEFAULT_VALUE), - 0, 255, - "If connecting using TCP/IP, should the driver set traffic class or type-of-service fields ?" + - " See the documentation for java.net.Socket.setTrafficClass() for more information.", - "5.0.7", NETWORK_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty tinyInt1isBit = new BooleanConnectionProperty( - "tinyInt1isBit", - true, - "Should the driver treat the datatype TINYINT(1) as the BIT type " - + "(because the server silently converts BIT -> TINYINT(1) when creating tables)?", - "3.0.16", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty traceProtocol = new BooleanConnectionProperty( - "traceProtocol", false, - "Should trace-level network protocol be logged?", "3.1.2", - DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty treatUtilDateAsTimestamp = new BooleanConnectionProperty( - "treatUtilDateAsTimestamp", true, - "Should the driver treat java.util.Date as a TIMESTAMP for the purposes of PreparedStatement.setObject()?", - "5.0.5", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty transformedBitIsBoolean = new BooleanConnectionProperty( - "transformedBitIsBoolean", - false, - "If the driver converts TINYINT(1) to a different type, should it use BOOLEAN instead of BIT " - + " for future compatibility with MySQL-5.0, as MySQL-5.0 has a BIT type?", - "3.1.9", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useCompression = new BooleanConnectionProperty( - "useCompression", - false, - "Use zlib compression when communicating with the server (true/false)? Defaults to 'false'.", - "3.0.17", CONNECTION_AND_AUTH_CATEGORY, Integer.MIN_VALUE); - - private StringConnectionProperty useConfigs = new StringConnectionProperty( - "useConfigs", - null, - "Load the comma-delimited list of configuration properties before parsing the " - + "URL or applying user-specified properties. These configurations are explained in the 'Configurations' of the documentation.", - "3.1.5", CONNECTION_AND_AUTH_CATEGORY, Integer.MAX_VALUE); - - private BooleanConnectionProperty useCursorFetch = new BooleanConnectionProperty( - "useCursorFetch", - false, - "If connected to MySQL > 5.0.2, and setFetchSize() > 0 on a statement, should " - + " that statement use cursor-based fetching to retrieve rows?", - "5.0.0", PERFORMANCE_CATEGORY, Integer.MAX_VALUE); - - private BooleanConnectionProperty useDynamicCharsetInfo = new BooleanConnectionProperty( - "useDynamicCharsetInfo", - true, - "Should the driver use a per-connection cache of character set information queried from the " - + " server when necessary, or use a built-in static mapping that is more efficient, but isn't " - + " aware of custom character sets or character sets implemented after the release of the JDBC driver?" - + "(this only affects the \"padCharsWithSpace\" configuration property and the " - + "ResultSetMetaData.getColumnDisplayWidth() method)." - , "5.0.6", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useFastIntParsing = new BooleanConnectionProperty( - "useFastIntParsing", - true, - "Use internal String->Integer conversion routines to avoid excessive object creation?", - "3.1.4", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useFastDateParsing = new BooleanConnectionProperty( - "useFastDateParsing", - true, - "Use internal String->Date/Time/Teimstamp conversion routines to avoid excessive object creation?", - "5.0.5", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useHostsInPrivileges = new BooleanConnectionProperty( - "useHostsInPrivileges", - true, - "Add '@hostname' to users in DatabaseMetaData.getColumn/TablePrivileges() (true/false), defaults to 'true'.", - "3.0.2", MISC_CATEGORY, Integer.MIN_VALUE); - private BooleanConnectionProperty useInformationSchema = new BooleanConnectionProperty( - "useInformationSchema", - false, - "When connected to MySQL-5.0.7 or newer, should the driver use the INFORMATION_SCHEMA to " - + " derive information used by DatabaseMetaData?", - "5.0.0", MISC_CATEGORY, Integer.MIN_VALUE); - private BooleanConnectionProperty useJDBCCompliantTimezoneShift = new BooleanConnectionProperty( - "useJDBCCompliantTimezoneShift", - false, - "Should the driver use JDBC-compliant rules when converting TIME/TIMESTAMP/DATETIME values' timezone information " + - "for those JDBC arguments which take a java.util.Calendar argument? (Notice that this " + - "option is exclusive of the \"useTimezone=true\" configuration option.)", - "5.0.0", - MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useLocalSessionState = new BooleanConnectionProperty( - "useLocalSessionState", - false, - "Should the driver refer to the internal values of autocommit and transaction isolation that are set " - + "by Connection.setAutoCommit() and Connection.setTransactionIsolation() and transaction state " - + "as maintained by the protocol, rather than querying the database or blindly " - + "sending commands to the database for commit() or rollback() method calls?", - "3.1.7", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useNanosForElapsedTime = new BooleanConnectionProperty( - "useNanosForElapsedTime", - false, - "For profiling/debugging functionality that measures elapsed time, should the driver " - + "try to use nanoseconds resolution if available (JDK >= 1.5)?", - "5.0.7", - DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useOldAliasMetadataBehavior = new BooleanConnectionProperty( - "useOldAliasMetadataBehavior", - true, - "Should the driver use the legacy behavior for \"AS\" clauses on columns and tables, and only " - + "return aliases (if any) for ResultSetMetaData.getColumnName() or ResultSetMetaData.getTableName() " - + "rather than the original column/table name?", - "5.0.4", - MISC_CATEGORY, - Integer.MIN_VALUE); - - private BooleanConnectionProperty useOldUTF8Behavior = new BooleanConnectionProperty( - "useOldUTF8Behavior", - false, - "Use the UTF-8 behavior the driver did when communicating with 4.0 and older servers", - "3.1.6", MISC_CATEGORY, Integer.MIN_VALUE); - - private boolean useOldUTF8BehaviorAsBoolean = false; - - private BooleanConnectionProperty useOnlyServerErrorMessages = new BooleanConnectionProperty( - "useOnlyServerErrorMessages", - true, - "Don't prepend 'standard' SQLState error messages to error messages returned by the server.", - "3.0.15", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useReadAheadInput = new BooleanConnectionProperty( - "useReadAheadInput", - true, - "Use newer, optimized non-blocking, buffered input stream when reading from the server?", - "3.1.5", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useSqlStateCodes = new BooleanConnectionProperty( - "useSqlStateCodes", - true, - "Use SQL Standard state codes instead of 'legacy' X/Open/SQL state codes (true/false), default is 'true'", - "3.1.3", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useSSL = new BooleanConnectionProperty( - "useSSL", - false, - "Use SSL when communicating with the server (true/false), defaults to 'false'", - "3.0.2", SECURITY_CATEGORY, 2); - - private BooleanConnectionProperty useSSPSCompatibleTimezoneShift = new BooleanConnectionProperty( - "useSSPSCompatibleTimezoneShift", - false, - "If migrating from an environment that was using server-side prepared statements, and the" - + " configuration property \"useJDBCCompliantTimeZoneShift\" set to \"true\", use compatible behavior" - + " when not using server-side prepared statements when sending TIMESTAMP values to the MySQL server.", - "5.0.5", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useStreamLengthsInPrepStmts = new BooleanConnectionProperty( - "useStreamLengthsInPrepStmts", - true, - "Honor stream length parameter in " - + "PreparedStatement/ResultSet.setXXXStream() method calls (true/false, defaults to 'true')?", - "3.0.2", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useTimezone = new BooleanConnectionProperty( - "useTimezone", - false, - "Convert time/date types between client and server timezones (true/false, defaults to 'false')?", - "3.0.2", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useUltraDevWorkAround = new BooleanConnectionProperty( - "ultraDevHack", - false, - "Create PreparedStatements for prepareCall() when required, because UltraDev " - + " is broken and issues a prepareCall() for _all_ statements? (true/false, defaults to 'false')", - "2.0.3", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useUnbufferedInput = new BooleanConnectionProperty( - "useUnbufferedInput", true, - "Don't use BufferedInputStream for reading data from the server", - "3.0.11", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useUnicode = new BooleanConnectionProperty( - "useUnicode", - true, - "Should the driver use Unicode character encodings when handling strings? Should only be used when the driver can't determine the character set mapping, or you are trying to 'force' the driver to use a character set that MySQL either doesn't natively support (such as UTF-8), true/false, defaults to 'true'", - "1.1g", MISC_CATEGORY, 0); - - // Cache these values, they are 'hot' - private boolean useUnicodeAsBoolean = true; - - private BooleanConnectionProperty useUsageAdvisor = new BooleanConnectionProperty( - "useUsageAdvisor", - false, - "Should the driver issue 'usage' warnings advising proper and efficient usage of JDBC and MySQL Connector/J to the log (true/false, defaults to 'false')?", - "3.1.1", DEBUGING_PROFILING_CATEGORY, 10); - - private boolean useUsageAdvisorAsBoolean = false; - - private BooleanConnectionProperty yearIsDateType = new BooleanConnectionProperty( - "yearIsDateType", - true, - "Should the JDBC driver treat the MySQL type \"YEAR\" as a java.sql.Date, or as a SHORT?", - "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 }, - "What should happen when the driver encounters DATETIME values that are composed " - + "entirely of zeroes (used by MySQL to represent invalid dates)? " - + "Valid values are '" - + ZERO_DATETIME_BEHAVIOR_EXCEPTION - + "', '" - + ZERO_DATETIME_BEHAVIOR_ROUND - + "' and '" - + ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL + "'.", "3.1.4", - MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useJvmCharsetConverters = new BooleanConnectionProperty("useJvmCharsetConverters", - false, "Always use the character encoding routines built into the JVM, rather than using " - + "lookup tables for single-byte character sets?", "5.0.1", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty useGmtMillisForDatetimes = new BooleanConnectionProperty("useGmtMillisForDatetimes", false, "Convert between session timezone and GMT before creating Date and Timestamp instances (value of \"false\" is legacy behavior, \"true\" leads to more JDBC-compliant behavior.", "3.1.12", MISC_CATEGORY, Integer.MIN_VALUE); - - private BooleanConnectionProperty dumpMetadataOnColumnNotFound = new BooleanConnectionProperty("dumpMetadataOnColumnNotFound", false, "Should the driver dump the field-level metadata of a result set into " + "the exception message when ResultSet.findColumn() fails?", "3.1.13", DEBUGING_PROFILING_CATEGORY, Integer.MIN_VALUE); - - protected DriverPropertyInfo[] exposeAsDriverPropertyInfoInternal( - Properties info, int slotsToReserve) throws SQLException { - initializeProperties(info); - - int numProperties = PROPERTY_LIST.size(); - - int listSize = numProperties + slotsToReserve; - - DriverPropertyInfo[] driverProperties = new DriverPropertyInfo[listSize]; - - for (int i = slotsToReserve; i < listSize; i++) { - java.lang.reflect.Field propertyField = (java.lang.reflect.Field) PROPERTY_LIST - .get(i - slotsToReserve); - - try { - ConnectionProperty propToExpose = (ConnectionProperty) propertyField - .get(this); - - if (info != null) { - propToExpose.initializeFrom(info); - } - - - driverProperties[i] = propToExpose.getAsDriverPropertyInfo(); - } catch (IllegalAccessException iae) { - throw SQLError.createSQLException("Internal properties failure", - SQLError.SQL_STATE_GENERAL_ERROR); - } - } - - return driverProperties; - } - - protected Properties exposeAsProperties(Properties info) - throws SQLException { - if (info == null) { - info = new Properties(); - } - - int numPropertiesToSet = PROPERTY_LIST.size(); - - for (int i = 0; i < numPropertiesToSet; i++) { - java.lang.reflect.Field propertyField = (java.lang.reflect.Field) PROPERTY_LIST - .get(i); - - try { - ConnectionProperty propToGet = (ConnectionProperty) propertyField - .get(this); - - Object propValue = propToGet.getValueAsObject(); - - if (propValue != null) { - info.setProperty(propToGet.getPropertyName(), propValue - .toString()); - } - } catch (IllegalAccessException iae) { - throw SQLError.createSQLException("Internal properties failure", - SQLError.SQL_STATE_GENERAL_ERROR); - } - } - - return info; - } - - /** * Returns a description of the connection properties as an XML document. - * + * * @return the connection properties as an XML document. * @throws SQLException * if an error occurs. */ - public String exposeAsXml() throws SQLException { - StringBuffer xmlBuf = new StringBuffer(); - xmlBuf.append(""); + public abstract String exposeAsXml() throws SQLException; - int numPropertiesToSet = PROPERTY_LIST.size(); - - int numCategories = PROPERTY_CATEGORIES.length; - - Map propertyListByCategory = new HashMap(); - - for (int i = 0; i < numCategories; i++) { - propertyListByCategory.put(PROPERTY_CATEGORIES[i], new Map[] { - new TreeMap(), new TreeMap() }); - } - - // - // The following properties are not exposed as 'normal' properties, but - // they are - // settable nonetheless, so we need to have them documented, make sure - // that they sort 'first' as #1 and #2 in the category - // - StringConnectionProperty userProp = new StringConnectionProperty( - NonRegisteringDriver.USER_PROPERTY_KEY, null, - "The user to connect as", "all", CONNECTION_AND_AUTH_CATEGORY, - Integer.MIN_VALUE + 1); - StringConnectionProperty passwordProp = new StringConnectionProperty( - NonRegisteringDriver.PASSWORD_PROPERTY_KEY, null, - "The password to use when connecting", "all", - CONNECTION_AND_AUTH_CATEGORY, Integer.MIN_VALUE + 2); - - Map[] connectionSortMaps = (Map[]) propertyListByCategory - .get(CONNECTION_AND_AUTH_CATEGORY); - TreeMap userMap = new TreeMap(); - userMap.put(userProp.getPropertyName(), userProp); - - connectionSortMaps[0].put(new Integer(userProp.getOrder()), userMap); - - TreeMap passwordMap = new TreeMap(); - passwordMap.put(passwordProp.getPropertyName(), passwordProp); - - connectionSortMaps[0] - .put(new Integer(passwordProp.getOrder()), passwordMap); - - try { - for (int i = 0; i < numPropertiesToSet; i++) { - java.lang.reflect.Field propertyField = (java.lang.reflect.Field) PROPERTY_LIST - .get(i); - ConnectionProperty propToGet = (ConnectionProperty) propertyField - .get(this); - Map[] sortMaps = (Map[]) propertyListByCategory.get(propToGet - .getCategoryName()); - int orderInCategory = propToGet.getOrder(); - - if (orderInCategory == Integer.MIN_VALUE) { - sortMaps[1].put(propToGet.getPropertyName(), propToGet); - } else { - Integer order = new Integer(orderInCategory); - - Map orderMap = (Map)sortMaps[0].get(order); - - if (orderMap == null) { - orderMap = new TreeMap(); - sortMaps[0].put(order, orderMap); - } - - orderMap.put(propToGet.getPropertyName(), propToGet); - } - } - - for (int j = 0; j < numCategories; j++) { - Map[] sortMaps = (Map[]) propertyListByCategory - .get(PROPERTY_CATEGORIES[j]); - Iterator orderedIter = sortMaps[0].values().iterator(); - Iterator alphaIter = sortMaps[1].values().iterator(); - - xmlBuf.append("\n "); - - while (orderedIter.hasNext()) { - Iterator orderedAlphaIter = ((Map)orderedIter.next()).values().iterator(); - - while (orderedAlphaIter.hasNext()) { - ConnectionProperty propToGet = (ConnectionProperty) orderedAlphaIter - .next(); - - xmlBuf.append("\n \n"); - xmlBuf.append(" "); - xmlBuf.append(propToGet.description); - xmlBuf.append("\n "); - } - } - - while (alphaIter.hasNext()) { - ConnectionProperty propToGet = (ConnectionProperty) alphaIter - .next(); - - xmlBuf.append("\n \n"); - xmlBuf.append(" "); - xmlBuf.append(propToGet.description); - xmlBuf.append("\n "); - } - - xmlBuf.append("\n "); - } - } catch (IllegalAccessException iae) { - throw SQLError.createSQLException("Internal properties failure", - SQLError.SQL_STATE_GENERAL_ERROR); - } - - xmlBuf.append("\n"); - - return xmlBuf.toString(); - } - /** * DOCUMENT ME! - * + * * @return */ - public boolean getAllowLoadLocalInfile() { - return this.allowLoadLocalInfile.getValueAsBoolean(); - } + public abstract boolean getAllowLoadLocalInfile(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getAllowMultiQueries() { - return this.allowMultiQueries.getValueAsBoolean(); - } + public abstract boolean getAllowMultiQueries(); /** * @return Returns the allowNanAndInf. */ - public boolean getAllowNanAndInf() { - return allowNanAndInf.getValueAsBoolean(); - } + public abstract boolean getAllowNanAndInf(); /** * @return Returns the allowUrlInLocalInfile. */ - public boolean getAllowUrlInLocalInfile() { - return this.allowUrlInLocalInfile.getValueAsBoolean(); - } + public abstract boolean getAllowUrlInLocalInfile(); /** * @return Returns the alwaysSendSetIsolation. */ - public boolean getAlwaysSendSetIsolation() { - return this.alwaysSendSetIsolation.getValueAsBoolean(); - } + public abstract boolean getAlwaysSendSetIsolation(); /** * @return Returns the autoDeserialize. */ - public boolean getAutoDeserialize() { - return autoDeserialize.getValueAsBoolean(); - } + public abstract boolean getAutoDeserialize(); - public boolean getAutoGenerateTestcaseScript() { - return this.autoGenerateTestcaseScriptAsBoolean; - } + public abstract boolean getAutoGenerateTestcaseScript(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getAutoReconnectForPools() { - return this.autoReconnectForPoolsAsBoolean; - } + public abstract boolean getAutoReconnectForPools(); /** * @return Returns the blobSendChunkSize. */ - public int getBlobSendChunkSize() { - return blobSendChunkSize.getValueAsInt(); - } + public abstract int getBlobSendChunkSize(); /** * DOCUMENT ME! - * + * * @return Returns if cacheCallableStatements is enabled */ - public boolean getCacheCallableStatements() { - return this.cacheCallableStatements.getValueAsBoolean(); - } + public abstract boolean getCacheCallableStatements(); /** * DOCUMENT ME! - * + * * @return Returns the cachePreparedStatements. */ - public boolean getCachePreparedStatements() { - return ((Boolean) this.cachePreparedStatements.getValueAsObject()) - .booleanValue(); - } + public abstract boolean getCachePreparedStatements(); /** * DOCUMENT ME! - * + * * @return DOCUMENT ME! */ - public boolean getCacheResultSetMetadata() { - return this.cacheResultSetMetaDataAsBoolean; - } + public abstract boolean getCacheResultSetMetadata(); /** * @return Returns the cacheServerConfiguration. */ - public boolean getCacheServerConfiguration() { - return cacheServerConfiguration.getValueAsBoolean(); - } + public abstract boolean getCacheServerConfiguration(); /** * DOCUMENT ME! - * + * * @return Returns the callableStatementCacheSize. */ - public int getCallableStatementCacheSize() { - return this.callableStatementCacheSize.getValueAsInt(); - } + public abstract int getCallableStatementCacheSize(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getCapitalizeTypeNames() { - return this.capitalizeTypeNames.getValueAsBoolean(); - } + public abstract boolean getCapitalizeTypeNames(); /** * DOCUMENT ME! - * + * * @return Returns the characterSetResults. */ - public String getCharacterSetResults() { - return this.characterSetResults.getValueAsString(); - } + public abstract String getCharacterSetResults(); /** * DOCUMENT ME! - * + * * @return Returns the clobberStreamingResults. */ - public boolean getClobberStreamingResults() { - return this.clobberStreamingResults.getValueAsBoolean(); - } + public abstract boolean getClobberStreamingResults(); - public String getClobCharacterEncoding() { - return this.clobCharacterEncoding.getValueAsString(); - } + public abstract String getClobCharacterEncoding(); /** * DOCUMENT ME! - * + * * @return Returns the connectionCollation. */ - public String getConnectionCollation() { - return this.connectionCollation.getValueAsString(); - } + public abstract String getConnectionCollation(); /** * DOCUMENT ME! - * + * * @return */ - public int getConnectTimeout() { - return this.connectTimeout.getValueAsInt(); - } + public abstract int getConnectTimeout(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getContinueBatchOnError() { - return this.continueBatchOnError.getValueAsBoolean(); - } + public abstract boolean getContinueBatchOnError(); - public boolean getCreateDatabaseIfNotExist() { - return this.createDatabaseIfNotExist.getValueAsBoolean(); - } + public abstract boolean getCreateDatabaseIfNotExist(); - public int getDefaultFetchSize() { - return this.defaultFetchSize.getValueAsInt(); - } + public abstract int getDefaultFetchSize(); /** * @return Returns the dontTrackOpenResources. */ - public boolean getDontTrackOpenResources() { - return this.dontTrackOpenResources.getValueAsBoolean(); - } + public abstract boolean getDontTrackOpenResources(); /** * DOCUMENT ME! - * + * * @return Returns the dumpQueriesOnException. */ - public boolean getDumpQueriesOnException() { - return this.dumpQueriesOnException.getValueAsBoolean(); - } + public abstract boolean getDumpQueriesOnException(); /** * @return Returns the dynamicCalendars. */ - public boolean getDynamicCalendars() { - return this.dynamicCalendars.getValueAsBoolean(); - } + public abstract boolean getDynamicCalendars(); /** * DOCUMENT ME! - * + * * @return Returns the elideSetAutoCommits. */ - public boolean getElideSetAutoCommits() { - return this.elideSetAutoCommits.getValueAsBoolean(); - } + public abstract boolean getElideSetAutoCommits(); - public boolean getEmptyStringsConvertToZero() { - return this.emptyStringsConvertToZero.getValueAsBoolean(); - } + public abstract boolean getEmptyStringsConvertToZero(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getEmulateLocators() { - return this.emulateLocators.getValueAsBoolean(); - } + public abstract boolean getEmulateLocators(); /** * @return Returns the emulateUnsupportedPstmts. */ - public boolean getEmulateUnsupportedPstmts() { - return this.emulateUnsupportedPstmts.getValueAsBoolean(); - } + public abstract boolean getEmulateUnsupportedPstmts(); /** * DOCUMENT ME! - * + * * @return Returns the enablePacketDebug. */ - public boolean getEnablePacketDebug() { - return this.enablePacketDebug.getValueAsBoolean(); - } + public abstract boolean getEnablePacketDebug(); /** * DOCUMENT ME! - * + * * @return */ - public String getEncoding() { - return this.characterEncodingAsString; - } + public abstract String getEncoding(); /** * DOCUMENT ME! - * + * * @return Returns the explainSlowQueries. */ - public boolean getExplainSlowQueries() { - return this.explainSlowQueries.getValueAsBoolean(); - } + public abstract boolean getExplainSlowQueries(); /** * DOCUMENT ME! - * + * * @return Returns the failOverReadOnly. */ - public boolean getFailOverReadOnly() { - return this.failOverReadOnly.getValueAsBoolean(); - } + public abstract boolean getFailOverReadOnly(); /** * DOCUMENT ME! - * + * * @return Returns the gatherPerformanceMetrics. */ - public boolean getGatherPerformanceMetrics() { - return this.gatherPerformanceMetrics.getValueAsBoolean(); - } + public abstract boolean getGatherPerformanceMetrics(); /** - * DOCUMENT ME! - * - * @return - */ - protected boolean getHighAvailability() { - return this.highAvailabilityAsBoolean; - } - - /** * @return Returns the holdResultsOpenOverStatementClose. */ - public boolean getHoldResultsOpenOverStatementClose() { - return holdResultsOpenOverStatementClose.getValueAsBoolean(); - } + public abstract boolean getHoldResultsOpenOverStatementClose(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getIgnoreNonTxTables() { - return this.ignoreNonTxTables.getValueAsBoolean(); - } + public abstract boolean getIgnoreNonTxTables(); /** * DOCUMENT ME! - * + * * @return */ - public int getInitialTimeout() { - return this.initialTimeout.getValueAsInt(); - } + public abstract int getInitialTimeout(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getInteractiveClient() { - return this.isInteractiveClient.getValueAsBoolean(); - } + public abstract boolean getInteractiveClient(); /** * DOCUMENT ME! - * + * * @return Returns the isInteractiveClient. */ - public boolean getIsInteractiveClient() { - return this.isInteractiveClient.getValueAsBoolean(); - } + public abstract boolean getIsInteractiveClient(); /** * DOCUMENT ME! - * + * * @return Returns the jdbcCompliantTruncation. */ - public boolean getJdbcCompliantTruncation() { - return this.jdbcCompliantTruncation.getValueAsBoolean(); - } + public abstract boolean getJdbcCompliantTruncation(); /** * @return Returns the dontTrackOpenResources. */ - public int getLocatorFetchBufferSize() { - return this.locatorFetchBufferSize.getValueAsInt(); - } + public abstract int getLocatorFetchBufferSize(); /** * DOCUMENT ME! - * + * * @return */ - public String getLogger() { - return this.loggerClassName.getValueAsString(); - } + public abstract String getLogger(); /** * DOCUMENT ME! - * + * * @return Returns the loggerClassName. */ - public String getLoggerClassName() { - return this.loggerClassName.getValueAsString(); - } + public abstract String getLoggerClassName(); /** * DOCUMENT ME! - * + * * @return Returns the logSlowQueries. */ - public boolean getLogSlowQueries() { - return this.logSlowQueries.getValueAsBoolean(); - } + public abstract boolean getLogSlowQueries(); - public boolean getMaintainTimeStats() { - return maintainTimeStatsAsBoolean; - } + public abstract boolean getMaintainTimeStats(); /** * DOCUMENT ME! - * + * * @return Returns the maxQuerySizeToLog. */ - public int getMaxQuerySizeToLog() { - return this.maxQuerySizeToLog.getValueAsInt(); - } + public abstract int getMaxQuerySizeToLog(); /** * DOCUMENT ME! - * + * * @return */ - public int getMaxReconnects() { - return this.maxReconnects.getValueAsInt(); - } + public abstract int getMaxReconnects(); /** * DOCUMENT ME! - * + * * @return */ - public int getMaxRows() { - return this.maxRowsAsInt; - } + public abstract int getMaxRows(); /** * Returns the number of queries that metadata can be cached if caching is * enabled. - * + * * @return the number of queries to cache metadata for. */ - public int getMetadataCacheSize() { - return this.metadataCacheSize.getValueAsInt(); - } + public abstract int getMetadataCacheSize(); /** * @return Returns the noDatetimeStringSync. */ - public boolean getNoDatetimeStringSync() { - return this.noDatetimeStringSync.getValueAsBoolean(); - } + public abstract boolean getNoDatetimeStringSync(); - public boolean getNullCatalogMeansCurrent() { - return this.nullCatalogMeansCurrent.getValueAsBoolean(); - } + public abstract boolean getNullCatalogMeansCurrent(); - public boolean getNullNamePatternMatchesAll() { - return this.nullNamePatternMatchesAll.getValueAsBoolean(); - } + public abstract boolean getNullNamePatternMatchesAll(); /** * DOCUMENT ME! - * + * * @return Returns the packetDebugBufferSize. */ - public int getPacketDebugBufferSize() { - return this.packetDebugBufferSize.getValueAsInt(); - } + public abstract int getPacketDebugBufferSize(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getParanoid() { - return this.paranoid.getValueAsBoolean(); - } + public abstract boolean getParanoid(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getPedantic() { - return this.pedantic.getValueAsBoolean(); - } + public abstract boolean getPedantic(); /** * DOCUMENT ME! - * + * * @return Returns the preparedStatementCacheSize. */ - public int getPreparedStatementCacheSize() { - return ((Integer) this.preparedStatementCacheSize.getValueAsObject()) - .intValue(); - } + public abstract int getPreparedStatementCacheSize(); /** * DOCUMENT ME! - * + * * @return Returns the preparedStatementCacheSqlLimit. */ - public int getPreparedStatementCacheSqlLimit() { - return ((Integer) this.preparedStatementCacheSqlLimit - .getValueAsObject()).intValue(); - } + public abstract int getPreparedStatementCacheSqlLimit(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getProfileSql() { - return this.profileSQLAsBoolean; - } + public abstract boolean getProfileSql(); /** * DOCUMENT ME! - * + * * @return Returns the profileSQL flag */ - public boolean getProfileSQL() { - return this.profileSQL.getValueAsBoolean(); - } + public abstract boolean getProfileSQL(); /** * @return Returns the propertiesTransform. */ - public String getPropertiesTransform() { - return this.propertiesTransform.getValueAsString(); - } + public abstract String getPropertiesTransform(); /** * DOCUMENT ME! - * + * * @return */ - public int getQueriesBeforeRetryMaster() { - return this.queriesBeforeRetryMaster.getValueAsInt(); - } + public abstract int getQueriesBeforeRetryMaster(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getReconnectAtTxEnd() { - return this.reconnectTxAtEndAsBoolean; - } + public abstract boolean getReconnectAtTxEnd(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getRelaxAutoCommit() { - return this.relaxAutoCommit.getValueAsBoolean(); - } + public abstract boolean getRelaxAutoCommit(); /** * DOCUMENT ME! - * + * * @return Returns the reportMetricsIntervalMillis. */ - public int getReportMetricsIntervalMillis() { - return this.reportMetricsIntervalMillis.getValueAsInt(); - } + public abstract int getReportMetricsIntervalMillis(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getRequireSSL() { - return this.requireSSL.getValueAsBoolean(); - } + public abstract boolean getRequireSSL(); - public boolean getRetainStatementAfterResultSetClose() { - return this.retainStatementAfterResultSetClose.getValueAsBoolean(); - } - /** * @return Returns the rollbackOnPooledClose. */ - public boolean getRollbackOnPooledClose() { - return this.rollbackOnPooledClose.getValueAsBoolean(); - } + public abstract boolean getRollbackOnPooledClose(); /** * Returns whether or not hosts will be picked in a round-robin fashion. - * + * * @return Returns the roundRobinLoadBalance property. */ - public boolean getRoundRobinLoadBalance() { - return this.roundRobinLoadBalance.getValueAsBoolean(); - } + public abstract boolean getRoundRobinLoadBalance(); /** * @return Returns the runningCTS13. */ - public boolean getRunningCTS13() { - return this.runningCTS13.getValueAsBoolean(); - } + public abstract boolean getRunningCTS13(); /** * DOCUMENT ME! - * + * * @return */ - public int getSecondsBeforeRetryMaster() { - return this.secondsBeforeRetryMaster.getValueAsInt(); - } + public abstract int getSecondsBeforeRetryMaster(); /** * Returns the 'serverTimezone' property. - * + * * @return the configured server timezone property. */ - public String getServerTimezone() { - return this.serverTimezone.getValueAsString(); - } + public abstract String getServerTimezone(); /** * @return Returns the sessionVariables. */ - public String getSessionVariables() { - return sessionVariables.getValueAsString(); - } + public abstract String getSessionVariables(); /** * DOCUMENT ME! - * + * * @return Returns the slowQueryThresholdMillis. */ - public int getSlowQueryThresholdMillis() { - return this.slowQueryThresholdMillis.getValueAsInt(); - } + public abstract int getSlowQueryThresholdMillis(); /** * DOCUMENT ME! - * + * * @return */ - public String getSocketFactoryClassName() { - return this.socketFactoryClassName.getValueAsString(); - } + public abstract String getSocketFactoryClassName(); /** * DOCUMENT ME! - * + * * @return */ - public int getSocketTimeout() { - return this.socketTimeout.getValueAsInt(); - } + public abstract int getSocketTimeout(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getStrictFloatingPoint() { - return this.strictFloatingPoint.getValueAsBoolean(); - } + public abstract boolean getStrictFloatingPoint(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getStrictUpdates() { - return this.strictUpdates.getValueAsBoolean(); - } + public abstract boolean getStrictUpdates(); /** * @return Returns the tinyInt1isBit. */ - public boolean getTinyInt1isBit() { - return this.tinyInt1isBit.getValueAsBoolean(); - } + public abstract boolean getTinyInt1isBit(); /** * DOCUMENT ME! - * + * * @return Returns the logProtocol. */ - public boolean getTraceProtocol() { - return this.traceProtocol.getValueAsBoolean(); - } + public abstract boolean getTraceProtocol(); - public boolean getTransformedBitIsBoolean() { - return this.transformedBitIsBoolean.getValueAsBoolean(); - } + public abstract boolean getTransformedBitIsBoolean(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getUseCompression() { - return this.useCompression.getValueAsBoolean(); - } + public abstract boolean getUseCompression(); /** * @return Returns the useFastIntParsing. */ - public boolean getUseFastIntParsing() { - return this.useFastIntParsing.getValueAsBoolean(); - } + public abstract boolean getUseFastIntParsing(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getUseHostsInPrivileges() { - return this.useHostsInPrivileges.getValueAsBoolean(); - } + public abstract boolean getUseHostsInPrivileges(); - public boolean getUseInformationSchema() { - return this.useInformationSchema.getValueAsBoolean(); - } + public abstract boolean getUseInformationSchema(); /** * @return Returns the useLocalSessionState. */ - public boolean getUseLocalSessionState() { - return this.useLocalSessionState.getValueAsBoolean(); - } + public abstract boolean getUseLocalSessionState(); /** * @return Returns the useOldUTF8Behavior. */ - public boolean getUseOldUTF8Behavior() { - return this.useOldUTF8BehaviorAsBoolean; - } + public abstract boolean getUseOldUTF8Behavior(); /** * @return Returns the useOnlyServerErrorMessages. */ - public boolean getUseOnlyServerErrorMessages() { - return this.useOnlyServerErrorMessages.getValueAsBoolean(); - } + public abstract boolean getUseOnlyServerErrorMessages(); /** * @return Returns the useReadAheadInput. */ - public boolean getUseReadAheadInput() { - return this.useReadAheadInput.getValueAsBoolean(); - } + public abstract boolean getUseReadAheadInput(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getUseServerPreparedStmts() { - return this.detectServerPreparedStmts.getValueAsBoolean(); - } + public abstract boolean getUseServerPreparedStmts(); /** * DOCUMENT ME! - * + * * @return Returns the useSqlStateCodes state. */ - public boolean getUseSqlStateCodes() { - return this.useSqlStateCodes.getValueAsBoolean(); - } + public abstract boolean getUseSqlStateCodes(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getUseSSL() { - return this.useSSL.getValueAsBoolean(); - } + public abstract boolean getUseSSL(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getUseStreamLengthsInPrepStmts() { - return this.useStreamLengthsInPrepStmts.getValueAsBoolean(); - } + public abstract boolean getUseStreamLengthsInPrepStmts(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getUseTimezone() { - return this.useTimezone.getValueAsBoolean(); - } + public abstract boolean getUseTimezone(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getUseUltraDevWorkAround() { - return this.useUltraDevWorkAround.getValueAsBoolean(); - } + public abstract boolean getUseUltraDevWorkAround(); /** * DOCUMENT ME! - * + * * @return Returns the useUnbufferedInput. */ - public boolean getUseUnbufferedInput() { - return this.useUnbufferedInput.getValueAsBoolean(); - } + public abstract boolean getUseUnbufferedInput(); /** * DOCUMENT ME! - * + * * @return */ - public boolean getUseUnicode() { - return this.useUnicodeAsBoolean; - } + public abstract boolean getUseUnicode(); /** * Returns whether or not the driver advises of proper usage. - * + * * @return the value of useUsageAdvisor */ - public boolean getUseUsageAdvisor() { - return this.useUsageAdvisorAsBoolean; - } + public abstract boolean getUseUsageAdvisor(); - public boolean getYearIsDateType() { - return this.yearIsDateType.getValueAsBoolean(); - } + public abstract boolean getYearIsDateType(); /** * @return Returns the zeroDateTimeBehavior. */ - public String getZeroDateTimeBehavior() { - return this.zeroDateTimeBehavior.getValueAsString(); - } + public abstract String getZeroDateTimeBehavior(); /** - * Initializes driver properties that come from a JNDI reference (in the - * case of a javax.sql.DataSource bound into some name service that doesn't - * handle Java objects directly). - * - * @param ref - * The JNDI Reference that holds RefAddrs for all properties - * @throws SQLException - * DOCUMENT ME! - */ - protected void initializeFromRef(Reference ref) throws SQLException { - int numPropertiesToSet = PROPERTY_LIST.size(); - - for (int i = 0; i < numPropertiesToSet; i++) { - java.lang.reflect.Field propertyField = (java.lang.reflect.Field) PROPERTY_LIST - .get(i); - - try { - ConnectionProperty propToSet = (ConnectionProperty) propertyField - .get(this); - - if (ref != null) { - propToSet.initializeFrom(ref); - } - } catch (IllegalAccessException iae) { - throw SQLError.createSQLException("Internal properties failure", - SQLError.SQL_STATE_GENERAL_ERROR); - } - } - - postInitialization(); - } - - /** - * Initializes driver properties that come from URL or properties passed to - * the driver manager. - * - * @param info - * DOCUMENT ME! - * @throws SQLException - * DOCUMENT ME! - */ - protected void initializeProperties(Properties info) throws SQLException { - if (info != null) { - // For backwards-compatibility - String profileSqlLc = info.getProperty("profileSql"); - - if (profileSqlLc != null) { - info.put("profileSQL", profileSqlLc); - } - - Properties infoCopy = (Properties) info.clone(); - - infoCopy.remove(NonRegisteringDriver.HOST_PROPERTY_KEY); - infoCopy.remove(NonRegisteringDriver.USER_PROPERTY_KEY); - infoCopy.remove(NonRegisteringDriver.PASSWORD_PROPERTY_KEY); - infoCopy.remove(NonRegisteringDriver.DBNAME_PROPERTY_KEY); - infoCopy.remove(NonRegisteringDriver.PORT_PROPERTY_KEY); - infoCopy.remove("profileSql"); - - int numPropertiesToSet = PROPERTY_LIST.size(); - - for (int i = 0; i < numPropertiesToSet; i++) { - java.lang.reflect.Field propertyField = (java.lang.reflect.Field) PROPERTY_LIST - .get(i); - - try { - ConnectionProperty propToSet = (ConnectionProperty) propertyField - .get(this); - - propToSet.initializeFrom(infoCopy); - } catch (IllegalAccessException iae) { - throw SQLError.createSQLException( - "Unable to initialize driver properties due to " - + iae.toString(), - SQLError.SQL_STATE_GENERAL_ERROR); - } - } - - // TODO -- Not yet - /* - * int numUnknownProperties = infoCopy.size(); if - * (numUnknownProperties > 0) { StringBuffer errorMessageBuf = new - * StringBuffer( "Unknown connection "); - * errorMessageBuf.append((numUnknownProperties == 1) ? "property " : - * "properties "); Iterator propNamesItor = - * infoCopy.keySet().iterator(); errorMessageBuf.append("'"); - * errorMessageBuf.append(propNamesItor.next().toString()); - * errorMessageBuf.append("'"); while (propNamesItor.hasNext()) { - * errorMessageBuf.append(", '"); - * errorMessageBuf.append(propNamesItor.next().toString()); - * errorMessageBuf.append("'"); } throw new - * SQLException(errorMessageBuf.toString(), - * SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); } - */ - postInitialization(); - } - } - - protected void postInitialization() throws SQLException { - - // Support 'old' profileSql capitalization - if (this.profileSql.getValueAsObject() != null) { - this.profileSQL.initializeFrom(this.profileSql.getValueAsObject() - .toString()); - } - - this.reconnectTxAtEndAsBoolean = ((Boolean) this.reconnectAtTxEnd - .getValueAsObject()).booleanValue(); - - // Adjust max rows - if (this.getMaxRows() == 0) { - // adjust so that it will become MysqlDefs.MAX_ROWS - // in execSQL() - this.maxRows.setValueAsObject(new Integer(-1)); - } - - // - // Check character encoding - // - String testEncoding = this.getEncoding(); - - if (testEncoding != null) { - // Attempt to use the encoding, and bail out if it - // can't be used - try { - String testString = "abc"; - testString.getBytes(testEncoding); - } catch (UnsupportedEncodingException UE) { - throw SQLError.createSQLException("Unsupported character " + "encoding '" - + testEncoding + "'.", "0S100"); - } - } - - // Metadata caching is only supported on JDK-1.4 and newer - // because it relies on LinkedHashMap being present. - // Check (and disable) if not supported - if (((Boolean) this.cacheResultSetMetadata.getValueAsObject()) - .booleanValue()) { - try { - Class.forName("java.util.LinkedHashMap"); - } catch (ClassNotFoundException cnfe) { - this.cacheResultSetMetadata.setValue(false); - } - } - - this.cacheResultSetMetaDataAsBoolean = this.cacheResultSetMetadata - .getValueAsBoolean(); - this.useUnicodeAsBoolean = this.useUnicode.getValueAsBoolean(); - this.characterEncodingAsString = ((String) this.characterEncoding - .getValueAsObject()); - this.highAvailabilityAsBoolean = this.autoReconnect.getValueAsBoolean(); - this.autoReconnectForPoolsAsBoolean = this.autoReconnectForPools - .getValueAsBoolean(); - this.maxRowsAsInt = ((Integer) this.maxRows.getValueAsObject()) - .intValue(); - this.profileSQLAsBoolean = this.profileSQL.getValueAsBoolean(); - this.useUsageAdvisorAsBoolean = this.useUsageAdvisor - .getValueAsBoolean(); - this.useOldUTF8BehaviorAsBoolean = this.useOldUTF8Behavior - .getValueAsBoolean(); - this.autoGenerateTestcaseScriptAsBoolean = this.autoGenerateTestcaseScript - .getValueAsBoolean(); - this.maintainTimeStatsAsBoolean = this.maintainTimeStats - .getValueAsBoolean(); - this.jdbcCompliantTruncationForReads = getJdbcCompliantTruncation(); - - if (getUseCursorFetch()) { - // assume they want to use server-side prepared statements - // because they're required for this functionality - setDetectServerPreparedStmts(true); - } - } - - /** * DOCUMENT ME! - * + * * @param property */ - public void setAllowLoadLocalInfile(boolean property) { - this.allowLoadLocalInfile.setValue(property); - } + public abstract void setAllowLoadLocalInfile(boolean property); /** * DOCUMENT ME! - * + * * @param property */ - public void setAllowMultiQueries(boolean property) { - this.allowMultiQueries.setValue(property); - } + public abstract void setAllowMultiQueries(boolean property); /** * @param allowNanAndInf * The allowNanAndInf to set. */ - public void setAllowNanAndInf(boolean flag) { - this.allowNanAndInf.setValue(flag); - } + public abstract void setAllowNanAndInf(boolean flag); /** * @param allowUrlInLocalInfile * The allowUrlInLocalInfile to set. */ - public void setAllowUrlInLocalInfile(boolean flag) { - this.allowUrlInLocalInfile.setValue(flag); - } + public abstract void setAllowUrlInLocalInfile(boolean flag); /** * @param alwaysSendSetIsolation * The alwaysSendSetIsolation to set. */ - public void setAlwaysSendSetIsolation(boolean flag) { - this.alwaysSendSetIsolation.setValue(flag); - } + public abstract void setAlwaysSendSetIsolation(boolean flag); /** * @param autoDeserialize * The autoDeserialize to set. */ - public void setAutoDeserialize(boolean flag) { - this.autoDeserialize.setValue(flag); - } + public abstract void setAutoDeserialize(boolean flag); - public void setAutoGenerateTestcaseScript(boolean flag) { - this.autoGenerateTestcaseScript.setValue(flag); - this.autoGenerateTestcaseScriptAsBoolean = this.autoGenerateTestcaseScript - .getValueAsBoolean(); - } + public abstract void setAutoGenerateTestcaseScript(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The autoReconnect to set. */ - public void setAutoReconnect(boolean flag) { - this.autoReconnect.setValue(flag); - } + public abstract void setAutoReconnect(boolean flag); /** * DOCUMENT ME! - * + * * @param property */ - public void setAutoReconnectForConnectionPools(boolean property) { - this.autoReconnectForPools.setValue(property); - this.autoReconnectForPoolsAsBoolean = this.autoReconnectForPools - .getValueAsBoolean(); - } + public abstract void setAutoReconnectForConnectionPools(boolean property); /** * DOCUMENT ME! - * + * * @param flag * The autoReconnectForPools to set. */ - public void setAutoReconnectForPools(boolean flag) { - this.autoReconnectForPools.setValue(flag); - } + public abstract void setAutoReconnectForPools(boolean flag); /** * @param blobSendChunkSize * The blobSendChunkSize to set. */ - public void setBlobSendChunkSize(String value) throws SQLException { - this.blobSendChunkSize.setValue(value); - } + public abstract void setBlobSendChunkSize(String value) throws SQLException; /** * DOCUMENT ME! - * + * * @param flag * The cacheCallableStatements to set. */ - public void setCacheCallableStatements(boolean flag) { - this.cacheCallableStatements.setValue(flag); - } + public abstract void setCacheCallableStatements(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The cachePreparedStatements to set. */ - public void setCachePreparedStatements(boolean flag) { - this.cachePreparedStatements.setValue(flag); - } + public abstract void setCachePreparedStatements(boolean flag); /** * Sets whether or not we should cache result set metadata. - * + * * @param property */ - public void setCacheResultSetMetadata(boolean property) { - this.cacheResultSetMetadata.setValue(property); - this.cacheResultSetMetaDataAsBoolean = this.cacheResultSetMetadata - .getValueAsBoolean(); - } + public abstract void setCacheResultSetMetadata(boolean property); /** * @param cacheServerConfiguration * The cacheServerConfiguration to set. */ - public void setCacheServerConfiguration(boolean flag) { - this.cacheServerConfiguration.setValue(flag); - } + public abstract void setCacheServerConfiguration(boolean flag); /** * Configures the number of callable statements to cache. (this is * configurable during the life of the connection). - * + * * @param size * The callableStatementCacheSize to set. + * @throws SQLException */ - public void setCallableStatementCacheSize(int size) { - this.callableStatementCacheSize.setValue(size); - } + public abstract void setCallableStatementCacheSize(int size) throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setCapitalizeDBMDTypes(boolean property) { - this.capitalizeTypeNames.setValue(property); - } + public abstract void setCapitalizeDBMDTypes(boolean property); /** * DOCUMENT ME! - * + * * @param flag * The capitalizeTypeNames to set. */ - public void setCapitalizeTypeNames(boolean flag) { - this.capitalizeTypeNames.setValue(flag); - } + public abstract void setCapitalizeTypeNames(boolean flag); /** * DOCUMENT ME! - * + * * @param encoding * The characterEncoding to set. */ - public void setCharacterEncoding(String encoding) { - this.characterEncoding.setValue(encoding); - } + public abstract void setCharacterEncoding(String encoding); /** * DOCUMENT ME! - * + * * @param characterSet * The characterSetResults to set. */ - public void setCharacterSetResults(String characterSet) { - this.characterSetResults.setValue(characterSet); - } + public abstract void setCharacterSetResults(String characterSet); /** * DOCUMENT ME! - * + * * @param flag * The clobberStreamingResults to set. */ - public void setClobberStreamingResults(boolean flag) { - this.clobberStreamingResults.setValue(flag); - } + public abstract void setClobberStreamingResults(boolean flag); - public void setClobCharacterEncoding(String encoding) { - this.clobCharacterEncoding.setValue(encoding); - } + public abstract void setClobCharacterEncoding(String encoding); /** * DOCUMENT ME! - * + * * @param collation * The connectionCollation to set. */ - public void setConnectionCollation(String collation) { - this.connectionCollation.setValue(collation); - } + public abstract void setConnectionCollation(String collation); /** * DOCUMENT ME! - * + * * @param timeoutMs + * @throws SQLException */ - public void setConnectTimeout(int timeoutMs) { - this.connectTimeout.setValue(timeoutMs); - } + public abstract void setConnectTimeout(int timeoutMs) throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setContinueBatchOnError(boolean property) { - this.continueBatchOnError.setValue(property); - } + public abstract void setContinueBatchOnError(boolean property); - public void setCreateDatabaseIfNotExist(boolean flag) { - this.createDatabaseIfNotExist.setValue(flag); - } + public abstract void setCreateDatabaseIfNotExist(boolean flag); - public void setDefaultFetchSize(int n) { - this.defaultFetchSize.setValue(n); - } + public abstract void setDefaultFetchSize(int n) throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setDetectServerPreparedStmts(boolean property) { - this.detectServerPreparedStmts.setValue(property); - } + public abstract void setDetectServerPreparedStmts(boolean property); /** * @param dontTrackOpenResources * The dontTrackOpenResources to set. */ - public void setDontTrackOpenResources(boolean flag) { - this.dontTrackOpenResources.setValue(flag); - } + public abstract void setDontTrackOpenResources(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The dumpQueriesOnException to set. */ - public void setDumpQueriesOnException(boolean flag) { - this.dumpQueriesOnException.setValue(flag); - } + public abstract void setDumpQueriesOnException(boolean flag); /** * @param dynamicCalendars * The dynamicCalendars to set. */ - public void setDynamicCalendars(boolean flag) { - this.dynamicCalendars.setValue(flag); - } + public abstract void setDynamicCalendars(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The elideSetAutoCommits to set. */ - public void setElideSetAutoCommits(boolean flag) { - this.elideSetAutoCommits.setValue(flag); - } + public abstract void setElideSetAutoCommits(boolean flag); - public void setEmptyStringsConvertToZero(boolean flag) { - this.emptyStringsConvertToZero.setValue(flag); - } + public abstract void setEmptyStringsConvertToZero(boolean flag); /** * DOCUMENT ME! - * + * * @param property */ - public void setEmulateLocators(boolean property) { - this.emulateLocators.setValue(property); - } + public abstract void setEmulateLocators(boolean property); /** * @param emulateUnsupportedPstmts * The emulateUnsupportedPstmts to set. */ - public void setEmulateUnsupportedPstmts(boolean flag) { - this.emulateUnsupportedPstmts.setValue(flag); - } + public abstract void setEmulateUnsupportedPstmts(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The enablePacketDebug to set. */ - public void setEnablePacketDebug(boolean flag) { - this.enablePacketDebug.setValue(flag); - } + public abstract void setEnablePacketDebug(boolean flag); /** * DOCUMENT ME! - * + * * @param property */ - public void setEncoding(String property) { - this.characterEncoding.setValue(property); - this.characterEncodingAsString = this.characterEncoding - .getValueAsString(); - } + public abstract void setEncoding(String property); /** * DOCUMENT ME! - * + * * @param flag * The explainSlowQueries to set. */ - public void setExplainSlowQueries(boolean flag) { - this.explainSlowQueries.setValue(flag); - } + public abstract void setExplainSlowQueries(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The failOverReadOnly to set. */ - public void setFailOverReadOnly(boolean flag) { - this.failOverReadOnly.setValue(flag); - } + public abstract void setFailOverReadOnly(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The gatherPerformanceMetrics to set. */ - public void setGatherPerformanceMetrics(boolean flag) { - this.gatherPerformanceMetrics.setValue(flag); - } + public abstract void setGatherPerformanceMetrics(boolean flag); /** - * DOCUMENT ME! - * - * @param property - */ - protected void setHighAvailability(boolean property) { - this.autoReconnect.setValue(property); - this.highAvailabilityAsBoolean = this.autoReconnect.getValueAsBoolean(); - } - - /** * @param holdResultsOpenOverStatementClose * The holdResultsOpenOverStatementClose to set. */ - public void setHoldResultsOpenOverStatementClose(boolean flag) { - this.holdResultsOpenOverStatementClose.setValue(flag); - } + public abstract void setHoldResultsOpenOverStatementClose(boolean flag); /** * DOCUMENT ME! - * + * * @param property */ - public void setIgnoreNonTxTables(boolean property) { - this.ignoreNonTxTables.setValue(property); - } + public abstract void setIgnoreNonTxTables(boolean property); /** * DOCUMENT ME! - * + * * @param property + * @throws SQLException */ - public void setInitialTimeout(int property) { - this.initialTimeout.setValue(property); - } + public abstract void setInitialTimeout(int property) throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setIsInteractiveClient(boolean property) { - this.isInteractiveClient.setValue(property); - } + public abstract void setIsInteractiveClient(boolean property); /** * DOCUMENT ME! - * + * * @param flag * The jdbcCompliantTruncation to set. */ - public void setJdbcCompliantTruncation(boolean flag) { - this.jdbcCompliantTruncation.setValue(flag); - } + public abstract void setJdbcCompliantTruncation(boolean flag); /** * @param locatorFetchBufferSize * The locatorFetchBufferSize to set. */ - public void setLocatorFetchBufferSize(String value) throws SQLException { - this.locatorFetchBufferSize.setValue(value); - } + public abstract void setLocatorFetchBufferSize(String value) + throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setLogger(String property) { - this.loggerClassName.setValueAsObject(property); - } + public abstract void setLogger(String property); /** * DOCUMENT ME! - * + * * @param className * The loggerClassName to set. */ - public void setLoggerClassName(String className) { - this.loggerClassName.setValue(className); - } + public abstract void setLoggerClassName(String className); /** * DOCUMENT ME! - * + * * @param flag * The logSlowQueries to set. */ - public void setLogSlowQueries(boolean flag) { - this.logSlowQueries.setValue(flag); - } + public abstract void setLogSlowQueries(boolean flag); - public void setMaintainTimeStats(boolean flag) { - this.maintainTimeStats.setValue(flag); - this.maintainTimeStatsAsBoolean = this.maintainTimeStats - .getValueAsBoolean(); - } + public abstract void setMaintainTimeStats(boolean flag); /** * DOCUMENT ME! - * + * * @param sizeInBytes * The maxQuerySizeToLog to set. + * @throws SQLException */ - public void setMaxQuerySizeToLog(int sizeInBytes) { - this.maxQuerySizeToLog.setValue(sizeInBytes); - } + public abstract void setMaxQuerySizeToLog(int sizeInBytes) throws SQLException; /** * DOCUMENT ME! - * + * * @param property + * @throws SQLException */ - public void setMaxReconnects(int property) { - this.maxReconnects.setValue(property); - } + public abstract void setMaxReconnects(int property) throws SQLException; /** * DOCUMENT ME! - * + * * @param property + * @throws SQLException */ - public void setMaxRows(int property) { - this.maxRows.setValue(property); - this.maxRowsAsInt = this.maxRows.getValueAsInt(); - } + public abstract void setMaxRows(int property) throws SQLException; /** * Sets the number of queries that metadata can be cached if caching is * enabled. - * + * * @param value * the number of queries to cache metadata for. + * @throws SQLException */ - public void setMetadataCacheSize(int value) { - this.metadataCacheSize.setValue(value); - } + public abstract void setMetadataCacheSize(int value) throws SQLException; /** * @param noDatetimeStringSync * The noDatetimeStringSync to set. */ - public void setNoDatetimeStringSync(boolean flag) { - this.noDatetimeStringSync.setValue(flag); - } + public abstract void setNoDatetimeStringSync(boolean flag); - public void setNullCatalogMeansCurrent(boolean value) { - this.nullCatalogMeansCurrent.setValue(value); - } + public abstract void setNullCatalogMeansCurrent(boolean value); - public void setNullNamePatternMatchesAll(boolean value) { - this.nullNamePatternMatchesAll.setValue(value); - } + public abstract void setNullNamePatternMatchesAll(boolean value); /** * DOCUMENT ME! - * + * * @param size * The packetDebugBufferSize to set. + * @throws SQLException */ - public void setPacketDebugBufferSize(int size) { - this.packetDebugBufferSize.setValue(size); - } + public abstract void setPacketDebugBufferSize(int size) throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setParanoid(boolean property) { - this.paranoid.setValue(property); - } + public abstract void setParanoid(boolean property); /** * DOCUMENT ME! - * + * * @param property */ - public void setPedantic(boolean property) { - this.pedantic.setValue(property); - } + public abstract void setPedantic(boolean property); /** * DOCUMENT ME! - * + * * @param cacheSize * The preparedStatementCacheSize to set. + * @throws SQLException */ - public void setPreparedStatementCacheSize(int cacheSize) { - this.preparedStatementCacheSize.setValue(cacheSize); - } + public abstract void setPreparedStatementCacheSize(int cacheSize) throws SQLException; /** * DOCUMENT ME! - * + * * @param cacheSqlLimit * The preparedStatementCacheSqlLimit to set. + * @throws SQLException */ - public void setPreparedStatementCacheSqlLimit(int cacheSqlLimit) { - this.preparedStatementCacheSqlLimit.setValue(cacheSqlLimit); - } + public abstract void setPreparedStatementCacheSqlLimit(int cacheSqlLimit) throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setProfileSql(boolean property) { - this.profileSQL.setValue(property); - this.profileSQLAsBoolean = this.profileSQL.getValueAsBoolean(); - } + public abstract void setProfileSql(boolean property); /** * DOCUMENT ME! - * + * * @param flag * The profileSQL to set. */ - public void setProfileSQL(boolean flag) { - this.profileSQL.setValue(flag); - } + public abstract void setProfileSQL(boolean flag); /** * @param propertiesTransform * The propertiesTransform to set. */ - public void setPropertiesTransform(String value) { - this.propertiesTransform.setValue(value); - } + public abstract void setPropertiesTransform(String value); /** * DOCUMENT ME! - * + * * @param property + * @throws SQLException */ - public void setQueriesBeforeRetryMaster(int property) { - this.queriesBeforeRetryMaster.setValue(property); - } + public abstract void setQueriesBeforeRetryMaster(int property) throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setReconnectAtTxEnd(boolean property) { - this.reconnectAtTxEnd.setValue(property); - this.reconnectTxAtEndAsBoolean = this.reconnectAtTxEnd - .getValueAsBoolean(); - } + public abstract void setReconnectAtTxEnd(boolean property); /** * DOCUMENT ME! - * + * * @param property */ - public void setRelaxAutoCommit(boolean property) { - this.relaxAutoCommit.setValue(property); - } + public abstract void setRelaxAutoCommit(boolean property); /** * DOCUMENT ME! - * + * * @param millis * The reportMetricsIntervalMillis to set. + * @throws SQLException */ - public void setReportMetricsIntervalMillis(int millis) { - this.reportMetricsIntervalMillis.setValue(millis); - } + public abstract void setReportMetricsIntervalMillis(int millis) throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setRequireSSL(boolean property) { - this.requireSSL.setValue(property); - } + public abstract void setRequireSSL(boolean property); - public void setRetainStatementAfterResultSetClose(boolean flag) { - this.retainStatementAfterResultSetClose.setValue(flag); - } + public abstract void setRetainStatementAfterResultSetClose(boolean flag); /** * @param rollbackOnPooledClose * The rollbackOnPooledClose to set. */ - public void setRollbackOnPooledClose(boolean flag) { - this.rollbackOnPooledClose.setValue(flag); - } + public abstract void setRollbackOnPooledClose(boolean flag); /** * Sets whether or not hosts will be picked in a round-robin fashion. - * + * * @param flag * The roundRobinLoadBalance property to set. */ - public void setRoundRobinLoadBalance(boolean flag) { - this.roundRobinLoadBalance.setValue(flag); - } + public abstract void setRoundRobinLoadBalance(boolean flag); /** * @param runningCTS13 * The runningCTS13 to set. */ - public void setRunningCTS13(boolean flag) { - this.runningCTS13.setValue(flag); - } + public abstract void setRunningCTS13(boolean flag); /** * DOCUMENT ME! - * + * * @param property + * @throws SQLException */ - public void setSecondsBeforeRetryMaster(int property) { - this.secondsBeforeRetryMaster.setValue(property); - } + public abstract void setSecondsBeforeRetryMaster(int property) throws SQLException; /** * DOCUMENT ME! - * + * * @param property * DOCUMENT ME! */ - public void setServerTimezone(String property) { - this.serverTimezone.setValue(property); - } + public abstract void setServerTimezone(String property); /** * @param sessionVariables * The sessionVariables to set. */ - public void setSessionVariables(String variables) { - this.sessionVariables.setValue(variables); - } + public abstract void setSessionVariables(String variables); /** * DOCUMENT ME! - * + * * @param millis * The slowQueryThresholdMillis to set. + * @throws SQLException */ - public void setSlowQueryThresholdMillis(int millis) { - this.slowQueryThresholdMillis.setValue(millis); - } + public abstract void setSlowQueryThresholdMillis(int millis) throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setSocketFactoryClassName(String property) { - this.socketFactoryClassName.setValue(property); - } + public abstract void setSocketFactoryClassName(String property); /** * DOCUMENT ME! - * + * * @param property + * @throws SQLException */ - public void setSocketTimeout(int property) { - this.socketTimeout.setValue(property); - } + public abstract void setSocketTimeout(int property) throws SQLException; /** * DOCUMENT ME! - * + * * @param property */ - public void setStrictFloatingPoint(boolean property) { - this.strictFloatingPoint.setValue(property); - } + public abstract void setStrictFloatingPoint(boolean property); /** * DOCUMENT ME! - * + * * @param property */ - public void setStrictUpdates(boolean property) { - this.strictUpdates.setValue(property); - } + public abstract void setStrictUpdates(boolean property); /** * @param tinyInt1isBit * The tinyInt1isBit to set. */ - public void setTinyInt1isBit(boolean flag) { - this.tinyInt1isBit.setValue(flag); - } + public abstract void setTinyInt1isBit(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The logProtocol to set. */ - public void setTraceProtocol(boolean flag) { - this.traceProtocol.setValue(flag); - } + public abstract void setTraceProtocol(boolean flag); - public void setTransformedBitIsBoolean(boolean flag) { - this.transformedBitIsBoolean.setValue(flag); - } + public abstract void setTransformedBitIsBoolean(boolean flag); /** * DOCUMENT ME! - * + * * @param property */ - public void setUseCompression(boolean property) { - this.useCompression.setValue(property); - } + public abstract void setUseCompression(boolean property); /** * @param useFastIntParsing * The useFastIntParsing to set. */ - public void setUseFastIntParsing(boolean flag) { - this.useFastIntParsing.setValue(flag); - } + public abstract void setUseFastIntParsing(boolean flag); /** * DOCUMENT ME! - * + * * @param property */ - public void setUseHostsInPrivileges(boolean property) { - this.useHostsInPrivileges.setValue(property); - } + public abstract void setUseHostsInPrivileges(boolean property); - public void setUseInformationSchema(boolean flag) { - this.useInformationSchema.setValue(flag); - } + public abstract void setUseInformationSchema(boolean flag); /** * @param useLocalSessionState * The useLocalSessionState to set. */ - public void setUseLocalSessionState(boolean flag) { - this.useLocalSessionState.setValue(flag); - } + public abstract void setUseLocalSessionState(boolean flag); /** * @param useOldUTF8Behavior * The useOldUTF8Behavior to set. */ - public void setUseOldUTF8Behavior(boolean flag) { - this.useOldUTF8Behavior.setValue(flag); - this.useOldUTF8BehaviorAsBoolean = this.useOldUTF8Behavior - .getValueAsBoolean(); - } + public abstract void setUseOldUTF8Behavior(boolean flag); /** * @param useOnlyServerErrorMessages * The useOnlyServerErrorMessages to set. */ - public void setUseOnlyServerErrorMessages(boolean flag) { - this.useOnlyServerErrorMessages.setValue(flag); - } + public abstract void setUseOnlyServerErrorMessages(boolean flag); /** * @param useReadAheadInput * The useReadAheadInput to set. */ - public void setUseReadAheadInput(boolean flag) { - this.useReadAheadInput.setValue(flag); - } + public abstract void setUseReadAheadInput(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The detectServerPreparedStmts to set. */ - public void setUseServerPreparedStmts(boolean flag) { - this.detectServerPreparedStmts.setValue(flag); - } + public abstract void setUseServerPreparedStmts(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The useSqlStateCodes to set. */ - public void setUseSqlStateCodes(boolean flag) { - this.useSqlStateCodes.setValue(flag); - } + public abstract void setUseSqlStateCodes(boolean flag); /** * DOCUMENT ME! - * + * * @param property */ - public void setUseSSL(boolean property) { - this.useSSL.setValue(property); - } + public abstract void setUseSSL(boolean property); /** * DOCUMENT ME! - * + * * @param property */ - public void setUseStreamLengthsInPrepStmts(boolean property) { - this.useStreamLengthsInPrepStmts.setValue(property); - } + public abstract void setUseStreamLengthsInPrepStmts(boolean property); /** * DOCUMENT ME! - * + * * @param property */ - public void setUseTimezone(boolean property) { - this.useTimezone.setValue(property); - } + public abstract void setUseTimezone(boolean property); /** * DOCUMENT ME! - * + * * @param property */ - public void setUseUltraDevWorkAround(boolean property) { - this.useUltraDevWorkAround.setValue(property); - } + public abstract void setUseUltraDevWorkAround(boolean property); /** * DOCUMENT ME! - * + * * @param flag * The useUnbufferedInput to set. */ - public void setUseUnbufferedInput(boolean flag) { - this.useUnbufferedInput.setValue(flag); - } + public abstract void setUseUnbufferedInput(boolean flag); /** * DOCUMENT ME! - * + * * @param flag * The useUnicode to set. */ - public void setUseUnicode(boolean flag) { - this.useUnicode.setValue(flag); - this.useUnicodeAsBoolean = this.useUnicode.getValueAsBoolean(); - } + public abstract void setUseUnicode(boolean flag); /** * Sets whether or not the driver advises of proper usage. - * + * * @param useUsageAdvisorFlag * whether or not the driver advises of proper usage. */ - public void setUseUsageAdvisor(boolean useUsageAdvisorFlag) { - this.useUsageAdvisor.setValue(useUsageAdvisorFlag); - this.useUsageAdvisorAsBoolean = this.useUsageAdvisor - .getValueAsBoolean(); - } + public abstract void setUseUsageAdvisor(boolean useUsageAdvisorFlag); - public void setYearIsDateType(boolean flag) { - this.yearIsDateType.setValue(flag); - } + public abstract void setYearIsDateType(boolean flag); /** * @param zeroDateTimeBehavior * The zeroDateTimeBehavior to set. */ - public void setZeroDateTimeBehavior(String behavior) { - this.zeroDateTimeBehavior.setValue(behavior); - } + public abstract void setZeroDateTimeBehavior(String behavior); - protected void storeToRef(Reference ref) throws SQLException { - int numPropertiesToSet = PROPERTY_LIST.size(); - - for (int i = 0; i < numPropertiesToSet; i++) { - java.lang.reflect.Field propertyField = (java.lang.reflect.Field) PROPERTY_LIST - .get(i); - - try { - ConnectionProperty propToStore = (ConnectionProperty) propertyField - .get(this); - - if (ref != null) { - propToStore.storeTo(ref); - } - } catch (IllegalAccessException iae) { - throw SQLError.createSQLException("Huh?"); - } - } - } - /** * DOCUMENT ME! - * + * * @return Returns the useUnbufferedInput. */ - public boolean useUnbufferedInput() { - return this.useUnbufferedInput.getValueAsBoolean(); - } + public abstract boolean useUnbufferedInput(); - public boolean getUseCursorFetch() { - return this.useCursorFetch.getValueAsBoolean(); - } + public abstract boolean getUseCursorFetch(); - public void setUseCursorFetch(boolean flag) { - this.useCursorFetch.setValue(flag); - } + public abstract void setUseCursorFetch(boolean flag); - public boolean getOverrideSupportsIntegrityEnhancementFacility() { - return this.overrideSupportsIntegrityEnhancementFacility.getValueAsBoolean(); - } + public abstract boolean getOverrideSupportsIntegrityEnhancementFacility(); - public void setOverrideSupportsIntegrityEnhancementFacility(boolean flag) { - this.overrideSupportsIntegrityEnhancementFacility.setValue(flag); - } + public abstract void setOverrideSupportsIntegrityEnhancementFacility( + boolean flag); - public boolean getNoTimezoneConversionForTimeType() { - return this.noTimezoneConversionForTimeType.getValueAsBoolean(); - } + public abstract boolean getNoTimezoneConversionForTimeType(); - public void setNoTimezoneConversionForTimeType(boolean flag) { - this.noTimezoneConversionForTimeType.setValue(flag); - } + public abstract void setNoTimezoneConversionForTimeType(boolean flag); - public boolean getUseJDBCCompliantTimezoneShift() { - return this.useJDBCCompliantTimezoneShift.getValueAsBoolean(); - } + public abstract boolean getUseJDBCCompliantTimezoneShift(); - public void setUseJDBCCompliantTimezoneShift(boolean flag) { - this.useJDBCCompliantTimezoneShift.setValue(flag); - } + public abstract void setUseJDBCCompliantTimezoneShift(boolean flag); - public boolean getAutoClosePStmtStreams() { - return this.autoClosePStmtStreams.getValueAsBoolean(); - } + public abstract boolean getAutoClosePStmtStreams(); - public void setAutoClosePStmtStreams(boolean flag) { - this.autoClosePStmtStreams.setValue(flag); - } + public abstract void setAutoClosePStmtStreams(boolean flag); - public boolean getProcessEscapeCodesForPrepStmts() { - return this.processEscapeCodesForPrepStmts.getValueAsBoolean(); - } + public abstract boolean getProcessEscapeCodesForPrepStmts(); - public void setProcessEscapeCodesForPrepStmts(boolean flag) { - this.processEscapeCodesForPrepStmts.setValue(flag); - } + public abstract void setProcessEscapeCodesForPrepStmts(boolean flag); - public boolean getUseGmtMillisForDatetimes() { - return this.useGmtMillisForDatetimes.getValueAsBoolean(); - } + public abstract boolean getUseGmtMillisForDatetimes(); - public void setUseGmtMillisForDatetimes(boolean flag) { - this.useGmtMillisForDatetimes.setValue(flag); - } + public abstract void setUseGmtMillisForDatetimes(boolean flag); - public boolean getDumpMetadataOnColumnNotFound() { - return this.dumpMetadataOnColumnNotFound.getValueAsBoolean(); - } + public abstract boolean getDumpMetadataOnColumnNotFound(); - public void setDumpMetadataOnColumnNotFound(boolean flag) { - this.dumpMetadataOnColumnNotFound.setValue(flag); - } + public abstract void setDumpMetadataOnColumnNotFound(boolean flag); - public String getResourceId() { - return this.resourceId.getValueAsString(); - } + public abstract String getResourceId(); - public void setResourceId(String resourceId) { - this.resourceId.setValue(resourceId); - } + public abstract void setResourceId(String resourceId); - public boolean getRewriteBatchedStatements() { - return this.rewriteBatchedStatements.getValueAsBoolean(); - } + public abstract boolean getRewriteBatchedStatements(); - public void setRewriteBatchedStatements(boolean flag) { - this.rewriteBatchedStatements.setValue(flag); - } + public abstract void setRewriteBatchedStatements(boolean flag); - public boolean getJdbcCompliantTruncationForReads() { - return this.jdbcCompliantTruncationForReads; - } + public abstract boolean getJdbcCompliantTruncationForReads(); - public void setJdbcCompliantTruncationForReads( - boolean jdbcCompliantTruncationForReads) { - this.jdbcCompliantTruncationForReads = jdbcCompliantTruncationForReads; - } + public abstract void setJdbcCompliantTruncationForReads( + boolean jdbcCompliantTruncationForReads); - public boolean getUseJvmCharsetConverters() { - return this.useJvmCharsetConverters.getValueAsBoolean(); - } + public abstract boolean getUseJvmCharsetConverters(); - public void setUseJvmCharsetConverters(boolean flag) { - this.useJvmCharsetConverters.setValue(flag); - } + public abstract void setUseJvmCharsetConverters(boolean flag); - public boolean getPinGlobalTxToPhysicalConnection() { - return this.pinGlobalTxToPhysicalConnection.getValueAsBoolean(); - } + public abstract boolean getPinGlobalTxToPhysicalConnection(); - public void setPinGlobalTxToPhysicalConnection(boolean flag) { - this.pinGlobalTxToPhysicalConnection.setValue(flag); - } + public abstract void setPinGlobalTxToPhysicalConnection(boolean flag); - /* - * "Aliases" which match the property names to make using - * from datasources easier. - */ + public abstract void setGatherPerfMetrics(boolean flag); - public void setGatherPerfMetrics(boolean flag) { - setGatherPerformanceMetrics(flag); - } + public abstract boolean getGatherPerfMetrics(); - public boolean getGatherPerfMetrics() { - return getGatherPerformanceMetrics(); - } + public abstract void setUltraDevHack(boolean flag); - public void setUltraDevHack(boolean flag) { - setUseUltraDevWorkAround(flag); - } + public abstract boolean getUltraDevHack(); - public boolean getUltraDevHack() { - return getUseUltraDevWorkAround(); - } + public abstract void setInteractiveClient(boolean property); - public void setInteractiveClient(boolean property) { - setIsInteractiveClient(property); - } + public abstract void setSocketFactory(String name); - public void setSocketFactory(String name) { - setSocketFactoryClassName(name); - } + public abstract String getSocketFactory(); - public String getSocketFactory() { - return getSocketFactoryClassName(); - } + public abstract void setUseServerPrepStmts(boolean flag); - public void setUseServerPrepStmts(boolean flag) { - setUseServerPreparedStmts(flag); - } + public abstract boolean getUseServerPrepStmts(); - public boolean getUseServerPrepStmts() { - return getUseServerPreparedStmts(); - } + public abstract void setCacheCallableStmts(boolean flag); - public void setCacheCallableStmts(boolean flag) { - setCacheCallableStatements(flag); - } + public abstract boolean getCacheCallableStmts(); - public boolean getCacheCallableStmts() { - return getCacheCallableStatements(); - } + public abstract void setCachePrepStmts(boolean flag); - public void setCachePrepStmts(boolean flag) { - setCachePreparedStatements(flag); - } + public abstract boolean getCachePrepStmts(); - public boolean getCachePrepStmts() { - return getCachePreparedStatements(); - } + public abstract void setCallableStmtCacheSize(int cacheSize) throws SQLException; - public void setCallableStmtCacheSize(int cacheSize) { - setCallableStatementCacheSize(cacheSize); - } + public abstract int getCallableStmtCacheSize(); - public int getCallableStmtCacheSize() { - return getCallableStatementCacheSize(); - } + public abstract void setPrepStmtCacheSize(int cacheSize) throws SQLException; - public void setPrepStmtCacheSize(int cacheSize) { - setPreparedStatementCacheSize(cacheSize); - } + public abstract int getPrepStmtCacheSize(); - public int getPrepStmtCacheSize() { - return getPreparedStatementCacheSize(); - } + public abstract void setPrepStmtCacheSqlLimit(int sqlLimit) throws SQLException; - public void setPrepStmtCacheSqlLimit(int sqlLimit) { - setPreparedStatementCacheSqlLimit(sqlLimit); - } + public abstract int getPrepStmtCacheSqlLimit(); - public int getPrepStmtCacheSqlLimit() { - return getPreparedStatementCacheSqlLimit(); - } + public abstract boolean getNoAccessToProcedureBodies(); - public boolean getNoAccessToProcedureBodies() { - return this.noAccessToProcedureBodies.getValueAsBoolean(); - } + public abstract void setNoAccessToProcedureBodies(boolean flag); - public void setNoAccessToProcedureBodies(boolean flag) { - this.noAccessToProcedureBodies.setValue(flag); - } + public abstract boolean getUseOldAliasMetadataBehavior(); - public boolean getUseOldAliasMetadataBehavior() { - return this.useOldAliasMetadataBehavior.getValueAsBoolean(); - } + public abstract void setUseOldAliasMetadataBehavior(boolean flag); - public void setUseOldAliasMetadataBehavior(boolean flag) { - this.useOldAliasMetadataBehavior.setValue(flag); - } + public abstract String getClientCertificateKeyStorePassword(); - public boolean getUseSSPSCompatibleTimezoneShift() { - return this.useSSPSCompatibleTimezoneShift.getValueAsBoolean(); - } + public abstract void setClientCertificateKeyStorePassword(String value); - public void setUseSSPSCompatibleTimezoneShift(boolean flag) { - this.useSSPSCompatibleTimezoneShift.setValue(flag); - } + public abstract String getClientCertificateKeyStoreType(); - public boolean getTreatUtilDateAsTimestamp() { - return this.treatUtilDateAsTimestamp.getValueAsBoolean(); - } + public abstract void setClientCertificateKeyStoreType(String value); - public void setTreatUtilDateAsTimestamp(boolean flag) { - this.treatUtilDateAsTimestamp.setValue(flag); - } + public abstract String getClientCertificateKeyStoreUrl(); - public boolean getUseFastDateParsing() { - return this.useFastDateParsing.getValueAsBoolean(); - } + public abstract void setClientCertificateKeyStoreUrl(String value); - public void setUseFastDateParsing(boolean flag) { - this.useFastDateParsing.setValue(flag); - } + public abstract String getTrustCertificateKeyStorePassword(); - public String getLocalSocketAddress() { - return this.localSocketAddress.getValueAsString(); - } + public abstract void setTrustCertificateKeyStorePassword(String value); - public void setLocalSocketAddress(String address) { - this.localSocketAddress.setValue(address); - } + public abstract String getTrustCertificateKeyStoreType(); - public void setUseConfigs(String configs) { - this.useConfigs.setValue(configs); - } + public abstract void setTrustCertificateKeyStoreType(String value); - public String getUseConfigs() { - return this.useConfigs.getValueAsString(); - } + public abstract String getTrustCertificateKeyStoreUrl(); - public boolean getGenerateSimpleParameterMetadata() { - return this.generateSimpleParameterMetadata.getValueAsBoolean(); - } + public abstract void setTrustCertificateKeyStoreUrl(String value); - public void setGenerateSimpleParameterMetadata(boolean flag) { - this.generateSimpleParameterMetadata.setValue(flag); - } + public abstract boolean getUseSSPSCompatibleTimezoneShift(); - public boolean getLogXaCommands() { - return this.logXaCommands.getValueAsBoolean(); - } + public abstract void setUseSSPSCompatibleTimezoneShift(boolean flag); - public void setLogXaCommands(boolean flag) { - this.logXaCommands.setValue(flag); - } + public abstract boolean getTreatUtilDateAsTimestamp(); - public int getResultSetSizeThreshold() { - return this.resultSetSizeThreshold.getValueAsInt(); - } + public abstract void setTreatUtilDateAsTimestamp(boolean flag); - public void setResultSetSizeThreshold(int threshold) { - this.resultSetSizeThreshold.setValue(threshold); - } + public abstract boolean getUseFastDateParsing(); - public boolean getEnableQueryTimeouts() { - return this.enableQueryTimeouts.getValueAsBoolean(); - } + public abstract void setUseFastDateParsing(boolean flag); - public void setEnableQueryTimeouts(boolean flag) { - this.enableQueryTimeouts.setValue(flag); - } + public abstract String getLocalSocketAddress(); - public boolean getPadCharsWithSpace() { - return this.padCharsWithSpace.getValueAsBoolean(); - } + public abstract void setLocalSocketAddress(String address); - public void setPadCharsWithSpace(boolean flag) { - this.padCharsWithSpace.setValue(flag); - } + public abstract void setUseConfigs(String configs); - public boolean getUseDynamicCharsetInfo() { - return this.useDynamicCharsetInfo.getValueAsBoolean(); - } + public abstract String getUseConfigs(); - public void setUseDynamicCharsetInfo(boolean flag) { - this.useDynamicCharsetInfo.setValue(flag); - } + public abstract boolean getGenerateSimpleParameterMetadata(); - public boolean getPopulateInsertRowWithDefaultValues() { - return this.populateInsertRowWithDefaultValues.getValueAsBoolean(); - } + public abstract void setGenerateSimpleParameterMetadata(boolean flag); - public void setPopulateInsertRowWithDefaultValues(boolean flag) { - this.populateInsertRowWithDefaultValues.setValue(flag); - } + public abstract boolean getLogXaCommands(); - public String getLoadBalanceStrategy() { - return this.loadBalanceStrategy.getValueAsString(); - } + public abstract void setLogXaCommands(boolean flag); - public void setLoadBalanceStrategy(String strategy) { - this.loadBalanceStrategy.setValue(strategy); - } + public abstract int getResultSetSizeThreshold(); - public boolean getUseNanosForElapsedTime() { - return this.useNanosForElapsedTime.getValueAsBoolean(); - } + public abstract void setResultSetSizeThreshold(int threshold) throws SQLException; - public void setUseNanosForElapsedTime(boolean flag) { - this.useNanosForElapsedTime.setValue(flag); - } + public abstract int getNetTimeoutForStreamingResults(); - public long getSlowQueryThresholdNanos() { - return this.slowQueryThresholdNanos.getValueAsLong(); - } + public abstract void setNetTimeoutForStreamingResults(int value) throws SQLException; - public void setSlowQueryThresholdNanos(long nanos) { - this.slowQueryThresholdNanos.setValue(nanos); - } + public abstract boolean getEnableQueryTimeouts(); - public boolean getTcpNoDelay() { - return this.tcpNoDelay.getValueAsBoolean(); - } + public abstract void setEnableQueryTimeouts(boolean flag); - public void setTcpNoDelay(boolean flag) { - this.tcpNoDelay.setValue(flag); - } + public abstract boolean getPadCharsWithSpace(); - public boolean getTcpKeepAlive() { - return this.tcpKeepAlive.getValueAsBoolean(); - } + public abstract void setPadCharsWithSpace(boolean flag); - public void setTcpKeepAlive(boolean flag) { - this.tcpKeepAlive.setValue(flag); - } + public abstract boolean getUseDynamicCharsetInfo(); - public int getTcpRcvBuf() { - return this.tcpRcvBuf.getValueAsInt(); - } + public abstract void setUseDynamicCharsetInfo(boolean flag); - public void setTcpRcvBuf(int bufSize) { - this.tcpRcvBuf.setValue(bufSize); - } + public abstract String getClientInfoProvider(); - public int getTcpSndBuf() { - return this.tcpSndBuf.getValueAsInt(); - } + public abstract void setClientInfoProvider(String classname); + + public abstract boolean getPopulateInsertRowWithDefaultValues(); - public void setTcpSndBuf(int bufSize) { - this.tcpSndBuf.setValue(bufSize); - } + public abstract void setPopulateInsertRowWithDefaultValues(boolean flag); + + public abstract String getLoadBalanceStrategy(); - public int getTcpTrafficClass() { - return this.tcpTrafficClass.getValueAsInt(); - } + public abstract void setLoadBalanceStrategy(String strategy); + + public abstract boolean getTcpNoDelay(); - public void setTcpTrafficClass(int classFlags) { - this.tcpTrafficClass.setValue(classFlags); - } + public abstract void setTcpNoDelay(boolean flag); - public boolean getIncludeInnodbStatusInDeadlockExceptions() { - return this.includeInnodbStatusInDeadlockExceptions.getValueAsBoolean(); - } + public abstract boolean getTcpKeepAlive(); - public void setIncludeInnodbStatusInDeadlockExceptions(boolean flag) { - this.includeInnodbStatusInDeadlockExceptions.setValue(flag); - } + public abstract void setTcpKeepAlive(boolean flag); - public boolean getBlobsAreStrings() { - return this.blobsAreStrings.getValueAsBoolean(); - } + public abstract int getTcpRcvBuf(); - public void setBlobsAreStrings(boolean flag) { - this.blobsAreStrings.setValue(flag); - } + public abstract void setTcpRcvBuf(int bufSize) throws SQLException; - public boolean getFunctionsNeverReturnBlobs() { - return this.functionsNeverReturnBlobs.getValueAsBoolean(); - } + public abstract int getTcpSndBuf(); + + public abstract void setTcpSndBuf(int bufSize) throws SQLException; - public void setFunctionsNeverReturnBlobs(boolean flag) { - this.functionsNeverReturnBlobs.setValue(flag); - } + public abstract int getTcpTrafficClass(); + + public abstract void setTcpTrafficClass(int classFlags) throws SQLException; + + public abstract boolean getUseNanosForElapsedTime(); + + public abstract void setUseNanosForElapsedTime(boolean flag); + + public abstract long getSlowQueryThresholdNanos(); + + public abstract void setSlowQueryThresholdNanos(long nanos) throws SQLException; + + public abstract String getStatementInterceptors(); + + public abstract void setStatementInterceptors(String value); + + public abstract boolean getUseDirectRowUnpack(); + + public abstract void setUseDirectRowUnpack(boolean flag); + + public abstract String getLargeRowSizeThreshold(); + + public abstract void setLargeRowSizeThreshold(String value) throws SQLException; + + public abstract boolean getUseBlobToStoreUTF8OutsideBMP(); + + public abstract void setUseBlobToStoreUTF8OutsideBMP(boolean flag); + + public abstract String getUtf8OutsideBmpExcludedColumnNamePattern(); + + public abstract void setUtf8OutsideBmpExcludedColumnNamePattern(String regexPattern); + + public abstract String getUtf8OutsideBmpIncludedColumnNamePattern(); + + public abstract void setUtf8OutsideBmpIncludedColumnNamePattern(String regexPattern); + + public abstract boolean getIncludeInnodbStatusInDeadlockExceptions(); + + public abstract void setIncludeInnodbStatusInDeadlockExceptions(boolean flag); + + public abstract boolean getIncludeThreadDumpInDeadlockExceptions(); + + public abstract void setIncludeThreadDumpInDeadlockExceptions(boolean flag); + + public abstract boolean getIncludeThreadNamesAsStatementComment(); + + public abstract void setIncludeThreadNamesAsStatementComment(boolean flag); + + public abstract boolean getBlobsAreStrings(); + + public abstract void setBlobsAreStrings(boolean flag); + + public abstract boolean getFunctionsNeverReturnBlobs(); + + public abstract void setFunctionsNeverReturnBlobs(boolean flag); + + public abstract boolean getAutoSlowLog(); + + public abstract void setAutoSlowLog(boolean flag); + + public abstract String getConnectionLifecycleInterceptors(); + + public abstract void setConnectionLifecycleInterceptors(String interceptors); + + public abstract String getProfilerEventHandler(); + + public abstract void setProfilerEventHandler(String handler); + + public boolean getVerifyServerCertificate(); + + public abstract void setVerifyServerCertificate(boolean flag); + + public abstract boolean getUseLegacyDatetimeCode(); + + public abstract void setUseLegacyDatetimeCode(boolean flag); + + public abstract int getSelfDestructOnPingSecondsLifetime(); + + public abstract void setSelfDestructOnPingSecondsLifetime(int seconds) throws SQLException; + + public abstract int getSelfDestructOnPingMaxOperations(); + + public abstract void setSelfDestructOnPingMaxOperations(int maxOperations) throws SQLException; + + public abstract boolean getUseColumnNamesInFindColumn(); + + public abstract void setUseColumnNamesInFindColumn(boolean flag); + + public abstract boolean getUseLocalTransactionState(); + + public abstract void setUseLocalTransactionState(boolean flag); + + public abstract boolean getCompensateOnDuplicateKeyUpdateCounts(); + + public abstract void setCompensateOnDuplicateKeyUpdateCounts(boolean flag); + + public abstract void setUseAffectedRows(boolean flag); + + public abstract boolean getUseAffectedRows(); + + public abstract void setPasswordCharacterEncoding(String characterSet); + + public abstract String getPasswordCharacterEncoding(); + + public abstract int getLoadBalanceBlacklistTimeout(); + + public abstract void setLoadBalanceBlacklistTimeout(int loadBalanceBlacklistTimeout) throws SQLException; + + public abstract void setRetriesAllDown(int retriesAllDown) throws SQLException; + + public abstract int getRetriesAllDown(); + + public ExceptionInterceptor getExceptionInterceptor(); + + public abstract void setExceptionInterceptors(String exceptionInterceptors); + + public abstract String getExceptionInterceptors(); + + + public abstract boolean getQueryTimeoutKillsConnection(); + + public abstract void setQueryTimeoutKillsConnection(boolean queryTimeoutKillsConnection); + + public int getMaxAllowedPacket(); + + boolean getRetainStatementAfterResultSetClose(); + + public abstract int getLoadBalancePingTimeout(); + + public abstract void setLoadBalancePingTimeout(int loadBalancePingTimeout) throws SQLException; + + public abstract boolean getLoadBalanceValidateConnectionOnSwapServer(); + + public abstract void setLoadBalanceValidateConnectionOnSwapServer(boolean loadBalanceValidateConnectionOnSwapServer); + + public abstract String getLoadBalanceConnectionGroup(); + + public abstract void setLoadBalanceConnectionGroup(String loadBalanceConnectionGroup); + + public abstract String getLoadBalanceExceptionChecker(); + + public abstract void setLoadBalanceExceptionChecker(String loadBalanceExceptionChecker); + + public abstract String getLoadBalanceSQLStateFailover(); + + public abstract void setLoadBalanceSQLStateFailover(String loadBalanceSQLStateFailover); + + public abstract String getLoadBalanceSQLExceptionSubclassFailover(); + + public abstract void setLoadBalanceSQLExceptionSubclassFailover(String loadBalanceSQLExceptionSubclassFailover); + + public abstract boolean getLoadBalanceEnableJMX(); + + public abstract void setLoadBalanceEnableJMX(boolean loadBalanceEnableJMX); + + public void setLoadBalanceAutoCommitStatementThreshold(int loadBalanceAutoCommitStatementThreshold) throws SQLException; + + public int getLoadBalanceAutoCommitStatementThreshold(); + + public void setLoadBalanceAutoCommitStatementRegex(String loadBalanceAutoCommitStatementRegex); + + public String getLoadBalanceAutoCommitStatementRegex(); + + public abstract void setAuthenticationPlugins(String authenticationPlugins); + + public abstract String getAuthenticationPlugins(); + + public abstract void setDisabledAuthenticationPlugins(String disabledAuthenticationPlugins); + + public abstract String getDisabledAuthenticationPlugins(); + + public abstract void setDefaultAuthenticationPlugin(String defaultAuthenticationPlugin); + + public abstract String getDefaultAuthenticationPlugin(); + + public abstract void setParseInfoCacheFactory(String factoryClassname); + + public abstract String getParseInfoCacheFactory(); + + public abstract void setServerConfigCacheFactory(String factoryClassname); + + public abstract String getServerConfigCacheFactory(); + + public abstract void setDisconnectOnExpiredPasswords(boolean disconnectOnExpiredPasswords); + + public abstract boolean getDisconnectOnExpiredPasswords(); + + public abstract boolean getAllowMasterDownConnections(); + + public abstract void setAllowMasterDownConnections(boolean connectIfMasterDown); + + public abstract boolean getReplicationEnableJMX(); + + public abstract void setReplicationEnableJMX(boolean replicationEnableJMX); + + public abstract void setGetProceduresReturnsFunctions(boolean getProcedureReturnsFunctions); + + public abstract boolean getGetProceduresReturnsFunctions(); + + public abstract void setDetectCustomCollations(boolean detectCustomCollations); + + public abstract boolean getDetectCustomCollations(); + + String getConnectionAttributes() throws SQLException; + + public abstract String getServerRSAPublicKeyFile(); + + public abstract void setServerRSAPublicKeyFile(String serverRSAPublicKeyFile) throws SQLException; + + public abstract boolean getAllowPublicKeyRetrieval(); + + public abstract void setAllowPublicKeyRetrieval(boolean allowPublicKeyRetrieval) throws SQLException; + } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesTransform.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesTransform.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesTransform.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesTransform.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,25 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */ + package com.mysql.jdbc; import java.sql.SQLException; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Constants.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Constants.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Constants.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Constants.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; /** @@ -31,17 +30,23 @@ * * @version $Id$ */ -class Constants { +public class Constants { /** * Avoids allocation of empty byte[] when representing 0-length strings. */ public final static byte[] EMPTY_BYTE_ARRAY = new byte[0]; - + /** * I18N'd representation of the abbreviation for "ms" */ public final static String MILLIS_I18N = Messages.getString("Milliseconds"); + + public final static byte[] SLASH_STAR_SPACE_AS_BYTES = new byte[] { + (byte) '/', (byte) '*', (byte) ' ' }; + public final static byte[] SPACE_STAR_SLASH_SPACE_AS_BYTES = new byte[] { + (byte) ' ', (byte) '*', (byte) '/', (byte) ' ' }; + /** * Prevents instantiation */ Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaData.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaData.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaData.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaData.java 30 Jul 2014 08:37:25 -0000 1.1.2.1 @@ -1,45 +1,50 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; -import java.io.UnsupportedEncodingException; +import static com.mysql.jdbc.DatabaseMetaData.ProcedureType.FUNCTION; +import static com.mysql.jdbc.DatabaseMetaData.ProcedureType.PROCEDURE; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Constructor; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; - import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; +import java.util.SortedMap; import java.util.StringTokenizer; import java.util.TreeMap; +import java.util.TreeSet; /** * JDBC Interface to Mysql functions @@ -63,46 +68,27 @@ * Exp $ */ public class DatabaseMetaData implements java.sql.DatabaseMetaData { - protected abstract class IterateBlock { - IteratorWithCleanup iterator; - IterateBlock(IteratorWithCleanup i) { - iterator = i; - } - - public void doForAll() throws SQLException { - try { - while (iterator.hasNext()) { - forEach(iterator.next()); - } - } finally { - iterator.close(); - } - } - - abstract void forEach(Object each) throws SQLException; - } - - protected abstract class IteratorWithCleanup { + protected abstract class IteratorWithCleanup { abstract void close() throws SQLException; abstract boolean hasNext() throws SQLException; - abstract Object next() throws SQLException; + abstract T next() throws SQLException; } - + class LocalAndReferencedColumns { String constraintName; - List localColumnsList; + List localColumnsList; String referencedCatalog; - List referencedColumnsList; + List referencedColumnsList; String referencedTable; - LocalAndReferencedColumns(List localColumns, List refColumns, + LocalAndReferencedColumns(List localColumns, List refColumns, String constName, String refCatalog, String refTable) { this.localColumnsList = localColumns; this.referencedColumnsList = refColumns; @@ -112,7 +98,7 @@ } } - protected class ResultSetIterator extends IteratorWithCleanup { + protected class ResultSetIterator extends IteratorWithCleanup { int colIndex; ResultSet resultSet; @@ -130,12 +116,12 @@ return resultSet.next(); } - Object next() throws SQLException { - return resultSet.getObject(colIndex); + String next() throws SQLException { + return resultSet.getObject(colIndex).toString(); } } - protected class SingleStringIterator extends IteratorWithCleanup { + protected class SingleStringIterator extends IteratorWithCleanup { boolean onFirst = true; String value; @@ -153,7 +139,7 @@ return onFirst; } - Object next() throws SQLException { + String next() throws SQLException { onFirst = false; return value; } @@ -184,6 +170,11 @@ TypeDescriptor(String typeInfo, String nullabilityInfo) throws SQLException { + if (typeInfo == null) { + throw SQLError.createSQLException("NULL typeinfo not supported.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + String mysqlType = ""; String fullMysqlType = null; @@ -206,9 +197,11 @@ boolean isUnsigned = false; - if (StringUtils.indexOfIgnoreCase(typeInfo, "unsigned") != -1) { - fullMysqlType = mysqlType + " unsigned"; - isUnsigned = true; + if ((StringUtils.indexOfIgnoreCase(typeInfo, "unsigned") != -1) && + (StringUtils.indexOfIgnoreCase(typeInfo, "set") != 0) && + (StringUtils.indexOfIgnoreCase(typeInfo, "enum") != 0)) { + fullMysqlType = mysqlType + " unsigned"; + isUnsigned = true; } else { fullMysqlType = mysqlType; } @@ -222,189 +215,192 @@ this.typeName = fullMysqlType; // Figure Out the Size - if (typeInfo != null) { - if (StringUtils.startsWithIgnoreCase(typeInfo, "enum")) { - String temp = typeInfo.substring(typeInfo.indexOf("("), - typeInfo.lastIndexOf(")")); - java.util.StringTokenizer tokenizer = new java.util.StringTokenizer( - temp, ","); - int maxLength = 0; + + if (StringUtils.startsWithIgnoreCase(typeInfo, "enum")) { + String temp = typeInfo.substring(typeInfo.indexOf("("), + typeInfo.lastIndexOf(")")); + java.util.StringTokenizer tokenizer = new java.util.StringTokenizer( + temp, ","); + int maxLength = 0; - while (tokenizer.hasMoreTokens()) { - maxLength = Math.max(maxLength, (tokenizer.nextToken() - .length() - 2)); - } + while (tokenizer.hasMoreTokens()) { + maxLength = Math.max(maxLength, (tokenizer.nextToken() + .length() - 2)); + } - this.columnSize = new Integer(maxLength); - this.decimalDigits = null; - } else if (StringUtils.startsWithIgnoreCase(typeInfo, "set")) { - String temp = typeInfo.substring(typeInfo.indexOf("("), - typeInfo.lastIndexOf(")")); - java.util.StringTokenizer tokenizer = new java.util.StringTokenizer( - temp, ","); - int maxLength = 0; + this.columnSize = Integer.valueOf(maxLength); + this.decimalDigits = null; + } else if (StringUtils.startsWithIgnoreCase(typeInfo, "set")) { + String temp = typeInfo.substring(typeInfo.indexOf("(") + 1, + typeInfo.lastIndexOf(")")); + java.util.StringTokenizer tokenizer = new java.util.StringTokenizer( + temp, ","); + int maxLength = 0; - while (tokenizer.hasMoreTokens()) { - String setMember = tokenizer.nextToken().trim(); + int numElements = tokenizer.countTokens(); + + if (numElements > 0) { + maxLength += (numElements - 1); + } + + while (tokenizer.hasMoreTokens()) { + String setMember = tokenizer.nextToken().trim(); - if (setMember.startsWith("'") - && setMember.endsWith("'")) { - maxLength += setMember.length() - 2; - } else { - maxLength += setMember.length(); - } + if (setMember.startsWith("'") + && setMember.endsWith("'")) { + maxLength += setMember.length() - 2; + } else { + maxLength += setMember.length(); } + } - this.columnSize = new Integer(maxLength); - this.decimalDigits = null; - } else if (typeInfo.indexOf(",") != -1) { - // Numeric with decimals - this.columnSize = new Integer(typeInfo.substring((typeInfo - .indexOf("(") + 1), (typeInfo.indexOf(","))).trim()); - this.decimalDigits = new Integer(typeInfo.substring( - (typeInfo.indexOf(",") + 1), - (typeInfo.indexOf(")"))).trim()); - } else { - this.columnSize = null; - this.decimalDigits = null; + this.columnSize = Integer.valueOf(maxLength); + this.decimalDigits = null; + } else if (typeInfo.indexOf(",") != -1) { + // Numeric with decimals + this.columnSize = Integer.valueOf(typeInfo.substring((typeInfo + .indexOf("(") + 1), (typeInfo.indexOf(","))).trim()); + this.decimalDigits = Integer.valueOf(typeInfo.substring( + (typeInfo.indexOf(",") + 1), + (typeInfo.indexOf(")"))).trim()); + } else { + this.columnSize = null; + this.decimalDigits = null; - /* 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) { - int endParenIndex = typeInfo.indexOf(")"); + /* 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) { + int endParenIndex = typeInfo.indexOf(")"); - if (endParenIndex == -1) { - endParenIndex = typeInfo.length(); - } + if (endParenIndex == -1) { + endParenIndex = typeInfo.length(); + } - this.columnSize = new Integer(typeInfo.substring( - (typeInfo.indexOf("(") + 1), endParenIndex).trim()); + this.columnSize = Integer.valueOf(typeInfo.substring( + (typeInfo.indexOf("(") + 1), endParenIndex).trim()); - // Adjust for pseudo-boolean - if (conn.getTinyInt1isBit() - && this.columnSize.intValue() == 1 - && StringUtils.startsWithIgnoreCase(typeInfo, - 0, "tinyint")) { - if (conn.getTransformedBitIsBoolean()) { - this.dataType = Types.BOOLEAN; - this.typeName = "BOOLEAN"; - } else { - this.dataType = Types.BIT; - this.typeName = "BIT"; - } + // Adjust for pseudo-boolean + if (conn.getTinyInt1isBit() + && this.columnSize.intValue() == 1 + && StringUtils.startsWithIgnoreCase(typeInfo, + 0, "tinyint")) { + if (conn.getTransformedBitIsBoolean()) { + this.dataType = Types.BOOLEAN; + this.typeName = "BOOLEAN"; + } else { + this.dataType = Types.BIT; + this.typeName = "BIT"; } - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "tinyint")) { - if (conn.getTinyInt1isBit() && typeInfo.indexOf("(1)") != -1) { - if (conn.getTransformedBitIsBoolean()) { - this.dataType = Types.BOOLEAN; - this.typeName = "BOOLEAN"; - } else { - this.dataType = Types.BIT; - this.typeName = "BIT"; - } + } + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "tinyint")) { + if (conn.getTinyInt1isBit() && typeInfo.indexOf("(1)") != -1) { + if (conn.getTransformedBitIsBoolean()) { + this.dataType = Types.BOOLEAN; + this.typeName = "BOOLEAN"; } else { - this.columnSize = new Integer(3); - this.decimalDigits = new Integer(0); + this.dataType = Types.BIT; + this.typeName = "BIT"; } - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "smallint")) { - this.columnSize = new Integer(5); - this.decimalDigits = new Integer(0); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "mediumint")) { - this.columnSize = new Integer(isUnsigned ? 8 : 7); - this.decimalDigits = new Integer(0); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "int")) { - this.columnSize = new Integer(10); - this.decimalDigits = new Integer(0); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "integer")) { - this.columnSize = new Integer(10); - this.decimalDigits = new Integer(0); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "bigint")) { - this.columnSize = new Integer(isUnsigned ? 20 : 19); - this.decimalDigits = new Integer(0); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "int24")) { - this.columnSize = new Integer(19); - this.decimalDigits = new Integer(0); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "real")) { - this.columnSize = new Integer(12); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "float")) { - this.columnSize = new Integer(12); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "decimal")) { - this.columnSize = new Integer(12); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "numeric")) { - this.columnSize = new Integer(12); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "double")) { - this.columnSize = new Integer(22); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "char")) { - this.columnSize = new Integer(1); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "varchar")) { - this.columnSize = new Integer(255); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "date")) { - this.columnSize = null; - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "time")) { - this.columnSize = null; - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "timestamp")) { - this.columnSize = null; - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "datetime")) { - this.columnSize = null; - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "tinyblob")) { - this.columnSize = new Integer(255); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "blob")) { - this.columnSize = new Integer(65535); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "mediumblob")) { - this.columnSize = new Integer(16777215); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "longblob")) { - this.columnSize = new Integer(Integer.MAX_VALUE); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "tinytext")) { - this.columnSize = new Integer(255); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "text")) { - this.columnSize = new Integer(65535); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "mediumtext")) { - this.columnSize = new Integer(16777215); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "longtext")) { - this.columnSize = new Integer(Integer.MAX_VALUE); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "enum")) { - this.columnSize = new Integer(255); - } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, - "set")) { - this.columnSize = new Integer(255); + } else { + this.columnSize = Integer.valueOf(3); + this.decimalDigits = Integer.valueOf(0); } - + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "smallint")) { + this.columnSize = Integer.valueOf(5); + this.decimalDigits = Integer.valueOf(0); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "mediumint")) { + this.columnSize = Integer.valueOf(isUnsigned ? 8 : 7); + this.decimalDigits = Integer.valueOf(0); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "int")) { + this.columnSize = Integer.valueOf(10); + this.decimalDigits = Integer.valueOf(0); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "integer")) { + this.columnSize = Integer.valueOf(10); + this.decimalDigits = Integer.valueOf(0); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "bigint")) { + this.columnSize = Integer.valueOf(isUnsigned ? 20 : 19); + this.decimalDigits = Integer.valueOf(0); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "int24")) { + this.columnSize = Integer.valueOf(19); + this.decimalDigits = Integer.valueOf(0); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "real")) { + this.columnSize = Integer.valueOf(12); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "float")) { + this.columnSize = Integer.valueOf(12); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "decimal")) { + this.columnSize = Integer.valueOf(12); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "numeric")) { + this.columnSize = Integer.valueOf(12); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "double")) { + this.columnSize = Integer.valueOf(22); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "char")) { + this.columnSize = Integer.valueOf(1); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "varchar")) { + this.columnSize = Integer.valueOf(255); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "timestamp")) { + this.columnSize = Integer.valueOf(19); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "datetime")) { + this.columnSize = Integer.valueOf(19); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "date")) { + this.columnSize = Integer.valueOf(10); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "time")) { + this.columnSize = Integer.valueOf(8); + + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "tinyblob")) { + this.columnSize = Integer.valueOf(255); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "blob")) { + this.columnSize = Integer.valueOf(65535); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "mediumblob")) { + this.columnSize = Integer.valueOf(16777215); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "longblob")) { + this.columnSize = Integer.valueOf(Integer.MAX_VALUE); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "tinytext")) { + this.columnSize = Integer.valueOf(255); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "text")) { + this.columnSize = Integer.valueOf(65535); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "mediumtext")) { + this.columnSize = Integer.valueOf(16777215); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "longtext")) { + this.columnSize = Integer.valueOf(Integer.MAX_VALUE); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "enum")) { + this.columnSize = Integer.valueOf(255); + } else if (StringUtils.startsWithIgnoreCaseAndWs(typeInfo, + "set")) { + this.columnSize = Integer.valueOf(255); } - } else { - this.decimalDigits = null; - this.columnSize = null; + } // BUFFER_LENGTH @@ -419,6 +415,10 @@ this.nullability = java.sql.DatabaseMetaData.columnNullable; this.isNullable = "YES"; + } else if (nullabilityInfo.equals("UNKNOWN")) { + this.nullability = java.sql.DatabaseMetaData.columnNullableUnknown; + this.isNullable = ""; + // IS_NULLABLE } else { this.nullability = java.sql.DatabaseMetaData.columnNoNulls; @@ -430,9 +430,228 @@ } } } + + /** + * Helper class to provide means of comparing indexes by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION. + */ + protected class IndexMetaDataKey implements Comparable { + Boolean columnNonUnique; + Short columnType; + String columnIndexName; + Short columnOrdinalPosition; - private static String mysqlKeywordsThatArentSQL92; + IndexMetaDataKey(boolean columnNonUnique, short columnType, String columnIndexName, + short columnOrdinalPosition) { + this.columnNonUnique = columnNonUnique; + this.columnType = columnType; + this.columnIndexName = columnIndexName; + this.columnOrdinalPosition = columnOrdinalPosition; + } + public int compareTo(IndexMetaDataKey indexInfoKey) { + int compareResult; + + if ((compareResult = columnNonUnique.compareTo(indexInfoKey.columnNonUnique)) != 0) { + return compareResult; + } + if ((compareResult = columnType.compareTo(indexInfoKey.columnType)) != 0) { + return compareResult; + } + if ((compareResult = columnIndexName.compareTo(indexInfoKey.columnIndexName)) != 0) { + return compareResult; + } + return columnOrdinalPosition.compareTo(indexInfoKey.columnOrdinalPosition); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (obj == this) { + return true; + } + + if (!(obj instanceof IndexMetaDataKey)) { + return false; + } + return compareTo((IndexMetaDataKey) obj) == 0; + } + } + + /** + * Helper class to provide means of comparing tables by TABLE_TYPE, TABLE_CAT, TABLE_SCHEM and TABLE_NAME. + */ + protected class TableMetaDataKey implements Comparable { + String tableType; + String tableCat; + String tableSchem; + String tableName; + + TableMetaDataKey(String tableType, String tableCat, String tableSchem, String tableName) { + this.tableType = tableType == null ? "" : tableType; + this.tableCat = tableCat == null ? "" : tableCat; + this.tableSchem = tableSchem == null ? "" : tableSchem; + this.tableName = tableName == null ? "" : tableName; + } + + public int compareTo(TableMetaDataKey tablesKey) { + int compareResult; + + if ((compareResult = tableType.compareTo(tablesKey.tableType)) != 0) { + return compareResult; + } + if ((compareResult = tableCat.compareTo(tablesKey.tableCat)) != 0) { + return compareResult; + } + if ((compareResult = tableSchem.compareTo(tablesKey.tableSchem)) != 0) { + return compareResult; + } + return tableName.compareTo(tablesKey.tableName); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (obj == this) { + return true; + } + + if (!(obj instanceof TableMetaDataKey)) { + return false; + } + return compareTo((TableMetaDataKey) obj) == 0; + } + } + + /** + * Helper/wrapper class to provide means of sorting objects by using a sorting key. + */ + protected class ComparableWrapper, V> implements + Comparable> { + K key; + V value; + + public ComparableWrapper(K key, V value) { + this.key = key; + this.value = value; + } + + public K getKey() { + return key; + } + + public V getValue() { + return value; + } + + public int compareTo(ComparableWrapper other) { + return getKey().compareTo(other.getKey()); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (obj == this) { + return true; + } + + if (!(obj instanceof ComparableWrapper)) { + return false; + } + + Object otherKey = ((ComparableWrapper) obj).getKey(); + return key.equals(otherKey); + } + + @Override + public String toString() { + return "{KEY:" + key + "; VALUE:" + value +"}"; + } + } + + /** + * 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"); + + private String name; + private byte[] nameAsBytes; + private String[] synonyms; + + TableType(String tableTypeName) { + this(tableTypeName, null); + } + + TableType(String tableTypeName, String[] tableTypeSynonyms) { + name = tableTypeName; + nameAsBytes = tableTypeName.getBytes(); + synonyms = tableTypeSynonyms; + } + + String getName() { + return name; + } + + byte[] asBytes() { + return nameAsBytes; + } + + boolean equalsTo(String tableTypeName) { + return name.equalsIgnoreCase(tableTypeName); + } + + static TableType getTableTypeEqualTo(String tableTypeName) { + for (TableType tableType : TableType.values()) { + if (tableType.equalsTo(tableTypeName)) { + return tableType; + } + } + return UNKNOWN; + } + + boolean compliesWith(String tableTypeName) { + if (equalsTo(tableTypeName)) { + return true; + } + if (synonyms != null) { + for (String synonym : synonyms) { + if (synonym.equalsIgnoreCase(tableTypeName)) { + return true; + } + } + } + return false; + } + + static TableType getTableTypeCompliantWith(String tableTypeName) { + for (TableType tableType : TableType.values()) { + if (tableType.compliesWith(tableTypeName)) { + return tableType; + } + } + return UNKNOWN; + } + } + + /** + * Enumeration for Procedure Types + */ + protected enum ProcedureType { + PROCEDURE, FUNCTION; + } + + protected static final int MAX_IDENTIFIER_LENGTH = 64; + private static final int DEFERRABILITY = 13; private static final int DELETE_RULE = 10; @@ -466,155 +685,171 @@ /** The table type for generic tables that support foreign keys. */ private static final String SUPPORTS_FK = "SUPPORTS_FK"; - private static final byte[] TABLE_AS_BYTES = "TABLE".getBytes(); + protected static final byte[] TABLE_AS_BYTES = "TABLE".getBytes(); + protected static final byte[] SYSTEM_TABLE_AS_BYTES = "SYSTEM TABLE".getBytes(); + private static final int UPDATE_RULE = 9; - private static final byte[] VIEW_AS_BYTES = "VIEW".getBytes(); - + protected static final byte[] VIEW_AS_BYTES = "VIEW".getBytes(); + + private static final Constructor JDBC_4_DBMD_SHOW_CTOR; + + private static final Constructor JDBC_4_DBMD_IS_CTOR; + static { - // Current as-of MySQL-5.1.16 - String[] allMySQLKeywords = new String[] { "ACCESSIBLE", "ADD", "ALL", - "ALTER", "ANALYZE", "AND", "AS", "ASC", "ASENSITIVE", "BEFORE", - "BETWEEN", "BIGINT", "BINARY", "BLOB", "BOTH", "BY", "CALL", - "CASCADE", "CASE", "CHANGE", "CHAR", "CHARACTER", "CHECK", - "COLLATE", "COLUMN", "CONDITION", "CONNECTION", "CONSTRAINT", - "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT_DATE", - "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", - "DATABASE", "DATABASES", "DAY_HOUR", "DAY_MICROSECOND", - "DAY_MINUTE", "DAY_SECOND", "DEC", "DECIMAL", "DECLARE", - "DEFAULT", "DELAYED", "DELETE", "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", "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", "IS", "ITERATE", "JOIN", - "KEY", "KEYS", "KILL", "LEADING", "LEAVE", "LEFT", "LIKE", - "LIMIT", "LINEAR", "LINES", "LOAD", "LOCALTIME", - "LOCALTIMESTAMP", "LOCK", "LONG", "LONGBLOB", "LONGTEXT", - "LOOP", "LOW_PRIORITY", "MATCH", "MEDIUMBLOB", "MEDIUMINT", - "MEDIUMTEXT", "MIDDLEINT", "MINUTE_MICROSECOND", - "MINUTE_SECOND", "MOD", "MODIFIES", "NATURAL", "NOT", - "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON", "OPTIMIZE", - "OPTION", "OPTIONALLY", "OR", "ORDER", "OUT", "OUTER", - "OUTFILE", "PRECISION", "PRIMARY", "PROCEDURE", "PURGE", - "RANGE", "READ", "READS", "READ_ONLY", "READ_WRITE", "REAL", - "REFERENCES", "REGEXP", "RELEASE", "RENAME", "REPEAT", - "REPLACE", "REQUIRE", "RESTRICT", "RETURN", "REVOKE", "RIGHT", - "RLIKE", "SCHEMA", "SCHEMAS", "SECOND_MICROSECOND", "SELECT", - "SENSITIVE", "SEPARATOR", "SET", "SHOW", "SMALLINT", "SPATIAL", - "SPECIFIC", "SQL", "SQLEXCEPTION", "SQLSTATE", "SQLWARNING", - "SQL_BIG_RESULT", "SQL_CALC_FOUND_ROWS", "SQL_SMALL_RESULT", - "SSL", "STARTING", "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", "WHEN", "WHERE", "WHILE", "WITH", - "WRITE", "X509", "XOR", "YEAR_MONTH", "ZEROFILL" }; - - String[] sql92Keywords = new String[] { "ABSOLUTE", "EXEC", "OVERLAPS", - "ACTION", "EXECUTE", "PAD", "ADA", "EXISTS", "PARTIAL", "ADD", - "EXTERNAL", "PASCAL", "ALL", "EXTRACT", "POSITION", "ALLOCATE", - "FALSE", "PRECISION", "ALTER", "FETCH", "PREPARE", "AND", - "FIRST", "PRESERVE", "ANY", "FLOAT", "PRIMARY", "ARE", "FOR", - "PRIOR", "AS", "FOREIGN", "PRIVILEGES", "ASC", "FORTRAN", - "PROCEDURE", "ASSERTION", "FOUND", "PUBLIC", "AT", "FROM", - "READ", "AUTHORIZATION", "FULL", "REAL", "AVG", "GET", - "REFERENCES", "BEGIN", "GLOBAL", "RELATIVE", "BETWEEN", "GO", - "RESTRICT", "BIT", "GOTO", "REVOKE", "BIT_LENGTH", "GRANT", - "RIGHT", "BOTH", "GROUP", "ROLLBACK", "BY", "HAVING", "ROWS", - "CASCADE", "HOUR", "SCHEMA", "CASCADED", "IDENTITY", "SCROLL", - "CASE", "IMMEDIATE", "SECOND", "CAST", "IN", "SECTION", - "CATALOG", "INCLUDE", "SELECT", "CHAR", "INDEX", "SESSION", - "CHAR_LENGTH", "INDICATOR", "SESSION_USER", "CHARACTER", - "INITIALLY", "SET", "CHARACTER_LENGTH", "INNER", "SIZE", - "CHECK", "INPUT", "SMALLINT", "CLOSE", "INSENSITIVE", "SOME", - "COALESCE", "INSERT", "SPACE", "COLLATE", "INT", "SQL", - "COLLATION", "INTEGER", "SQLCA", "COLUMN", "INTERSECT", - "SQLCODE", "COMMIT", "INTERVAL", "SQLERROR", "CONNECT", "INTO", - "SQLSTATE", "CONNECTION", "IS", "SQLWARNING", "CONSTRAINT", - "ISOLATION", "SUBSTRING", "CONSTRAINTS", "JOIN", "SUM", - "CONTINUE", "KEY", "SYSTEM_USER", "CONVERT", "LANGUAGE", - "TABLE", "CORRESPONDING", "LAST", "TEMPORARY", "COUNT", - "LEADING", "THEN", "CREATE", "LEFT", "TIME", "CROSS", "LEVEL", - "TIMESTAMP", "CURRENT", "LIKE", "TIMEZONE_HOUR", - "CURRENT_DATE", "LOCAL", "TIMEZONE_MINUTE", "CURRENT_TIME", - "LOWER", "TO", "CURRENT_TIMESTAMP", "MATCH", "TRAILING", - "CURRENT_USER", "MAX", "TRANSACTION", "CURSOR", "MIN", - "TRANSLATE", "DATE", "MINUTE", "TRANSLATION", "DAY", "MODULE", - "TRIM", "DEALLOCATE", "MONTH", "TRUE", "DEC", "NAMES", "UNION", - "DECIMAL", "NATIONAL", "UNIQUE", "DECLARE", "NATURAL", - "UNKNOWN", "DEFAULT", "NCHAR", "UPDATE", "DEFERRABLE", "NEXT", - "UPPER", "DEFERRED", "NO", "USAGE", "DELETE", "NONE", "USER", - "DESC", "NOT", "USING", "DESCRIBE", "NULL", "VALUE", - "DESCRIPTOR", "NULLIF", "VALUES", "DIAGNOSTICS", "NUMERIC", - "VARCHAR", "DISCONNECT", "OCTET_LENGTH", "VARYING", "DISTINCT", - "OF", "VIEW", "DOMAIN", "ON", "WHEN", "DOUBLE", "ONLY", - "WHENEVER", "DROP", "OPEN", "WHERE", "ELSE", "OPTION", "WITH", - "END", "OR", "WORK", "END-EXEC", "ORDER", "WRITE", "ESCAPE", - "OUTER", "YEAR", "EXCEPT", "OUTPUT", "ZONE", "EXCEPTION" }; - - TreeMap mySQLKeywordMap = new TreeMap(); - - for (int i = 0; i < allMySQLKeywords.length; i++) { - mySQLKeywordMap.put(allMySQLKeywords[i], null); + 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 }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_DBMD_IS_CTOR = null; + JDBC_4_DBMD_SHOW_CTOR = null; } - - HashMap sql92KeywordMap = new HashMap(sql92Keywords.length); - - for (int i = 0; i < sql92Keywords.length; i++) { - sql92KeywordMap.put(sql92Keywords[i], null); - } - - Iterator it = sql92KeywordMap.keySet().iterator(); - - while (it.hasNext()) { - mySQLKeywordMap.remove(it.next()); - } - - StringBuffer keywordBuf = new StringBuffer(); - - it = mySQLKeywordMap.keySet().iterator(); - - if (it.hasNext()) { - keywordBuf.append(it.next().toString()); - } - - while (it.hasNext()) { - keywordBuf.append(","); - keywordBuf.append(it.next().toString()); - } - - mysqlKeywordsThatArentSQL92 = keywordBuf.toString(); } - static java.sql.ResultSet buildResultSet(com.mysql.jdbc.Field[] fields, - java.util.ArrayList rows, Connection c) throws SQLException { - int fieldsLength = fields.length; + // MySQL reserved words (all versions superset) + private static final String[] MYSQL_KEYWORDS = new String[] { "ACCESSIBLE", "ADD", "ALL", "ALTER", "ANALYZE", + "AND", "AS", "ASC", "ASENSITIVE", "BEFORE", "BETWEEN", "BIGINT", "BINARY", "BLOB", "BOTH", "BY", "CALL", + "CASCADE", "CASE", "CHANGE", "CHAR", "CHARACTER", "CHECK", "COLLATE", "COLUMN", "CONDITION", "CONSTRAINT", + "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", + "CURRENT_USER", "CURSOR", "DATABASE", "DATABASES", "DAY_HOUR", "DAY_MICROSECOND", "DAY_MINUTE", + "DAY_SECOND", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DELAYED", "DELETE", "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", "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", "NONBLOCKING", "NOT", "NO_WRITE_TO_BINLOG", "NULL", "NUMERIC", "ON", + "OPTIMIZE", "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", "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", "WHEN", "WHERE", "WHILE", + "WITH", "WRITE", "XOR", "YEAR_MONTH", "ZEROFILL" }; - for (int i = 0; i < fieldsLength; i++) { - fields[i].setConnection(c); - fields[i].setUseOldNameMetadata(true); - } + // 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", "ASSERTION", "AT", "AUTHORIZATION", "AVG", "BEGIN", "BETWEEN", + "BIT", "BIT_LENGTH", "BOTH", "BY", "CASCADE", "CASCADED", "CASE", "CAST", "CATALOG", "CHAR", "CHARACTER", + "CHARACTER_LENGTH", "CHAR_LENGTH", "CHECK", "CLOSE", "COALESCE", "COLLATE", "COLLATION", "COLUMN", + "COMMIT", "CONNECT", "CONNECTION", "CONSTRAINT", "CONSTRAINTS", "CONTINUE", "CONVERT", "CORRESPONDING", + "COUNT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", + "CURSOR", "DATE", "DAY", "DEALLOCATE", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DEFERRABLE", "DEFERRED", + "DELETE", "DESC", "DESCRIBE", "DESCRIPTOR", "DIAGNOSTICS", "DISCONNECT", "DISTINCT", "DOMAIN", "DOUBLE", + "DROP", "ELSE", "END", "END-EXEC", "ESCAPE", "EXCEPT", "EXCEPTION", "EXEC", "EXECUTE", "EXISTS", + "EXTERNAL", "EXTRACT", "FALSE", "FETCH", "FIRST", "FLOAT", "FOR", "FOREIGN", "FOUND", "FROM", "FULL", + "GET", "GLOBAL", "GO", "GOTO", "GRANT", "GROUP", "HAVING", "HOUR", "IDENTITY", "IMMEDIATE", "IN", + "INDICATOR", "INITIALLY", "INNER", "INPUT", "INSENSITIVE", "INSERT", "INT", "INTEGER", "INTERSECT", + "INTERVAL", "INTO", "IS", "ISOLATION", "JOIN", "KEY", "LANGUAGE", "LAST", "LEADING", "LEFT", "LEVEL", + "LIKE", "LOCAL", "LOWER", "MATCH", "MAX", "MIN", "MINUTE", "MODULE", "MONTH", "NAMES", "NATIONAL", + "NATURAL", "NCHAR", "NEXT", "NO", "NOT", "NULL", "NULLIF", "NUMERIC", "OCTET_LENGTH", "OF", "ON", "ONLY", + "OPEN", "OPTION", "OR", "ORDER", "OUTER", "OUTPUT", "OVERLAPS", "PAD", "PARTIAL", "POSITION", "PRECISION", + "PREPARE", "PRESERVE", "PRIMARY", "PRIOR", "PRIVILEGES", "PROCEDURE", "PUBLIC", "READ", "REAL", + "REFERENCES", "RELATIVE", "RESTRICT", "REVOKE", "RIGHT", "ROLLBACK", "ROWS", "SCHEMA", "SCROLL", "SECOND", + "SECTION", "SELECT", "SESSION", "SESSION_USER", "SET", "SIZE", "SMALLINT", "SOME", "SPACE", "SQL", + "SQLCODE", "SQLERROR", "SQLSTATE", "SUBSTRING", "SUM", "SYSTEM_USER", "TABLE", "TEMPORARY", "THEN", "TIME", + "TIMESTAMP", "TIMEZONE_HOUR", "TIMEZONE_MINUTE", "TO", "TRAILING", "TRANSACTION", "TRANSLATE", + "TRANSLATION", "TRIM", "TRUE", "UNION", "UNIQUE", "UNKNOWN", "UPDATE", "UPPER", "USAGE", "USER", "USING", + "VALUE", "VALUES", "VARCHAR", "VARYING", "VIEW", "WHEN", "WHENEVER", "WHERE", "WITH", "WORK", "WRITE", + "YEAR", "ZONE" }; - return new com.mysql.jdbc.ResultSet(c.getCatalog(), fields, - new RowDataStatic(rows), c, null); - } + // SQL:2003 reserved words from 'ISO/IEC 9075-2:2003 (E), 2003-07-25' + private static final String[] SQL2003_KEYWORDS = new String[] { "ABS", "ALL", "ALLOCATE", "ALTER", "AND", "ANY", + "ARE", "ARRAY", "AS", "ASENSITIVE", "ASYMMETRIC", "AT", "ATOMIC", "AUTHORIZATION", "AVG", "BEGIN", + "BETWEEN", "BIGINT", "BINARY", "BLOB", "BOOLEAN", "BOTH", "BY", "CALL", "CALLED", "CARDINALITY", + "CASCADED", "CASE", "CAST", "CEIL", "CEILING", "CHAR", "CHARACTER", "CHARACTER_LENGTH", "CHAR_LENGTH", + "CHECK", "CLOB", "CLOSE", "COALESCE", "COLLATE", "COLLECT", "COLUMN", "COMMIT", "CONDITION", "CONNECT", + "CONSTRAINT", "CONVERT", "CORR", "CORRESPONDING", "COUNT", "COVAR_POP", "COVAR_SAMP", "CREATE", "CROSS", + "CUBE", "CUME_DIST", "CURRENT", "CURRENT_DATE", "CURRENT_DEFAULT_TRANSFORM_GROUP", "CURRENT_PATH", + "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_TRANSFORM_GROUP_FOR_TYPE", "CURRENT_USER", + "CURSOR", "CYCLE", "DATE", "DAY", "DEALLOCATE", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DELETE", + "DENSE_RANK", "DEREF", "DESCRIBE", "DETERMINISTIC", "DISCONNECT", "DISTINCT", "DOUBLE", "DROP", "DYNAMIC", + "EACH", "ELEMENT", "ELSE", "END", "END-EXEC", "ESCAPE", "EVERY", "EXCEPT", "EXEC", "EXECUTE", "EXISTS", + "EXP", "EXTERNAL", "EXTRACT", "FALSE", "FETCH", "FILTER", "FLOAT", "FLOOR", "FOR", "FOREIGN", "FREE", + "FROM", "FULL", "FUNCTION", "FUSION", "GET", "GLOBAL", "GRANT", "GROUP", "GROUPING", "HAVING", "HOLD", + "HOUR", "IDENTITY", "IN", "INDICATOR", "INNER", "INOUT", "INSENSITIVE", "INSERT", "INT", "INTEGER", + "INTERSECT", "INTERSECTION", "INTERVAL", "INTO", "IS", "JOIN", "LANGUAGE", "LARGE", "LATERAL", "LEADING", + "LEFT", "LIKE", "LN", "LOCAL", "LOCALTIME", "LOCALTIMESTAMP", "LOWER", "MATCH", "MAX", "MEMBER", "MERGE", + "METHOD", "MIN", "MINUTE", "MOD", "MODIFIES", "MODULE", "MONTH", "MULTISET", "NATIONAL", "NATURAL", + "NCHAR", "NCLOB", "NEW", "NO", "NONE", "NORMALIZE", "NOT", "NULL", "NULLIF", "NUMERIC", "OCTET_LENGTH", + "OF", "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" }; + private static volatile String mysqlKeywords = null; + /** The connection to the database */ - protected Connection conn; + protected MySQLConnection conn; /** The 'current' database name being used */ protected String database = null; /** What character to use when quoting identifiers */ protected String quotedId = null; + // We need to provide factory-style methods so we can support both JDBC3 (and older) + // and JDBC4 runtimes, otherwise the class verifier complains... + + 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)) { + return new DatabaseMetaDataUsingInfoSchema(connToSet, + databaseToSet); + } + + return new DatabaseMetaData(connToSet, databaseToSet); + } + + if (checkForInfoSchema && connToSet != null + && connToSet.getUseInformationSchema() + && connToSet.versionMeetsMinimum(5, 0, 7)) { + + return (DatabaseMetaData) Util.handleNewInstance( + JDBC_4_DBMD_IS_CTOR, new Object[] { connToSet, + databaseToSet }, connToSet.getExceptionInterceptor()); + } + + return (DatabaseMetaData) Util.handleNewInstance(JDBC_4_DBMD_SHOW_CTOR, + new Object[] { connToSet, databaseToSet }, connToSet.getExceptionInterceptor()); + } + /** * Creates a new DatabaseMetaData object. * @@ -623,10 +858,11 @@ * @param databaseToSet * DOCUMENT ME! */ - public DatabaseMetaData(Connection connToSet, String databaseToSet) { + protected DatabaseMetaData(MySQLConnection connToSet, String databaseToSet) { this.conn = connToSet; this.database = databaseToSet; - + this.exceptionInterceptor = this.conn.getExceptionInterceptor(); + try { this.quotedId = this.conn.supportsQuotedIdentifiers() ? getIdentifierQuoteString() : ""; @@ -662,13 +898,39 @@ } private java.sql.ResultSet buildResultSet(com.mysql.jdbc.Field[] fields, - java.util.ArrayList rows) throws SQLException { + java.util.ArrayList rows) throws SQLException { return buildResultSet(fields, rows, this.conn); } + + static java.sql.ResultSet buildResultSet(com.mysql.jdbc.Field[] fields, + java.util.ArrayList rows, MySQLConnection c) throws SQLException { + int fieldsLength = fields.length; - private void convertToJdbcFunctionList(String catalog, + for (int i = 0; i < fieldsLength; i++) { + int jdbcType = fields[i].getSQLType(); + + switch (jdbcType) { + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + fields[i].setCharacterSet(c.getCharacterSetMetadata()); + break; + default: + // do nothing + } + + fields[i].setConnection(c); + fields[i].setUseOldNameMetadata(true); + } + + return com.mysql.jdbc.ResultSetImpl.getInstance(c.getCatalog(), fields, + new RowDataStatic(rows), c, null, false); + } + + protected void convertToJdbcFunctionList(String catalog, ResultSet proceduresRs, boolean needsClientFiltering, String db, - Map procedureRowsOrderedByName, int nameIndex) throws SQLException { + List> procedureRows, int nameIndex, + Field[] fields) throws SQLException { while (proceduresRs.next()) { boolean shouldAdd = true; @@ -686,24 +948,52 @@ if (shouldAdd) { String functionName = proceduresRs.getString(nameIndex); - byte[][] rowData = new byte[8][]; - rowData[0] = catalog == null ? null : s2b(catalog); - rowData[1] = null; - rowData[2] = s2b(functionName); - rowData[3] = null; - rowData[4] = null; - rowData[5] = null; - rowData[6] = null; - rowData[7] = s2b(Integer.toString(procedureReturnsResult)); + + byte[][] rowData = null; + + if (fields != null && fields.length == 9) { + + rowData = new byte[9][]; + rowData[0] = catalog == null ? null : s2b(catalog); // PROCEDURE_CAT + rowData[1] = null; // PROCEDURE_SCHEM + rowData[2] = s2b(functionName); // PROCEDURE_NAME + rowData[3] = null; // reserved1 + rowData[4] = null; // reserved2 + rowData[5] = null; // reserved3 + rowData[6] = s2b(proceduresRs.getString("comment")); // REMARKS + rowData[7] = s2b(Integer.toString(procedureReturnsResult)); // PROCEDURE_TYPE + rowData[8] = s2b(functionName); + } else { + + rowData = new byte[6][]; + + rowData[0] = catalog == null ? null : s2b(catalog); // FUNCTION_CAT + rowData[1] = null; // FUNCTION_SCHEM + rowData[2] = s2b(functionName); // FUNCTION_NAME + rowData[3] = s2b(proceduresRs.getString("comment")); // REMARKS + rowData[4] = s2b(Integer.toString(getJDBC4FunctionNoTableConstant())); // FUNCTION_TYPE + rowData[5] = s2b(functionName); // SPECFIC NAME + } - procedureRowsOrderedByName.put(functionName, rowData); + procedureRows.add(new ComparableWrapper(functionName, new ByteArrayRow(rowData, + getExceptionInterceptor()))); } } } - - private void convertToJdbcProcedureList(boolean fromSelect, String catalog, + + /** + * Getter to JDBC4 DatabaseMetaData.functionNoTable constant. + * This method must be overridden by JDBC4 subclasses. This implementation should never be called. + * + * @return 0 + */ + protected int getJDBC4FunctionNoTableConstant() { + return 0; + } + + protected void convertToJdbcProcedureList(boolean fromSelect, String catalog, ResultSet proceduresRs, boolean needsClientFiltering, String db, - Map procedureRowsOrderedByName, int nameIndex) throws SQLException { + List> procedureRows, int nameIndex) throws SQLException { while (proceduresRs.next()) { boolean shouldAdd = true; @@ -721,83 +1011,144 @@ if (shouldAdd) { String procedureName = proceduresRs.getString(nameIndex); - byte[][] rowData = new byte[8][]; + byte[][] rowData = new byte[9][]; rowData[0] = catalog == null ? null : s2b(catalog); rowData[1] = null; rowData[2] = s2b(procedureName); rowData[3] = null; rowData[4] = null; rowData[5] = null; - rowData[6] = null; + rowData[6] = s2b(proceduresRs.getString("comment")); boolean isFunction = fromSelect ? "FUNCTION" .equalsIgnoreCase(proceduresRs.getString("type")) : false; rowData[7] = s2b(isFunction ? Integer .toString(procedureReturnsResult) : Integer - .toString(procedureResultUnknown)); + .toString(procedureNoResult)); - procedureRowsOrderedByName.put(procedureName, rowData); + rowData[8] = s2b(procedureName); + + procedureRows.add(new ComparableWrapper(procedureName, new ByteArrayRow(rowData, + getExceptionInterceptor()))); } } } - private byte[][] convertTypeDescriptorToProcedureRow( - byte[] procNameAsBytes, String paramName, boolean isOutParam, - boolean isInParam, boolean isReturnParam, TypeDescriptor typeDesc) + private ResultSetRow convertTypeDescriptorToProcedureRow( + byte[] procNameAsBytes, byte[] procCatAsBytes, String paramName, boolean isOutParam, + boolean isInParam, boolean isReturnParam, TypeDescriptor typeDesc, + boolean forGetFunctionColumns, + int ordinal) throws SQLException { - byte[][] row = new byte[14][]; - row[0] = null; // PROCEDURE_CAT + byte[][] row = forGetFunctionColumns ? new byte[17][] : new byte[20][]; + row[0] = procCatAsBytes; // PROCEDURE_CAT row[1] = null; // PROCEDURE_SCHEM row[2] = procNameAsBytes; // PROCEDURE/NAME row[3] = s2b(paramName); // COLUMN_NAME - // COLUMN_TYPE - if (isInParam && isOutParam) { - row[4] = s2b(String.valueOf(procedureColumnInOut)); - } else if (isInParam) { - row[4] = s2b(String.valueOf(procedureColumnIn)); - } else if (isOutParam) { - row[4] = s2b(String.valueOf(procedureColumnOut)); - } else if (isReturnParam) { - row[4] = s2b(String.valueOf(procedureColumnReturn)); - } else { - row[4] = s2b(String.valueOf(procedureColumnUnknown)); - } + row[4] = s2b(String.valueOf(getColumnType(isOutParam, isInParam, isReturnParam, forGetFunctionColumns))); // COLUMN_TYPE row[5] = s2b(Short.toString(typeDesc.dataType)); // DATA_TYPE row[6] = s2b(typeDesc.typeName); // TYPE_NAME - row[7] = typeDesc.columnSize == null ? null : s2b(typeDesc.columnSize - .toString()); // PRECISION - row[8] = s2b(Integer.toString(typeDesc.bufferLength)); // LENGTH - row[9] = typeDesc.decimalDigits == null ? null - : s2b(typeDesc.decimalDigits.toString()); // SCALE + row[7] = typeDesc.columnSize == null ? null : s2b(typeDesc.columnSize.toString()); // PRECISION + row[8] = row[7]; // LENGTH + row[9] = typeDesc.decimalDigits == null ? null : s2b(typeDesc.decimalDigits.toString()); // SCALE row[10] = s2b(Integer.toString(typeDesc.numPrecRadix)); // RADIX // Map 'column****' to 'procedure****' switch (typeDesc.nullability) { case columnNoNulls: - row[11] = s2b(Integer.toString(procedureNoNulls)); // NULLABLE - + row[11] = s2b(String.valueOf(procedureNoNulls)); // NULLABLE break; case columnNullable: - row[11] = s2b(Integer.toString(procedureNullable)); // NULLABLE - + row[11] = s2b(String.valueOf(procedureNullable)); // NULLABLE break; case columnNullableUnknown: - row[11] = s2b(Integer.toString(procedureNullableUnknown)); // nullable - + row[11] = s2b(String.valueOf(procedureNullableUnknown)); // NULLABLE break; default: - throw SQLError - .createSQLException( - "Internal error while parsing callable statement metadata (unknown nullability value fount)", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException( + "Internal error while parsing callable statement metadata (unknown nullability value fount)", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } + row[12] = null; - return row; + + if (forGetFunctionColumns) { + // CHAR_OCTECT_LENGTH + row[13] = null; + + // ORDINAL_POSITION + row[14] = s2b(String.valueOf(ordinal)); + + // IS_NULLABLE + row[15] = s2b(typeDesc.isNullable); + + // SPECIFIC_NAME + row[16] = procNameAsBytes; + } else { + // COLUMN_DEF + row[13] = null; + + // SQL_DATA_TYPE (future use) + row[14] = null; + + // SQL_DATETIME_SUB (future use) + row[15] = null; + + // CHAR_OCTET_LENGTH + row[16] = null; + + // ORDINAL_POSITION + row[17] = s2b(String.valueOf(ordinal)); + + // IS_NULLABLE + row[18] = s2b(typeDesc.isNullable); + + // SPECIFIC_NAME + row[19] = procNameAsBytes; + } + + return new ByteArrayRow(row, getExceptionInterceptor()); } + + /** + * Determines the COLUMN_TYPE information based on parameter type (IN, OUT or INOUT) or function return parameter. + * + * @param isOutParam + * Indicates whether it's an output parameter. + * @param isInParam + * Indicates whether it's an input parameter. + * @param isReturnParam + * Indicates whether it's a function return parameter. + * @param forGetFunctionColumns + * Indicates whether the column belong to a function. This argument is required for JDBC4, in which case + * this method must be overridden to provide the correct functionality. + * + * @return The corresponding COLUMN_TYPE as in java.sql.getProcedureColumns API. + */ + protected int getColumnType(boolean isOutParam, boolean isInParam, boolean isReturnParam, + boolean forGetFunctionColumns) { + if (isInParam && isOutParam) { + return procedureColumnInOut; + } else if (isInParam) { + return procedureColumnIn; + } else if (isOutParam) { + return procedureColumnOut; + } else if (isReturnParam) { + return procedureColumnReturn; + } else { + return procedureColumnUnknown; + } + } + private ExceptionInterceptor exceptionInterceptor; + + protected ExceptionInterceptor getExceptionInterceptor() { + return this.exceptionInterceptor; + } + /** * Does a data definition statement within a transaction force the * transaction to commit? @@ -850,61 +1201,6 @@ } /** - * Finds the end of the parameter declaration from the output of "SHOW - * CREATE PROCEDURE". - * - * @param beginIndex - * should be the index of the procedure body that contains the - * first "(". - * @param procedureDef - * the procedure body - * @param quoteChar - * the identifier quote character in use - * @return the ending index of the parameter declaration, not including the - * closing ")" - * @throws SQLException - * if a parse error occurs. - */ - private int endPositionOfParameterDeclaration(int beginIndex, - String procedureDef, String quoteChar) throws SQLException { - int currentPos = beginIndex + 1; - int parenDepth = 1; // counting the first openParen - - while (parenDepth > 0 && currentPos < procedureDef.length()) { - int closedParenIndex = StringUtils.indexOfIgnoreCaseRespectQuotes( - currentPos, procedureDef, ")", quoteChar.charAt(0), - !this.conn.isNoBackslashEscapesSet()); - - if (closedParenIndex != -1) { - int nextOpenParenIndex = StringUtils - .indexOfIgnoreCaseRespectQuotes(currentPos, - procedureDef, "(", quoteChar.charAt(0), - !this.conn.isNoBackslashEscapesSet()); - - if (nextOpenParenIndex != -1 - && nextOpenParenIndex < closedParenIndex) { - parenDepth++; - currentPos = closedParenIndex + 1; // set after closed - // paren that increases - // depth - } else { - parenDepth--; - currentPos = closedParenIndex; // start search from same - // position - } - } else { - // we should always get closed paren of some sort - throw SQLError - .createSQLException( - "Internal error when parsing callable statement metadata", - SQLError.SQL_STATE_GENERAL_ERROR); - } - } - - return currentPos; - } - - /** * Extracts foreign key info for one table. * * @param rows @@ -917,139 +1213,122 @@ * @throws SQLException * if a database access error occurs */ - public List extractForeignKeyForTable(ArrayList rows, + public List extractForeignKeyForTable(ArrayList rows, java.sql.ResultSet rs, String catalog) throws SQLException { byte[][] row = new byte[3][]; row[0] = rs.getBytes(1); row[1] = s2b(SUPPORTS_FK); - + String createTableString = rs.getString(2); StringTokenizer lineTokenizer = new StringTokenizer(createTableString, "\n"); StringBuffer commentBuf = new StringBuffer("comment; "); boolean firstTime = true; - + String quoteChar = getIdentifierQuoteString(); - + if (quoteChar == null) { quoteChar = "`"; } - + while (lineTokenizer.hasMoreTokens()) { String line = lineTokenizer.nextToken().trim(); - + String constraintName = null; - + if (StringUtils.startsWithIgnoreCase(line, "CONSTRAINT")) { boolean usingBackTicks = true; - int beginPos = line.indexOf(quoteChar); - + int beginPos = StringUtils.indexOfQuoteDoubleAware(line, quoteChar, 0); + if (beginPos == -1) { beginPos = line.indexOf("\""); usingBackTicks = false; } - + if (beginPos != -1) { int endPos = -1; - + if (usingBackTicks) { - endPos = line.indexOf(quoteChar, beginPos + 1); + endPos = StringUtils.indexOfQuoteDoubleAware(line, quoteChar, beginPos + 1); } else { - endPos = line.indexOf("\"", beginPos + 1); + endPos = StringUtils.indexOfQuoteDoubleAware(line, "\"", beginPos + 1); } - + if (endPos != -1) { constraintName = line.substring(beginPos + 1, endPos); line = line.substring(endPos + 1, line.length()).trim(); } } } - + + if (line.startsWith("FOREIGN KEY")) { if (line.endsWith(",")) { line = line.substring(0, line.length() - 1); } - + char quote = this.quotedId.charAt(0); - + int indexOfFK = line.indexOf("FOREIGN KEY"); - + String localColumnName = null; - String referencedCatalogName = this.quotedId + catalog - + this.quotedId; + String referencedCatalogName = StringUtils.quoteIdentifier(catalog, this.conn.getPedantic()); String referencedTableName = null; String referencedColumnName = null; - + + if (indexOfFK != -1) { int afterFk = indexOfFK + "FOREIGN KEY".length(); - - int indexOfRef = StringUtils - .indexOfIgnoreCaseRespectQuotes(afterFk, line, - "REFERENCES", quote, true); - + + int indexOfRef = StringUtils.indexOfIgnoreCaseRespectQuotes(afterFk, line, "REFERENCES", quote, true); + if (indexOfRef != -1) { - + int indexOfParenOpen = line.indexOf('(', afterFk); - int indexOfParenClose = StringUtils - .indexOfIgnoreCaseRespectQuotes( - indexOfParenOpen, line, ")", quote, - true); - + int indexOfParenClose = StringUtils.indexOfIgnoreCaseRespectQuotes(indexOfParenOpen, line, ")", quote, true); + if (indexOfParenOpen == -1 || indexOfParenClose == -1) { // throw SQLError.createSQLException(); } - - localColumnName = line.substring(indexOfParenOpen + 1, - indexOfParenClose); - + + localColumnName = line.substring(indexOfParenOpen + 1, indexOfParenClose); + int afterRef = indexOfRef + "REFERENCES".length(); - - int referencedColumnBegin = StringUtils - .indexOfIgnoreCaseRespectQuotes(afterRef, line, - "(", quote, true); - + + int referencedColumnBegin = StringUtils.indexOfIgnoreCaseRespectQuotes(afterRef, line, "(", quote, true); + if (referencedColumnBegin != -1) { - referencedTableName = line.substring(afterRef, - referencedColumnBegin); - - int referencedColumnEnd = StringUtils - .indexOfIgnoreCaseRespectQuotes( - referencedColumnBegin + 1, line, - ")", quote, true); - + referencedTableName = line.substring(afterRef, referencedColumnBegin); + + int referencedColumnEnd = StringUtils.indexOfIgnoreCaseRespectQuotes(referencedColumnBegin + 1, line, ")", quote, true); + if (referencedColumnEnd != -1) { - referencedColumnName = line.substring( - referencedColumnBegin + 1, - referencedColumnEnd); + referencedColumnName = line.substring(referencedColumnBegin + 1, referencedColumnEnd); } - - int indexOfCatalogSep = StringUtils - .indexOfIgnoreCaseRespectQuotes(0, - referencedTableName, ".", quote, - true); - + + int indexOfCatalogSep = StringUtils.indexOfIgnoreCaseRespectQuotes(0, referencedTableName, ".", quote, true); + if (indexOfCatalogSep != -1) { - referencedCatalogName = referencedTableName - .substring(0, indexOfCatalogSep); - referencedTableName = referencedTableName - .substring(indexOfCatalogSep + 1); + referencedCatalogName = referencedTableName.substring(0, indexOfCatalogSep); + referencedTableName = referencedTableName.substring(indexOfCatalogSep + 1); } } } } - + + if (!firstTime) { commentBuf.append("; "); } else { firstTime = false; } - + if (constraintName != null) { commentBuf.append(constraintName); } else { commentBuf.append("not_available"); } - + commentBuf.append("("); commentBuf.append(localColumnName); commentBuf.append(") REFER "); @@ -1059,21 +1338,21 @@ commentBuf.append("("); commentBuf.append(referencedColumnName); commentBuf.append(")"); - + int lastParenIndex = line.lastIndexOf(")"); - + if (lastParenIndex != (line.length() - 1)) { - String cascadeOptions = cascadeOptions = line + String cascadeOptions = line .substring(lastParenIndex + 1); commentBuf.append(" "); commentBuf.append(cascadeOptions); } } } - + row[2] = s2b(commentBuf.toString()); - rows.add(row); - + rows.add(new ByteArrayRow(row, getExceptionInterceptor())); + return rows; } @@ -1095,7 +1374,7 @@ */ public ResultSet extractForeignKeyFromCreateTable(String catalog, String tableName) throws SQLException { - ArrayList tableList = new ArrayList(); + ArrayList tableList = new ArrayList(); java.sql.ResultSet rs = null; java.sql.Statement stmt = null; @@ -1117,7 +1396,7 @@ } } - ArrayList rows = new ArrayList(); + ArrayList rows = new ArrayList(); Field[] fields = new Field[3]; fields[0] = new Field("", "Name", Types.CHAR, Integer.MAX_VALUE); fields[1] = new Field("", "Type", Types.CHAR, 255); @@ -1134,12 +1413,12 @@ try { for (int i = 0; i < numTables; i++) { - String tableToExtract = (String) tableList.get(i); - - String query = new StringBuffer("SHOW CREATE TABLE ").append( - quoteChar).append(catalog).append(quoteChar) - .append(".").append(quoteChar).append(tableToExtract) - .append(quoteChar).toString(); + String tableToExtract = tableList.get(i); + + String query = new StringBuffer("SHOW CREATE TABLE ") + .append(StringUtils.quoteIdentifier(catalog, this.conn.getPedantic())).append(".") + .append(StringUtils.quoteIdentifier(tableToExtract, this.conn.getPedantic())).toString(); + try { rs = stmt.executeQuery(query); } catch (SQLException sqlEx) { @@ -1176,65 +1455,6 @@ } /** - * Finds the end of the RETURNS clause for SQL Functions by using any of the - * keywords allowed after the RETURNS clause, or a label. - * - * @param procedureDefn - * the function body containing the definition of the function - * @param quoteChar - * the identifier quote string in use - * @param positionOfReturnKeyword - * the position of "RETRUNS" in the definition - * @return the end of the returns clause - * @throws SQLException - * if a parse error occurs - */ - private int findEndOfReturnsClause(String procedureDefn, String quoteChar, - int positionOfReturnKeyword) throws SQLException { - /* - * characteristic: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | - * NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { - * DEFINER | INVOKER } | COMMENT 'string' - */ - - String[] tokens = new String[] { "LANGUAGE", "NOT", "DETERMINISTIC", - "CONTAINS", "NO", "READ", "MODIFIES", "SQL", "COMMENT", "BEGIN", - "RETURN" }; - - int startLookingAt = positionOfReturnKeyword + "RETURNS".length() + 1; - - for (int i = 0; i < tokens.length; i++) { - int endOfReturn = StringUtils.indexOfIgnoreCaseRespectQuotes( - startLookingAt, procedureDefn, tokens[i], quoteChar - .charAt(0), !this.conn.isNoBackslashEscapesSet()); - - if (endOfReturn != -1) { - return endOfReturn; - } - } - - // Label? - int endOfReturn = StringUtils.indexOfIgnoreCaseRespectQuotes( - startLookingAt, procedureDefn, ":", quoteChar.charAt(0), - !this.conn.isNoBackslashEscapesSet()); - - if (endOfReturn != -1) { - // seek back until whitespace - for (int i = endOfReturn; i > 0; i--) { - if (Character.isWhitespace(procedureDefn.charAt(i))) { - return i; - } - } - } - - // We can't parse it. - - throw SQLError.createSQLException( - "Internal error when parsing callable statement metadata", - SQLError.SQL_STATE_GENERAL_ERROR); - } - - /** * @see DatabaseMetaData#getAttributes(String, String, String, String) */ public java.sql.ResultSet getAttributes(String arg0, String arg1, @@ -1262,7 +1482,7 @@ fields[19] = new Field("", "SCOPE_TABLE", Types.CHAR, 32); fields[20] = new Field("", "SOURCE_DATA_TYPE", Types.SMALLINT, 32); - return buildResultSet(fields, new ArrayList()); + return buildResultSet(fields, new ArrayList()); } /** @@ -1315,38 +1535,34 @@ throws SQLException { if (table == null) { throw SQLError.createSQLException("Table not specified.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } Field[] fields = new Field[8]; fields[0] = new Field("", "SCOPE", Types.SMALLINT, 5); fields[1] = new Field("", "COLUMN_NAME", Types.CHAR, 32); - fields[2] = new Field("", "DATA_TYPE", Types.SMALLINT, 32); + fields[2] = new Field("", "DATA_TYPE", Types.INTEGER, 32); fields[3] = new Field("", "TYPE_NAME", Types.CHAR, 32); fields[4] = new Field("", "COLUMN_SIZE", Types.INTEGER, 10); fields[5] = new Field("", "BUFFER_LENGTH", Types.INTEGER, 10); - fields[6] = new Field("", "DECIMAL_DIGITS", Types.INTEGER, 10); + fields[6] = new Field("", "DECIMAL_DIGITS", Types.SMALLINT, 10); fields[7] = new Field("", "PSEUDO_COLUMN", Types.SMALLINT, 5); - final ArrayList rows = new ArrayList(); + final ArrayList rows = new ArrayList(); final Statement stmt = this.conn.getMetadataSafeStatement(); try { - new IterateBlock(getCatalogIterator(catalog)) { - void forEach(Object catalogStr) throws SQLException { + new IterateBlock(getCatalogIterator(catalog)) { + void forEach(String catalogStr) throws SQLException { ResultSet results = null; try { StringBuffer queryBuf = new StringBuffer( "SHOW COLUMNS FROM "); - queryBuf.append(quotedId); - queryBuf.append(table); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(table, conn.getPedantic())); queryBuf.append(" FROM "); - queryBuf.append(quotedId); - queryBuf.append(catalogStr.toString()); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())); results = stmt.executeQuery(queryBuf.toString()); @@ -1422,11 +1638,14 @@ java.sql.DatabaseMetaData.bestRowNotPseudo) .getBytes(); - rows.add(rowVal); + rows.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); } } } - + } catch (SQLException sqlEx) { + if (!SQLError.SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND.equals(sqlEx.getSQLState())) { + throw sqlEx; + } } finally { if (results != null) { try { @@ -1484,67 +1703,70 @@ * * @see #getSearchStringEscape */ - private void getCallStmtParameterTypes(String catalog, String procName, - String parameterNamePattern, List resultRows) throws SQLException { + protected void getCallStmtParameterTypes(String catalog, String procName, ProcedureType procType, + String parameterNamePattern, List resultRows) throws SQLException { + getCallStmtParameterTypes(catalog, procName, procType, + parameterNamePattern, resultRows, false); + } + + private void getCallStmtParameterTypes(String catalog, String procName, ProcedureType procType, + String parameterNamePattern, List resultRows, + boolean forGetFunctionColumns) throws SQLException { java.sql.Statement paramRetrievalStmt = null; java.sql.ResultSet paramRetrievalRs = null; if (parameterNamePattern == null) { if (this.conn.getNullNamePatternMatchesAll()) { parameterNamePattern = "%"; } else { - throw SQLError - .createSQLException( - "Parameter/Column name pattern can not be NULL or empty.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError.createSQLException( + "Parameter/Column name pattern can not be NULL or empty.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } - byte[] procNameAsBytes = null; - - try { - procNameAsBytes = procName.getBytes("UTF-8"); - } catch (UnsupportedEncodingException ueEx) { - procNameAsBytes = s2b(procName); - } - String quoteChar = getIdentifierQuoteString(); String parameterDef = null; + byte[] procNameAsBytes = null; + byte[] procCatAsBytes = null; + boolean isProcedureInAnsiMode = false; String storageDefnDelims = null; String storageDefnClosures = null; try { paramRetrievalStmt = this.conn.getMetadataSafeStatement(); - - if (this.conn.lowerCaseTableNames() && catalog != null - && catalog.length() != 0) { - // Workaround for bug in server wrt. to + + String oldCatalog = this.conn.getCatalog(); + if (this.conn.lowerCaseTableNames() && catalog != null + && catalog.length() != 0 && oldCatalog != null + && oldCatalog.length() != 0) { + // Workaround for bug in server wrt. to // SHOW CREATE PROCEDURE not respecting // lower-case table names - - String oldCatalog = this.conn.getCatalog(); + ResultSet rs = null; - + try { - this.conn.setCatalog(catalog); + // TODO it isn't right to eliminate all quote chars if catalog name contains them in the middle + this.conn.setCatalog(catalog.replaceAll(quoteChar, "")); rs = paramRetrievalStmt.executeQuery("SELECT DATABASE()"); rs.next(); - + catalog = rs.getString(1); - + } finally { - + this.conn.setCatalog(oldCatalog); - + if (rs != null) { rs.close(); } } } - + if (paramRetrievalStmt.getMaxRows() != 0) { paramRetrievalStmt.setMaxRows(0); } @@ -1568,6 +1790,29 @@ dbName = catalog; } + // Moved from above so that procName is *without* database as expected + // by the rest of code + // Removing QuoteChar to get output as it was before PROC_CAT fixes + String tmpProcName = procName; + tmpProcName = tmpProcName.replaceAll(quoteChar, ""); + try { + procNameAsBytes = StringUtils.getBytes(tmpProcName, "UTF-8"); + } catch (UnsupportedEncodingException ueEx) { + procNameAsBytes = s2b(tmpProcName); + + // Set all fields to connection encoding + } + + tmpProcName = dbName; + tmpProcName = tmpProcName.replaceAll(quoteChar, ""); + try { + procCatAsBytes = StringUtils.getBytes(tmpProcName, "UTF-8"); + } catch (UnsupportedEncodingException ueEx) { + procCatAsBytes = s2b(tmpProcName); + + // Set all fields to connection encoding + } + StringBuffer procNameBuf = new StringBuffer(); if (dbName != null) { @@ -1596,32 +1841,24 @@ procNameBuf.append(quoteChar); } - boolean parsingFunction = false; - - try { - paramRetrievalRs = paramRetrievalStmt - .executeQuery("SHOW CREATE PROCEDURE " - + procNameBuf.toString()); - parsingFunction = false; - } catch (SQLException sqlEx) { - paramRetrievalRs = paramRetrievalStmt - .executeQuery("SHOW CREATE FUNCTION " - + procNameBuf.toString()); - parsingFunction = true; + String fieldName = null; + if (procType == PROCEDURE) { + paramRetrievalRs = paramRetrievalStmt.executeQuery("SHOW CREATE PROCEDURE " + procNameBuf.toString()); + fieldName = "Create Procedure"; + } else { + paramRetrievalRs = paramRetrievalStmt.executeQuery("SHOW CREATE FUNCTION " + procNameBuf.toString()); + fieldName = "Create Function"; } if (paramRetrievalRs.next()) { - String procedureDef = parsingFunction ? paramRetrievalRs - .getString("Create Function") : paramRetrievalRs - .getString("Create Procedure"); - - if (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.", - SQLError.SQL_STATE_GENERAL_ERROR); + 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.", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } try { @@ -1639,63 +1876,66 @@ storageDefnDelims = "(" + identifierMarkers; storageDefnClosures = ")" + identifierMarkers; - // sanitize/normalize by stripping out comments - procedureDef = StringUtils.stripComments(procedureDef, - identifierAndStringMarkers, identifierAndStringMarkers, true, false, true, true); - - int openParenIndex = StringUtils - .indexOfIgnoreCaseRespectQuotes(0, procedureDef, "(", - quoteChar.charAt(0), !this.conn - .isNoBackslashEscapesSet()); - int endOfParamDeclarationIndex = 0; + if (procedureDef != null && procedureDef.length() != 0) { + // sanitize/normalize by stripping out comments + procedureDef = StringUtils.stripComments(procedureDef, + identifierAndStringMarkers, identifierAndStringMarkers, true, false, true, true); + + int openParenIndex = StringUtils + .indexOfIgnoreCaseRespectQuotes(0, procedureDef, "(", + quoteChar.charAt(0), !this.conn + .isNoBackslashEscapesSet()); + int endOfParamDeclarationIndex = 0; - endOfParamDeclarationIndex = endPositionOfParameterDeclaration( - openParenIndex, procedureDef, quoteChar); + endOfParamDeclarationIndex = endPositionOfParameterDeclaration( + openParenIndex, procedureDef, quoteChar); - if (parsingFunction) { + if (procType == FUNCTION) { - // Grab the return column since it needs - // to go first in the output result set - int returnsIndex = StringUtils - .indexOfIgnoreCaseRespectQuotes(0, procedureDef, - " RETURNS ", quoteChar.charAt(0), - !this.conn.isNoBackslashEscapesSet()); + // Grab the return column since it needs + // to go first in the output result set + int returnsIndex = StringUtils + .indexOfIgnoreCaseRespectQuotes(0, procedureDef, + " RETURNS ", quoteChar.charAt(0), + !this.conn.isNoBackslashEscapesSet()); - int endReturnsDef = findEndOfReturnsClause(procedureDef, - quoteChar, returnsIndex); + int endReturnsDef = findEndOfReturnsClause(procedureDef, + quoteChar, returnsIndex); - // Trim off whitespace after "RETURNS" - - int declarationStart = returnsIndex + "RETURNS ".length(); - - while (declarationStart < procedureDef.length()) { - if (Character.isWhitespace(procedureDef.charAt(declarationStart))) { - declarationStart++; - } else { - break; + // Trim off whitespace after "RETURNS" + + int declarationStart = returnsIndex + "RETURNS ".length(); + + while (declarationStart < procedureDef.length()) { + if (Character.isWhitespace(procedureDef.charAt(declarationStart))) { + declarationStart++; + } else { + break; + } } + + String returnsDefn = procedureDef.substring(declarationStart, endReturnsDef).trim(); + TypeDescriptor returnDescriptor = new TypeDescriptor( + returnsDefn, "YES"); + + resultRows.add(convertTypeDescriptorToProcedureRow( + procNameAsBytes, procCatAsBytes, "", false, false, true, + returnDescriptor, forGetFunctionColumns, 0)); } - - String returnsDefn = procedureDef.substring(declarationStart, endReturnsDef).trim(); - TypeDescriptor returnDescriptor = new TypeDescriptor( - returnsDefn, null); - resultRows.add(convertTypeDescriptorToProcedureRow( - procNameAsBytes, "", false, false, true, - returnDescriptor)); - } + if ((openParenIndex == -1) + || (endOfParamDeclarationIndex == -1)) { + // parse error? + throw SQLError + .createSQLException( + "Internal error when parsing callable statement metadata", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + } - if ((openParenIndex == -1) - || (endOfParamDeclarationIndex == -1)) { - // parse error? - throw SQLError - .createSQLException( - "Internal error when parsing callable statement metadata", - SQLError.SQL_STATE_GENERAL_ERROR); + parameterDef = procedureDef.substring(openParenIndex + 1, + endOfParamDeclarationIndex); } - - parameterDef = procedureDef.substring(openParenIndex + 1, - endOfParamDeclarationIndex); + } } finally { SQLException sqlExRethrow = null; @@ -1726,20 +1966,23 @@ } if (parameterDef != null) { - - List parseList = StringUtils.split(parameterDef, ",", + int ordinal = 1; + + List parseList = StringUtils.split(parameterDef, ",", storageDefnDelims, storageDefnClosures, true); int parseListLen = parseList.size(); for (int i = 0; i < parseListLen; i++) { - String declaration = (String) parseList.get(i); + String declaration = parseList.get(i); if (declaration.trim().length() == 0) { - break; // no parameters actually declared, but whitespace - // spans lines + break; // no parameters actually declared, but whitespace spans lines } - + + // Bug#52167, tokenizer will break if declaration + // contains special characters like \n + declaration = declaration.replaceAll("[\\t\\n\\x0B\\f\\r]", " "); StringTokenizer declarationTok = new StringTokenizer( declaration, " \t"); @@ -1756,10 +1999,9 @@ if (declarationTok.hasMoreTokens()) { paramName = declarationTok.nextToken(); } else { - throw SQLError - .createSQLException( - "Internal error when parsing callable statement metadata (missing parameter name)", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException( + "Internal error when parsing callable statement metadata (missing parameter name)", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } else if (possibleParamName.equalsIgnoreCase("INOUT")) { isOutParam = true; @@ -1768,10 +2010,9 @@ if (declarationTok.hasMoreTokens()) { paramName = declarationTok.nextToken(); } else { - throw SQLError - .createSQLException( - "Internal error when parsing callable statement metadata (missing parameter name)", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException( + "Internal error when parsing callable statement metadata (missing parameter name)", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } else if (possibleParamName.equalsIgnoreCase("IN")) { isOutParam = false; @@ -1780,10 +2021,9 @@ if (declarationTok.hasMoreTokens()) { paramName = declarationTok.nextToken(); } else { - throw SQLError - .createSQLException( - "Internal error when parsing callable statement metadata (missing parameter name)", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException( + "Internal error when parsing callable statement metadata (missing parameter name)", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } else { isOutParam = false; @@ -1805,34 +2045,33 @@ String typeInfo = typeInfoBuf.toString(); - typeDesc = new TypeDescriptor(typeInfo, null); + typeDesc = new TypeDescriptor(typeInfo, "YES"); } else { - throw SQLError - .createSQLException( - "Internal error when parsing callable statement metadata (missing parameter type)", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException( + "Internal error when parsing callable statement metadata (missing parameter type)", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } if ((paramName.startsWith("`") && paramName.endsWith("`")) || (isProcedureInAnsiMode && paramName.startsWith("\"") && paramName.endsWith("\""))) { paramName = paramName.substring(1, paramName.length() - 1); } - + int wildCompareRes = StringUtils.wildCompare(paramName, parameterNamePattern); if (wildCompareRes != StringUtils.WILD_COMPARE_NO_MATCH) { - byte[][] row = convertTypeDescriptorToProcedureRow( - procNameAsBytes, paramName, isOutParam, - isInParam, false, typeDesc); + ResultSetRow row = convertTypeDescriptorToProcedureRow( + procNameAsBytes, procCatAsBytes, paramName, isOutParam, + isInParam, false, typeDesc, forGetFunctionColumns, + ordinal++); resultRows.add(row); } } else { - throw SQLError - .createSQLException( - "Internal error when parsing callable statement metadata (unknown output from 'SHOW CREATE PROCEDURE')", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException( + "Internal error when parsing callable statement metadata (unknown output from 'SHOW CREATE PROCEDURE')", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } } else { @@ -1841,8 +2080,129 @@ // exist, is it an error.... } } + /** + * Finds the end of the parameter declaration from the output of "SHOW + * CREATE PROCEDURE". + * + * @param beginIndex + * should be the index of the procedure body that contains the + * first "(". + * @param procedureDef + * the procedure body + * @param quoteChar + * the identifier quote character in use + * @return the ending index of the parameter declaration, not including the + * closing ")" + * @throws SQLException + * if a parse error occurs. + */ + private int endPositionOfParameterDeclaration(int beginIndex, + String procedureDef, String quoteChar) throws SQLException { + int currentPos = beginIndex + 1; + int parenDepth = 1; // counting the first openParen + while (parenDepth > 0 && currentPos < procedureDef.length()) { + int closedParenIndex = StringUtils.indexOfIgnoreCaseRespectQuotes( + currentPos, procedureDef, ")", quoteChar.charAt(0), + !this.conn.isNoBackslashEscapesSet()); + + if (closedParenIndex != -1) { + int nextOpenParenIndex = StringUtils + .indexOfIgnoreCaseRespectQuotes(currentPos, + procedureDef, "(", quoteChar.charAt(0), + !this.conn.isNoBackslashEscapesSet()); + + if (nextOpenParenIndex != -1 + && nextOpenParenIndex < closedParenIndex) { + parenDepth++; + currentPos = closedParenIndex + 1; // set after closed + // paren that increases + // depth + } else { + parenDepth--; + currentPos = closedParenIndex; // start search from same + // position + } + } else { + // we should always get closed paren of some sort + throw SQLError + .createSQLException( + "Internal error when parsing callable statement metadata", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + } + } + + return currentPos; + } + /** + * Finds the end of the RETURNS clause for SQL Functions by using any of the + * keywords allowed after the RETURNS clause, or a label. + * + * @param procedureDefn + * the function body containing the definition of the function + * @param quoteChar + * the identifier quote string in use + * @param positionOfReturnKeyword + * the position of "RETRUNS" in the definition + * @return the end of the returns clause + * @throws SQLException + * if a parse error occurs + */ + private int findEndOfReturnsClause(String procedureDefn, String quoteChar, + int positionOfReturnKeyword) throws SQLException { + /* + * characteristic: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | + * NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { + * DEFINER | INVOKER } | COMMENT 'string' + */ + + String[] tokens = new String[] { "LANGUAGE", "NOT", "DETERMINISTIC", + "CONTAINS", "NO", "READ", "MODIFIES", "SQL", "COMMENT", "BEGIN", + "RETURN" }; + + int startLookingAt = positionOfReturnKeyword + "RETURNS".length() + 1; + + int endOfReturn = -1; + + for (int i = 0; i < tokens.length; i++) { + int nextEndOfReturn = StringUtils.indexOfIgnoreCaseRespectQuotes( + startLookingAt, procedureDefn, tokens[i], quoteChar + .charAt(0), !this.conn.isNoBackslashEscapesSet()); + + if (nextEndOfReturn != -1) { + if (endOfReturn == -1 || (nextEndOfReturn < endOfReturn)) { + endOfReturn = nextEndOfReturn; + } + } + } + + if (endOfReturn != -1) { + return endOfReturn; + } + + // Label? + endOfReturn = StringUtils.indexOfIgnoreCaseRespectQuotes( + startLookingAt, procedureDefn, ":", quoteChar.charAt(0), + !this.conn.isNoBackslashEscapesSet()); + + if (endOfReturn != -1) { + // seek back until whitespace + for (int i = endOfReturn; i > 0; i--) { + if (Character.isWhitespace(procedureDefn.charAt(i))) { + return i; + } + } + } + + // We can't parse it. + + throw SQLError.createSQLException( + "Internal error when parsing callable statement metadata", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + } + + /** * Parses the cascade option string and returns the DBMD constant that * represents it (for deletes) * @@ -1900,25 +2260,30 @@ return java.sql.DatabaseMetaData.importedKeyNoAction; } - protected IteratorWithCleanup getCatalogIterator(String catalogSpec) + protected IteratorWithCleanup getCatalogIterator(String catalogSpec) throws SQLException { - IteratorWithCleanup allCatalogsIter; + IteratorWithCleanup allCatalogsIter; if (catalogSpec != null) { if (!catalogSpec.equals("")) { - allCatalogsIter = new SingleStringIterator(catalogSpec); + if (conn.getPedantic()) { + allCatalogsIter = new SingleStringIterator(catalogSpec); + } else { + allCatalogsIter = new SingleStringIterator(StringUtils.unQuoteIdentifier(catalogSpec, this.conn.useAnsiQuotedIdentifiers())); + } } else { // legacy mode of operation allCatalogsIter = new SingleStringIterator(this.database); } } else if (this.conn.getNullCatalogMeansCurrent()) { + allCatalogsIter = new SingleStringIterator(this.database); } else { allCatalogsIter = new ResultSetIterator(getCatalogs(), 1); } return allCatalogsIter; } - + /** * Get the catalog names available in this database. The results are ordered * by catalog name. @@ -1948,12 +2313,12 @@ fields[0] = new Field("", "TABLE_CAT", Types.VARCHAR, resultsMD .getColumnDisplaySize(1)); - ArrayList tuples = new ArrayList(); + ArrayList tuples = new ArrayList(); while (results.next()) { byte[][] rowVal = new byte[1][]; rowVal[0] = results.getBytes(1); - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); } return buildResultSet(fields, tuples); @@ -2078,7 +2443,7 @@ Statement stmt = null; ResultSet results = null; - ArrayList grantRows = new ArrayList(); + ArrayList grantRows = new ArrayList(); try { stmt = this.conn.createStatement(); @@ -2127,7 +2492,7 @@ tuple[5] = s2b(fullUser.toString()); tuple[6] = s2b(privilege); tuple[7] = null; - grantRows.add(tuple); + grantRows.add(new ByteArrayRow(tuple, getExceptionInterceptor())); } } } @@ -2223,55 +2588,30 @@ } else { throw SQLError.createSQLException( "Column name pattern can not be NULL or empty.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } final String colPattern = columnNamePattern; - Field[] fields = new Field[23]; - fields[0] = new Field("", "TABLE_CAT", Types.CHAR, 255); - fields[1] = new Field("", "TABLE_SCHEM", Types.CHAR, 0); - fields[2] = new Field("", "TABLE_NAME", Types.CHAR, 255); - fields[3] = new Field("", "COLUMN_NAME", Types.CHAR, 32); - fields[4] = new Field("", "DATA_TYPE", Types.SMALLINT, 5); - fields[5] = new Field("", "TYPE_NAME", Types.CHAR, 16); - fields[6] = new Field("", "COLUMN_SIZE", Types.INTEGER, Integer - .toString(Integer.MAX_VALUE).length()); - fields[7] = new Field("", "BUFFER_LENGTH", Types.INTEGER, 10); - fields[8] = new Field("", "DECIMAL_DIGITS", Types.INTEGER, 10); - fields[9] = new Field("", "NUM_PREC_RADIX", Types.INTEGER, 10); - fields[10] = new Field("", "NULLABLE", Types.INTEGER, 10); - fields[11] = new Field("", "REMARKS", Types.CHAR, 0); - fields[12] = new Field("", "COLUMN_DEF", Types.CHAR, 0); - fields[13] = new Field("", "SQL_DATA_TYPE", Types.INTEGER, 10); - fields[14] = new Field("", "SQL_DATETIME_SUB", Types.INTEGER, 10); - fields[15] = new Field("", "CHAR_OCTET_LENGTH", Types.INTEGER, Integer - .toString(Integer.MAX_VALUE).length()); - fields[16] = new Field("", "ORDINAL_POSITION", Types.INTEGER, 10); - fields[17] = new Field("", "IS_NULLABLE", Types.CHAR, 3); - fields[18] = new Field("", "SCOPE_CATALOG", Types.CHAR, 255); - fields[19] = new Field("", "SCOPE_SCHEMA", Types.CHAR, 255); - fields[20] = new Field("", "SCOPE_TABLE", Types.CHAR, 255); - fields[21] = new Field("", "SOURCE_DATA_TYPE", Types.SMALLINT, 10); - fields[22] = new Field("", "IS_AUTOINCREMENT", Types.CHAR, 3); + Field[] fields = createColumnsFields(); - final ArrayList rows = new ArrayList(); + final ArrayList rows = new ArrayList(); final Statement stmt = this.conn.getMetadataSafeStatement(); try { - new IterateBlock(getCatalogIterator(catalog)) { - void forEach(Object catalogStr) throws SQLException { + new IterateBlock(getCatalogIterator(catalog)) { + void forEach(String catalogStr) throws SQLException { - ArrayList tableNameList = new ArrayList(); + ArrayList tableNameList = new ArrayList(); if (tableNamePattern == null) { // Select from all tables java.sql.ResultSet tables = null; try { - tables = getTables(catalog, schemaPattern, "%", + tables = getTables(catalogStr, schemaPattern, "%", new String[0]); while (tables.next()) { @@ -2295,7 +2635,7 @@ java.sql.ResultSet tables = null; try { - tables = getTables(catalog, schemaPattern, + tables = getTables(catalogStr, schemaPattern, tableNamePattern, new String[0]); while (tables.next()) { @@ -2317,11 +2657,8 @@ } } - java.util.Iterator tableNames = tableNameList.iterator(); - - while (tableNames.hasNext()) { - String tableName = (String) tableNames.next(); - + for (String tableName : tableNameList) { + ResultSet results = null; try { @@ -2332,13 +2669,9 @@ } queryBuf.append("COLUMNS FROM "); - queryBuf.append(quotedId); - queryBuf.append(tableName); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(tableName, conn.getPedantic())); queryBuf.append(" FROM "); - queryBuf.append(quotedId); - queryBuf.append(catalogStr.toString()); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())); queryBuf.append(" LIKE '"); queryBuf.append(colPattern); queryBuf.append("'"); @@ -2349,7 +2682,7 @@ // this, so we do it the 'hard' way...Once _SYSTEM // tables are in, this should be much easier boolean fixUpOrdinalsRequired = false; - Map ordinalFixUpMap = null; + Map ordinalFixUpMap = null; if (!colPattern.equals("%")) { fixUpOrdinalsRequired = true; @@ -2362,19 +2695,14 @@ } fullColumnQueryBuf.append("COLUMNS FROM "); - fullColumnQueryBuf.append(quotedId); - fullColumnQueryBuf.append(tableName); - fullColumnQueryBuf.append(quotedId); + fullColumnQueryBuf.append(StringUtils.quoteIdentifier(tableName, conn.getPedantic())); fullColumnQueryBuf.append(" FROM "); - fullColumnQueryBuf.append(quotedId); - fullColumnQueryBuf - .append(catalogStr.toString()); - fullColumnQueryBuf.append(quotedId); + fullColumnQueryBuf.append(StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())); results = stmt.executeQuery(fullColumnQueryBuf .toString()); - ordinalFixUpMap = new HashMap(); + ordinalFixUpMap = new HashMap(); int fullOrdinalPos = 1; @@ -2383,7 +2711,7 @@ .getString("Field"); ordinalFixUpMap.put(fullOrdColName, - new Integer(fullOrdinalPos++)); + Integer.valueOf(fullOrdinalPos++)); } } @@ -2392,8 +2720,8 @@ int ordPos = 1; while (results.next()) { - byte[][] rowVal = new byte[23][]; - rowVal[0] = s2b(catalog); // TABLE_CAT + byte[][] rowVal = new byte[24][]; + rowVal[0] = s2b(catalogStr); // TABLE_CAT rowVal[1] = null; // TABLE_SCHEM (No schemas // in MySQL) @@ -2410,12 +2738,29 @@ // DATA_TYPE (jdbc) rowVal[5] = s2b(typeDesc.typeName); // TYPE_NAME // (native) - rowVal[6] = typeDesc.columnSize == null ? null - : s2b(typeDesc.columnSize.toString()); - rowVal[7] = s2b(Integer - .toString(typeDesc.bufferLength)); - rowVal[8] = typeDesc.decimalDigits == null ? null - : s2b(typeDesc.decimalDigits.toString()); + if (typeDesc.columnSize == null) { + rowVal[6] = null; + } 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.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[7] = s2b(Integer.toString(typeDesc.bufferLength)); + rowVal[8] = typeDesc.decimalDigits == null ? null : s2b(typeDesc.decimalDigits.toString()); rowVal[9] = s2b(Integer .toString(typeDesc.numPrecRadix)); rowVal[10] = s2b(Integer @@ -2444,15 +2789,11 @@ rowVal[13] = new byte[] { (byte) '0' }; // SQL_DATA_TYPE rowVal[14] = new byte[] { (byte) '0' }; // SQL_DATE_TIME_SUB - - if (StringUtils.indexOfIgnoreCase( - typeDesc.typeName, "CHAR") != -1 - || StringUtils.indexOfIgnoreCase( - typeDesc.typeName, "BLOB") != -1 - || StringUtils.indexOfIgnoreCase( - typeDesc.typeName, "TEXT") != -1 - || StringUtils.indexOfIgnoreCase( - typeDesc.typeName, "BINARY") != -1) { + + if (StringUtils.indexOfIgnoreCase(typeDesc.typeName, "CHAR") != -1 || + StringUtils.indexOfIgnoreCase(typeDesc.typeName, "BLOB") != -1 || + StringUtils.indexOfIgnoreCase(typeDesc.typeName, "TEXT") != -1 || + StringUtils.indexOfIgnoreCase(typeDesc.typeName, "BINARY") != -1) { rowVal[15] = rowVal[6]; // CHAR_OCTET_LENGTH } else { rowVal[15] = null; @@ -2465,17 +2806,16 @@ } else { String origColName = results .getString("Field"); - Integer realOrdinal = (Integer) ordinalFixUpMap + Integer realOrdinal = ordinalFixUpMap .get(origColName); if (realOrdinal != null) { rowVal[16] = realOrdinal.toString() .getBytes(); } else { - throw SQLError - .createSQLException( - "Can not find column in full column list to determine true ordinal position.", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException( + "Can not find column in full column list to determine true ordinal position.", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } @@ -2497,8 +2837,9 @@ "auto_increment") != -1 ? "YES" : "NO"); } + rowVal[23] = s2b(""); - rows.add(rowVal); + rows.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); } } finally { if (results != null) { @@ -2525,6 +2866,37 @@ return results; } + protected Field[] createColumnsFields() { + Field[] fields = new Field[24]; + fields[0] = new Field("", "TABLE_CAT", Types.CHAR, 255); + fields[1] = new Field("", "TABLE_SCHEM", Types.CHAR, 0); + fields[2] = new Field("", "TABLE_NAME", Types.CHAR, 255); + fields[3] = new Field("", "COLUMN_NAME", Types.CHAR, 32); + fields[4] = new Field("", "DATA_TYPE", Types.INTEGER, 5); + fields[5] = new Field("", "TYPE_NAME", Types.CHAR, 16); + fields[6] = new Field("", "COLUMN_SIZE", Types.INTEGER, Integer + .toString(Integer.MAX_VALUE).length()); + fields[7] = new Field("", "BUFFER_LENGTH", Types.INTEGER, 10); + fields[8] = new Field("", "DECIMAL_DIGITS", Types.INTEGER, 10); + fields[9] = new Field("", "NUM_PREC_RADIX", Types.INTEGER, 10); + fields[10] = new Field("", "NULLABLE", Types.INTEGER, 10); + fields[11] = new Field("", "REMARKS", Types.CHAR, 0); + fields[12] = new Field("", "COLUMN_DEF", Types.CHAR, 0); + fields[13] = new Field("", "SQL_DATA_TYPE", Types.INTEGER, 10); + fields[14] = new Field("", "SQL_DATETIME_SUB", Types.INTEGER, 10); + fields[15] = new Field("", "CHAR_OCTET_LENGTH", Types.INTEGER, Integer + .toString(Integer.MAX_VALUE).length()); + fields[16] = new Field("", "ORDINAL_POSITION", Types.INTEGER, 10); + fields[17] = new Field("", "IS_NULLABLE", Types.CHAR, 3); + fields[18] = new Field("", "SCOPE_CATALOG", Types.CHAR, 255); + fields[19] = new Field("", "SCOPE_SCHEMA", Types.CHAR, 255); + fields[20] = new Field("", "SCOPE_TABLE", Types.CHAR, 255); + fields[21] = new Field("", "SOURCE_DATA_TYPE", Types.SMALLINT, 10); + fields[22] = new Field("", "IS_AUTOINCREMENT", Types.CHAR, 3); // JDBC 4 + fields[23] = new Field("", "IS_GENERATEDCOLUMN", Types.CHAR, 3); // JDBC 4.1 + return fields; + } + /** * JDBC 2.0 Return the connection that produced this metadata object. * @@ -2609,35 +2981,21 @@ final String foreignTable) throws SQLException { if (primaryTable == null) { throw SQLError.createSQLException("Table not specified.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } - Field[] fields = new Field[14]; - fields[0] = new Field("", "PKTABLE_CAT", Types.CHAR, 255); - fields[1] = new Field("", "PKTABLE_SCHEM", Types.CHAR, 0); - fields[2] = new Field("", "PKTABLE_NAME", Types.CHAR, 255); - fields[3] = new Field("", "PKCOLUMN_NAME", Types.CHAR, 32); - fields[4] = new Field("", "FKTABLE_CAT", Types.CHAR, 255); - fields[5] = new Field("", "FKTABLE_SCHEM", Types.CHAR, 0); - fields[6] = new Field("", "FKTABLE_NAME", Types.CHAR, 255); - fields[7] = new Field("", "FKCOLUMN_NAME", Types.CHAR, 32); - fields[8] = new Field("", "KEY_SEQ", Types.SMALLINT, 2); - fields[9] = new Field("", "UPDATE_RULE", Types.SMALLINT, 2); - fields[10] = new Field("", "DELETE_RULE", Types.SMALLINT, 2); - fields[11] = new Field("", "FK_NAME", Types.CHAR, 0); - fields[12] = new Field("", "PK_NAME", Types.CHAR, 0); - fields[13] = new Field("", "DEFERRABILITY", Types.INTEGER, 2); + Field[] fields = createFkMetadataFields(); - final ArrayList tuples = new ArrayList(); + final ArrayList tuples = new ArrayList(); if (this.conn.versionMeetsMinimum(3, 23, 0)) { final Statement stmt = this.conn.getMetadataSafeStatement(); try { - new IterateBlock(getCatalogIterator(foreignCatalog)) { - void forEach(Object catalogStr) throws SQLException { + new IterateBlock(getCatalogIterator(foreignCatalog)) { + void forEach(String catalogStr) throws SQLException { ResultSet fkresults = null; @@ -2648,13 +3006,11 @@ */ if (conn.versionMeetsMinimum(3, 23, 50)) { fkresults = extractForeignKeyFromCreateTable( - catalogStr.toString(), null); + catalogStr, null); } else { StringBuffer queryBuf = new StringBuffer( "SHOW TABLE STATUS FROM "); - queryBuf.append(quotedId); - queryBuf.append(catalogStr.toString()); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())); fkresults = stmt.executeQuery(queryBuf .toString()); @@ -2696,14 +3052,15 @@ int keySeq = 0; - Iterator referencingColumns = parsedInfo.localColumnsList + Iterator referencingColumns = parsedInfo.localColumnsList .iterator(); - Iterator referencedColumns = parsedInfo.referencedColumnsList + Iterator referencedColumns = parsedInfo.referencedColumnsList .iterator(); while (referencingColumns.hasNext()) { - String referencingColumn = removeQuotedId(referencingColumns - .next().toString()); + String referencingColumn = StringUtils.unQuoteIdentifier( + referencingColumns.next(), + conn.useAnsiQuotedIdentifiers()); // one tuple for each table // between @@ -2738,8 +3095,9 @@ } tuple[2] = s2b(parsedInfo.referencedTable); // PKTABLE_NAME - tuple[3] = s2b(removeQuotedId(referencedColumns - .next().toString())); // PKCOLUMN_NAME + tuple[3] = s2b(StringUtils.unQuoteIdentifier( + referencedColumns.next(), + conn.useAnsiQuotedIdentifiers())); // PKCOLUMN_NAME tuple[8] = Integer.toString( keySeq).getBytes(); // KEY_SEQ @@ -2755,7 +3113,7 @@ .toString( java.sql.DatabaseMetaData.importedKeyNotDeferrable) .getBytes(); - tuples.add(tuple); + tuples.add(new ByteArrayRow(tuple, getExceptionInterceptor())); keySeq++; } } @@ -2789,6 +3147,25 @@ return results; } + protected Field[] createFkMetadataFields() { + Field[] fields = new Field[14]; + fields[0] = new Field("", "PKTABLE_CAT", Types.CHAR, 255); + fields[1] = new Field("", "PKTABLE_SCHEM", Types.CHAR, 0); + fields[2] = new Field("", "PKTABLE_NAME", Types.CHAR, 255); + fields[3] = new Field("", "PKCOLUMN_NAME", Types.CHAR, 32); + fields[4] = new Field("", "FKTABLE_CAT", Types.CHAR, 255); + fields[5] = new Field("", "FKTABLE_SCHEM", Types.CHAR, 0); + fields[6] = new Field("", "FKTABLE_NAME", Types.CHAR, 255); + fields[7] = new Field("", "FKCOLUMN_NAME", Types.CHAR, 32); + fields[8] = new Field("", "KEY_SEQ", Types.SMALLINT, 2); + fields[9] = new Field("", "UPDATE_RULE", Types.SMALLINT, 2); + fields[10] = new Field("", "DELETE_RULE", Types.SMALLINT, 2); + fields[11] = new Field("", "FK_NAME", Types.CHAR, 0); + fields[12] = new Field("", "PK_NAME", Types.CHAR, 0); + fields[13] = new Field("", "DEFERRABILITY", Types.SMALLINT, 2); + return fields; + } + /** * @see DatabaseMetaData#getDatabaseMajorVersion() */ @@ -2868,7 +3245,7 @@ * DOCUMENT ME! */ public String getDriverName() throws SQLException { - return "MySQL-AB JDBC Driver"; + return NonRegisteringDriver.NAME; } /** @@ -2945,35 +3322,21 @@ final String table) throws SQLException { if (table == null) { throw SQLError.createSQLException("Table not specified.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } - Field[] fields = new Field[14]; - fields[0] = new Field("", "PKTABLE_CAT", Types.CHAR, 255); - fields[1] = new Field("", "PKTABLE_SCHEM", Types.CHAR, 0); - fields[2] = new Field("", "PKTABLE_NAME", Types.CHAR, 255); - fields[3] = new Field("", "PKCOLUMN_NAME", Types.CHAR, 32); - fields[4] = new Field("", "FKTABLE_CAT", Types.CHAR, 255); - fields[5] = new Field("", "FKTABLE_SCHEM", Types.CHAR, 0); - fields[6] = new Field("", "FKTABLE_NAME", Types.CHAR, 255); - fields[7] = new Field("", "FKCOLUMN_NAME", Types.CHAR, 32); - fields[8] = new Field("", "KEY_SEQ", Types.SMALLINT, 2); - fields[9] = new Field("", "UPDATE_RULE", Types.SMALLINT, 2); - fields[10] = new Field("", "DELETE_RULE", Types.SMALLINT, 2); - fields[11] = new Field("", "FK_NAME", Types.CHAR, 255); - fields[12] = new Field("", "PK_NAME", Types.CHAR, 0); - fields[13] = new Field("", "DEFERRABILITY", Types.INTEGER, 2); + Field[] fields = createFkMetadataFields(); - final ArrayList rows = new ArrayList(); + final ArrayList rows = new ArrayList(); if (this.conn.versionMeetsMinimum(3, 23, 0)) { final Statement stmt = this.conn.getMetadataSafeStatement(); try { - new IterateBlock(getCatalogIterator(catalog)) { - void forEach(Object catalogStr) throws SQLException { + new IterateBlock(getCatalogIterator(catalog)) { + void forEach(String catalogStr) throws SQLException { ResultSet fkresults = null; try { @@ -2985,13 +3348,11 @@ // we can use 'SHOW CREATE TABLE' fkresults = extractForeignKeyFromCreateTable( - catalogStr.toString(), null); + catalogStr, null); } else { StringBuffer queryBuf = new StringBuffer( "SHOW TABLE STATUS FROM "); - queryBuf.append(quotedId); - queryBuf.append(catalogStr.toString()); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())); fkresults = stmt.executeQuery(queryBuf .toString()); @@ -3028,7 +3389,7 @@ String keys = commentTokens .nextToken(); getExportKeyResults( - catalogStr.toString(), + catalogStr, tableNameWithCase, keys, rows, @@ -3084,8 +3445,8 @@ * @throws SQLException * if a database access error occurs */ - private void getExportKeyResults(String catalog, String exportingTable, - String keysComment, List tuples, String fkTableName) + protected void getExportKeyResults(String catalog, String exportingTable, + String keysComment, List tuples, String fkTableName) throws SQLException { getResultsImpl(catalog, exportingTable, keysComment, tuples, fkTableName, true); @@ -3112,7 +3473,7 @@ * the comment from 'SHOW TABLE STATUS' * @return int[] [0] = delete action, [1] = update action */ - private int[] getForeignKeyActions(String commentString) { + protected int[] getForeignKeyActions(String commentString) { int[] actions = new int[] { java.sql.DatabaseMetaData.importedKeyNoAction, java.sql.DatabaseMetaData.importedKeyNoAction }; @@ -3214,35 +3575,21 @@ final String table) throws SQLException { if (table == null) { throw SQLError.createSQLException("Table not specified.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } - Field[] fields = new Field[14]; - fields[0] = new Field("", "PKTABLE_CAT", Types.CHAR, 255); - fields[1] = new Field("", "PKTABLE_SCHEM", Types.CHAR, 0); - fields[2] = new Field("", "PKTABLE_NAME", Types.CHAR, 255); - fields[3] = new Field("", "PKCOLUMN_NAME", Types.CHAR, 32); - fields[4] = new Field("", "FKTABLE_CAT", Types.CHAR, 255); - fields[5] = new Field("", "FKTABLE_SCHEM", Types.CHAR, 0); - fields[6] = new Field("", "FKTABLE_NAME", Types.CHAR, 255); - fields[7] = new Field("", "FKCOLUMN_NAME", Types.CHAR, 32); - fields[8] = new Field("", "KEY_SEQ", Types.SMALLINT, 2); - fields[9] = new Field("", "UPDATE_RULE", Types.SMALLINT, 2); - fields[10] = new Field("", "DELETE_RULE", Types.SMALLINT, 2); - fields[11] = new Field("", "FK_NAME", Types.CHAR, 255); - fields[12] = new Field("", "PK_NAME", Types.CHAR, 0); - fields[13] = new Field("", "DEFERRABILITY", Types.INTEGER, 2); + Field[] fields = createFkMetadataFields(); + + final ArrayList rows = new ArrayList(); - final ArrayList rows = new ArrayList(); - if (this.conn.versionMeetsMinimum(3, 23, 0)) { final Statement stmt = this.conn.getMetadataSafeStatement(); try { - new IterateBlock(getCatalogIterator(catalog)) { - void forEach(Object catalogStr) throws SQLException { + new IterateBlock(getCatalogIterator(catalog)) { + void forEach(String catalogStr) throws SQLException { ResultSet fkresults = null; try { @@ -3254,14 +3601,12 @@ // we can use 'SHOW CREATE TABLE' fkresults = extractForeignKeyFromCreateTable( - catalogStr.toString(), table); + catalogStr, table); } else { StringBuffer queryBuf = new StringBuffer( "SHOW TABLE STATUS "); queryBuf.append(" FROM "); - queryBuf.append(quotedId); - queryBuf.append(catalogStr.toString()); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())); queryBuf.append(" LIKE '"); queryBuf.append(table); queryBuf.append("'"); @@ -3297,8 +3642,8 @@ .hasMoreTokens()) { String keys = commentTokens .nextToken(); - getImportKeyResults(catalogStr - .toString(), table, + getImportKeyResults(catalogStr, + table, keys, rows); } } @@ -3348,8 +3693,8 @@ * @throws SQLException * if a database access error occurs */ - private void getImportKeyResults(String catalog, String importingTable, - String keysComment, List tuples) throws SQLException { + protected void getImportKeyResults(String catalog, String importingTable, + String keysComment, List tuples) throws SQLException { getResultsImpl(catalog, importingTable, keysComment, tuples, null, false); } @@ -3421,41 +3766,25 @@ * Sub_part */ - Field[] fields = new Field[13]; - fields[0] = new Field("", "TABLE_CAT", Types.CHAR, 255); - fields[1] = new Field("", "TABLE_SCHEM", Types.CHAR, 0); - fields[2] = new Field("", "TABLE_NAME", Types.CHAR, 255); - fields[3] = new Field("", "NON_UNIQUE", Types.CHAR, 4); - fields[4] = new Field("", "INDEX_QUALIFIER", Types.CHAR, 1); - fields[5] = new Field("", "INDEX_NAME", Types.CHAR, 32); - fields[6] = new Field("", "TYPE", Types.CHAR, 32); - fields[7] = new Field("", "ORDINAL_POSITION", Types.SMALLINT, 5); - fields[8] = new Field("", "COLUMN_NAME", Types.CHAR, 32); - fields[9] = new Field("", "ASC_OR_DESC", Types.CHAR, 1); - fields[10] = new Field("", "CARDINALITY", Types.INTEGER, 10); - fields[11] = new Field("", "PAGES", Types.INTEGER, 10); - fields[12] = new Field("", "FILTER_CONDITION", Types.CHAR, 32); + Field[] fields = createIndexInfoFields(); - final ArrayList rows = new ArrayList(); + final SortedMap sortedRows = new TreeMap(); + final ArrayList rows = new ArrayList(); final Statement stmt = this.conn.getMetadataSafeStatement(); try { - new IterateBlock(getCatalogIterator(catalog)) { - void forEach(Object catalogStr) throws SQLException { + new IterateBlock(getCatalogIterator(catalog)) { + void forEach(String catalogStr) throws SQLException { ResultSet results = null; try { StringBuffer queryBuf = new StringBuffer( "SHOW INDEX FROM "); - queryBuf.append(quotedId); - queryBuf.append(table); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(table, conn.getPedantic())); queryBuf.append(" FROM "); - queryBuf.append(quotedId); - queryBuf.append(catalogStr.toString()); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())); try { results = stmt.executeQuery(queryBuf.toString()); @@ -3475,9 +3804,8 @@ while (results != null && results.next()) { byte[][] row = new byte[14][]; - row[0] = ((catalogStr.toString() == null) ? new byte[0] - : s2b(catalogStr.toString())); - ; + row[0] = ((catalogStr == null) ? new byte[0] + : s2b(catalogStr)); row[1] = null; row[2] = results.getBytes("Table"); @@ -3488,23 +3816,35 @@ : s2b("false")); row[4] = new byte[0]; row[5] = results.getBytes("Key_name"); - row[6] = Integer.toString( - java.sql.DatabaseMetaData.tableIndexOther) + short indexType = java.sql.DatabaseMetaData.tableIndexOther; + row[6] = Integer.toString(indexType) .getBytes(); row[7] = results.getBytes("Seq_in_index"); row[8] = results.getBytes("Column_name"); row[9] = results.getBytes("Collation"); - row[10] = results.getBytes("Cardinality"); + + // Cardinality can be much larger than Integer's range, + // so we clamp it to conform to the API + long cardinality = results.getLong("Cardinality"); + + if (cardinality > Integer.MAX_VALUE) { + cardinality = Integer.MAX_VALUE; + } + + row[10] = s2b(String.valueOf(cardinality)); row[11] = s2b("0"); row[12] = null; + IndexMetaDataKey indexInfoKey = new IndexMetaDataKey(!indexIsUnique, indexType, + results.getString("Key_name").toLowerCase(), results.getShort("Seq_in_index")); + if (unique) { if (indexIsUnique) { - rows.add(row); + sortedRows.put(indexInfoKey, new ByteArrayRow(row, getExceptionInterceptor())); } } else { // All rows match - rows.add(row); + sortedRows.put(indexInfoKey, new ByteArrayRow(row, getExceptionInterceptor())); } } } finally { @@ -3520,6 +3860,11 @@ } } }.doForAll(); + + Iterator sortedRowsIterator = sortedRows.values().iterator(); + while (sortedRowsIterator.hasNext()) { + rows.add(sortedRowsIterator.next()); + } java.sql.ResultSet indexInfo = buildResultSet(fields, rows); @@ -3531,11 +3876,29 @@ } } + protected Field[] createIndexInfoFields() { + Field[] fields = new Field[13]; + fields[0] = new Field("", "TABLE_CAT", Types.CHAR, 255); + fields[1] = new Field("", "TABLE_SCHEM", Types.CHAR, 0); + fields[2] = new Field("", "TABLE_NAME", Types.CHAR, 255); + fields[3] = new Field("", "NON_UNIQUE", Types.BOOLEAN, 4); + fields[4] = new Field("", "INDEX_QUALIFIER", Types.CHAR, 1); + fields[5] = new Field("", "INDEX_NAME", Types.CHAR, 32); + fields[6] = new Field("", "TYPE", Types.SMALLINT, 32); + fields[7] = new Field("", "ORDINAL_POSITION", Types.SMALLINT, 5); + fields[8] = new Field("", "COLUMN_NAME", Types.CHAR, 32); + fields[9] = new Field("", "ASC_OR_DESC", Types.CHAR, 1); + fields[10] = new Field("", "CARDINALITY", Types.INTEGER, 20); + fields[11] = new Field("", "PAGES", Types.INTEGER, 10); + fields[12] = new Field("", "FILTER_CONDITION", Types.CHAR, 32); + return fields; + } + /** * @see DatabaseMetaData#getJDBCMajorVersion() */ public int getJDBCMajorVersion() throws SQLException { - return 3; + return 4; } /** @@ -3815,34 +4178,29 @@ if (table == null) { throw SQLError.createSQLException("Table not specified.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } - final ArrayList rows = new ArrayList(); + final ArrayList rows = new ArrayList(); final Statement stmt = this.conn.getMetadataSafeStatement(); try { - new IterateBlock(getCatalogIterator(catalog)) { - void forEach(Object catalogStr) throws SQLException { + new IterateBlock(getCatalogIterator(catalog)) { + void forEach(String catalogStr) throws SQLException { ResultSet rs = null; try { StringBuffer queryBuf = new StringBuffer( "SHOW KEYS FROM "); - queryBuf.append(quotedId); - queryBuf.append(table); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(table, conn.getPedantic())); queryBuf.append(" FROM "); - queryBuf.append(quotedId); - queryBuf.append(catalogStr.toString()); - queryBuf.append(quotedId); + queryBuf.append(StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())); rs = stmt.executeQuery(queryBuf.toString()); - ArrayList tuples = new ArrayList(); - TreeMap sortMap = new TreeMap(); + TreeMap sortMap = new TreeMap(); while (rs.next()) { String keyType = rs.getString("Key_name"); @@ -3851,8 +4209,8 @@ if (keyType.equalsIgnoreCase("PRIMARY") || keyType.equalsIgnoreCase("PRI")) { byte[][] tuple = new byte[6][]; - tuple[0] = ((catalogStr.toString() == null) ? new byte[0] - : s2b(catalogStr.toString())); + tuple[0] = ((catalogStr == null) ? new byte[0] + : s2b(catalogStr)); tuple[1] = null; tuple[2] = s2b(table); @@ -3867,10 +4225,10 @@ } // Now pull out in column name sorted order - Iterator sortedIterator = sortMap.values().iterator(); + Iterator sortedIterator = sortMap.values().iterator(); while (sortedIterator.hasNext()) { - rows.add(sortedIterator.next()); + rows.add(new ByteArrayRow(sortedIterator.next(), getExceptionInterceptor())); } } finally { @@ -3908,7 +4266,7 @@ * in column number order. *

*

- * Each row in the ResultSet is a parameter desription or column description + * Each row in the ResultSet is a parameter description or column description * with the following fields: *

    *
  1. PROCEDURE_CAT String => procedure catalog (may be null) @@ -3941,12 +4299,23 @@ * *
  2. *
  3. REMARKS String => comment describing parameter/column
  4. + *
  5. COLUMN_DEF String => default value for the column (may be null)
  6. + *
  7. SQL_DATA_TYPE int => reserved for future use
  8. + *
  9. SQL_DATETIME_SUB int => reserved for future use
  10. + *
  11. CHAR_OCTET_LENGTH int => the maximum length of binary and character based columns. For any other datatype the returned value is a NULL
  12. + *
  13. ORDINAL_POSITION int => the ordinal position, starting from 1. A value of 0 is returned if this row describes the procedure's return value.
  14. + *
  15. IS_NULLABLE String => ISO rules are used to determine the nullability for a column. + *
      + *
    • YES --- if the parameter can include NULLs
    • + *
    • NO --- if the parameter cannot include NULLs
    • + *
    • empty string --- if the nullability for the parameter is unknown
    • + *
    + *
  16. + *
  17. SPECIFIC_NAME String => the name which uniquely identifies this procedure within its schema.
  18. *
*

*

- * Note: Some databases may not return the column descriptions for a - * procedure. Additional columns beyond REMARKS can be defined by the - * database. + * Note: Some databases may not return the column descriptions for a procedure. *

* * @param catalog @@ -3966,73 +4335,179 @@ public java.sql.ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException { + Field[] fields = createProcedureColumnsFields(); + + return getProcedureOrFunctionColumns( + fields, catalog, schemaPattern, + procedureNamePattern, columnNamePattern, + true, true); + } - Field[] fields = new Field[13]; + protected Field[] createProcedureColumnsFields() { + Field[] fields = new Field[20]; - fields[0] = new Field("", "PROCEDURE_CAT", Types.CHAR, 0); - fields[1] = new Field("", "PROCEDURE_SCHEM", Types.CHAR, 0); - fields[2] = new Field("", "PROCEDURE_NAME", Types.CHAR, 0); - fields[3] = new Field("", "COLUMN_NAME", Types.CHAR, 0); - fields[4] = new Field("", "COLUMN_TYPE", Types.CHAR, 0); - fields[5] = new Field("", "DATA_TYPE", Types.SMALLINT, 0); - fields[6] = new Field("", "TYPE_NAME", Types.CHAR, 0); - fields[7] = new Field("", "PRECISION", Types.INTEGER, 0); - fields[8] = new Field("", "LENGTH", Types.INTEGER, 0); - fields[9] = new Field("", "SCALE", Types.SMALLINT, 0); - fields[10] = new Field("", "RADIX", Types.SMALLINT, 0); - fields[11] = new Field("", "NULLABLE", Types.SMALLINT, 0); - fields[12] = new Field("", "REMARKS", Types.CHAR, 0); + fields[0] = new Field("", "PROCEDURE_CAT", Types.CHAR, 512); + fields[1] = new Field("", "PROCEDURE_SCHEM", Types.CHAR, 512); + fields[2] = new Field("", "PROCEDURE_NAME", Types.CHAR, 512); + fields[3] = new Field("", "COLUMN_NAME", Types.CHAR, 512); + fields[4] = new Field("", "COLUMN_TYPE", Types.CHAR, 64); + fields[5] = new Field("", "DATA_TYPE", Types.SMALLINT, 6); + fields[6] = new Field("", "TYPE_NAME", Types.CHAR, 64); + fields[7] = new Field("", "PRECISION", Types.INTEGER, 12); + fields[8] = new Field("", "LENGTH", Types.INTEGER, 12); + fields[9] = new Field("", "SCALE", Types.SMALLINT, 12); + fields[10] = new Field("", "RADIX", Types.SMALLINT, 6); + fields[11] = new Field("", "NULLABLE", Types.SMALLINT, 6); + fields[12] = new Field("", "REMARKS", Types.CHAR, 512); + fields[13] = new Field("", "COLUMN_DEF", Types.CHAR, 512); + fields[14] = new Field("", "SQL_DATA_TYPE", Types.INTEGER, 12); + fields[15] = new Field("", "SQL_DATETIME_SUB", Types.INTEGER, 12); + fields[16] = new Field("", "CHAR_OCTET_LENGTH", Types.INTEGER, 12); + fields[17] = new Field("", "ORDINAL_POSITION", Types.INTEGER, 12); + fields[18] = new Field("", "IS_NULLABLE", Types.CHAR, 512); + fields[19] = new Field("", "SPECIFIC_NAME", Types.CHAR, 512); + return fields; + } + + protected java.sql.ResultSet getProcedureOrFunctionColumns( + Field[] fields, String catalog, String schemaPattern, + String procedureOrFunctionNamePattern, + String columnNamePattern, boolean returnProcedures, + boolean returnFunctions) throws SQLException { - List proceduresToExtractList = new ArrayList(); - + List> procsOrFuncsToExtractList = new ArrayList>(); + //Main container to be passed to getProceduresAndOrFunctions + ResultSet procsAndOrFuncsRs = null; + if (supportsStoredProcedures()) { - if ((procedureNamePattern.indexOf("%") == -1) - && (procedureNamePattern.indexOf("?") == -1)) { - proceduresToExtractList.add(procedureNamePattern); - } else { + try { + //getProceduresAndOrFunctions does NOT expect procedureOrFunctionNamePattern + //in form of DB_NAME.SP_NAME thus we need to remove it + String tmpProcedureOrFunctionNamePattern = null; + //Check if NOT a pattern first, then "sanitize" + if ((procedureOrFunctionNamePattern != null) && (!procedureOrFunctionNamePattern.equals("%"))) { + tmpProcedureOrFunctionNamePattern = StringUtils.sanitizeProcOrFuncName(procedureOrFunctionNamePattern); + } - ResultSet procedureNameRs = null; + //Sanity check, if NamePattern is still NULL, we have a wildcard and not the name + if (tmpProcedureOrFunctionNamePattern == null) { + tmpProcedureOrFunctionNamePattern = procedureOrFunctionNamePattern; + } else { + //So we have a name to check meaning more actual processing + //Keep the Catalog parsed, maybe we'll need it at some point + //in the future... + String tmpCatalog = catalog; + List parseList = StringUtils.splitDBdotName(tmpProcedureOrFunctionNamePattern, tmpCatalog, + this.quotedId, this.conn.isNoBackslashEscapesSet()); + + //There *should* be 2 rows, if any. + if (parseList.size() == 2) { + tmpCatalog = parseList.get(0); + tmpProcedureOrFunctionNamePattern = parseList.get(1); + } else { + //keep values as they are + } + } + + procsAndOrFuncsRs = getProceduresAndOrFunctions( + createFieldMetadataForGetProcedures(), + catalog, schemaPattern, + tmpProcedureOrFunctionNamePattern, returnProcedures, + returnFunctions); - try { + // Demand: PARAM_CAT for SP. + // Goal: proceduresToExtractList has to have db.sp entries. + + // Due to https://intranet.mysql.com/secure/paste/displaypaste.php?codeid=10704 + // introducing new variables, ignoring ANSI mode + + String tmpstrPNameRs = null; + String tmpstrCatNameRs = null; - procedureNameRs = getProcedures(catalog, schemaPattern, - procedureNamePattern); - - while (procedureNameRs.next()) { - proceduresToExtractList.add(procedureNameRs - .getString(3)); + boolean hasResults = false; + while (procsAndOrFuncsRs.next()) { + tmpstrCatNameRs = procsAndOrFuncsRs.getString(1); + tmpstrPNameRs = procsAndOrFuncsRs.getString(3); + + if (!((tmpstrCatNameRs.startsWith(this.quotedId) && tmpstrCatNameRs.endsWith(this.quotedId)) || + (tmpstrCatNameRs.startsWith("\"") && tmpstrCatNameRs.endsWith("\"")))) { + tmpstrCatNameRs = this.quotedId + tmpstrCatNameRs + this.quotedId; } + if (!((tmpstrPNameRs.startsWith(this.quotedId) && tmpstrPNameRs.endsWith(this.quotedId)) || + (tmpstrPNameRs.startsWith("\"") && tmpstrPNameRs.endsWith("\"")))) { + tmpstrPNameRs = this.quotedId + tmpstrPNameRs + this.quotedId; + } - // Required to be sorted in name-order by JDBC spec, - // in 'normal' case getProcedures takes care of this for us, - // but if system tables are inaccessible, we need to sort... - // so just do this to be safe... - Collections.sort(proceduresToExtractList); - } finally { - SQLException rethrowSqlEx = null; + procsOrFuncsToExtractList.add(new ComparableWrapper( + tmpstrCatNameRs + "." + tmpstrPNameRs, + procsAndOrFuncsRs.getShort(8) == procedureNoResult ? PROCEDURE + : FUNCTION)); + hasResults = true; + } - if (procedureNameRs != null) { - try { - procedureNameRs.close(); - } catch (SQLException sqlEx) { - rethrowSqlEx = sqlEx; - } - } + // FIX for Bug#56305, allowing the code to proceed with empty fields causing NPE later + if (!hasResults) { +// 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()); + } else { + Collections.sort(procsOrFuncsToExtractList); + } - if (rethrowSqlEx != null) { - throw rethrowSqlEx; + // Required to be sorted in name-order by JDBC spec, + // in 'normal' case getProcedures takes care of this for us, + // but if system tables are inaccessible, we need to sort... + // so just do this to be safe... + //Collections.sort(proceduresToExtractList); + } finally { + SQLException rethrowSqlEx = null; + + if (procsAndOrFuncsRs != null) { + try { + procsAndOrFuncsRs.close(); + } catch (SQLException sqlEx) { + rethrowSqlEx = sqlEx; } } + + if (rethrowSqlEx != null) { + throw rethrowSqlEx; + } } } - ArrayList resultRows = new ArrayList(); + ArrayList resultRows = new ArrayList(); + int idx = 0; + String procNameToCall = ""; + + for (ComparableWrapper procOrFunc : procsOrFuncsToExtractList) { + String procName = procOrFunc.getKey(); + ProcedureType procType = procOrFunc.getValue(); - for (Iterator iter = proceduresToExtractList.iterator(); iter.hasNext();) { - String procName = (String) iter.next(); - - getCallStmtParameterTypes(catalog, procName, columnNamePattern, - resultRows); + //Continuing from above (database_name.sp_name) + if (!" ".equals(this.quotedId)) { + idx = StringUtils.indexOfIgnoreCaseRespectQuotes(0, + procName, ".", this.quotedId.charAt(0), !this.conn + .isNoBackslashEscapesSet()); + } else { + idx = procName.indexOf("."); + } + + if (idx > 0) { + catalog = procName.substring(0,idx); + if (quotedId != " " && catalog.startsWith(quotedId) && catalog.endsWith(quotedId)) { + catalog = procName.substring(1, catalog.length() - 1); + } + procNameToCall = procName; // Leave as CAT.PROC, needed later + } else { + //No catalog. Not sure how to handle right now... + procNameToCall = procName; + } + getCallStmtParameterTypes(catalog, procNameToCall, procType, columnNamePattern, + resultRows, + fields.length == 17 /* for getFunctionColumns */); } return buildResultSet(fields, resultRows); @@ -4081,52 +4556,84 @@ public java.sql.ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException { - return getProceduresAndOrFunctions(catalog, schemaPattern, + Field[] fields = createFieldMetadataForGetProcedures(); + + return getProceduresAndOrFunctions(fields, catalog, schemaPattern, procedureNamePattern, true, true); } - protected java.sql.ResultSet getProceduresAndOrFunctions(String catalog, - String schemaPattern, String procedureNamePattern, - final boolean returnProcedures, final boolean returnFunctions) - throws SQLException { + protected Field[] createFieldMetadataForGetProcedures() { + Field[] fields = new Field[9]; + fields[0] = new Field("", "PROCEDURE_CAT", Types.CHAR, 255); + fields[1] = new Field("", "PROCEDURE_SCHEM", Types.CHAR, 255); + fields[2] = new Field("", "PROCEDURE_NAME", Types.CHAR, 255); + fields[3] = new Field("", "reserved1", Types.CHAR, 0); + fields[4] = new Field("", "reserved2", Types.CHAR, 0); + fields[5] = new Field("", "reserved3", Types.CHAR, 0); + fields[6] = new Field("", "REMARKS", Types.CHAR, 255); + fields[7] = new Field("", "PROCEDURE_TYPE", Types.SMALLINT, 6); + fields[8] = new Field("", "SPECIFIC_NAME", Types.CHAR, 255); + + return fields; + } + + /** + * + * @param fields + * @param catalog + * @param schemaPattern + * @param procedureNamePattern + * @param returnProcedures + * @param returnFunctions + * @return + * @throws SQLException + */ + protected java.sql.ResultSet getProceduresAndOrFunctions( + final Field[] fields, + String catalog, + String schemaPattern, + String procedureNamePattern, + final boolean returnProcedures, + final boolean returnFunctions) throws SQLException { if ((procedureNamePattern == null) || (procedureNamePattern.length() == 0)) { if (this.conn.getNullNamePatternMatchesAll()) { procedureNamePattern = "%"; } else { throw SQLError.createSQLException( "Procedure name pattern can not be NULL or empty.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } - Field[] fields = new Field[8]; - fields[0] = new Field("", "PROCEDURE_CAT", Types.CHAR, 0); - fields[1] = new Field("", "PROCEDURE_SCHEM", Types.CHAR, 0); - fields[2] = new Field("", "PROCEDURE_NAME", Types.CHAR, 0); - fields[3] = new Field("", "reserved1", Types.CHAR, 0); - fields[4] = new Field("", "reserved2", Types.CHAR, 0); - fields[5] = new Field("", "reserved3", Types.CHAR, 0); - fields[6] = new Field("", "REMARKS", Types.CHAR, 0); - fields[7] = new Field("", "PROCEDURE_TYPE", Types.SMALLINT, 0); + final ArrayList procedureRows = new ArrayList(); - final ArrayList procedureRows = new ArrayList(); - if (supportsStoredProcedures()) { final String procNamePattern = procedureNamePattern; - final Map procedureRowsOrderedByName = new TreeMap(); + final List> procedureRowsToSort = new ArrayList>(); - new IterateBlock(getCatalogIterator(catalog)) { - void forEach(Object catalogStr) throws SQLException { - String db = catalogStr.toString(); + new IterateBlock(getCatalogIterator(catalog)) { + void forEach(String catalogStr) throws SQLException { + String db = catalogStr; boolean fromSelect = false; ResultSet proceduresRs = null; boolean needsClientFiltering = true; - PreparedStatement proceduresStmt = conn - .clientPrepareStatement("SELECT name, type FROM mysql.proc WHERE name like ? and db <=> ? ORDER BY name"); + StringBuffer selectFromMySQLProcSQL = new StringBuffer(); + + selectFromMySQLProcSQL.append("SELECT name, type, comment FROM mysql.proc WHERE "); + if (returnProcedures && !returnFunctions) { + selectFromMySQLProcSQL.append("type = 'PROCEDURE' and "); + } else if (!returnProcedures && returnFunctions) { + selectFromMySQLProcSQL.append("type = 'FUNCTION' and "); + } + selectFromMySQLProcSQL.append("name like ? and db <=> ? ORDER BY name, type"); + + java.sql.PreparedStatement proceduresStmt = conn.clientPrepareStatement(selectFromMySQLProcSQL + .toString()); + try { // // Try using system tables first, as this is a little @@ -4136,6 +4643,9 @@ boolean hasTypeColumn = false; if (db != null) { + if(conn.lowerCaseTableNames()){ + db = db.toLowerCase(); + } proceduresStmt.setString(2, db); } else { proceduresStmt.setNull(2, Types.VARCHAR); @@ -4171,7 +4681,7 @@ nameIndex = 1; } - proceduresStmt = conn + proceduresStmt = conn .clientPrepareStatement("SHOW PROCEDURE STATUS LIKE ?"); if (proceduresStmt.getMaxRows() != 0) { @@ -4185,8 +4695,8 @@ if (returnProcedures) { convertToJdbcProcedureList(fromSelect, db, - proceduresRs, needsClientFiltering, db, - procedureRowsOrderedByName, nameIndex); + proceduresRs, needsClientFiltering, db, + procedureRowsToSort, nameIndex); } if (!hasTypeColumn) { @@ -4206,20 +4716,19 @@ proceduresRs = proceduresStmt.executeQuery(); - if (returnFunctions) { - convertToJdbcFunctionList(db, proceduresRs, - needsClientFiltering, db, - procedureRowsOrderedByName, nameIndex); - } } + //Should be here, not in IF block! + if (returnFunctions) { + convertToJdbcFunctionList(db, proceduresRs, + needsClientFiltering, db, + procedureRowsToSort, nameIndex, + fields); + } // Now, sort them - - Iterator proceduresIter = procedureRowsOrderedByName - .values().iterator(); - - while (proceduresIter.hasNext()) { - procedureRows.add(proceduresIter.next()); + Collections.sort(procedureRowsToSort); + for (ComparableWrapper procRow : procedureRowsToSort) { + procedureRows.add(procRow.getValue()); } } finally { SQLException rethrowSqlEx = null; @@ -4251,6 +4760,7 @@ return buildResultSet(fields, procedureRows); } + /** * What's the database vendor's preferred term for "procedure"? * @@ -4270,7 +4780,7 @@ } private void getResultsImpl(String catalog, String table, - String keysComment, List tuples, String fkTableName, + String keysComment, List tuples, String fkTableName, boolean isExport) throws SQLException { LocalAndReferencedColumns parsedInfo = parseTableStatusIntoLocalAndReferencedColumns(keysComment); @@ -4281,24 +4791,21 @@ if (parsedInfo.localColumnsList.size() != parsedInfo.referencedColumnsList .size()) { - throw SQLError - .createSQLException( - "Error parsing foreign keys definition," - + "number of local and referenced columns is not the same.", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException( + "Error parsing foreign keys definition," + + "number of local and referenced columns is not the same.", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } - Iterator localColumnNames = parsedInfo.localColumnsList.iterator(); - Iterator referColumnNames = parsedInfo.referencedColumnsList.iterator(); + Iterator localColumnNames = parsedInfo.localColumnsList.iterator(); + Iterator referColumnNames = parsedInfo.referencedColumnsList.iterator(); int keySeqIndex = 1; while (localColumnNames.hasNext()) { byte[][] tuple = new byte[14][]; - String lColumnName = removeQuotedId(localColumnNames.next() - .toString()); - String rColumnName = removeQuotedId(referColumnNames.next() - .toString()); + String lColumnName = StringUtils.unQuoteIdentifier(localColumnNames.next(), this.conn.useAnsiQuotedIdentifiers()); + String rColumnName = StringUtils.unQuoteIdentifier(referColumnNames.next(), this.conn.useAnsiQuotedIdentifiers()); tuple[FKTABLE_CAT] = ((catalog == null) ? new byte[0] : s2b(catalog)); tuple[FKTABLE_SCHEM] = null; @@ -4319,7 +4826,7 @@ tuple[PK_NAME] = null; // not available from show table status tuple[DEFERRABILITY] = s2b(Integer .toString(java.sql.DatabaseMetaData.importedKeyNotDeferrable)); - tuples.add(tuple); + tuples.add(new ByteArrayRow(tuple, getExceptionInterceptor())); } } @@ -4340,10 +4847,10 @@ */ public java.sql.ResultSet getSchemas() throws SQLException { Field[] fields = new Field[2]; - fields[0] = new Field("", "TABLE_SCHEM", java.sql.Types.CHAR, 0); - fields[1] = new Field("", "TABLE_CATALOG", java.sql.Types.CHAR, 0); + fields[0] = new Field("", "TABLE_SCHEM", java.sql.Types.CHAR, 0); + fields[1] = new Field("", "TABLE_CATALOG", java.sql.Types.CHAR, 0); - ArrayList tuples = new ArrayList(); + ArrayList tuples = new ArrayList(); java.sql.ResultSet results = buildResultSet(fields, tuples); return results; @@ -4379,15 +4886,36 @@ } /** - * Get a comma separated list of all a database's SQL keywords that are NOT - * also SQL92 keywords. + * Get a comma separated list of all a database's SQL keywords that are NOT also SQL92/SQL2003 keywords. * * @return the list * @throws SQLException * DOCUMENT ME! */ public String getSQLKeywords() throws SQLException { - return mysqlKeywordsThatArentSQL92; + if (mysqlKeywords != null) { + return mysqlKeywords; + } + + synchronized (DatabaseMetaData.class) { + // double check, maybe it's already set + if (mysqlKeywords != null) { + return mysqlKeywords; + } + + Set mysqlKeywordSet = new TreeSet(); + StringBuffer mysqlKeywordsBuffer = new StringBuffer(); + + Collections.addAll(mysqlKeywordSet, MYSQL_KEYWORDS); + mysqlKeywordSet.removeAll(Arrays.asList(Util.isJdbc4() ? SQL2003_KEYWORDS : SQL92_KEYWORDS)); + + for (String keyword : mysqlKeywordSet) { + mysqlKeywordsBuffer.append(",").append(keyword); + } + + mysqlKeywords = mysqlKeywordsBuffer.substring(1); + return mysqlKeywords; + } } /** @@ -4433,7 +4961,7 @@ fields[2] = new Field("", "TABLE_NAME", Types.CHAR, 32); fields[3] = new Field("", "SUPERTABLE_NAME", Types.CHAR, 32); - return buildResultSet(fields, new ArrayList()); + return buildResultSet(fields, new ArrayList()); } /** @@ -4442,14 +4970,14 @@ public java.sql.ResultSet getSuperTypes(String arg0, String arg1, String arg2) throws SQLException { Field[] fields = new Field[6]; - fields[0] = new Field("", "TABLE_CAT", Types.CHAR, 32); - fields[1] = new Field("", "TABLE_SCHEM", Types.CHAR, 32); + fields[0] = new Field("", "TYPE_CAT", Types.CHAR, 32); + fields[1] = new Field("", "TYPE_SCHEM", Types.CHAR, 32); fields[2] = new Field("", "TYPE_NAME", Types.CHAR, 32); fields[3] = new Field("", "SUPERTYPE_CAT", Types.CHAR, 32); fields[4] = new Field("", "SUPERTYPE_SCHEM", Types.CHAR, 32); fields[5] = new Field("", "SUPERTYPE_NAME", Types.CHAR, 32); - return buildResultSet(fields, new ArrayList()); + return buildResultSet(fields, new ArrayList()); } /** @@ -4463,7 +4991,7 @@ return "DATABASE,USER,SYSTEM_USER,SESSION_USER,PASSWORD,ENCRYPT,LAST_INSERT_ID,VERSION"; } - private String getTableNameWithCase(String table) { + protected String getTableNameWithCase(String table) { String tableNameWithCase = (this.conn.lowerCaseTableNames() ? table .toLowerCase() : table); @@ -4513,7 +5041,7 @@ } else { throw SQLError.createSQLException( "Table name pattern can not be NULL or empty.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @@ -4541,7 +5069,7 @@ grantQuery.append("'"); ResultSet results = null; - ArrayList grantRows = new ArrayList(); + ArrayList grantRows = new ArrayList(); Statement stmt = null; try { @@ -4600,7 +5128,7 @@ tuple[4] = s2b(fullUser.toString()); tuple[5] = s2b(privilege); tuple[6] = null; - grantRows.add(tuple); + grantRows.add(new ByteArrayRow(tuple, getExceptionInterceptor())); } } finally { if (columnResults != null) { @@ -4684,77 +5212,88 @@ } else { throw SQLError.createSQLException( "Table name pattern can not be NULL or empty.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } - Field[] fields = new Field[5]; - fields[0] = new Field("", "TABLE_CAT", java.sql.Types.VARCHAR, 255); - fields[1] = new Field("", "TABLE_SCHEM", java.sql.Types.VARCHAR, 0); - fields[2] = new Field("", "TABLE_NAME", java.sql.Types.VARCHAR, 255); - fields[3] = new Field("", "TABLE_TYPE", java.sql.Types.VARCHAR, 5); - fields[4] = new Field("", "REMARKS", java.sql.Types.VARCHAR, 0); + final SortedMap sortedRows = new TreeMap(); + final ArrayList tuples = new ArrayList(); - final ArrayList tuples = new ArrayList(); - final Statement stmt = this.conn.getMetadataSafeStatement(); - final String tableNamePat = tableNamePattern; + final String tableNamePat; + String tmpCat = ""; + + if ((catalog == null) || (catalog.length() == 0)) { + if (this.conn.getNullCatalogMeansCurrent()) { + tmpCat = this.database; + } + } else { + tmpCat = catalog; + } + + List parseList = StringUtils.splitDBdotName(tableNamePattern, tmpCat, + quotedId , conn.isNoBackslashEscapesSet()); + //There *should* be 2 rows, if any. + if (parseList.size() == 2) { + tableNamePat = parseList.get(1); + } else { + tableNamePat = tableNamePattern; + } try { + new IterateBlock(getCatalogIterator(catalog)) { + void forEach(String catalogStr) throws SQLException { + boolean operatingOnSystemDB = "information_schema".equalsIgnoreCase(catalogStr) + || "mysql".equalsIgnoreCase(catalogStr) + || "performance_schema".equalsIgnoreCase(catalogStr); - new IterateBlock(getCatalogIterator(catalog)) { - void forEach(Object catalogStr) throws SQLException { ResultSet results = null; try { - if (!conn.versionMeetsMinimum(5, 0, 2)) { - try { - results = stmt.executeQuery("SHOW TABLES FROM " - + quotedId + catalogStr.toString() - + quotedId + " LIKE '" + tableNamePat - + "'"); - } catch (SQLException sqlEx) { - if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE - .equals(sqlEx.getSQLState())) { - throw sqlEx; - } - - return; + try { + results = stmt.executeQuery((!conn.versionMeetsMinimum(5, 0, 2) ? "SHOW TABLES FROM " + : "SHOW FULL TABLES FROM ") + + StringUtils.quoteIdentifier(catalogStr, conn.getPedantic()) + + " LIKE '" + + tableNamePat + "'"); + } catch (SQLException sqlEx) { + if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE.equals(sqlEx.getSQLState())) { + throw sqlEx; } - } else { - try { - results = stmt - .executeQuery("SHOW FULL TABLES FROM " - + quotedId - + catalogStr.toString() - + quotedId + " LIKE '" - + tableNamePat + "'"); - } catch (SQLException sqlEx) { - if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE - .equals(sqlEx.getSQLState())) { - throw sqlEx; - } - return; - } + return; } boolean shouldReportTables = false; boolean shouldReportViews = false; - + boolean shouldReportSystemTables = false; + boolean shouldReportSystemViews = false; + boolean shouldReportLocalTemporaries = false; + if (types == null || types.length == 0) { shouldReportTables = true; shouldReportViews = true; + shouldReportSystemTables = true; + shouldReportSystemViews = true; + shouldReportLocalTemporaries = true; } else { for (int i = 0; i < types.length; i++) { - if ("TABLE".equalsIgnoreCase(types[i])) { + if (TableType.TABLE.equalsTo(types[i])) { shouldReportTables = true; - } - if ("VIEW".equalsIgnoreCase(types[i])) { + } else if (TableType.VIEW.equalsTo(types[i])) { shouldReportViews = true; + + } else if (TableType.SYSTEM_TABLE.equalsTo(types[i])) { + shouldReportSystemTables = true; + + } else if (TableType.SYSTEM_VIEW.equalsTo(types[i])) { + shouldReportSystemViews = true; + + } else if (TableType.LOCAL_TEMPORARY.equalsTo(types[i])) { + shouldReportLocalTemporaries = true; } } } @@ -4790,100 +5329,108 @@ } } - TreeMap tablesOrderedByName = null; - TreeMap viewsOrderedByName = null; - while (results.next()) { - byte[][] row = new byte[5][]; - row[0] = (catalogStr.toString() == null) ? null - : s2b(catalogStr.toString()); + byte[][] row = new byte[10][]; + row[0] = (catalogStr == null) ? null + : s2b(catalogStr); row[1] = null; row[2] = results.getBytes(1); row[4] = new byte[0]; + row[5] = null; + row[6] = null; + row[7] = null; + row[8] = null; + row[9] = null; if (hasTableTypes) { String tableType = results .getString(typeColumnIndex); - if (("table".equalsIgnoreCase(tableType) || "base table" - .equalsIgnoreCase(tableType)) - && shouldReportTables) { - row[3] = TABLE_AS_BYTES; + switch (TableType.getTableTypeCompliantWith(tableType)) { + case TABLE: + boolean reportTable = false; + TableMetaDataKey tablesKey = null; - if (tablesOrderedByName == null) { - tablesOrderedByName = new TreeMap(); - } + if (operatingOnSystemDB && shouldReportSystemTables) { + row[3] = TableType.SYSTEM_TABLE.asBytes(); + tablesKey = new TableMetaDataKey(TableType.SYSTEM_TABLE.getName(), + catalogStr, null, results.getString(1)); + reportTable = true; - tablesOrderedByName.put(results - .getString(1), row); - } else if ("view".equalsIgnoreCase(tableType) - && shouldReportViews) { - row[3] = VIEW_AS_BYTES; + } else if (!operatingOnSystemDB && shouldReportTables) { + row[3] = TableType.TABLE.asBytes(); + tablesKey = new TableMetaDataKey(TableType.TABLE.getName(), catalogStr, + null, results.getString(1)); + reportTable = true; + } - if (viewsOrderedByName == null) { - viewsOrderedByName = new TreeMap(); - } + if (reportTable) { + sortedRows.put(tablesKey, new ByteArrayRow(row, getExceptionInterceptor())); + } + break; - viewsOrderedByName.put( - results.getString(1), row); - } else if (!hasTableTypes) { - // punt? - row[3] = TABLE_AS_BYTES; + case VIEW: + if (shouldReportViews) { + row[3] = TableType.VIEW.asBytes(); + sortedRows.put(new TableMetaDataKey(TableType.VIEW.getName(), + catalogStr, null, results.getString(1)), new ByteArrayRow(row, + getExceptionInterceptor())); + } + break; - if (tablesOrderedByName == null) { - tablesOrderedByName = new TreeMap(); - } + case SYSTEM_TABLE: + if (shouldReportSystemTables) { + row[3] = TableType.SYSTEM_TABLE.asBytes(); + sortedRows.put(new TableMetaDataKey(TableType.SYSTEM_TABLE.getName(), + catalogStr, null, results.getString(1)), new ByteArrayRow(row, + getExceptionInterceptor())); + } + break; - tablesOrderedByName.put(results - .getString(1), row); + case SYSTEM_VIEW: + if (shouldReportSystemViews) { + row[3] = TableType.SYSTEM_VIEW.asBytes(); + sortedRows.put(new TableMetaDataKey(TableType.SYSTEM_VIEW.getName(), + catalogStr, null, results.getString(1)), new ByteArrayRow(row, + getExceptionInterceptor())); + } + break; + + case LOCAL_TEMPORARY: + if (shouldReportLocalTemporaries) { + row[3] = TableType.LOCAL_TEMPORARY.asBytes(); + sortedRows.put(new TableMetaDataKey(TableType.LOCAL_TEMPORARY.getName(), + catalogStr, null, results.getString(1)), new ByteArrayRow(row, + getExceptionInterceptor())); + } + break; + + default: + row[3] = TableType.TABLE.asBytes(); + sortedRows.put(new TableMetaDataKey(TableType.TABLE.getName(), catalogStr, + null, results.getString(1)), new ByteArrayRow(row, + getExceptionInterceptor())); + break; } } else { if (shouldReportTables) { // Pre-MySQL-5.0.1, tables only - row[3] = TABLE_AS_BYTES; - - if (tablesOrderedByName == null) { - tablesOrderedByName = new TreeMap(); - } - - tablesOrderedByName.put(results - .getString(1), row); + row[3] = TableType.TABLE.asBytes(); + sortedRows.put(new TableMetaDataKey(TableType.TABLE.getName(), catalogStr, null, + results.getString(1)), new ByteArrayRow(row, getExceptionInterceptor())); } } } - // They are ordered by TABLE_TYPE, - // * TABLE_SCHEM and TABLE_NAME. - - if (tablesOrderedByName != null) { - Iterator tablesIter = tablesOrderedByName.values() - .iterator(); - - while (tablesIter.hasNext()) { - tuples.add(tablesIter.next()); - } - } - - if (viewsOrderedByName != null) { - Iterator viewsIter = viewsOrderedByName.values() - .iterator(); - - while (viewsIter.hasNext()) { - tuples.add(viewsIter.next()); - } - } - } finally { if (results != null) { try { results.close(); } catch (Exception ex) { - ; } results = null; } - } } }.doForAll(); @@ -4893,10 +5440,26 @@ } } - java.sql.ResultSet tables = buildResultSet(fields, tuples); + tuples.addAll(sortedRows.values()); + java.sql.ResultSet tables = buildResultSet(createTablesFields(), tuples); return tables; } + + protected Field[] createTablesFields() { + Field[] fields = new Field[10]; + fields[0] = new Field("", "TABLE_CAT", java.sql.Types.VARCHAR, 255); + fields[1] = new Field("", "TABLE_SCHEM", java.sql.Types.VARCHAR, 0); + fields[2] = new Field("", "TABLE_NAME", java.sql.Types.VARCHAR, 255); + fields[3] = new Field("", "TABLE_TYPE", java.sql.Types.VARCHAR, 5); + fields[4] = new Field("", "REMARKS", java.sql.Types.VARCHAR, 0); + fields[5] = new Field("", "TYPE_CAT", java.sql.Types.VARCHAR, 0); + fields[6] = new Field("", "TYPE_SCHEM", java.sql.Types.VARCHAR, 0); + fields[7] = new Field("", "TYPE_NAME", java.sql.Types.VARCHAR, 0); + fields[8] = new Field("", "SELF_REFERENCING_COL_NAME", java.sql.Types.VARCHAR, 0); + fields[9] = new Field("", "REF_GENERATION", java.sql.Types.VARCHAR, 0); + return fields; + } /** * Get the table types available in this database. The results are ordered @@ -4916,24 +5479,21 @@ * DOCUMENT ME! */ public java.sql.ResultSet getTableTypes() throws SQLException { - ArrayList tuples = new ArrayList(); - Field[] fields = new Field[1]; - fields[0] = new Field("", "TABLE_TYPE", Types.VARCHAR, 5); + ArrayList tuples = new ArrayList(); + Field[] fields = new Field[] { new Field("", "TABLE_TYPE", Types.VARCHAR, 256) }; - byte[][] tableTypeRow = new byte[1][]; - tableTypeRow[0] = TABLE_AS_BYTES; - tuples.add(tableTypeRow); + boolean minVersion5_0_1 = this.conn.versionMeetsMinimum(5, 0, 1); - if (this.conn.versionMeetsMinimum(5, 0, 1)) { - byte[][] viewTypeRow = new byte[1][]; - viewTypeRow[0] = VIEW_AS_BYTES; - tuples.add(viewTypeRow); + tuples.add(new ByteArrayRow(new byte[][] { TableType.LOCAL_TEMPORARY.asBytes() }, getExceptionInterceptor())); + tuples.add(new ByteArrayRow(new byte[][] { TableType.SYSTEM_TABLE.asBytes() }, getExceptionInterceptor())); + if (minVersion5_0_1) { + tuples.add(new ByteArrayRow(new byte[][] { TableType.SYSTEM_VIEW.asBytes() }, getExceptionInterceptor())); } + tuples.add(new ByteArrayRow(new byte[][] { TableType.TABLE.asBytes() }, getExceptionInterceptor())); + if (minVersion5_0_1) { + tuples.add(new ByteArrayRow(new byte[][] { TableType.VIEW.asBytes() }, getExceptionInterceptor())); + } - byte[][] tempTypeRow = new byte[1][]; - tempTypeRow[0] = s2b("LOCAL TEMPORARY"); - tuples.add(tempTypeRow); - return buildResultSet(fields, tuples); } @@ -5056,17 +5616,17 @@ public java.sql.ResultSet getTypeInfo() throws SQLException { Field[] fields = new Field[18]; fields[0] = new Field("", "TYPE_NAME", Types.CHAR, 32); - fields[1] = new Field("", "DATA_TYPE", Types.SMALLINT, 5); + fields[1] = new Field("", "DATA_TYPE", Types.INTEGER, 5); fields[2] = new Field("", "PRECISION", Types.INTEGER, 10); fields[3] = new Field("", "LITERAL_PREFIX", Types.CHAR, 4); fields[4] = new Field("", "LITERAL_SUFFIX", Types.CHAR, 4); fields[5] = new Field("", "CREATE_PARAMS", Types.CHAR, 32); fields[6] = new Field("", "NULLABLE", Types.SMALLINT, 5); - fields[7] = new Field("", "CASE_SENSITIVE", Types.CHAR, 3); + fields[7] = new Field("", "CASE_SENSITIVE", Types.BOOLEAN, 3); fields[8] = new Field("", "SEARCHABLE", Types.SMALLINT, 3); - fields[9] = new Field("", "UNSIGNED_ATTRIBUTE", Types.CHAR, 3); - fields[10] = new Field("", "FIXED_PREC_SCALE", Types.CHAR, 3); - fields[11] = new Field("", "AUTO_INCREMENT", Types.CHAR, 3); + fields[9] = new Field("", "UNSIGNED_ATTRIBUTE", Types.BOOLEAN, 3); + fields[10] = new Field("", "FIXED_PREC_SCALE", Types.BOOLEAN, 3); + fields[11] = new Field("", "AUTO_INCREMENT", Types.BOOLEAN, 3); fields[12] = new Field("", "LOCAL_TYPE_NAME", Types.CHAR, 32); fields[13] = new Field("", "MINIMUM_SCALE", Types.SMALLINT, 5); fields[14] = new Field("", "MAXIMUM_SCALE", Types.SMALLINT, 5); @@ -5075,7 +5635,7 @@ fields[17] = new Field("", "NUM_PREC_RADIX", Types.INTEGER, 10); byte[][] rowVal = null; - ArrayList tuples = new ArrayList(); + ArrayList tuples = new ArrayList(); /* * The following are ordered by java.sql.Types, and then by how closely @@ -5111,7 +5671,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: BOOL (silently converted to TINYINT(1)) JDBC Type: BIT @@ -5143,7 +5703,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: TINYINT JDBC Type: TINYINT @@ -5175,7 +5735,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); rowVal = new byte[18][]; rowVal[0] = s2b("TINYINT UNSIGNED"); @@ -5204,7 +5764,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: BIGINT JDBC Type: BIGINT @@ -5236,7 +5796,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); rowVal = new byte[18][]; rowVal[0] = s2b("BIGINT UNSIGNED"); @@ -5265,7 +5825,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: LONG VARBINARY JDBC Type: LONGVARBINARY @@ -5297,7 +5857,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: MEDIUMBLOB JDBC Type: LONGVARBINARY @@ -5329,7 +5889,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: LONGBLOB JDBC Type: LONGVARBINARY @@ -5363,7 +5923,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: BLOB JDBC Type: LONGVARBINARY @@ -5395,7 +5955,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: TINYBLOB JDBC Type: LONGVARBINARY @@ -5427,7 +5987,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: VARBINARY (sliently converted to VARCHAR(M) BINARY) JDBC @@ -5460,7 +6020,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: BINARY (silently converted to CHAR(M) BINARY) JDBC Type: @@ -5493,7 +6053,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: LONG VARCHAR JDBC Type: LONGVARCHAR @@ -5525,7 +6085,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: MEDIUMTEXT JDBC Type: LONGVARCHAR @@ -5557,7 +6117,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: LONGTEXT JDBC Type: LONGVARCHAR @@ -5591,7 +6151,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: TEXT JDBC Type: LONGVARCHAR @@ -5623,7 +6183,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: TINYTEXT JDBC Type: LONGVARCHAR @@ -5655,7 +6215,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: CHAR JDBC Type: CHAR @@ -5687,7 +6247,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); // The maximum number of digits for DECIMAL or NUMERIC is 65 (64 from MySQL 5.0.3 to 5.0.5). @@ -5732,7 +6292,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: DECIMAL JDBC Type: DECIMAL @@ -5764,7 +6324,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: INTEGER JDBC Type: INTEGER @@ -5796,7 +6356,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); rowVal = new byte[18][]; rowVal[0] = s2b("INTEGER UNSIGNED"); @@ -5825,7 +6385,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: INT JDBC Type: INTEGER @@ -5857,7 +6417,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); rowVal = new byte[18][]; rowVal[0] = s2b("INT UNSIGNED"); @@ -5886,7 +6446,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: MEDIUMINT JDBC Type: INTEGER @@ -5918,7 +6478,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); rowVal = new byte[18][]; rowVal[0] = s2b("MEDIUMINT UNSIGNED"); @@ -5947,7 +6507,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: SMALLINT JDBC Type: SMALLINT @@ -5979,7 +6539,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); rowVal = new byte[18][]; rowVal[0] = s2b("SMALLINT UNSIGNED"); @@ -6008,7 +6568,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: FLOAT JDBC Type: REAL (this is the SINGLE PERCISION @@ -6041,7 +6601,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: DOUBLE JDBC Type: DOUBLE @@ -6073,7 +6633,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: DOUBLE PRECISION JDBC Type: DOUBLE @@ -6105,7 +6665,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: REAL (does not map to Types.REAL) JDBC Type: DOUBLE @@ -6137,7 +6697,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: VARCHAR JDBC Type: VARCHAR @@ -6169,7 +6729,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: ENUM JDBC Type: VARCHAR @@ -6201,7 +6761,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: SET JDBC Type: VARCHAR @@ -6233,7 +6793,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: DATE JDBC Type: DATE @@ -6265,7 +6825,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: TIME JDBC Type: TIME @@ -6297,7 +6857,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: DATETIME JDBC Type: TIMESTAMP @@ -6329,7 +6889,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); /* * MySQL Type: TIMESTAMP JDBC Type: TIMESTAMP @@ -6361,7 +6921,7 @@ rowVal[15] = s2b("0"); // SQL Data Type (not used) rowVal[16] = s2b("0"); // SQL DATETIME SUB (not used) rowVal[17] = s2b("10"); // NUM_PREC_RADIX (2 or 10) - tuples.add(rowVal); + tuples.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); return buildResultSet(fields, tuples); } @@ -6409,15 +6969,16 @@ */ public java.sql.ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException { - Field[] fields = new Field[6]; + Field[] fields = new Field[7]; fields[0] = new Field("", "TYPE_CAT", Types.VARCHAR, 32); fields[1] = new Field("", "TYPE_SCHEM", Types.VARCHAR, 32); fields[2] = new Field("", "TYPE_NAME", Types.VARCHAR, 32); fields[3] = new Field("", "CLASS_NAME", Types.VARCHAR, 32); - fields[4] = new Field("", "DATA_TYPE", Types.VARCHAR, 32); + fields[4] = new Field("", "DATA_TYPE", Types.INTEGER, 10); fields[5] = new Field("", "REMARKS", Types.VARCHAR, 32); + fields[6] = new Field("", "BASE_TYPE", Types.SMALLINT, 10); - ArrayList tuples = new ArrayList(); + ArrayList tuples = new ArrayList(); return buildResultSet(fields, tuples); } @@ -6514,20 +7075,158 @@ * DOCUMENT ME! */ public java.sql.ResultSet getVersionColumns(String catalog, String schema, - String table) throws SQLException { + final String table) throws SQLException { + + if (table == null) { + throw SQLError.createSQLException("Table not specified.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + Field[] fields = new Field[8]; fields[0] = new Field("", "SCOPE", Types.SMALLINT, 5); fields[1] = new Field("", "COLUMN_NAME", Types.CHAR, 32); - fields[2] = new Field("", "DATA_TYPE", Types.SMALLINT, 5); + fields[2] = new Field("", "DATA_TYPE", Types.INTEGER, 5); fields[3] = new Field("", "TYPE_NAME", Types.CHAR, 16); - fields[4] = new Field("", "COLUMN_SIZE", Types.CHAR, 16); - fields[5] = new Field("", "BUFFER_LENGTH", Types.CHAR, 16); - fields[6] = new Field("", "DECIMAL_DIGITS", Types.CHAR, 16); + fields[4] = new Field("", "COLUMN_SIZE", Types.INTEGER, 16); + fields[5] = new Field("", "BUFFER_LENGTH", Types.INTEGER, 16); + fields[6] = new Field("", "DECIMAL_DIGITS", Types.SMALLINT, 16); fields[7] = new Field("", "PSEUDO_COLUMN", Types.SMALLINT, 5); - return buildResultSet(fields, new ArrayList()); + final ArrayList rows = new ArrayList(); - // do TIMESTAMP columns count? + final Statement stmt = this.conn.getMetadataSafeStatement(); + + try { + + new IterateBlock(getCatalogIterator(catalog)) { + void forEach(String catalogStr) throws SQLException { + + ResultSet results = null; + boolean with_where = conn.versionMeetsMinimum(5, 0, 0); + + try { + StringBuffer whereBuf = new StringBuffer(" Extra LIKE '%on update CURRENT_TIMESTAMP%'"); + List rsFields = new ArrayList(); + + // for versions prior to 5.1.23 we can get "on update CURRENT_TIMESTAMP" + // only from SHOW CREATE TABLE + if (!conn.versionMeetsMinimum(5, 1, 23)) { + + whereBuf = new StringBuffer(); + boolean firstTime = true; + + String query = new StringBuffer("SHOW CREATE TABLE ") + .append(StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())).append(".") + .append(StringUtils.quoteIdentifier(table, conn.getPedantic())).toString(); + + results = stmt.executeQuery(query); + while (results.next()) { + String createTableString = results.getString(2); + StringTokenizer lineTokenizer = new StringTokenizer(createTableString, "\n"); + + while (lineTokenizer.hasMoreTokens()) { + String line = lineTokenizer.nextToken().trim(); + if (StringUtils.indexOfIgnoreCase(line, "on update CURRENT_TIMESTAMP") > -1) { + boolean usingBackTicks = true; + int beginPos = line.indexOf(quotedId); + + if (beginPos == -1) { + beginPos = line.indexOf("\""); + usingBackTicks = false; + } + + if (beginPos != -1) { + int endPos = -1; + + if (usingBackTicks) { + endPos = line.indexOf(quotedId, beginPos + 1); + } else { + endPos = line.indexOf("\"", beginPos + 1); + } + + if (endPos != -1) { + if (with_where) { + if (!firstTime) { + whereBuf.append(" or"); + } else { + firstTime = false; + } + whereBuf.append(" Field='"); + whereBuf.append(line.substring(beginPos + 1, endPos)); + whereBuf.append("'"); + } else { + rsFields.add(line.substring(beginPos + 1, endPos)); + } + } + } + } + } + } + } + + if (whereBuf.length() > 0 || rsFields.size() > 0) { + StringBuffer queryBuf = new StringBuffer("SHOW "); + queryBuf.append("COLUMNS FROM "); + queryBuf.append(StringUtils.quoteIdentifier(table, conn.getPedantic())); + queryBuf.append(" FROM "); + queryBuf.append(StringUtils.quoteIdentifier(catalogStr, conn.getPedantic())); + if (with_where) { + queryBuf.append(" WHERE"); + queryBuf.append(whereBuf.toString()); + } + + results = stmt.executeQuery(queryBuf.toString()); + + while (results.next()) { + if (with_where || rsFields.contains(results.getString("Field"))) { + TypeDescriptor typeDesc = new TypeDescriptor(results.getString("Type"), results.getString("Null")); + byte[][] rowVal = new byte[8][]; + // SCOPE is not used + rowVal[0] = null; + // COLUMN_NAME + rowVal[1] = results.getBytes("Field"); + // DATA_TYPE + rowVal[2] = Short.toString(typeDesc.dataType).getBytes(); + // TYPE_NAME + rowVal[3] = s2b(typeDesc.typeName); + // COLUMN_SIZE + rowVal[4] = typeDesc.columnSize == null ? null : s2b(typeDesc.columnSize.toString()); + // BUFFER_LENGTH + rowVal[5] = s2b(Integer.toString(typeDesc.bufferLength)); + // DECIMAL_DIGITS + rowVal[6] = typeDesc.decimalDigits == null ? null : s2b(typeDesc.decimalDigits.toString()); + // PSEUDO_COLUMN + rowVal[7] = Integer.toString(java.sql.DatabaseMetaData.versionColumnNotPseudo).getBytes(); + + rows.add(new ByteArrayRow(rowVal, getExceptionInterceptor())); + } + } + } + } catch (SQLException sqlEx) { + if (!SQLError.SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND.equals(sqlEx.getSQLState())) { + throw sqlEx; + } + } finally { + if (results != null) { + try { + results.close(); + } catch (Exception ex) { + ; + } + + results = null; + } + } + + } + }.doForAll(); + } finally { + if (stmt != null) { + stmt.close(); + } + } + + return buildResultSet(fields, rows); } /** @@ -6709,7 +7408,7 @@ return false; } - private LocalAndReferencedColumns parseTableStatusIntoLocalAndReferencedColumns( + protected LocalAndReferencedColumns parseTableStatusIntoLocalAndReferencedColumns( String keysComment) throws SQLException { // keys will equal something like this: // (parent_service_id child_service_id) REFER @@ -6737,14 +7436,14 @@ true); if (indexOfOpenParenLocalColumns == -1) { - throw SQLError.createSQLException( - "Error parsing foreign keys definition," - + " couldn't find start of local columns list.", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException("Error parsing foreign keys definition," + + " couldn't find start of local columns list.", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } - String constraintName = removeQuotedId(keysComment.substring(0, - indexOfOpenParenLocalColumns).trim()); + String constraintName = StringUtils.unQuoteIdentifier( + keysComment.substring(0, indexOfOpenParenLocalColumns).trim(), + this.conn.useAnsiQuotedIdentifiers()); keysComment = keysComment.substring(indexOfOpenParenLocalColumns, keysComment.length()); @@ -6755,10 +7454,9 @@ quoteChar, true); if (indexOfCloseParenLocalColumns == -1) { - throw SQLError.createSQLException( - "Error parsing foreign keys definition," - + " couldn't find end of local columns list.", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException("Error parsing foreign keys definition," + + " couldn't find end of local columns list.", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } String localColumnNamesString = keysCommentTrimmed.substring(1, @@ -6768,23 +7466,19 @@ keysCommentTrimmed, "REFER ", this.quotedId.charAt(0), true); if (indexOfRefer == -1) { - throw SQLError - .createSQLException( - "Error parsing foreign keys definition," - + " couldn't find start of referenced tables list.", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException("Error parsing foreign keys definition," + + " couldn't find start of referenced tables list.", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } int indexOfOpenParenReferCol = StringUtils .indexOfIgnoreCaseRespectQuotes(indexOfRefer, keysCommentTrimmed, "(", quoteChar, false); if (indexOfOpenParenReferCol == -1) { - throw SQLError - .createSQLException( - "Error parsing foreign keys definition," - + " couldn't find start of referenced columns list.", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException("Error parsing foreign keys definition," + + " couldn't find start of referenced columns list.", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } String referCatalogTableString = keysCommentTrimmed.substring( @@ -6794,66 +7488,40 @@ referCatalogTableString, "/", this.quotedId.charAt(0), false); if (indexOfSlash == -1) { - throw SQLError.createSQLException( - "Error parsing foreign keys definition," - + " couldn't find name of referenced catalog.", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException("Error parsing foreign keys definition," + + " couldn't find name of referenced catalog.", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } - String referCatalog = removeQuotedId(referCatalogTableString.substring( - 0, indexOfSlash)); - String referTable = removeQuotedId(referCatalogTableString.substring( - indexOfSlash + 1).trim()); + String referCatalog = StringUtils.unQuoteIdentifier( + referCatalogTableString.substring(0, indexOfSlash), + this.conn.useAnsiQuotedIdentifiers()); + String referTable = StringUtils.unQuoteIdentifier( + referCatalogTableString.substring(indexOfSlash + 1).trim(), + this.conn.useAnsiQuotedIdentifiers()); int indexOfCloseParenRefer = StringUtils .indexOfIgnoreCaseRespectQuotes(indexOfOpenParenReferCol, keysCommentTrimmed, ")", quoteChar, true); if (indexOfCloseParenRefer == -1) { - throw SQLError.createSQLException( - "Error parsing foreign keys definition," - + " couldn't find end of referenced columns list.", - SQLError.SQL_STATE_GENERAL_ERROR); + throw SQLError.createSQLException("Error parsing foreign keys definition," + + " couldn't find end of referenced columns list.", + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } String referColumnNamesString = keysCommentTrimmed.substring( indexOfOpenParenReferCol + 1, indexOfCloseParenRefer); - List referColumnsList = StringUtils.split(referColumnNamesString, + List referColumnsList = StringUtils.split(referColumnNamesString, columnsDelimitter, this.quotedId, this.quotedId, false); - List localColumnsList = StringUtils.split(localColumnNamesString, + List localColumnsList = StringUtils.split(localColumnNamesString, columnsDelimitter, this.quotedId, this.quotedId, false); return new LocalAndReferencedColumns(localColumnsList, referColumnsList, constraintName, referCatalog, referTable); } - private String removeQuotedId(String s) { - if (s == null) { - return null; - } - - if (this.quotedId.equals("")) { - return s; - } - - s = s.trim(); - - int frontOffset = 0; - int backOffset = s.length(); - int quoteLength = this.quotedId.length(); - - if (s.startsWith(this.quotedId)) { - frontOffset = quoteLength; - } - - if (s.endsWith(this.quotedId)) { - backOffset -= quoteLength; - } - - return s.substring(frontOffset, backOffset); - } - /** * Converts the given string to bytes, using the connection's character * encoding, or if not available, the JVM default encoding. @@ -6862,8 +7530,14 @@ * DOCUMENT ME! * @return DOCUMENT ME! */ - private byte[] s2b(String s) throws SQLException { - return StringUtils.s2b(s, this.conn); + protected byte[] s2b(String s) throws SQLException { + if (s == null) { + return null; + } + + return StringUtils.getBytes(s, this.conn.getCharacterSetMetadata(), + this.conn.getServerCharacterEncoding(), this.conn + .parserKnowsUnicode(), this.conn, getExceptionInterceptor()); } /** @@ -6875,7 +7549,7 @@ * DOCUMENT ME! */ public boolean storesLowerCaseIdentifiers() throws SQLException { - return this.conn.lowerCaseTableNames(); + return this.conn.storesLowerCaseTableName(); } /** @@ -6887,7 +7561,7 @@ * DOCUMENT ME! */ public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { - return this.conn.lowerCaseTableNames(); + return this.conn.storesLowerCaseTableName(); } /** @@ -6899,9 +7573,8 @@ * DOCUMENT ME! */ public boolean storesMixedCaseIdentifiers() throws SQLException { - return !this.conn.lowerCaseTableNames(); + return !this.conn.storesLowerCaseTableName(); } - /** * Does the database store mixed case quoted SQL identifiers in mixed case? * A JDBC compliant driver will always return false. @@ -6911,7 +7584,7 @@ * DOCUMENT ME! */ public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { - return !this.conn.lowerCaseTableNames(); + return !this.conn.storesLowerCaseTableName(); } /** @@ -7144,16 +7817,16 @@ return false; } - /* - * We don't handle the BIT type yet. - */ + /* + * We don't handle the BIT type yet. + */ 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: @@ -7186,14 +7859,14 @@ return false; } - /* MySQL doesn't support a NULL type. */ + /* MySQL doesn't support a NULL type. */ 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) { @@ -7209,7 +7882,7 @@ return false; } - /* Dates can be converted to char/binary types. */ + /* Dates can be converted to char/binary types. */ case java.sql.Types.DATE: switch (toType) { @@ -7225,7 +7898,7 @@ return false; } - /* Time can be converted to char/binary types */ + /* Time can be converted to char/binary types */ case java.sql.Types.TIME: switch (toType) { @@ -7241,10 +7914,10 @@ return false; } - /* - * Timestamp can be converted to char/binary types and date/time - * types (with loss of precision). - */ + /* + * Timestamp can be converted to char/binary types and date/time types + * (with loss of precision). + */ case java.sql.Types.TIMESTAMP: switch (toType) { @@ -7262,7 +7935,7 @@ return false; } - /* We shouldn't get here! */ + /* We shouldn't get here! */ default: return false; // not sure } @@ -7415,8 +8088,8 @@ public boolean supportsIntegrityEnhancementFacility() throws SQLException { if (!this.conn.getOverrideSupportsIntegrityEnhancementFacility()) { return false; - } - + } + return true; } @@ -7494,7 +8167,7 @@ * DOCUMENT ME! */ public boolean supportsMultipleResultSets() throws SQLException { - return false; + return this.conn.versionMeetsMinimum(4, 1, 0); } /** @@ -7640,26 +8313,26 @@ if ((concurrency == ResultSet.CONCUR_READ_ONLY) || (concurrency == ResultSet.CONCUR_UPDATABLE)) { return true; - } else { - throw SQLError.createSQLException( - "Illegal arguments to supportsResultSetConcurrency()", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } + throw SQLError.createSQLException( + "Illegal arguments to supportsResultSetConcurrency()", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + case ResultSet.TYPE_FORWARD_ONLY: if ((concurrency == ResultSet.CONCUR_READ_ONLY) || (concurrency == ResultSet.CONCUR_UPDATABLE)) { return true; - } else { - throw SQLError.createSQLException( - "Illegal arguments to supportsResultSetConcurrency()", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } + throw SQLError.createSQLException( + "Illegal arguments to supportsResultSetConcurrency()", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + case ResultSet.TYPE_SCROLL_SENSITIVE: return false; default: throw SQLError.createSQLException( "Illegal arguments to supportsResultSetConcurrency()", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @@ -7937,4 +8610,233 @@ public boolean usesLocalFiles() throws SQLException { return false; } + + // + // JDBC-4.0 functions that aren't reliant on Java6 + // + + /** + * Retrieves a list of the client info properties that the driver supports. The result set contains the following + * columns + *

+ *

    + *
  1. NAME String=> The name of the client info property
    + *
  2. MAX_LEN int=> The maximum length of the value for the property
    + *
  3. DEFAULT_VALUE String=> The default value of the property
    + *
  4. DESCRIPTION String=> A description of the property. This will typically contain information as to + * where this property is stored in the database. + *
+ *

+ * The ResultSet is sorted by the NAME column + *

+ * + * @return A ResultSet object; each row is a supported client info property + *

+ * @exception SQLException + * if a database access error occurs + *

+ * @since 1.6 + */ + public ResultSet getClientInfoProperties() throws SQLException { + // We don't have any built-ins, we actually support whatever + // the client wants to provide, however we don't have a way + // to express this with the interface given + Field[] fields = new Field[4]; + fields[0] = new Field("", "NAME", Types.VARCHAR, 255); + fields[1] = new Field("", "MAX_LEN", Types.INTEGER, 10); + fields[2] = new Field("", "DEFAULT_VALUE", Types.VARCHAR, 255); + fields[3] = new Field("", "DESCRIPTION", Types.VARCHAR, 255); + + return buildResultSet(fields, new ArrayList(), this.conn); + } + + /** + * Retrieves a description of the given catalog's system or user + * function parameters and return type. + * + * @see java.sql.DatabaseMetaData#getFunctionColumns(String, String, String, String) + * @since 1.6 + */ + public ResultSet getFunctionColumns(String catalog, + String schemaPattern, + String functionNamePattern, + String columnNamePattern) throws SQLException { + Field[] fields = createFunctionColumnsFields(); + + return getProcedureOrFunctionColumns( + fields, catalog, schemaPattern, + functionNamePattern, columnNamePattern, + false, true); + } + + protected Field[] createFunctionColumnsFields() { + Field[] fields = { + new Field("", "FUNCTION_CAT", Types.VARCHAR, 512), + new Field("", "FUNCTION_SCHEM", Types.VARCHAR, 512), + new Field("", "FUNCTION_NAME", Types.VARCHAR, 512), + new Field("", "COLUMN_NAME", Types.VARCHAR, 512), + new Field("", "COLUMN_TYPE", Types.VARCHAR, 64), + new Field("", "DATA_TYPE", Types.SMALLINT, 6), + new Field("", "TYPE_NAME", Types.VARCHAR, 64), + new Field("", "PRECISION", Types.INTEGER, 12), + new Field("", "LENGTH", Types.INTEGER, 12), + new Field("", "SCALE", Types.SMALLINT, 12), + new Field("", "RADIX", Types.SMALLINT, 6), + new Field("", "NULLABLE", Types.SMALLINT, 6), + new Field("", "REMARKS", Types.VARCHAR, 512), + new Field("", "CHAR_OCTET_LENGTH", Types.INTEGER, 32), + new Field("", "ORDINAL_POSITION", Types.INTEGER, 32), + new Field("", "IS_NULLABLE", Types.VARCHAR, 12), + new Field("", "SPECIFIC_NAME", Types.VARCHAR, 64)}; + return fields; + } + + /** + * Retrieves a description of the system and user functions available + * in the given catalog. + *

+ * Only system and user function descriptions matching the schema and + * function name criteria are returned. They are ordered by + * FUNCTION_CAT, FUNCTION_SCHEM, + * FUNCTION_NAME and + * SPECIFIC_ NAME. + * + *

Each function description has the the following columns: + *

    + *
  1. FUNCTION_CAT String => function catalog (may be null) + *
  2. FUNCTION_SCHEM String => function schema (may be null) + *
  3. FUNCTION_NAME String => function name. This is the name + * used to invoke the function + *
  4. REMARKS String => explanatory comment on the function + *
  5. FUNCTION_TYPE short => kind of function: + *
      + *
    • functionResultUnknown - Cannot determine if a return value + * or table will be returned + *
    • functionNoTable- Does not return a table + *
    • functionReturnsTable - Returns a table + *
    + *
  6. SPECIFIC_NAME String => the name which uniquely identifies + * this function within its schema. This is a user specified, or DBMS + * generated, name that may be different then the FUNCTION_NAME + * for example with overload functions + *
+ *

+ * A user may not have permission to execute any of the functions that are + * returned by getFunctions + * + * @param catalog a catalog name; must match the catalog name as it + * is stored in the database; "" retrieves those without a catalog; + * null means that the catalog name should not be used to narrow + * the search + * @param schemaPattern a schema name pattern; must match the schema name + * as it is stored in the database; "" retrieves those without a schema; + * null means that the schema name should not be used to narrow + * the search + * @param functionNamePattern a function name pattern; must match the + * function name as it is stored in the database + * @return ResultSet - each row is a function description + * @exception SQLException if a database access error occurs + * @see #getSearchStringEscape + * @since 1.6 + */ + public java.sql.ResultSet getFunctions(String catalog, String schemaPattern, + String functionNamePattern) throws SQLException { + Field[] fields = new Field[6]; + + fields[0] = new Field("", "FUNCTION_CAT", Types.CHAR, 255); + fields[1] = new Field("", "FUNCTION_SCHEM", Types.CHAR, 255); + fields[2] = new Field("", "FUNCTION_NAME", Types.CHAR, 255); + fields[3] = new Field("", "REMARKS", Types.CHAR, 255); + fields[4] = new Field("", "FUNCTION_TYPE", Types.SMALLINT, 6); + fields[5] = new Field("", "SPECIFIC_NAME", Types.CHAR, 255); + + return getProceduresAndOrFunctions( + fields, + catalog, + schemaPattern, + functionNamePattern, + false, + true); + } + + public boolean providesQueryObjectGenerator() throws SQLException { + return false; + } + + /** + * + * @param catalog + * @param schemaPattern + * @return + * @throws SQLException + */ + public ResultSet getSchemas(String catalog, + String schemaPattern) throws SQLException { + Field[] fields = { + new Field("", "TABLE_SCHEM", Types.VARCHAR, 255), + new Field("", "TABLE_CATALOG", Types.VARCHAR, 255) + }; + + return buildResultSet(fields, new ArrayList()); + } + + public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException { + return true; + } + + /** + * Get a prepared statement to query information_schema tables. + * + * @return PreparedStatement + * @throws SQLException + */ + protected java.sql.PreparedStatement prepareMetaDataSafeStatement(String sql) + throws SQLException { + // Can't use server-side here as we coerce a lot of types to match + // the spec. + java.sql.PreparedStatement pStmt = this.conn.clientPrepareStatement(sql); + + if (pStmt.getMaxRows() != 0) { + pStmt.setMaxRows(0); + } + + ((com.mysql.jdbc.Statement) pStmt).setHoldResultsOpenOverClose(true); + + return pStmt; + } + + /** + * JDBC-4.1 + * + * @param catalog + * @param schemaPattern + * @param tableNamePattern + * @param columnNamePattern + * @return + * @throws SQLException + */ + public java.sql.ResultSet getPseudoColumns(String catalog, + String schemaPattern, String tableNamePattern, + String columnNamePattern) throws SQLException { + Field[] fields = { new Field("", "TABLE_CAT", Types.VARCHAR, 512), + new Field("", "TABLE_SCHEM", Types.VARCHAR, 512), + new Field("", "TABLE_NAME", Types.VARCHAR, 512), + new Field("", "COLUMN_NAME", Types.VARCHAR, 512), + new Field("", "DATA_TYPE", Types.INTEGER, 12), + new Field("", "COLUMN_SIZE", Types.INTEGER, 12), + new Field("", "DECIMAL_DIGITS", Types.INTEGER, 12), + new Field("", "NUM_PREC_RADIX", Types.INTEGER, 12), + new Field("", "COLUMN_USAGE", Types.VARCHAR, 512), + new Field("", "REMARKS", Types.VARCHAR, 512), + new Field("", "CHAR_OCTET_LENGTH", Types.INTEGER, 12), + new Field("", "IS_NULLABLE", Types.VARCHAR, 512) }; + + return buildResultSet(fields, new ArrayList()); + } + + // JDBC-4.1 + public boolean generatedKeyAlwaysReturned() + throws SQLException { + return true; + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaDataUsingInfoSchema.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaDataUsingInfoSchema.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaDataUsingInfoSchema.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/DatabaseMetaDataUsingInfoSchema.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,30 +1,32 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */ + package com.mysql.jdbc; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; +import java.util.List; /** * DatabaseMetaData implementation that uses INFORMATION_SCHEMA available in @@ -35,15 +37,41 @@ */ public class DatabaseMetaDataUsingInfoSchema extends DatabaseMetaData { - public DatabaseMetaDataUsingInfoSchema(Connection connToSet, - String databaseToSet) { + protected enum JDBC4FunctionConstant { + // COLUMN_TYPE values + FUNCTION_COLUMN_UNKNOWN, FUNCTION_COLUMN_IN, FUNCTION_COLUMN_INOUT, FUNCTION_COLUMN_OUT, + FUNCTION_COLUMN_RETURN, FUNCTION_COLUMN_RESULT, + // NULLABLE values + FUNCTION_NO_NULLS, FUNCTION_NULLABLE, FUNCTION_NULLABLE_UNKNOWN; + } + + private boolean hasReferentialConstraintsView; + private final boolean hasParametersView; + + protected DatabaseMetaDataUsingInfoSchema(MySQLConnection connToSet, + String databaseToSet) throws SQLException { super(connToSet, databaseToSet); + + this.hasReferentialConstraintsView = + this.conn.versionMeetsMinimum(5, 1, 10); + + ResultSet rs = null; + + try { + rs = super.getTables("INFORMATION_SCHEMA", null, "PARAMETERS", new String[0]); + + this.hasParametersView = rs.next(); + } finally { + if (rs != null) { + rs.close(); + } + } } - private ResultSet executeMetadataQuery(PreparedStatement pStmt) + protected ResultSet executeMetadataQuery(java.sql.PreparedStatement pStmt) throws SQLException { ResultSet rs = pStmt.executeQuery(); - ((com.mysql.jdbc.ResultSet) rs).setOwningStatement(null); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).setOwningStatement(null); return rs; } @@ -92,7 +120,7 @@ } else { throw SQLError.createSQLException( "Column name pattern can not be NULL or empty.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @@ -109,7 +137,7 @@ + "TABLE_NAME =? AND COLUMN_NAME LIKE ? ORDER BY " + "COLUMN_NAME, PRIVILEGE_TYPE"; - PreparedStatement pStmt = null; + java.sql.PreparedStatement pStmt = null; try { pStmt = prepareMetaDataSafeStatement(sql); @@ -124,7 +152,7 @@ pStmt.setString(3, columnNamePattern); ResultSet rs = executeMetadataQuery(pStmt); - ((com.mysql.jdbc.ResultSet) rs).redefineFieldsForDBMD(new Field[] { + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(new Field[] { new Field("", "TABLE_CAT", Types.CHAR, 64), new Field("", "TABLE_SCHEM", Types.CHAR, 1), new Field("", "TABLE_NAME", Types.CHAR, 64), @@ -194,7 +222,7 @@ } else { throw SQLError.createSQLException( "Column name pattern can not be NULL or empty.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @@ -212,15 +240,14 @@ sqlBuf.append(" AS DATA_TYPE, "); if (conn.getCapitalizeTypeNames()) { - sqlBuf.append("UPPER(CASE WHEN LOCATE('unsigned', COLUMN_TYPE) != 0 AND LOCATE('unsigned', DATA_TYPE) = 0 THEN CONCAT(DATA_TYPE, ' unsigned') ELSE DATA_TYPE END) AS TYPE_NAME,"); + sqlBuf.append("UPPER(CASE WHEN LOCATE('unsigned', COLUMN_TYPE) != 0 AND LOCATE('unsigned', DATA_TYPE) = 0 AND LOCATE('set', DATA_TYPE) <> 1 AND LOCATE('enum', DATA_TYPE) <> 1 THEN CONCAT(DATA_TYPE, ' unsigned') ELSE DATA_TYPE END) AS TYPE_NAME,"); } else { - sqlBuf.append("CASE WHEN LOCATE('unsigned', COLUMN_TYPE) != 0 AND LOCATE('unsigned', DATA_TYPE) = 0 THEN CONCAT(DATA_TYPE, ' unsigned') ELSE DATA_TYPE END AS TYPE_NAME,"); + sqlBuf.append("CASE WHEN LOCATE('unsigned', COLUMN_TYPE) != 0 AND LOCATE('unsigned', DATA_TYPE) = 0 AND LOCATE('set', DATA_TYPE) <> 1 AND LOCATE('enum', DATA_TYPE) <> 1 THEN CONCAT(DATA_TYPE, ' unsigned') ELSE DATA_TYPE END AS TYPE_NAME,"); } sqlBuf - .append("CASE WHEN CHARACTER_MAXIMUM_LENGTH IS NULL THEN NUMERIC_PRECISION ELSE CASE WHEN CHARACTER_MAXIMUM_LENGTH > " - + Integer.MAX_VALUE + " THEN " + Integer.MAX_VALUE + - " ELSE CHARACTER_MAXIMUM_LENGTH END END AS COLUMN_SIZE, " + .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," @@ -237,13 +264,44 @@ + "NULL AS SCOPE_TABLE," + "NULL AS SOURCE_DATA_TYPE," + "IF (EXTRA LIKE '%auto_increment%','YES','NO') AS IS_AUTOINCREMENT " - + "FROM INFORMATION_SCHEMA.COLUMNS WHERE " - + "TABLE_SCHEMA LIKE ? AND " - + "TABLE_NAME LIKE ? AND COLUMN_NAME LIKE ? " - + "ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION"); + + "FROM INFORMATION_SCHEMA.COLUMNS WHERE "); - PreparedStatement pStmt = null; + final boolean operatingOnInformationSchema = "information_schema".equalsIgnoreCase(catalog); + + if (catalog != null) { + if ((operatingOnInformationSchema) || ((StringUtils.indexOfIgnoreCase(0, catalog, "%") == -1) + && (StringUtils.indexOfIgnoreCase(0, catalog, "_") == -1))) { + sqlBuf.append("TABLE_SCHEMA = ? AND "); + } else { + sqlBuf.append("TABLE_SCHEMA LIKE ? AND "); + } + + } else { + sqlBuf.append("TABLE_SCHEMA LIKE ? AND "); + } + if (tableName != null) { + if ((StringUtils.indexOfIgnoreCase(0, tableName, "%") == -1) + && (StringUtils.indexOfIgnoreCase(0, tableName, "_") == -1)) { + sqlBuf.append("TABLE_NAME = ? AND "); + } else { + sqlBuf.append("TABLE_NAME LIKE ? AND "); + } + + } else { + sqlBuf.append("TABLE_NAME LIKE ? AND "); + } + + if ((StringUtils.indexOfIgnoreCase(0, columnNamePattern, "%") == -1) + && (StringUtils.indexOfIgnoreCase(0, columnNamePattern, "_") == -1)) { + sqlBuf.append("COLUMN_NAME = ? "); + } else { + sqlBuf.append("COLUMN_NAME LIKE ? "); + } + sqlBuf.append("ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION"); + + java.sql.PreparedStatement pStmt = null; + try { pStmt = prepareMetaDataSafeStatement(sqlBuf.toString()); @@ -258,32 +316,7 @@ ResultSet rs = executeMetadataQuery(pStmt); - ((com.mysql.jdbc.ResultSet) rs).redefineFieldsForDBMD(new Field[] { - new Field("", "TABLE_CAT", Types.CHAR, 255), - new Field("", "TABLE_SCHEM", Types.CHAR, 0), - new Field("", "TABLE_NAME", Types.CHAR, 255), - new Field("", "COLUMN_NAME", Types.CHAR, 32), - new Field("", "DATA_TYPE", Types.SMALLINT, 5), - new Field("", "TYPE_NAME", Types.CHAR, 16), - new Field("", "COLUMN_SIZE", Types.INTEGER, Integer - .toString(Integer.MAX_VALUE).length()), - new Field("", "BUFFER_LENGTH", Types.INTEGER, 10), - new Field("", "DECIMAL_DIGITS", Types.INTEGER, 10), - new Field("", "NUM_PREC_RADIX", Types.INTEGER, 10), - new Field("", "NULLABLE", Types.INTEGER, 10), - new Field("", "REMARKS", Types.CHAR, 0), - new Field("", "COLUMN_DEF", Types.CHAR, 0), - new Field("", "SQL_DATA_TYPE", Types.INTEGER, 10), - new Field("", "SQL_DATETIME_SUB", Types.INTEGER, 10), - new Field("", "CHAR_OCTET_LENGTH", Types.INTEGER, Integer - .toString(Integer.MAX_VALUE).length()), - new Field("", "ORDINAL_POSITION", Types.INTEGER, 10), - new Field("", "IS_NULLABLE", Types.CHAR, 3), - new Field("", "SCOPE_CATALOG", Types.CHAR, 255), - new Field("", "SCOPE_SCHEMA", Types.CHAR, 255), - new Field("", "SCOPE_TABLE", Types.CHAR, 255), - new Field("", "SOURCE_DATA_TYPE", Types.SMALLINT, 10), - new Field("", "IS_AUTOINCREMENT", Types.CHAR, 3) }); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(createColumnsFields()); return rs; } finally { if (pStmt != null) { @@ -364,7 +397,7 @@ String foreignSchema, String foreignTable) throws SQLException { if (primaryTable == null) { throw SQLError.createSQLException("Table not specified.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } if (primaryCatalog == null) { @@ -379,22 +412,6 @@ } } - Field[] fields = new Field[14]; - fields[0] = new Field("", "PKTABLE_CAT", Types.CHAR, 255); - fields[1] = new Field("", "PKTABLE_SCHEM", Types.CHAR, 0); - fields[2] = new Field("", "PKTABLE_NAME", Types.CHAR, 255); - fields[3] = new Field("", "PKCOLUMN_NAME", Types.CHAR, 32); - fields[4] = new Field("", "FKTABLE_CAT", Types.CHAR, 255); - fields[5] = new Field("", "FKTABLE_SCHEM", Types.CHAR, 0); - fields[6] = new Field("", "FKTABLE_NAME", Types.CHAR, 255); - fields[7] = new Field("", "FKCOLUMN_NAME", Types.CHAR, 32); - fields[8] = new Field("", "KEY_SEQ", Types.SMALLINT, 2); - fields[9] = new Field("", "UPDATE_RULE", Types.SMALLINT, 2); - fields[10] = new Field("", "DELETE_RULE", Types.SMALLINT, 2); - fields[11] = new Field("", "FK_NAME", Types.CHAR, 0); - fields[12] = new Field("", "PK_NAME", Types.CHAR, 0); - fields[13] = new Field("", "DEFERRABILITY", Types.INTEGER, 2); - String sql = "SELECT " + "A.REFERENCED_TABLE_SCHEMA AS PKTABLE_CAT," + "NULL AS PKTABLE_SCHEM," @@ -405,26 +422,31 @@ + "A.TABLE_NAME AS FKTABLE_NAME, " + "A.COLUMN_NAME AS FKCOLUMN_NAME, " + "A.ORDINAL_POSITION AS KEY_SEQ," - + importedKeyRestrict + + generateUpdateRuleClause() + " AS UPDATE_RULE," - + importedKeyRestrict + + generateDeleteRuleClause() + " AS DELETE_RULE," + "A.CONSTRAINT_NAME AS FK_NAME," - + "NULL AS PK_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," + + "INFORMATION_SCHEMA.KEY_COLUMN_USAGE A JOIN " + "INFORMATION_SCHEMA.TABLE_CONSTRAINTS B " + + "USING (TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME) " + + generateOptionalRefContraintsJoin() + "WHERE " - + "A.TABLE_SCHEMA=B.TABLE_SCHEMA AND A.TABLE_NAME=B.TABLE_NAME " - + "AND " - + "A.CONSTRAINT_NAME=B.CONSTRAINT_NAME AND B.CONSTRAINT_TYPE IS NOT NULL " + + "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"; - PreparedStatement pStmt = null; + java.sql.PreparedStatement pStmt = null; try { pStmt = prepareMetaDataSafeStatement(sql); @@ -445,21 +467,7 @@ pStmt.setString(4, foreignTable); ResultSet rs = executeMetadataQuery(pStmt); - ((com.mysql.jdbc.ResultSet) rs).redefineFieldsForDBMD(new Field[] { - new Field("", "PKTABLE_CAT", Types.CHAR, 255), - new Field("", "PKTABLE_SCHEM", Types.CHAR, 0), - new Field("", "PKTABLE_NAME", Types.CHAR, 255), - new Field("", "PKCOLUMN_NAME", Types.CHAR, 32), - new Field("", "FKTABLE_CAT", Types.CHAR, 255), - new Field("", "FKTABLE_SCHEM", Types.CHAR, 0), - new Field("", "FKTABLE_NAME", Types.CHAR, 255), - new Field("", "FKCOLUMN_NAME", Types.CHAR, 32), - new Field("", "KEY_SEQ", Types.SMALLINT, 2), - new Field("", "UPDATE_RULE", Types.SMALLINT, 2), - new Field("", "DELETE_RULE", Types.SMALLINT, 2), - new Field("", "FK_NAME", Types.CHAR, 0), - new Field("", "PK_NAME", Types.CHAR, 0), - new Field("", "DEFERRABILITY", Types.INTEGER, 2) }); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(createFkMetadataFields()); return rs; } finally { @@ -534,14 +542,16 @@ if (table == null) { throw SQLError.createSQLException("Table not specified.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } if (catalog == null) { if (this.conn.getNullCatalogMeansCurrent()) { catalog = this.database; } } + + //CASCADE, SET NULL, SET DEFAULT, RESTRICT, NO ACTION String sql = "SELECT " + "A.REFERENCED_TABLE_SCHEMA AS PKTABLE_CAT," @@ -553,25 +563,30 @@ + "A.TABLE_NAME AS FKTABLE_NAME," + "A.COLUMN_NAME AS FKCOLUMN_NAME, " + "A.ORDINAL_POSITION AS KEY_SEQ," - + importedKeyRestrict + + generateUpdateRuleClause() + " AS UPDATE_RULE," - + importedKeyRestrict + + generateDeleteRuleClause() + " AS DELETE_RULE," + "A.CONSTRAINT_NAME AS FK_NAME," - + "NULL AS PK_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," + + "INFORMATION_SCHEMA.KEY_COLUMN_USAGE A JOIN " + "INFORMATION_SCHEMA.TABLE_CONSTRAINTS B " + + "USING (TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME) " + + generateOptionalRefContraintsJoin() + "WHERE " - + "A.TABLE_SCHEMA=B.TABLE_SCHEMA AND A.TABLE_NAME=B.TABLE_NAME " - + "AND " - + "A.CONSTRAINT_NAME=B.CONSTRAINT_NAME AND B.CONSTRAINT_TYPE IS NOT NULL " + + "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"; - PreparedStatement pStmt = null; + java.sql.PreparedStatement pStmt = null; try { pStmt = prepareMetaDataSafeStatement(sql); @@ -586,21 +601,7 @@ ResultSet rs = executeMetadataQuery(pStmt); - ((com.mysql.jdbc.ResultSet) rs).redefineFieldsForDBMD(new Field[] { - new Field("", "PKTABLE_CAT", Types.CHAR, 255), - new Field("", "PKTABLE_SCHEM", Types.CHAR, 0), - new Field("", "PKTABLE_NAME", Types.CHAR, 255), - new Field("", "PKCOLUMN_NAME", Types.CHAR, 32), - new Field("", "FKTABLE_CAT", Types.CHAR, 255), - new Field("", "FKTABLE_SCHEM", Types.CHAR, 0), - new Field("", "FKTABLE_NAME", Types.CHAR, 255), - new Field("", "FKCOLUMN_NAME", Types.CHAR, 32), - new Field("", "KEY_SEQ", Types.SMALLINT, 2), - new Field("", "UPDATE_RULE", Types.SMALLINT, 2), - new Field("", "DELETE_RULE", Types.SMALLINT, 2), - new Field("", "FK_NAME", Types.CHAR, 255), - new Field("", "PK_NAME", Types.CHAR, 0), - new Field("", "DEFERRABILITY", Types.INTEGER, 2) }); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(createFkMetadataFields()); return rs; } finally { @@ -611,32 +612,34 @@ } - /* - * - * getTablePrivileges - * - * if (getMysqlVersion() > 49999) { if (!strcasecmp("localhost", - * m_pSettings->pConnection->host)) { sprintf(user, "A.GRANTEE = - * \"'%s'@'localhost'\" OR A.GRANTEE LIKE \"'%'@'localhost'\"", - * m_pSettings->pConnection->user, m_pSettings->pConnection->user); } else { - * sprintf(user, "\"'%s'@'%s'\" LIKE A.GRANTEE", - * m_pSettings->pConnection->user, m_pSettings->pConnection->host); } - * - * sprintf(query, "SELECT DISTINCT A.TABLE_CATALOG, B.TABLE_SCHEMA, - * B.TABLE_NAME, CURRENT_USER(), " \ "A.PRIVILEGE_TYPE FROM - * INFORMATION_SCHEMA.USER_PRIVILEGES A, INFORMATION_SCHEMA.TABLES B " \ - * "WHERE B.TABLE_SCHEMA LIKE '%s' AND B.TABLE_NAME LIKE '%s' AND (%s) " \ - * "UNION " \ "SELECT DISTINCT A.TABLE_CATALOG, B.TABLE_SCHEMA, - * B.TABLE_NAME, CURRENT_USER(), A.PRIVILEGE_TYPE " \ "FROM - * INFORMATION_SCHEMA.SCHEMA_PRIVILEGES A, INFORMATION_SCHEMA.TABLES B WHERE " \ - * "B.TABLE_SCHEMA LIKE '%s' AND B.TABLE_NAME LIKE '%s' AND (%s) " \ "UNION "\ - * "SELECT DISTINCT A.TABLE_CATALOG, A.TABLE_SCHEMA, A.TABLE_NAME, - * CURRENT_USER, A.PRIVILEGE_TYPE FROM " \ - * "INFORMATION_SCHEMA.TABLE_PRIVILEGES A WHERE A.TABLE_SCHEMA LIKE '%s' AND - * A.TABLE_NAME LIKE '%s' " \ "AND (%s)", schemaName, tableName, user, - * schemaName, tableName, user, schemaName, tableName, user ); - */ + private String generateOptionalRefContraintsJoin() { + return ((this.hasReferentialConstraintsView) ? "JOIN " + + "INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R " + + "ON (R.CONSTRAINT_NAME = B.CONSTRAINT_NAME " + + "AND R.TABLE_NAME = B.TABLE_NAME AND " + + "R.CONSTRAINT_SCHEMA = B.TABLE_SCHEMA) " : ""); + } + private String generateDeleteRuleClause() { + return ((this.hasReferentialConstraintsView) ? + "CASE WHEN R.DELETE_RULE='CASCADE' THEN " + String.valueOf(importedKeyCascade) + + " WHEN R.DELETE_RULE='SET NULL' THEN " + String.valueOf(importedKeySetNull) + + " WHEN R.DELETE_RULE='SET DEFAULT' THEN " + String.valueOf(importedKeySetDefault) + + " WHEN R.DELETE_RULE='RESTRICT' THEN " + String.valueOf(importedKeyRestrict) + + " WHEN R.DELETE_RULE='NO ACTION' THEN " + String.valueOf(importedKeyNoAction) + + " ELSE " + String.valueOf(importedKeyNoAction) + " END " : String.valueOf(importedKeyRestrict)); + } + + private String generateUpdateRuleClause() { + return ((this.hasReferentialConstraintsView) ? + "CASE WHEN R.UPDATE_RULE='CASCADE' THEN " + String.valueOf(importedKeyCascade) + + " WHEN R.UPDATE_RULE='SET NULL' THEN " + String.valueOf(importedKeySetNull) + + " WHEN R.UPDATE_RULE='SET DEFAULT' THEN " + String.valueOf(importedKeySetDefault) + + " WHEN R.UPDATE_RULE='RESTRICT' THEN " + String.valueOf(importedKeyRestrict) + + " WHEN R.UPDATE_RULE='NO ACTION' THEN " + String.valueOf(importedKeyNoAction) + + " ELSE " + String.valueOf(importedKeyNoAction) + " END " : String.valueOf(importedKeyRestrict)); + } + /** * Get a description of the primary key columns that are referenced by a * table's foreign key columns (the primary keys imported by a table). They @@ -700,7 +703,7 @@ String table) throws SQLException { if (table == null) { throw SQLError.createSQLException("Table not specified.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } if (catalog == null) { @@ -719,25 +722,34 @@ + "A.TABLE_NAME AS FKTABLE_NAME, " + "A.COLUMN_NAME AS FKCOLUMN_NAME, " + "A.ORDINAL_POSITION AS KEY_SEQ," - + importedKeyRestrict + + generateUpdateRuleClause() + " AS UPDATE_RULE," - + importedKeyRestrict + + generateDeleteRuleClause() + " AS DELETE_RULE," + "A.CONSTRAINT_NAME AS FK_NAME," - + "NULL AS PK_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, " - + "INFORMATION_SCHEMA.TABLE_CONSTRAINTS B WHERE A.TABLE_SCHEMA LIKE ? " - + "AND A.CONSTRAINT_NAME=B.CONSTRAINT_NAME AND A.TABLE_NAME=? " - + "AND " - + "B.TABLE_NAME=? AND A.REFERENCED_TABLE_SCHEMA IS NOT NULL " - + " ORDER BY " + + "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"; - PreparedStatement pStmt = null; + java.sql.PreparedStatement pStmt = null; try { pStmt = prepareMetaDataSafeStatement(sql); @@ -749,25 +761,10 @@ } pStmt.setString(2, table); - pStmt.setString(3, table); ResultSet rs = executeMetadataQuery(pStmt); - ((com.mysql.jdbc.ResultSet) rs).redefineFieldsForDBMD(new Field[] { - new Field("", "PKTABLE_CAT", Types.CHAR, 255), - new Field("", "PKTABLE_SCHEM", Types.CHAR, 0), - new Field("", "PKTABLE_NAME", Types.CHAR, 255), - new Field("", "PKCOLUMN_NAME", Types.CHAR, 32), - new Field("", "FKTABLE_CAT", Types.CHAR, 255), - new Field("", "FKTABLE_SCHEM", Types.CHAR, 0), - new Field("", "FKTABLE_NAME", Types.CHAR, 255), - new Field("", "FKCOLUMN_NAME", Types.CHAR, 32), - new Field("", "KEY_SEQ", Types.SMALLINT, 2), - new Field("", "UPDATE_RULE", Types.SMALLINT, 2), - new Field("", "DELETE_RULE", Types.SMALLINT, 2), - new Field("", "FK_NAME", Types.CHAR, 255), - new Field("", "PK_NAME", Types.CHAR, 0), - new Field("", "DEFERRABILITY", Types.INTEGER, 2) }); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(createFkMetadataFields()); return rs; } finally { @@ -854,7 +851,7 @@ sqlBuf.append("ORDER BY NON_UNIQUE, INDEX_NAME, SEQ_IN_INDEX"); - PreparedStatement pStmt = null; + java.sql.PreparedStatement pStmt = null; try { if (catalog == null) { @@ -875,20 +872,7 @@ ResultSet rs = executeMetadataQuery(pStmt); - ((com.mysql.jdbc.ResultSet) rs).redefineFieldsForDBMD(new Field[] { - new Field("", "TABLE_CAT", Types.CHAR, 255), - new Field("", "TABLE_SCHEM", Types.CHAR, 0), - new Field("", "TABLE_NAME", Types.CHAR, 255), - new Field("", "NON_UNIQUE", Types.CHAR, 4), - new Field("", "INDEX_QUALIFIER", Types.CHAR, 1), - new Field("", "INDEX_NAME", Types.CHAR, 32), - new Field("", "TYPE", Types.CHAR, 32), - new Field("", "ORDINAL_POSITION", Types.SMALLINT, 5), - new Field("", "COLUMN_NAME", Types.CHAR, 32), - new Field("", "ASC_OR_DESC", Types.CHAR, 1), - new Field("", "CARDINALITY", Types.INTEGER, 10), - new Field("", "PAGES", Types.INTEGER, 10), - new Field("", "FILTER_CONDITION", Types.CHAR, 32) }); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(createIndexInfoFields()); return rs; } finally { @@ -934,15 +918,15 @@ if (table == null) { throw SQLError.createSQLException("Table not specified.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } String sql = "SELECT TABLE_SCHEMA AS TABLE_CAT, NULL AS TABLE_SCHEM, TABLE_NAME, " + "COLUMN_NAME, SEQ_IN_INDEX AS KEY_SEQ, 'PRIMARY' AS PK_NAME FROM INFORMATION_SCHEMA.STATISTICS " + "WHERE TABLE_SCHEMA LIKE ? AND TABLE_NAME LIKE ? AND " + "INDEX_NAME='PRIMARY' ORDER BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX"; - PreparedStatement pStmt = null; + java.sql.PreparedStatement pStmt = null; try { pStmt = prepareMetaDataSafeStatement(sql); @@ -956,7 +940,7 @@ pStmt.setString(2, table); ResultSet rs = executeMetadataQuery(pStmt); - ((com.mysql.jdbc.ResultSet) rs).redefineFieldsForDBMD(new Field[] { + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(new Field[] { new Field("", "TABLE_CAT", Types.CHAR, 255), new Field("", "TABLE_SCHEM", Types.CHAR, 0), new Field("", "TABLE_NAME", Types.CHAR, 255), @@ -1022,7 +1006,7 @@ } else { throw SQLError.createSQLException( "Procedure name pattern can not be NULL or empty.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @@ -1032,6 +1016,8 @@ if (this.conn.getNullCatalogMeansCurrent()) { db = this.database; } + } else { + db = catalog; } String sql = "SELECT ROUTINE_SCHEMA AS PROCEDURE_CAT, " @@ -1042,12 +1028,14 @@ + "CASE WHEN ROUTINE_TYPE = 'PROCEDURE' THEN " + procedureNoResult + " WHEN ROUTINE_TYPE='FUNCTION' THEN " + procedureReturnsResult + " ELSE " + procedureResultUnknown - + " END AS PROCEDURE_TYPE " + + " END AS PROCEDURE_TYPE, " + + "ROUTINE_NAME AS SPECIFIC_NAME " + "FROM INFORMATION_SCHEMA.ROUTINES WHERE " + + getRoutineTypeConditionForGetProcedures() + "ROUTINE_SCHEMA LIKE ? AND ROUTINE_NAME LIKE ? " - + "ORDER BY ROUTINE_SCHEMA, ROUTINE_NAME"; + + "ORDER BY ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE"; - PreparedStatement pStmt = null; + java.sql.PreparedStatement pStmt = null; try { pStmt = prepareMetaDataSafeStatement(sql); @@ -1061,15 +1049,7 @@ pStmt.setString(2, procedureNamePattern); ResultSet rs = executeMetadataQuery(pStmt); - ((com.mysql.jdbc.ResultSet) rs).redefineFieldsForDBMD(new Field[] { - new Field("", "PROCEDURE_CAT", Types.CHAR, 0), - new Field("", "PROCEDURE_SCHEM", Types.CHAR, 0), - new Field("", "PROCEDURE_NAME", Types.CHAR, 0), - new Field("", "reserved1", Types.CHAR, 0), - new Field("", "reserved2", Types.CHAR, 0), - new Field("", "reserved3", Types.CHAR, 0), - new Field("", "REMARKS", Types.CHAR, 0), - new Field("", "PROCEDURE_TYPE", Types.SMALLINT, 0) }); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(createFieldMetadataForGetProcedures()); return rs; } finally { @@ -1080,6 +1060,216 @@ } /** + * Returns a condition to be injected in the query that returns metadata for procedures only. Overridden by + * subclasses when needed. When not empty must end with "AND ". + * + * @return String with the condition to be injected. + */ + protected String getRoutineTypeConditionForGetProcedures() { + return ""; + } + + /** + * Retrieves a description of the given catalog's stored procedure parameter + * and result columns. + * + *

Only descriptions matching the schema, procedure and + * parameter name criteria are returned. They are ordered by + * PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value, + * if any, is first. Next are the parameter descriptions in call + * order. The column descriptions follow in column number order. + * + *

Each row in the ResultSet is a parameter description or + * column description with the following fields: + *

    + *
  1. PROCEDURE_CAT String => procedure catalog (may be null) + *
  2. PROCEDURE_SCHEM String => procedure schema (may be null) + *
  3. PROCEDURE_NAME String => procedure name + *
  4. COLUMN_NAME String => column/parameter name + *
  5. COLUMN_TYPE Short => kind of column/parameter: + *
      + *
    • procedureColumnUnknown - nobody knows + *
    • procedureColumnIn - IN parameter + *
    • procedureColumnInOut - INOUT parameter + *
    • procedureColumnOut - OUT parameter + *
    • procedureColumnReturn - procedure return value + *
    • procedureColumnResult - result column in ResultSet + *
    + *
  6. DATA_TYPE int => SQL type from java.sql.Types + *
  7. TYPE_NAME String => SQL type name, for a UDT type the + * type name is fully qualified + *
  8. PRECISION int => precision + *
  9. LENGTH int => length in bytes of data + *
  10. SCALE short => scale + *
  11. RADIX short => radix + *
  12. NULLABLE short => can it contain NULL. + *
      + *
    • procedureNoNulls - does not allow NULL values + *
    • procedureNullable - allows NULL values + *
    • procedureNullableUnknown - nullability unknown + *
    + *
  13. REMARKS String => comment describing parameter/column + *
+ * + *

Note: Some databases may not return the column + * descriptions for a procedure. Additional columns beyond + * REMARKS can be defined by the database. + * + * @param catalog a catalog name; must match the catalog name as it + * is stored in the database; "" retrieves those without a catalog; + * null means that the catalog name should not be used to narrow + * the search + * @param schemaPattern a schema name pattern; must match the schema name + * as it is stored in the database; "" retrieves those without a schema; + * null means that the schema name should not be used to narrow + * the search + * @param procedureNamePattern a procedure name pattern; must match the + * procedure name as it is stored in the database + * @param columnNamePattern a column name pattern; must match the column name + * as it is stored in the database + * @return ResultSet - each row describes a stored procedure parameter or + * column + * @exception SQLException if a database access error occurs + * @see #getSearchStringEscape + */ + public ResultSet getProcedureColumns(String catalog, String schemaPattern, + String procedureNamePattern, String columnNamePattern) + throws SQLException { + if (!this.hasParametersView) { + return getProcedureColumnsNoISParametersView(catalog, schemaPattern, procedureNamePattern, columnNamePattern); + } + + if ((procedureNamePattern == null) + || (procedureNamePattern.length() == 0)) { + if (this.conn.getNullNamePatternMatchesAll()) { + procedureNamePattern = "%"; + } else { + throw SQLError.createSQLException( + "Procedure name pattern can not be NULL or empty.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + } + + String db = null; + + if (catalog == null) { + if (this.conn.getNullCatalogMeansCurrent()) { + db = this.database; + } + } else { + db = catalog; + } + + // Here's what we get from MySQL ... + // SPECIFIC_CATALOG NULL + // SPECIFIC_SCHEMA db17 + // SPECIFIC_NAME p + // ORDINAL_POSITION 1 + // PARAMETER_MODE OUT + // PARAMETER_NAME a + // DATA_TYPE int + // CHARACTER_MAXIMUM_LENGTH NULL + // CHARACTER_OCTET_LENGTH NULL + // CHARACTER_SET_NAME NULL + // COLLATION_NAME NULL + // NUMERIC_PRECISION 10 + // NUMERIC_SCALE 0 + // DTD_IDENTIFIER int(11) + + StringBuffer sqlBuf = new StringBuffer("SELECT SPECIFIC_SCHEMA AS PROCEDURE_CAT, " + + "NULL AS `PROCEDURE_SCHEM`, " + + "SPECIFIC_NAME AS `PROCEDURE_NAME`, " + + "IFNULL(PARAMETER_NAME, '') AS `COLUMN_NAME`, " + + "CASE WHEN PARAMETER_MODE = 'IN' THEN " + procedureColumnIn + + " WHEN PARAMETER_MODE = 'OUT' THEN " + procedureColumnOut + + " WHEN PARAMETER_MODE = 'INOUT' THEN " + procedureColumnInOut + + " WHEN ORDINAL_POSITION = 0 THEN " + procedureColumnReturn + + " ELSE " + procedureColumnUnknown + + " END AS `COLUMN_TYPE`, "); + + //DATA_TYPE + MysqlDefs.appendJdbcTypeMappingQuery(sqlBuf, "DATA_TYPE"); + + sqlBuf.append(" AS `DATA_TYPE`, "); + + // TYPE_NAME + if (conn.getCapitalizeTypeNames()) { + sqlBuf.append("UPPER(CASE WHEN LOCATE('unsigned', DATA_TYPE) != 0 AND LOCATE('unsigned', DATA_TYPE) = 0 THEN CONCAT(DATA_TYPE, ' unsigned') ELSE DATA_TYPE END) AS `TYPE_NAME`,"); + } else { + sqlBuf.append("CASE WHEN LOCATE('unsigned', DATA_TYPE) != 0 AND LOCATE('unsigned', DATA_TYPE) = 0 THEN CONCAT(DATA_TYPE, ' unsigned') ELSE DATA_TYPE END AS `TYPE_NAME`,"); + } + + // PRECISION int => precision + sqlBuf.append("NUMERIC_PRECISION AS `PRECISION`, "); + // LENGTH int => length in bytes of data + 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 LENGTH, "); + + // SCALE short => scale + sqlBuf.append("NUMERIC_SCALE AS `SCALE`, "); + // RADIX short => radix + sqlBuf.append("10 AS RADIX,"); + sqlBuf.append(procedureNullable + " AS `NULLABLE`, " + + "NULL AS `REMARKS`, " + + "NULL AS `COLUMN_DEF`, " + + "NULL AS `SQL_DATA_TYPE`, " + + "NULL AS `SQL_DATETIME_SUB`, " + + "CHARACTER_OCTET_LENGTH AS `CHAR_OCTET_LENGTH`, " + + "ORDINAL_POSITION, " + + "'YES' AS `IS_NULLABLE`, " + + "SPECIFIC_NAME " + + "FROM INFORMATION_SCHEMA.PARAMETERS WHERE " + + getRoutineTypeConditionForGetProcedureColumns() + + "SPECIFIC_SCHEMA LIKE ? AND SPECIFIC_NAME LIKE ? AND (PARAMETER_NAME LIKE ? OR PARAMETER_NAME IS NULL) " + + "ORDER BY SPECIFIC_SCHEMA, SPECIFIC_NAME, ROUTINE_TYPE, ORDINAL_POSITION"); + + java.sql.PreparedStatement pStmt = null; + + try { + pStmt = prepareMetaDataSafeStatement(sqlBuf.toString()); + + if (db != null) { + pStmt.setString(1, db); + } else { + pStmt.setString(1, "%"); + } + + pStmt.setString(2, procedureNamePattern); + pStmt.setString(3, columnNamePattern); + + ResultSet rs = executeMetadataQuery(pStmt); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(createProcedureColumnsFields()); + + return rs; + } finally { + if (pStmt != null) { + pStmt.close(); + } + } + } + + /** + * Redirects to another implementation of #getProcedureColumns. Subclasses may need to override this method. + * + * @see getProcedureColumns + */ + protected ResultSet getProcedureColumnsNoISParametersView(String catalog, String schemaPattern, + String procedureNamePattern, String columnNamePattern) throws SQLException { + return super.getProcedureColumns(catalog, schemaPattern, procedureNamePattern, columnNamePattern); + } + + /** + * Returns a condition to be injected in the query that returns metadata for procedure columns only. Overridden by + * subclasses when needed. When not empty must end with "AND ". + * + * @return String with the condition to be injected. + */ + protected String getRoutineTypeConditionForGetProcedureColumns() { + return ""; + } + + /** * Get a description of tables available in a catalog. *

* Only table descriptions matching the catalog, schema, table name and type @@ -1129,19 +1319,65 @@ } else { throw SQLError.createSQLException( "Table name pattern can not be NULL or empty.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } - PreparedStatement pStmt = null; + final String tableNamePat; + String tmpCat = ""; + + if ((catalog == null) || (catalog.length() == 0)) { + if (this.conn.getNullCatalogMeansCurrent()) { + tmpCat = this.database; + } + } else { + tmpCat = catalog; + } + + List parseList = StringUtils.splitDBdotName(tableNamePattern, tmpCat, + quotedId , conn.isNoBackslashEscapesSet()); + //There *should* be 2 rows, if any. + if (parseList.size() == 2) { + tableNamePat = parseList.get(1); + } else { + tableNamePat = tableNamePattern; + } + java.sql.PreparedStatement pStmt = null; + String sql = "SELECT TABLE_SCHEMA AS TABLE_CAT, " + "NULL AS TABLE_SCHEM, TABLE_NAME, " - + "CASE WHEN TABLE_TYPE='BASE TABLE' THEN 'TABLE' WHEN TABLE_TYPE='TEMPORARY' THEN 'LOCAL_TEMPORARY' ELSE TABLE_TYPE END AS TABLE_TYPE, " - + "TABLE_COMMENT AS REMARKS " - + "FROM INFORMATION_SCHEMA.TABLES WHERE " - + "TABLE_SCHEMA LIKE ? AND TABLE_NAME LIKE ? AND TABLE_TYPE IN (?,?,?) " - + "ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME"; + + "CASE WHEN TABLE_TYPE='BASE TABLE' THEN CASE WHEN TABLE_SCHEMA = 'mysql' OR TABLE_SCHEMA = 'performance_schema' THEN 'SYSTEM TABLE' ELSE 'TABLE' END " + + "WHEN TABLE_TYPE='TEMPORARY' THEN 'LOCAL_TEMPORARY' ELSE TABLE_TYPE END AS TABLE_TYPE, " + + "TABLE_COMMENT AS REMARKS, NULL AS TYPE_CAT, NULL AS TYPE_SCHEM, NULL AS TYPE_NAME, NULL AS SELF_REFERENCING_COL_NAME, NULL AS REF_GENERATION " + + "FROM INFORMATION_SCHEMA.TABLES WHERE "; + + final boolean operatingOnInformationSchema = "information_schema".equalsIgnoreCase(catalog); + if (catalog != null) { + if ((operatingOnInformationSchema) || ((StringUtils.indexOfIgnoreCase(0, catalog, "%") == -1) + && (StringUtils.indexOfIgnoreCase(0, catalog, "_") == -1))) { + sql += "TABLE_SCHEMA = ? "; + } else { + sql += "TABLE_SCHEMA LIKE ? "; + } + + } else { + sql += "TABLE_SCHEMA LIKE ? "; + } + + if (tableNamePat != null) { + if ((StringUtils.indexOfIgnoreCase(0, tableNamePat, "%") == -1) + && (StringUtils.indexOfIgnoreCase(0, tableNamePat, "_") == -1)) { + sql += "AND TABLE_NAME = ? "; + } else { + sql += "AND TABLE_NAME LIKE ? "; + } + + } else { + sql += "AND TABLE_NAME LIKE ? "; + } + sql = sql + "HAVING TABLE_TYPE IN (?,?,?,?,?) "; + sql = sql + "ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME"; try { pStmt = prepareMetaDataSafeStatement(sql); @@ -1151,44 +1387,311 @@ pStmt.setString(1, "%"); } - pStmt.setString(2, tableNamePattern); + pStmt.setString(2, tableNamePat); // This overloading of IN (...) allows us to cache this // prepared statement if (types == null || types.length == 0) { - pStmt.setString(3, "BASE TABLE"); - pStmt.setString(4, "VIEW"); - pStmt.setString(5, "TEMPORARY"); + TableType[] tableTypes = TableType.values(); + for (int i = 0; i < 5; i++) { + pStmt.setString(3 + i, tableTypes[i].getName()); + } } else { - pStmt.setNull(3, Types.VARCHAR); - pStmt.setNull(4, Types.VARCHAR); - pStmt.setNull(5, Types.VARCHAR); + for (int i = 0; i < 5; i++) { + pStmt.setNull(3 + i, Types.VARCHAR); + } + int idx = 3; for (int i = 0; i < types.length; i++) { - if ("TABLE".equalsIgnoreCase(types[i])) { - pStmt.setString(3, "BASE TABLE"); + TableType tableType = TableType.getTableTypeEqualTo(types[i]); + if (tableType != TableType.UNKNOWN) { + pStmt.setString(idx++, tableType.getName()); } + } + } - if ("VIEW".equalsIgnoreCase(types[i])) { - pStmt.setString(4, "VIEW"); - } + ResultSet rs = executeMetadataQuery(pStmt); - if ("LOCAL TEMPORARY".equalsIgnoreCase(types[i])) { - pStmt.setString(5, "TEMPORARY"); - } - } + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(createTablesFields()); + + return rs; + } finally { + if (pStmt != null) { + pStmt.close(); } + } + } + + public boolean gethasParametersView() { + return this.hasParametersView; + } + + @Override + public ResultSet getVersionColumns(String catalog, String schema, + String table) throws SQLException { + + if (catalog == null) { + if (this.conn.getNullCatalogMeansCurrent()) { + catalog = this.database; + } + } + + if (table == null) { + throw SQLError.createSQLException("Table not specified.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + + StringBuffer sqlBuf = new StringBuffer("SELECT NULL AS SCOPE, COLUMN_NAME, "); + + MysqlDefs.appendJdbcTypeMappingQuery(sqlBuf, "DATA_TYPE"); + sqlBuf.append(" AS DATA_TYPE, "); + + sqlBuf.append("COLUMN_TYPE AS TYPE_NAME, "); + 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, "); + sqlBuf.append( + MysqlIO.getMaxBuf() + " AS BUFFER_LENGTH," + + "NUMERIC_SCALE AS DECIMAL_DIGITS, " + + Integer.toString(java.sql.DatabaseMetaData.versionColumnNotPseudo) + " AS PSEUDO_COLUMN " + + "FROM INFORMATION_SCHEMA.COLUMNS " + + "WHERE TABLE_SCHEMA LIKE ? AND TABLE_NAME LIKE ?" + + " AND EXTRA LIKE '%on update CURRENT_TIMESTAMP%'"); + + java.sql.PreparedStatement pStmt = null; + + try { + pStmt = prepareMetaDataSafeStatement(sqlBuf.toString()); + + if (catalog != null) { + pStmt.setString(1, catalog); + } else { + pStmt.setString(1, "%"); + } + + pStmt.setString(2, table); + ResultSet rs = executeMetadataQuery(pStmt); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(new Field[] { + new Field("", "SCOPE", Types.SMALLINT, 5), + new Field("", "COLUMN_NAME", Types.CHAR, 32), + new Field("", "DATA_TYPE", Types.INTEGER, 5), + new Field("", "TYPE_NAME", Types.CHAR, 16), + new Field("", "COLUMN_SIZE", Types.INTEGER, 16), + new Field("", "BUFFER_LENGTH", Types.INTEGER, 16), + new Field("", "DECIMAL_DIGITS", Types.SMALLINT, 16), + new Field("", "PSEUDO_COLUMN", Types.SMALLINT, 5) + }); - ((com.mysql.jdbc.ResultSet) rs).redefineFieldsForDBMD(new Field[] { - new Field("", "TABLE_CAT", java.sql.Types.VARCHAR, - (catalog == null) ? 0 : catalog.length()), - new Field("", "TABLE_SCHEM", java.sql.Types.VARCHAR, 0), - new Field("", "TABLE_NAME", java.sql.Types.VARCHAR, 255), - new Field("", "TABLE_TYPE", java.sql.Types.VARCHAR, 5), - new Field("", "REMARKS", java.sql.Types.VARCHAR, 0) }); + return rs; + } finally { + if (pStmt != null) { + pStmt.close(); + } + } + } + // + // JDBC-4.0 functions that aren't reliant on Java6 + // + + /** + * Retrieves a description of the given catalog's system or user + * function parameters and return type. + * + *

Only descriptions matching the schema, function and + * parameter name criteria are returned. They are ordered by + * FUNCTION_CAT, FUNCTION_SCHEM, + * FUNCTION_NAME and + * SPECIFIC_ NAME. Within this, the return value, + * if any, is first. Next are the parameter descriptions in call + * order. The column descriptions follow in column number order. + * + *

Each row in the ResultSet + * is a parameter description, column description or + * return type description with the following fields: + *

    + *
  1. FUNCTION_CAT String => function catalog (may be null) + *
  2. FUNCTION_SCHEM String => function schema (may be null) + *
  3. FUNCTION_NAME String => function name. This is the name + * used to invoke the function + *
  4. COLUMN_NAME String => column/parameter name + *
  5. COLUMN_TYPE Short => kind of column/parameter: + *
      + *
    • functionColumnUnknown - nobody knows + *
    • functionColumnIn - IN parameter + *
    • functionColumnInOut - INOUT parameter + *
    • functionColumnOut - OUT parameter + *
    • functionColumnReturn - function return value + *
    • functionColumnResult - Indicates that the parameter or column + * is a column in the ResultSet + *
    + *
  6. DATA_TYPE int => SQL type from java.sql.Types + *
  7. TYPE_NAME String => SQL type name, for a UDT type the + * type name is fully qualified + *
  8. PRECISION int => precision + *
  9. LENGTH int => length in bytes of data + *
  10. SCALE short => scale - null is returned for data types where + * SCALE is not applicable. + *
  11. RADIX short => radix + *
  12. NULLABLE short => can it contain NULL. + *
      + *
    • functionNoNulls - does not allow NULL values + *
    • functionNullable - allows NULL values + *
    • functionNullableUnknown - nullability unknown + *
    + *
  13. REMARKS String => comment describing column/parameter + *
  14. CHAR_OCTET_LENGTH int => the maximum length of binary + * and character based parameters or columns. For any other datatype the returned value + * is a NULL + *
  15. ORDINAL_POSITION int => the ordinal position, starting + * from 1, for the input and output parameters. A value of 0 + * is returned if this row describes the function's return value. + * For result set columns, it is the + * ordinal position of the column in the result set starting from 1. + *
  16. IS_NULLABLE String => ISO rules are used to determine + * the nullability for a parameter or column. + *
      + *
    • YES --- if the parameter or column can include NULLs + *
    • NO --- if the parameter or column cannot include NULLs + *
    • empty string --- if the nullability for the + * parameter or column is unknown + *
    + *
  17. SPECIFIC_NAME String => the name which uniquely identifies + * this function within its schema. This is a user specified, or DBMS + * generated, name that may be different then the FUNCTION_NAME + * for example with overload functions + *
+ * + *

The PRECISION column represents the specified column size for the given + * parameter or column. + * For numeric data, this is the maximum precision. For character data, this is the length in characters. + * For datetime datatypes, this is the length in characters of the String representation (assuming the + * maximum allowed precision of the fractional seconds component). For binary data, this is the length in bytes. For the ROWID datatype, + * this is the length in bytes. Null is returned for data types where the + * column size is not applicable. + * @param catalog a catalog name; must match the catalog name as it + * is stored in the database; "" retrieves those without a catalog; + * null means that the catalog name should not be used to narrow + * the search + * @param schemaPattern a schema name pattern; must match the schema name + * as it is stored in the database; "" retrieves those without a schema; + * null means that the schema name should not be used to narrow + * the search + * @param functionNamePattern a procedure name pattern; must match the + * function name as it is stored in the database + * @param columnNamePattern a parameter name pattern; must match the + * parameter or column name as it is stored in the database + * @return ResultSet - each row describes a + * user function parameter, column or return type + * + * @exception SQLException if a database access error occurs + * @see #getSearchStringEscape + * @since 1.6 + */ + public ResultSet getFunctionColumns(String catalog, + String schemaPattern, + String functionNamePattern, + String columnNamePattern) throws SQLException { + if (!this.hasParametersView) { + return super.getFunctionColumns(catalog, schemaPattern, functionNamePattern, columnNamePattern); + } + + if ((functionNamePattern == null) + || (functionNamePattern.length() == 0)) { + if (this.conn.getNullNamePatternMatchesAll()) { + functionNamePattern = "%"; + } else { + throw SQLError.createSQLException( + "Procedure name pattern can not be NULL or empty.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + } + + String db = null; + + if (catalog == null) { + if (this.conn.getNullCatalogMeansCurrent()) { + db = this.database; + } + } else { + db = catalog; + } + + // FUNCTION_CAT + // FUNCTION_SCHEM + // FUNCTION_NAME + // COLUMN_NAME + // COLUMN_TYPE + StringBuffer sqlBuf = new StringBuffer("SELECT SPECIFIC_SCHEMA AS FUNCTION_CAT, " + + "NULL AS `FUNCTION_SCHEM`, " + + "SPECIFIC_NAME AS `FUNCTION_NAME`, " + + "IFNULL(PARAMETER_NAME, '') AS `COLUMN_NAME`, " + + "CASE WHEN PARAMETER_MODE = 'IN' THEN " + getJDBC4FunctionConstant(JDBC4FunctionConstant.FUNCTION_COLUMN_IN) + + " WHEN PARAMETER_MODE = 'OUT' THEN " + getJDBC4FunctionConstant(JDBC4FunctionConstant.FUNCTION_COLUMN_OUT) + + " WHEN PARAMETER_MODE = 'INOUT' THEN " + getJDBC4FunctionConstant(JDBC4FunctionConstant.FUNCTION_COLUMN_INOUT) + + " WHEN ORDINAL_POSITION = 0 THEN " + getJDBC4FunctionConstant(JDBC4FunctionConstant.FUNCTION_COLUMN_RETURN) + + " ELSE " + getJDBC4FunctionConstant(JDBC4FunctionConstant.FUNCTION_COLUMN_UNKNOWN) + + " END AS `COLUMN_TYPE`, "); + + //DATA_TYPE + MysqlDefs.appendJdbcTypeMappingQuery(sqlBuf, "DATA_TYPE"); + + sqlBuf.append(" AS `DATA_TYPE`, "); + + // TYPE_NAME + if (conn.getCapitalizeTypeNames()) { + sqlBuf.append("UPPER(CASE WHEN LOCATE('unsigned', DATA_TYPE) != 0 AND LOCATE('unsigned', DATA_TYPE) = 0 THEN CONCAT(DATA_TYPE, ' unsigned') ELSE DATA_TYPE END) AS `TYPE_NAME`,"); + } else { + sqlBuf.append("CASE WHEN LOCATE('unsigned', DATA_TYPE) != 0 AND LOCATE('unsigned', DATA_TYPE) = 0 THEN CONCAT(DATA_TYPE, ' unsigned') ELSE DATA_TYPE END AS `TYPE_NAME`,"); + } + + // PRECISION int => precision + sqlBuf.append("NUMERIC_PRECISION AS `PRECISION`, "); + // LENGTH int => length in bytes of data + 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 LENGTH, "); + + // SCALE short => scale + sqlBuf.append("NUMERIC_SCALE AS `SCALE`, "); + // RADIX short => radix + sqlBuf.append("10 AS RADIX,"); + // NULLABLE + // REMARKS + // CHAR_OCTET_LENGTH * + // ORDINAL_POSITION * + // IS_NULLABLE * + // SPECIFIC_NAME * + sqlBuf.append(getJDBC4FunctionConstant(JDBC4FunctionConstant.FUNCTION_NULLABLE) + " AS `NULLABLE`, " + + " NULL AS `REMARKS`, " + + "CHARACTER_OCTET_LENGTH AS `CHAR_OCTET_LENGTH`, " + + " ORDINAL_POSITION, " + + "'YES' AS `IS_NULLABLE`, " + + "SPECIFIC_NAME " + + "FROM INFORMATION_SCHEMA.PARAMETERS WHERE " + + "SPECIFIC_SCHEMA LIKE ? AND SPECIFIC_NAME LIKE ? AND (PARAMETER_NAME LIKE ? OR PARAMETER_NAME IS NULL) " + + "AND ROUTINE_TYPE='FUNCTION' ORDER BY SPECIFIC_SCHEMA, SPECIFIC_NAME, ORDINAL_POSITION"); + + java.sql.PreparedStatement pStmt = null; + + try { + pStmt = prepareMetaDataSafeStatement(sqlBuf.toString()); + + if (db != null) { + pStmt.setString(1, db); + } else { + pStmt.setString(1, "%"); + } + + pStmt.setString(2, functionNamePattern); + pStmt.setString(3, columnNamePattern); + + ResultSet rs = executeMetadataQuery(pStmt); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).redefineFieldsForDBMD(createFunctionColumnsFields()); + return rs; } finally { if (pStmt != null) { @@ -1197,18 +1700,130 @@ } } - private PreparedStatement prepareMetaDataSafeStatement(String sql) - throws SQLException { - // Can't use server-side here as we coerce a lot of types to match - // the spec. - PreparedStatement pStmt = this.conn.clientPrepareStatement(sql); + /** + * Getter to JDBC4 DatabaseMetaData.function* constants. + * This method must be overridden by JDBC4 subclasses. this implementation should never be called. + * + * @param constant + * the constant id from DatabaseMetaData fields to return. + * + * @return 0 + */ + protected int getJDBC4FunctionConstant(JDBC4FunctionConstant constant) { + return 0; + } - if (pStmt.getMaxRows() != 0) { - pStmt.setMaxRows(0); + /** + * Retrieves a description of the system and user functions available + * in the given catalog. + *

+ * Only system and user function descriptions matching the schema and + * function name criteria are returned. They are ordered by + * FUNCTION_CAT, FUNCTION_SCHEM, + * FUNCTION_NAME and + * SPECIFIC_ NAME. + * + *

Each function description has the the following columns: + *

    + *
  1. FUNCTION_CAT String => function catalog (may be null) + *
  2. FUNCTION_SCHEM String => function schema (may be null) + *
  3. FUNCTION_NAME String => function name. This is the name + * used to invoke the function + *
  4. REMARKS String => explanatory comment on the function + *
  5. FUNCTION_TYPE short => kind of function: + *
      + *
    • functionResultUnknown - Cannot determine if a return value + * or table will be returned + *
    • functionNoTable- Does not return a table + *
    • functionReturnsTable - Returns a table + *
    + *
  6. SPECIFIC_NAME String => the name which uniquely identifies + * this function within its schema. This is a user specified, or DBMS + * generated, name that may be different then the FUNCTION_NAME + * for example with overload functions + *
+ *

+ * A user may not have permission to execute any of the functions that are + * returned by getFunctions + * + * @param catalog a catalog name; must match the catalog name as it + * is stored in the database; "" retrieves those without a catalog; + * null means that the catalog name should not be used to narrow + * the search + * @param schemaPattern a schema name pattern; must match the schema name + * as it is stored in the database; "" retrieves those without a schema; + * null means that the schema name should not be used to narrow + * the search + * @param functionNamePattern a function name pattern; must match the + * function name as it is stored in the database + * @return ResultSet - each row is a function description + * @exception SQLException if a database access error occurs + * @see #getSearchStringEscape + * @since 1.6 + */ + public java.sql.ResultSet getFunctions(String catalog, String schemaPattern, + String functionNamePattern) throws SQLException { + + if ((functionNamePattern == null) + || (functionNamePattern.length() == 0)) { + if (this.conn.getNullNamePatternMatchesAll()) { + functionNamePattern = "%"; + } else { + throw SQLError.createSQLException( + "Function name pattern can not be NULL or empty.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } } - pStmt.setHoldResultsOpenOverClose(true); + String db = null; - return pStmt; + if (catalog == null) { + if (this.conn.getNullCatalogMeansCurrent()) { + db = this.database; + } + } else { + db = catalog; + } + + String sql = "SELECT ROUTINE_SCHEMA AS FUNCTION_CAT, NULL AS FUNCTION_SCHEM, " + + "ROUTINE_NAME AS FUNCTION_NAME, ROUTINE_COMMENT AS REMARKS, " + getJDBC4FunctionNoTableConstant() + + " AS FUNCTION_TYPE, ROUTINE_NAME AS SPECIFIC_NAME FROM INFORMATION_SCHEMA.ROUTINES " + + "WHERE ROUTINE_TYPE LIKE 'FUNCTION' AND ROUTINE_SCHEMA LIKE ? AND " + + "ROUTINE_NAME LIKE ? ORDER BY FUNCTION_CAT, FUNCTION_SCHEM, FUNCTION_NAME, SPECIFIC_NAME"; + + java.sql.PreparedStatement pStmt = null; + + try { + pStmt = prepareMetaDataSafeStatement(sql); + + pStmt.setString(1, db != null ? db : "%"); + 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) + }); + + return rs; + } finally { + if (pStmt != null) { + pStmt.close(); + } + } } + + /** + * Getter to JDBC4 DatabaseMetaData.functionNoTable constant. + * This method must be overridden by JDBC4 subclasses. this implementation should never be called. + * + * @return 0 + */ + protected int getJDBC4FunctionNoTableConstant() { + return 0; + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/DocsConnectionPropsHelper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/DocsConnectionPropsHelper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/DocsConnectionPropsHelper.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/DocsConnectionPropsHelper.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,19 +1,36 @@ /* - * Created on Jan 12, 2004 - * - * To change the template for this generated file go to - * Window - Preferences - Java - Code Generation - Code and Comments + Copyright (c) 2004, 2014, 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 FLOSS 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; /** * @author mmatthew * - * To change the template for this generated type comment go to Window - - * Preferences - Java - Code Generation - Code and Comments */ -public class DocsConnectionPropsHelper extends ConnectionProperties { +public class DocsConnectionPropsHelper extends ConnectionPropertiesImpl { + static final long serialVersionUID = -1580779062220390294L; + public static void main(String[] args) throws Exception { System.out.println(new DocsConnectionPropsHelper().exposeAsXml()); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Driver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Driver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Driver.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Driver.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.SQLException; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessor.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessor.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,38 +1,32 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ -/** - * EscapeProcessor performs all escape code processing as outlined in the JDBC - * spec by JavaSoft. - */ package com.mysql.jdbc; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; - +import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Collections; import java.util.GregorianCalendar; @@ -42,13 +36,17 @@ import java.util.StringTokenizer; import java.util.TimeZone; +/** + * EscapeProcessor performs all escape code processing as outlined in the JDBC + * spec by JavaSoft. + */ class EscapeProcessor { - private static Map JDBC_CONVERT_TO_MYSQL_TYPE_MAP; + private static Map JDBC_CONVERT_TO_MYSQL_TYPE_MAP; - private static Map JDBC_NO_CONVERT_TO_MYSQL_EXPRESSION_MAP; + private static Map JDBC_NO_CONVERT_TO_MYSQL_EXPRESSION_MAP; static { - Map tempMap = new HashMap(); + Map tempMap = new HashMap(); tempMap.put("BIGINT", "0 + ?"); tempMap.put("BINARY", "BINARY"); @@ -71,7 +69,7 @@ JDBC_CONVERT_TO_MYSQL_TYPE_MAP = Collections.unmodifiableMap(tempMap); - tempMap = new HashMap(JDBC_CONVERT_TO_MYSQL_TYPE_MAP); + tempMap = new HashMap(JDBC_CONVERT_TO_MYSQL_TYPE_MAP); tempMap.put("BINARY", "CONCAT(?)"); tempMap.put("CHAR", "CONCAT(?)"); @@ -100,8 +98,8 @@ * DOCUMENT ME! */ public static final Object escapeSQL(String sql, - boolean serverSupportsConvertFn, - Connection conn) throws java.sql.SQLException { + boolean serverSupportsConvertFn, MySQLConnection conn) + throws java.sql.SQLException { boolean replaceEscapeSequence = false; String escapeSequence = null; @@ -125,7 +123,7 @@ EscapeTokenizer escapeTokenizer = new EscapeTokenizer(sql); - byte usesVariables = Statement.USES_VARIABLES_FALSE; + byte usesVariables = StatementImpl.USES_VARIABLES_FALSE; boolean callingStoredFunction = false; while (escapeTokenizer.hasMoreTokens()) { @@ -135,8 +133,9 @@ if (token.charAt(0) == '{') { // It's an escape code if (!token.endsWith("}")) { - throw SQLError.createSQLException("Not a valid escape sequence: " - + token); + throw SQLError + .createSQLException("Not a valid escape sequence: " + + token, conn.getExceptionInterceptor()); } if (token.length() > 2) { @@ -157,7 +156,7 @@ } else { remaining = ((EscapeProcessorResult) remainingResults).escapedSql; - if (usesVariables != Statement.USES_VARIABLES_TRUE) { + if (usesVariables != StatementImpl.USES_VARIABLES_TRUE) { usesVariables = ((EscapeProcessorResult) remainingResults).usesVariables; } } @@ -186,16 +185,21 @@ escapeSequence = st.nextToken(); if (escapeSequence.length() < 3) { - newSql.append(token); // it's just part of the query, push possible syntax errors onto server's shoulders + newSql.append(token); // it's just part of the + // query, push possible + // syntax errors onto + // server's shoulders } else { - escapeSequence = escapeSequence.substring(1, - escapeSequence.length() - 1); + escapeSequence.length() - 1); replaceEscapeSequence = true; } } catch (java.util.NoSuchElementException e) { - newSql.append(token); // it's just part of the query, push possible syntax errors onto server's shoulders + newSql.append(token); // it's just part of the + // query, push possible + // syntax errors onto + // server's shoulders } } else if (StringUtils.startsWithIgnoreCase(collapsedToken, "{fn")) { @@ -209,7 +213,7 @@ if (StringUtils.startsWithIgnoreCaseAndWs(fnToken, "convert")) { newSql.append(processConvertToken(fnToken, - serverSupportsConvertFn)); + serverSupportsConvertFn, conn)); } else { // just pass functions right to the DB newSql.append(fnToken); @@ -220,14 +224,17 @@ int endPos = token.lastIndexOf('\''); // no } if ((startPos == -1) || (endPos == -1)) { - newSql.append(token); // it's just part of the query, push possible syntax errors onto server's shoulders + newSql.append(token); // it's just part of the + // query, push possible + // syntax errors onto + // server's shoulders } else { - + String argument = token.substring(startPos, endPos); - + try { - StringTokenizer st = new StringTokenizer(argument, - " -"); + StringTokenizer st = new StringTokenizer( + argument, " -"); String year4 = st.nextToken(); String month2 = st.nextToken(); String day2 = st.nextToken(); @@ -237,199 +244,15 @@ } catch (java.util.NoSuchElementException e) { throw SQLError.createSQLException( "Syntax error for DATE escape sequence '" - + argument + "'", "42000"); + + argument + "'", "42000", conn.getExceptionInterceptor()); } } } else if (StringUtils.startsWithIgnoreCase(collapsedToken, "{ts")) { - int startPos = token.indexOf('\'') + 1; - int endPos = token.lastIndexOf('\''); // no } - - if ((startPos == -1) || (endPos == -1)) { - newSql.append(token); // it's just part of the query, push possible syntax errors onto server's shoulders - } else { - - String argument = token.substring(startPos, endPos); - - try { - StringTokenizer st = new StringTokenizer(argument, - " .-:"); - String year4 = st.nextToken(); - String month2 = st.nextToken(); - String day2 = st.nextToken(); - String hour = st.nextToken(); - String minute = st.nextToken(); - String second = st.nextToken(); - - /* - * For now, we get the fractional seconds part, but - * we don't use it, as MySQL doesn't support it in - * it's TIMESTAMP data type - * - * String fractionalSecond = ""; - * - * if (st.hasMoreTokens()) { fractionalSecond = - * st.nextToken(); } - */ - /* - * Use the full format because number format will - * not work for "between" clauses. - * - * Ref. Mysql Docs - * - * You can specify DATETIME, DATE and TIMESTAMP - * values using any of a common set of formats: - * - * As a string in either 'YYYY-MM-DD HH:MM:SS' or - * 'YY-MM-DD HH:MM:SS' format. - * - * Thanks to Craig Longman for pointing out this bug - */ - 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("'"); - } else { - Calendar sessionCalendar; - - 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); - int day2Int = Integer.parseInt(day2); - int hourInt = Integer.parseInt(hour); - int minuteInt = Integer.parseInt(minute); - int secondInt = Integer.parseInt(second); - - synchronized (sessionCalendar) { - boolean useGmtMillis = conn.getUseGmtMillisForDatetimes(); - - Timestamp toBeAdjusted = TimeUtil.fastTimestampCreate(useGmtMillis, - useGmtMillis ? Calendar.getInstance(TimeZone.getTimeZone("GMT")): null, - sessionCalendar, - year4Int, - month2Int, - day2Int, - hourInt, - minuteInt, - secondInt, - 0); - - Timestamp inServerTimezone = TimeUtil.changeTimezone( - conn, - sessionCalendar, - null, - toBeAdjusted, - sessionCalendar.getTimeZone(), - conn.getServerTimezoneTZ(), - false); - - - newSql.append("'"); - - String timezoneLiteral = inServerTimezone.toString(); - - int indexOfDot = timezoneLiteral.indexOf("."); - - if (indexOfDot != -1) { - timezoneLiteral = timezoneLiteral.substring(0, indexOfDot); - } - - newSql.append(timezoneLiteral); - } - - newSql.append("'"); - - - } catch (NumberFormatException nfe) { - throw SQLError.createSQLException("Syntax error in TIMESTAMP escape sequence '" - + token + "'.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } - } catch (java.util.NoSuchElementException e) { - throw SQLError.createSQLException( - "Syntax error for TIMESTAMP escape sequence '" - + argument + "'", "42000"); - } - } + processTimestampToken(conn, newSql, token); } else if (StringUtils.startsWithIgnoreCase(collapsedToken, "{t")) { - int startPos = token.indexOf('\'') + 1; - int endPos = token.lastIndexOf('\''); // no } - - if ((startPos == -1) || (endPos == -1)) { - newSql.append(token); // it's just part of the query, push possible syntax errors onto server's shoulders - } else { - - String argument = token.substring(startPos, endPos); - - try { - StringTokenizer st = new StringTokenizer(argument, - " :"); - String hour = st.nextToken(); - String minute = st.nextToken(); - String second = st.nextToken(); - - if (!conn.getUseTimezone()) { - String timeString = "'" + hour + ":" + minute + ":" - + second + "'"; - newSql.append(timeString); - } else { - Calendar sessionCalendar = null; - - if (conn != null) { - sessionCalendar = conn.getCalendarInstanceForSessionOrNew(); - } else { - sessionCalendar = new GregorianCalendar(); - } - - try { - int hourInt = Integer.parseInt(hour); - int minuteInt = Integer.parseInt(minute); - int secondInt = Integer.parseInt(second); - - synchronized (sessionCalendar) { - Time toBeAdjusted = TimeUtil.fastTimeCreate( - sessionCalendar, - hourInt, - minuteInt, - secondInt); - - Time inServerTimezone = TimeUtil.changeTimezone( - conn, - sessionCalendar, - null, - toBeAdjusted, - sessionCalendar.getTimeZone(), - conn.getServerTimezoneTZ(), - false); - - newSql.append("'"); - newSql.append(inServerTimezone.toString()); - newSql.append("'"); - } - - } catch (NumberFormatException nfe) { - throw SQLError.createSQLException("Syntax error in TIMESTAMP escape sequence '" - + token + "'.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } - } catch (java.util.NoSuchElementException e) { - throw SQLError.createSQLException( - "Syntax error for escape sequence '" - + argument + "'", "42000"); - } - } + processTimeToken(conn, newSql, token); } else if (StringUtils.startsWithIgnoreCase(collapsedToken, "{call") || StringUtils.startsWithIgnoreCase(collapsedToken, @@ -438,7 +261,7 @@ int startPos = StringUtils.indexOfIgnoreCase(token, "CALL") + 5; int endPos = token.length() - 1; - + if (StringUtils.startsWithIgnoreCase(collapsedToken, "{?=call")) { callingStoredFunction = true; @@ -449,26 +272,31 @@ newSql.append("CALL "); newSql.append(token.substring(startPos, endPos)); } - + for (int i = endPos - 1; i >= startPos; i--) { char c = token.charAt(i); - + if (Character.isWhitespace(c)) { continue; } - + if (c != ')') { - newSql.append("()"); // handle no-parenthesis no-arg call not supported - // by MySQL parser + newSql.append("()"); // handle no-parenthesis + // no-arg call not + // supported + // by MySQL parser } - + break; } } else if (StringUtils.startsWithIgnoreCase(collapsedToken, "{oj")) { // MySQL already handles this escape sequence // because of ODBC. Cool. newSql.append(token); + } else { + // not an escape code, just part of the query + newSql.append(token); } } else { newSql.append(token); // it's just part of the query @@ -500,17 +328,314 @@ epr.escapedSql = escapedSql; epr.callingStoredFunction = callingStoredFunction; - if (usesVariables != Statement.USES_VARIABLES_TRUE) { + if (usesVariables != StatementImpl.USES_VARIABLES_TRUE) { if (escapeTokenizer.sawVariableUse()) { - epr.usesVariables = Statement.USES_VARIABLES_TRUE; + epr.usesVariables = StatementImpl.USES_VARIABLES_TRUE; } else { - epr.usesVariables = Statement.USES_VARIABLES_FALSE; + epr.usesVariables = StatementImpl.USES_VARIABLES_FALSE; } } return epr; } + private static void processTimeToken(MySQLConnection conn, + StringBuffer newSql, String token) throws SQLException { + int startPos = token.indexOf('\'') + 1; + int endPos = token.lastIndexOf('\''); // no } + + if ((startPos == -1) || (endPos == -1)) { + newSql.append(token); // it's just part of the + // query, push possible + // syntax errors onto + // server's shoulders + } else { + + String argument = token.substring(startPos, endPos); + + try { + StringTokenizer st = new StringTokenizer( + argument, " :."); + String hour = st.nextToken(); + String minute = st.nextToken(); + String second = st.nextToken(); + + boolean serverSupportsFractionalSecond = false; + String fractionalSecond = ""; + + if (st.hasMoreTokens()) { + if (conn.versionMeetsMinimum(5, 6, 4)) { + serverSupportsFractionalSecond = true; + fractionalSecond = "."+st.nextToken(); + } + } + + if (conn != null && (!conn.getUseTimezone() || !conn.getUseLegacyDatetimeCode())) { + newSql.append("'"); + newSql.append(hour); + newSql.append(":"); + newSql.append(minute); + newSql.append(":"); + newSql.append(second); + newSql.append(fractionalSecond); + newSql.append("'"); + } else { + Calendar sessionCalendar = null; + + if (conn != null) { + sessionCalendar = conn + .getCalendarInstanceForSessionOrNew(); + } else { + sessionCalendar = new GregorianCalendar(); + } + + try { + int hourInt = Integer.parseInt(hour); + int minuteInt = Integer + .parseInt(minute); + int secondInt = Integer + .parseInt(second); + + synchronized (sessionCalendar) { + Time toBeAdjusted = TimeUtil + .fastTimeCreate( + sessionCalendar, + hourInt, minuteInt, + secondInt, conn.getExceptionInterceptor()); + + Time inServerTimezone = TimeUtil + .changeTimezone( + conn, + sessionCalendar, + null, + toBeAdjusted, + sessionCalendar + .getTimeZone(), + conn + .getServerTimezoneTZ(), + false); + + newSql.append("'"); + newSql.append(inServerTimezone + .toString()); + + if (serverSupportsFractionalSecond) { + newSql.append(fractionalSecond); + } + + newSql.append("'"); + } + + } catch (NumberFormatException nfe) { + throw SQLError + .createSQLException( + "Syntax error in TIMESTAMP escape sequence '" + + token + "'.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, conn.getExceptionInterceptor()); + } + } + } catch (java.util.NoSuchElementException e) { + throw SQLError.createSQLException( + "Syntax error for escape sequence '" + + argument + "'", "42000", conn.getExceptionInterceptor()); + } + } + } + + private static void processTimestampToken(MySQLConnection conn, + StringBuffer newSql, String token) throws SQLException { + int startPos = token.indexOf('\'') + 1; + int endPos = token.lastIndexOf('\''); // no } + + if ((startPos == -1) || (endPos == -1)) { + newSql.append(token); // it's just part of the + // query, push possible + // syntax errors onto + // server's shoulders + } else { + + String argument = token.substring(startPos, endPos); + + try { + if (conn != null && !conn.getUseLegacyDatetimeCode()) { + Timestamp ts = Timestamp.valueOf(argument); + SimpleDateFormat tsdf = new SimpleDateFormat( + "''yyyy-MM-dd HH:mm:ss", Locale.US); //$NON-NLS-1$ + + tsdf + .setTimeZone(conn + .getServerTimezoneTZ()); + + newSql.append(tsdf.format(ts)); + + if (ts.getNanos() > 0 && conn.versionMeetsMinimum(5, 6, 4)) { + newSql.append('.'); + newSql.append(TimeUtil.formatNanos(ts.getNanos(), true, true)); + } + + newSql.append('\''); + + } else { + StringTokenizer st = new StringTokenizer( + argument, " .-:"); + try { + String year4 = st.nextToken(); + String month2 = st.nextToken(); + String day2 = st.nextToken(); + String hour = st.nextToken(); + String minute = st.nextToken(); + String second = st.nextToken(); + + boolean serverSupportsFractionalSecond = false; + String fractionalSecond = ""; + if (st.hasMoreTokens()) { + if (conn.versionMeetsMinimum(5, 6, 4)) { + serverSupportsFractionalSecond = true; + fractionalSecond = "."+st.nextToken(); + } + } + + /* + * Use the full format because number + * format will not work for "between" + * clauses. + * + * Ref. Mysql Docs + * + * You can specify DATETIME, DATE and + * TIMESTAMP values using any of a + * common set of formats: + * + * As a string in either 'YYYY-MM-DD + * HH:MM:SS' or 'YY-MM-DD HH:MM:SS' + * format. + * + * Thanks to Craig Longman for pointing + * out this bug + */ + + if (conn != null && + !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; + + 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); + int day2Int = Integer + .parseInt(day2); + int hourInt = Integer + .parseInt(hour); + int minuteInt = Integer + .parseInt(minute); + int secondInt = Integer + .parseInt(second); + + synchronized (sessionCalendar) { + boolean useGmtMillis = conn + .getUseGmtMillisForDatetimes(); + + Timestamp toBeAdjusted = TimeUtil + .fastTimestampCreate( + useGmtMillis, + useGmtMillis ? Calendar + .getInstance(TimeZone + .getTimeZone("GMT")) + : null, + sessionCalendar, + year4Int, + month2Int, + day2Int, + hourInt, + minuteInt, + secondInt, + 0); + + Timestamp inServerTimezone = TimeUtil + .changeTimezone( + conn, + sessionCalendar, + null, + toBeAdjusted, + sessionCalendar + .getTimeZone(), + conn + .getServerTimezoneTZ(), + false); + + newSql.append("'"); + + String timezoneLiteral = inServerTimezone + .toString(); + + int indexOfDot = timezoneLiteral + .indexOf("."); + + if (indexOfDot != -1) { + timezoneLiteral = timezoneLiteral + .substring(0, + indexOfDot); + } + + newSql + .append(timezoneLiteral); + } + + if (serverSupportsFractionalSecond) { + newSql.append(fractionalSecond); + } + newSql.append("'"); + + } catch (NumberFormatException nfe) { + throw SQLError + .createSQLException( + "Syntax error in TIMESTAMP escape sequence '" + + token + + "'.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, conn.getExceptionInterceptor()); + } + } + } catch (java.util.NoSuchElementException e) { + throw SQLError.createSQLException( + "Syntax error for TIMESTAMP escape sequence '" + + argument + "'", + "42000", conn.getExceptionInterceptor()); + } + } + } catch (IllegalArgumentException illegalArgumentException) { + SQLException sqlEx = SQLError + .createSQLException( + "Syntax error for TIMESTAMP escape sequence '" + + argument + "'", + "42000", conn.getExceptionInterceptor()); + sqlEx.initCause(illegalArgumentException); + + throw sqlEx; + } + } + } + /** * Re-writes {fn convert (expr, type)} as cast(expr AS type) * @@ -519,7 +644,7 @@ * @throws SQLException */ private static String processConvertToken(String functionToken, - boolean serverSupportsConvertFn) throws SQLException { + boolean serverSupportsConvertFn, MySQLConnection conn) throws SQLException { // The JDBC spec requires these types: // // BIGINT @@ -554,30 +679,31 @@ 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); + throw SQLError + .createSQLException( + "Syntax error while processing {fn convert (... , ...)} token, missing opening parenthesis in token '" + + functionToken + "'.", + SQLError.SQL_STATE_SYNTAX_ERROR, conn.getExceptionInterceptor()); } - int tokenLength = functionToken.length(); - int indexOfComma = functionToken.lastIndexOf(","); if (indexOfComma == -1) { - throw SQLError.createSQLException( - "Syntax error while processing {fn convert (... , ...)} token, missing comma in token '" - + functionToken + "'.", - SQLError.SQL_STATE_SYNTAX_ERROR); + throw SQLError + .createSQLException( + "Syntax error while processing {fn convert (... , ...)} token, missing comma in token '" + + functionToken + "'.", + SQLError.SQL_STATE_SYNTAX_ERROR, conn.getExceptionInterceptor()); } 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); + throw SQLError + .createSQLException( + "Syntax error while processing {fn convert (... , ...)} token, missing closing parenthesis in token '" + + functionToken + "'.", + SQLError.SQL_STATE_SYNTAX_ERROR, conn.getExceptionInterceptor()); } @@ -595,10 +721,10 @@ } if (serverSupportsConvertFn) { - newType = (String) JDBC_CONVERT_TO_MYSQL_TYPE_MAP.get(trimmedType + newType = JDBC_CONVERT_TO_MYSQL_TYPE_MAP.get(trimmedType .toUpperCase(Locale.ENGLISH)); } else { - newType = (String) JDBC_NO_CONVERT_TO_MYSQL_EXPRESSION_MAP + newType = JDBC_NO_CONVERT_TO_MYSQL_EXPRESSION_MAP .get(trimmedType.toUpperCase(Locale.ENGLISH)); // We need a 'special' check here to give a better error message. If @@ -609,18 +735,19 @@ // (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); + 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()); } } if (newType == null) { throw SQLError.createSQLException("Unsupported conversion type '" + type.trim() + "' found while processing escape token.", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, conn.getExceptionInterceptor()); } int replaceIndex = newType.indexOf("?"); @@ -633,16 +760,16 @@ .length())); return convertRewrite.toString(); - } else { + } - StringBuffer castRewrite = new StringBuffer("CAST("); - castRewrite.append(expression); - castRewrite.append(" AS "); - castRewrite.append(newType); - castRewrite.append(")"); + StringBuffer castRewrite = new StringBuffer("CAST("); + castRewrite.append(expression); + castRewrite.append(" AS "); + castRewrite.append(newType); + castRewrite.append(")"); - return castRewrite.toString(); - } + return castRewrite.toString(); + } /** Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessorResult.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessorResult.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessorResult.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeProcessorResult.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; /** @@ -39,5 +38,5 @@ String escapedSql; - byte usesVariables = Statement.USES_VARIABLES_FALSE; + byte usesVariables = StatementImpl.USES_VARIABLES_FALSE; } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeTokenizer.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeTokenizer.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeTokenizer.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/EscapeTokenizer.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; /** @@ -30,49 +29,38 @@ * @author Mark Matthews */ public class EscapeTokenizer { - // ~ Instance fields - // -------------------------------------------------------- + private static final char CHR_ESCAPE = '\\'; + private static final char CHR_SGL_QUOTE = '\''; + private static final char CHR_DBL_QUOTE = '"'; + private static final char CHR_LF = '\n'; + private static final char CHR_CR = '\r'; + private static final char CHR_COMMENT = '-'; + private static final char CHR_BEGIN_TOKEN = '{'; + private static final char CHR_END_TOKEN = '}'; + private static final char CHR_VARIABLE = '@'; - private int bracesLevel = 0; + private String source = null; + private int sourceLength = 0; + private int pos = 0; private boolean emittingEscapeCode = false; - - private boolean inComment = false; - + private boolean sawVariableUse = false; + private int bracesLevel = 0; private boolean inQuotes = false; - - private char lastChar = 0; - - private char lastLastChar = 0; - - private int pos = 0; - private char quoteChar = 0; - private boolean sawVariableUse = false; - - private String source = null; - - private int sourceLength = 0; - - // ~ Constructors - // ----------------------------------------------------------- - /** * Creates a new EscapeTokenizer object. * - * @param s + * @param source * the string to tokenize */ - public EscapeTokenizer(String s) { - this.source = s; - this.sourceLength = s.length(); + public EscapeTokenizer(String source) { + this.source = source; + this.sourceLength = source.length(); this.pos = 0; } - // ~ Methods - // ---------------------------------------------------------------- - /** * Does this tokenizer have more tokens available? * @@ -89,105 +77,109 @@ */ public synchronized String nextToken() { StringBuffer tokenBuf = new StringBuffer(); + boolean backslashEscape = false; if (this.emittingEscapeCode) { - tokenBuf.append("{"); //$NON-NLS-1$ + // Previous token ended at the beginning of an escape code, so this token must start with '{' + tokenBuf.append("{"); this.emittingEscapeCode = false; } for (; this.pos < this.sourceLength; this.pos++) { char c = this.source.charAt(this.pos); - // Detect variable usage - - if (!this.inQuotes && c == '@') { - this.sawVariableUse = true; + // process escape char: (\) + if (c == CHR_ESCAPE) { + tokenBuf.append(c); + backslashEscape = !backslashEscape; + continue; } - if (c == '\'' || c == '"') { - if (this.inQuotes && c == quoteChar) { - if (this.pos + 1 < this.sourceLength) { - if (this.source.charAt(this.pos + 1) == quoteChar) { - // Doubled-up quote escape - tokenBuf.append(quoteChar); - tokenBuf.append(quoteChar); - this.pos++; - continue; - } - } - } - if (this.lastChar != '\\') { - if (this.inQuotes) { - if (this.quoteChar == c) { + // process quotes: ('|") + if ((c == CHR_SGL_QUOTE || c == CHR_DBL_QUOTE) && !backslashEscape) { + tokenBuf.append(c); + if (this.inQuotes) { + if (c == this.quoteChar) { + // look ahead for doubled quote + if ((this.pos + 1 < this.sourceLength) && (this.source.charAt(this.pos + 1) == this.quoteChar)) { + tokenBuf.append(c); + this.pos++; // consume following char '\'' or '"' + } else { this.inQuotes = false; } - } else { - this.inQuotes = true; - this.quoteChar = c; } - } else if (this.lastLastChar == '\\') { - if (this.inQuotes) { - if (this.quoteChar == c) { - this.inQuotes = false; - } - } else { - this.inQuotes = true; - this.quoteChar = c; - } + } else { + this.inQuotes = true; + this.quoteChar = c; } + continue; + } + // process new line: (\n|\r) + if ((c == CHR_LF) || (c == CHR_CR)) { tokenBuf.append(c); - } else if (c == '-') { - if ((this.lastChar == '-') - && ((this.lastLastChar != '\\') & !this.inQuotes)) { - this.inComment = true; - } + backslashEscape = false; + continue; + } - tokenBuf.append(c); - } else if ((c == '\n') || (c == '\r')) { - this.inComment = false; - - tokenBuf.append(c); - } else if (c == '{') { - if (this.inQuotes || this.inComment) { + if (!this.inQuotes && !backslashEscape) { + // process comments: (--) + if (c == CHR_COMMENT) { tokenBuf.append(c); - } else { - this.bracesLevel++; + // look ahead for double hyphen + if ((this.pos + 1 < this.sourceLength) && (this.source.charAt(this.pos + 1) == CHR_COMMENT)) { + // consume following chars until new line or end of string + while (++this.pos < this.sourceLength && c != CHR_LF && c != CHR_CR) { + c = this.source.charAt(this.pos); + tokenBuf.append(c); + } + this.pos--; + } + continue; + } + // process begin token: ({) + if (c == CHR_BEGIN_TOKEN) { + this.bracesLevel++; if (this.bracesLevel == 1) { - this.pos++; this.emittingEscapeCode = true; - + this.pos++; // consume char '{' before returning return tokenBuf.toString(); } - tokenBuf.append(c); + continue; } - } else if (c == '}') { - tokenBuf.append(c); - if (!this.inQuotes && !this.inComment) { - this.lastChar = c; - + // process end token: (}) + if (c == CHR_END_TOKEN) { + tokenBuf.append(c); this.bracesLevel--; - if (this.bracesLevel == 0) { - this.pos++; - + this.pos++; // consume char '}' before returning return tokenBuf.toString(); } + continue; } - } else { - tokenBuf.append(c); + + // detect variable usage: (@) + if (c == CHR_VARIABLE) { + this.sawVariableUse = true; + } } - this.lastLastChar = this.lastChar; - this.lastChar = c; + tokenBuf.append(c); + backslashEscape = false; } return tokenBuf.toString(); } + /** + * Returns true if a variable reference was found. Note that this information isn't accurate until finishing to + * process all tokens from source String. It also can't be used as per token basis. + * + * @return true if a variable reference was found. + */ boolean sawVariableUse() { return this.sawVariableUse; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ExceptionInterceptor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ExportControlled.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/ExportControlled.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ExportControlled.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ExportControlled.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,33 +1,59 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.Socket; +import java.net.SocketException; +import java.net.URL; +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.CertificateException; +import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.X509EncodedKeySpec; +import java.sql.SQLException; +import java.util.Properties; +import javax.crypto.Cipher; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import com.mysql.jdbc.util.Base64Decoder; + /** * Holds functionality that falls under export-control regulations. * @@ -37,6 +63,8 @@ * Exp $ */ public class ExportControlled { + private static final String SQL_STATE_BAD_SSL_PARAMS = "08000"; + protected static boolean enabled() { // we may wish to un-static-ify this class // this static method call may be removed entirely by the compiler @@ -57,38 +85,276 @@ * perform the handshake. */ protected static void transformSocketToSSLSocket(MysqlIO mysqlIO) - throws CommunicationsException { - javax.net.ssl.SSLSocketFactory sslFact = (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory - .getDefault(); + throws SQLException { + SocketFactory sslFact = new StandardSSLSocketFactory(getSSLSocketFactoryDefaultOrConfigured(mysqlIO), mysqlIO.socketFactory, mysqlIO.mysqlConnection); try { - mysqlIO.mysqlConnection = sslFact.createSocket( - mysqlIO.mysqlConnection, mysqlIO.host, mysqlIO.port, true); + mysqlIO.mysqlConnection = sslFact.connect(mysqlIO.host, mysqlIO.port, null); // need to force TLSv1, or else JSSE tries to do a SSLv2 handshake // which MySQL doesn't understand - ((javax.net.ssl.SSLSocket) mysqlIO.mysqlConnection) - .setEnabledProtocols(new String[] { "TLSv1" }); //$NON-NLS-1$ - ((javax.net.ssl.SSLSocket) mysqlIO.mysqlConnection) - .startHandshake(); + ((SSLSocket) mysqlIO.mysqlConnection).setEnabledProtocols(new String[] { "TLSv1" }); + ((SSLSocket) mysqlIO.mysqlConnection).startHandshake(); if (mysqlIO.connection.getUseUnbufferedInput()) { mysqlIO.mysqlInput = mysqlIO.mysqlConnection.getInputStream(); } else { - mysqlIO.mysqlInput = new BufferedInputStream( - mysqlIO.mysqlConnection.getInputStream(), 16384); + mysqlIO.mysqlInput = new BufferedInputStream(mysqlIO.mysqlConnection.getInputStream(), 16384); } - mysqlIO.mysqlOutput = new BufferedOutputStream( - mysqlIO.mysqlConnection.getOutputStream(), 16384); + mysqlIO.mysqlOutput = new BufferedOutputStream(mysqlIO.mysqlConnection.getOutputStream(), 16384); mysqlIO.mysqlOutput.flush(); + + mysqlIO.socketFactory = sslFact; + } catch (IOException ioEx) { - throw new CommunicationsException(mysqlIO.connection, - mysqlIO.lastPacketSentTimeMs, ioEx); + throw SQLError.createCommunicationsException(mysqlIO.connection, + mysqlIO.getLastPacketSentTimeMs(), mysqlIO.getLastPacketReceivedTimeMs(), + ioEx, mysqlIO.getExceptionInterceptor()); } } + /** + * Implementation of internal socket factory to wrap the SSL socket. + */ + public static class StandardSSLSocketFactory implements SocketFactory { + private SSLSocket rawSocket = null; + private final SSLSocketFactory sslFact; + private final SocketFactory existingSocketFactory; + private final Socket existingSocket; + + public StandardSSLSocketFactory(SSLSocketFactory sslFact, SocketFactory existingSocketFactory, Socket existingSocket) { + this.sslFact = sslFact; + this.existingSocketFactory = existingSocketFactory; + this.existingSocket = existingSocket; + } + public Socket afterHandshake() throws SocketException, IOException { + this.existingSocketFactory.afterHandshake(); + return this.rawSocket; + } + + public Socket beforeHandshake() throws SocketException, IOException { + return this.rawSocket; + } + + public Socket connect(String host, int portNumber, Properties props) throws SocketException, IOException { + this.rawSocket = (SSLSocket) sslFact.createSocket(this.existingSocket, host, portNumber, true); + return this.rawSocket; + } + + } + private ExportControlled() { /* prevent instantiation */ } + + 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 trustCertificateKeyStorePassword = mysqlIO.connection + .getTrustCertificateKeyStorePassword(); + + if (StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl) + && StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl)) { + if (mysqlIO.connection.getVerifyServerCertificate()) { + return (SSLSocketFactory) SSLSocketFactory + .getDefault(); + } + } + + TrustManagerFactory tmf = null; + KeyManagerFactory kmf = null; + + try { + tmf = TrustManagerFactory.getInstance(TrustManagerFactory + .getDefaultAlgorithm()); + kmf = KeyManagerFactory.getInstance(KeyManagerFactory + .getDefaultAlgorithm()); + } catch (NoSuchAlgorithmException nsae) { + throw SQLError + .createSQLException( + "Default algorithm definitions for TrustManager and/or KeyManager are invalid. Check java security properties file.", + SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor()); + } + + if (!StringUtils.isNullOrEmpty(clientCertificateKeyStoreUrl)) { + InputStream ksIS = null; + try { + if (!StringUtils.isNullOrEmpty(clientCertificateKeyStoreType)) { + KeyStore clientKeyStore = KeyStore + .getInstance(clientCertificateKeyStoreType); + URL ksURL = new URL(clientCertificateKeyStoreUrl); + char[] password = (clientCertificateKeyStorePassword == null) ? new char[0] + : clientCertificateKeyStorePassword.toCharArray(); + ksIS = ksURL.openStream(); + clientKeyStore.load(ksIS, password); + kmf.init(clientKeyStore, password); + } + } catch (UnrecoverableKeyException uke) { + throw SQLError + .createSQLException( + "Could not recover keys from client keystore. Check password?", + SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor()); + } 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 client" + + clientCertificateKeyStoreType + " keystore from " + + clientCertificateKeyStoreUrl, mysqlIO.getExceptionInterceptor()); + } catch (MalformedURLException mue) { + throw SQLError.createSQLException(clientCertificateKeyStoreUrl + + " 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 " + + clientCertificateKeyStoreUrl + " [" + + ioe.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor()); + sqlEx.initCause(ioe); + + 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 + } + } + } + } + + if (!StringUtils.isNullOrEmpty(trustCertificateKeyStoreUrl)) { + + InputStream ksIS = null; + try { + if (!StringUtils.isNullOrEmpty(trustCertificateKeyStoreType)) { + KeyStore trustKeyStore = KeyStore + .getInstance(trustCertificateKeyStoreType); + URL ksURL = new URL(trustCertificateKeyStoreUrl); + + 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()); + + sqlEx.initCause(ioe); + + 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 + } + } + } + } + + SSLContext sslContext = null; + + 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); + + 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) { + throw SQLError.createSQLException("KeyManagementException: " + + kme.getMessage(), SQL_STATE_BAD_SSL_PARAMS, 0, false, mysqlIO.getExceptionInterceptor()); + } + } + + public static boolean isSSLEstablished(MysqlIO mysqlIO) { + return SSLSocket.class.isAssignableFrom(mysqlIO.mysqlConnection.getClass()); + } + + public static RSAPublicKey decodeRSAPublicKey(String key, ExceptionInterceptor interceptor) throws SQLException { + + try { + if (key == null) throw new SQLException("key parameter is null"); + + int offset = key.indexOf("\n")+1; + int len = key.indexOf("-----END PUBLIC KEY-----") - offset; + + // TODO: use standard decoders with Java 6+ + byte[] certificateData = Base64Decoder.decode(key.getBytes(), offset, len); + + X509EncodedKeySpec spec = new X509EncodedKeySpec(certificateData); + KeyFactory kf = KeyFactory.getInstance("RSA"); + return (RSAPublicKey) kf.generatePublic(spec); + } catch (Exception ex) { + throw SQLError.createSQLException("Unable to decode public key", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, ex, interceptor); + } + } + + public static byte[] encryptWithRSAPublicKey(byte[] source, RSAPublicKey key, ExceptionInterceptor interceptor) throws SQLException { + try { + Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher.doFinal(source); + } catch (Exception ex) { + throw SQLError.createSQLException(ex.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, ex, interceptor); + } + } + + } \ No newline at end of file Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/Extension.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/FailoverConnectionProxy.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Field.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Field.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Field.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Field.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,32 +1,32 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.UnsupportedEncodingException; import java.sql.SQLException; import java.sql.Types; +import java.util.regex.PatternSyntaxException; /** * Field is a class used to describe fields in a ResultSet @@ -52,7 +52,7 @@ private String collationName = null; - private Connection connection = null; + private MySQLConnection connection = null; private String databaseName = null; @@ -61,10 +61,10 @@ // database name info private int databaseNameStart = -1; - private int defaultValueLength = -1; + protected int defaultValueLength = -1; // default value info - from COM_LIST_FIELDS execution - private int defaultValueStart = -1; + protected int defaultValueStart = -1; private String fullName = null; @@ -111,11 +111,13 @@ private boolean isSingleBit; private int maxBytesPerChar; + + private final boolean valueNeedsQuoting; /** * Constructor used when communicating with 4.1 and newer servers */ - Field(Connection conn, byte[] buffer, int databaseNameStart, + Field(MySQLConnection conn, byte[] buffer, int databaseNameStart, int databaseNameLength, int tableNameStart, int tableNameLength, int originalTableNameStart, int originalTableNameLength, int nameStart, int nameLength, int originalColumnNameStart, @@ -156,18 +158,22 @@ checkForImplicitTemporaryTable(); // Re-map to 'real' blob type, if we're a BLOB - + boolean isFromFunction = this.originalTableNameLength == 0; + if (this.mysqlType == MysqlDefs.FIELD_TYPE_BLOB) { - boolean isFromFunction = this.originalTableNameLength == 0; - if (this.connection != null && this.connection.getBlobsAreStrings() || (this.connection.getFunctionsNeverReturnBlobs() && isFromFunction)) { this.sqlType = Types.VARCHAR; this.mysqlType = MysqlDefs.FIELD_TYPE_VARCHAR; } else if (this.charsetIndex == 63 || !this.connection.versionMeetsMinimum(4, 1, 0)) { - setBlobTypeBasedOnLength(); - this.sqlType = MysqlDefs.mysqlToJavaType(this.mysqlType); + if (this.connection.getUseBlobToStoreUTF8OutsideBMP() + && shouldSetupForUtf8StringInBlob()) { + setupForUtf8StringInBlob(); + } else { + setBlobTypeBasedOnLength(); + this.sqlType = MysqlDefs.mysqlToJavaType(this.mysqlType); + } } else { // *TEXT masquerading as blob this.mysqlType = MysqlDefs.FIELD_TYPE_VAR_STRING; @@ -192,6 +198,12 @@ this.charsetName = this.connection .getCharsetNameForIndex(this.charsetIndex); + // ucs2, utf16, and utf32 cannot be used as a client character set, + // but if it was received from server under some circumstances + // we can parse them as utf16 + if ("UnicodeBig".equals(this.charsetName)) { + this.charsetName = "UTF-16"; + } // Handle VARBINARY/BINARY (server doesn't have a different type // for this @@ -202,9 +214,12 @@ this.mysqlType == MysqlDefs.FIELD_TYPE_VAR_STRING && isBinary && this.charsetIndex == 63) { - if (this.isOpaqueBinary()) { + if (this.connection != null && (this.connection.getFunctionsNeverReturnBlobs() && isFromFunction)) { + this.sqlType = Types.VARCHAR; + this.mysqlType = MysqlDefs.FIELD_TYPE_VARCHAR; + } else if (this.isOpaqueBinary()) { this.sqlType = Types.VARBINARY; - } + } } if (this.connection.versionMeetsMinimum(4, 1, 0) && @@ -279,12 +294,74 @@ break; } } + this.valueNeedsQuoting = determineNeedsQuoting(); } + private boolean shouldSetupForUtf8StringInBlob() throws SQLException { + String includePattern = this.connection + .getUtf8OutsideBmpIncludedColumnNamePattern(); + String excludePattern = this.connection + .getUtf8OutsideBmpExcludedColumnNamePattern(); + + if (excludePattern != null + && !StringUtils.isEmptyOrWhitespaceOnly(excludePattern)) { + try { + if (getOriginalName().matches(excludePattern)) { + if (includePattern != null + && !StringUtils.isEmptyOrWhitespaceOnly(includePattern)) { + try { + if (getOriginalName().matches(includePattern)) { + return true; + } + } catch (PatternSyntaxException pse) { + SQLException sqlEx = SQLError + .createSQLException( + "Illegal regex specified for \"utf8OutsideBmpIncludedColumnNamePattern\"", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.connection.getExceptionInterceptor()); + + if (!this.connection.getParanoid()) { + sqlEx.initCause(pse); + } + + throw sqlEx; + } + } + + return false; + } + } catch (PatternSyntaxException pse) { + SQLException sqlEx = SQLError + .createSQLException( + "Illegal regex specified for \"utf8OutsideBmpExcludedColumnNamePattern\"", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.connection.getExceptionInterceptor()); + + if (!this.connection.getParanoid()) { + sqlEx.initCause(pse); + } + + throw sqlEx; + } + } + + return true; + } + + private void setupForUtf8StringInBlob() { + if (this.length == MysqlDefs.LENGTH_TINYBLOB || this.length == MysqlDefs.LENGTH_BLOB) { + this.mysqlType = MysqlDefs.FIELD_TYPE_VARCHAR; + this.sqlType = Types.VARCHAR; + } else { + this.mysqlType = MysqlDefs.FIELD_TYPE_VAR_STRING; + this.sqlType = Types.LONGVARCHAR; + } + + this.charsetIndex = 33; + } + /** * Constructor used when communicating with pre 4.1 servers */ - Field(Connection conn, byte[] buffer, int nameStart, int nameLength, + 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, @@ -302,8 +379,45 @@ this.sqlType = jdbcType; this.colFlag = 0; this.colDecimals = 0; + this.valueNeedsQuoting = determineNeedsQuoting(); } - + + /** + * Used by prepared statements to re-use result set data conversion methods + * when generating bound parmeter retrieval instance for statement + * interceptors. + * + * @param tableName + * not used + * @param columnName + * not used + * @param charsetIndex + * the MySQL collation/character set index + * @param jdbcType + * from java.sql.Types + * @param length + * length in characters or bytes (for BINARY data). + */ + Field(String tableName, String columnName, int charsetIndex, int jdbcType, + int length) { + this.tableName = tableName; + this.name = columnName; + this.length = length; + this.sqlType = jdbcType; + this.colFlag = 0; + this.colDecimals = 0; + this.charsetIndex = charsetIndex; + this.valueNeedsQuoting = determineNeedsQuoting(); + + switch (this.sqlType) { + case Types.BINARY: + case Types.VARBINARY: + this.colFlag |= 128; + this.colFlag |= 16; + break; + } + } + private void checkForImplicitTemporaryTable() { this.isImplicitTempTable = this.tableNameLength > 5 && this.buffer[tableNameStart] == (byte) '#' @@ -322,6 +436,18 @@ return this.charsetName; } + public void setCharacterSet(String javaEncodingName) throws SQLException { + this.charsetName = javaEncodingName; + try { + this.charsetIndex = CharsetMapping + .getCharsetIndexForMysqlEncodingName(javaEncodingName); + } catch (RuntimeException ex) { + SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + sqlEx.initCause(ex); + throw sqlEx; + } + } + public synchronized String getCollation() throws SQLException { if (this.collationName == null) { if (this.connection != null) { @@ -387,15 +513,21 @@ } } } else { - this.collationName = CharsetMapping.INDEX_TO_COLLATION[charsetIndex]; + try { + this.collationName = CharsetMapping.INDEX_TO_COLLATION[charsetIndex]; + } catch (RuntimeException ex) { + SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + sqlEx.initCause(ex); + throw sqlEx; + } } } } } return this.collationName; } - + public String getColumnLabel() throws SQLException { return getName(); // column name if not aliased, alias if used } @@ -479,9 +611,8 @@ public synchronized int getMaxBytesPerCharacter() throws SQLException { if (this.maxBytesPerChar == 0) { - this.maxBytesPerChar = this.connection.getMaxBytesPerChar(getCharacterSet()); + this.maxBytesPerChar = this.connection.getMaxBytesPerChar(this.charsetIndex, getCharacterSet()); } - return this.maxBytesPerChar; } @@ -606,17 +737,8 @@ stringStart, stringLength); } else { // we have no converter, use JVM converter - byte[] stringBytes = new byte[stringLength]; - - int endIndex = stringStart + stringLength; - int pos = 0; - - for (int i = stringStart; i < endIndex; i++) { - stringBytes[pos++] = this.buffer[i]; - } - try { - stringVal = new String(stringBytes, encoding); + stringVal = StringUtils.toString(buffer, stringStart, stringLength, encoding); } catch (UnsupportedEncodingException ue) { throw new RuntimeException(Messages .getString("Field.12") + encoding //$NON-NLS-1$ @@ -794,6 +916,10 @@ return ((this.colFlag & 32) > 0); } + public void setUnsigned() { + this.colFlag |= 32; + } + /** * DOCUMENT ME! * @@ -841,10 +967,12 @@ * @param conn * DOCUMENT ME! */ - public void setConnection(Connection conn) { + public void setConnection(MySQLConnection conn) { this.connection = conn; - this.charsetName = this.connection.getEncoding(); + if (this.charsetName == null || this.charsetIndex == 0) { + this.charsetName = this.connection.getEncoding(); + } } void setMysqlType(int type) { @@ -858,31 +986,72 @@ public String toString() { try { - StringBuffer asString = new StringBuffer(128); + StringBuffer asString = new StringBuffer(); asString.append(super.toString()); - - asString.append("\n catalog: "); + asString.append("["); + asString.append("catalog="); asString.append(this.getDatabaseName()); - asString.append("\n table name: "); + asString.append(",tableName="); asString.append(this.getTableName()); - asString.append("\n original table name: "); + asString.append(",originalTableName="); asString.append(this.getOriginalTableName()); - asString.append("\n column name: "); + asString.append(",columnName="); asString.append(this.getName()); - asString.append("\n original column name: "); + asString.append(",originalColumnName="); asString.append(this.getOriginalName()); - asString.append("\n MySQL data type: "); + asString.append(",mysqlType="); asString.append(getMysqlType()); asString.append("("); asString.append(MysqlDefs.typeToName(getMysqlType())); asString.append(")"); - - if (this.buffer != null) { - asString.append("\n\nData as received from server:\n\n"); - asString.append(StringUtils.dumpAsHex(this.buffer, - this.buffer.length)); + asString.append(",flags="); + + if (isAutoIncrement()) { + asString.append(" AUTO_INCREMENT"); } + + if (isPrimaryKey()) { + asString.append(" PRIMARY_KEY"); + } + + if (isUniqueKey()) { + asString.append(" UNIQUE_KEY"); + } + + if (isBinary()) { + asString.append(" BINARY"); + } + + if (isBlob()) { + asString.append(" BLOB"); + } + + if (isMultipleKey()) { + asString.append(" MULTI_KEY"); + } + + if (isUnsigned()) { + asString.append(" UNSIGNED"); + } + + if (isZeroFill()) { + asString.append(" ZEROFILL"); + } + asString.append(", charsetIndex="); + asString.append(this.charsetIndex); + asString.append(", charsetName="); + asString.append(this.charsetName); + + + //if (this.buffer != null) { + // asString.append("\n\nData as received from server:\n\n"); + // asString.append(StringUtils.dumpAsHex(this.buffer, + // this.buffer.length)); + //} + + asString.append("]"); + return asString.toString(); } catch (Throwable t) { return super.toString(); @@ -892,4 +1061,31 @@ protected boolean isSingleBit() { return this.isSingleBit; } + + protected boolean getvalueNeedsQuoting() { + return this.valueNeedsQuoting; + } + + private boolean determineNeedsQuoting() { + boolean retVal = false; + + switch (this.sqlType) { + case Types.BIGINT: + case Types.BIT: + case Types.DECIMAL: + case Types.DOUBLE: + case Types.FLOAT: + case Types.INTEGER: + case Types.NUMERIC: + case Types.REAL: + case Types.SMALLINT: + case Types.TINYINT: + retVal = false; + break; + default: + retVal = true; + } + return retVal; + + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/IterateBlock.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4CallableStatement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4ClientInfoProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4ClientInfoProviderSP.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4CommentClientInfoProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4Connection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4DatabaseMetaData.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4DatabaseMetaDataUsingInfoSchema.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4LoadBalancedMySQLConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4MySQLConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4MysqlSQLXML.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4NClob.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4PreparedStatement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4PreparedStatementHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4ResultSet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4ServerPreparedStatement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/JDBC4UpdatableResultSet.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/LicenseConfiguration.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/LicenseConfiguration.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/LicenseConfiguration.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/LicenseConfiguration.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,31 +1,29 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.SQLException; - import java.util.Map; /** @@ -49,7 +47,7 @@ * @throws SQLException * if commercial license is required, but not found */ - static void checkLicenseType(Map serverVariables) throws SQLException { + static void checkLicenseType(Map serverVariables) throws SQLException { // This is a GPL build, so we don't check anything... } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalanceExceptionChecker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedAutoCommitInterceptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedMySQLConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancingConnectionProxy.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancingConnectionProxy.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancingConnectionProxy.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancingConnectionProxy.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,38 +1,44 @@ /* - Copyright (C) 2007 MySQL AB + Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + */ 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.lang.reflect.Proxy; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; +import java.util.concurrent.Executor; /** * An implementation of java.sql.Connection that load balances requests across a @@ -43,9 +49,10 @@ * reading data. * * This implementation will invalidate connections that it detects have had - * communication errors when processing a request. A new connection to the - * problematic host will be attempted the next time it is selected by the load - * balancing algorithm. + * communication errors when processing a request. Problematic hosts will be + * added to a global blacklist for loadBalanceBlacklistTimeout ms, after which + * they will be removed from the blacklist and made eligible once again to be + * selected for new connections. * * This implementation is thread-safe, but it's questionable whether sharing a * connection instance amongst threads is a good idea, given that transactions @@ -54,10 +61,23 @@ * @version $Id$ * */ -public class LoadBalancingConnectionProxy implements InvocationHandler, PingTarget { +public class LoadBalancingConnectionProxy implements InvocationHandler, + PingTarget { private static Method getLocalTimeMethod; + + private long totalPhysicalConnections = 0; + private long activePhysicalConnections = 0; + private String hostToRemove = null; + private long lastUsed = 0; + private long transactionCount = 0; + private ConnectionGroup connectionGroup = null; + protected String closedReason = null; + protected boolean closedExplicitly = false; + protected boolean autoReconnect = false; + public static final String BLACKLIST_TIMEOUT_PROPERTY_KEY = "loadBalanceBlacklistTimeout"; + static { try { getLocalTimeMethod = System.class.getMethod("nanoTime", @@ -69,87 +89,6 @@ } } - interface BalanceStrategy { - abstract Connection pickConnection() throws SQLException; - } - - class BestResponseTimeBalanceStrategy implements BalanceStrategy { - - public Connection pickConnection() throws SQLException { - long minResponseTime = Long.MAX_VALUE; - - int bestHostIndex = 0; - - long[] localResponseTimes = new long[responseTimes.length]; - - synchronized (responseTimes) { - System.arraycopy(responseTimes, 0, localResponseTimes, 0, responseTimes.length); - } - - SQLException ex = null; - - for (int attempts = 0; attempts < 1200 /* 5 minutes */; attempts++) { - for (int i = 0; i < localResponseTimes.length; i++) { - long candidateResponseTime = localResponseTimes[i]; - - if (candidateResponseTime < minResponseTime) { - if (candidateResponseTime == 0) { - bestHostIndex = i; - - break; - } - - bestHostIndex = i; - minResponseTime = candidateResponseTime; - } - } - - if (bestHostIndex == localResponseTimes.length - 1) { - // try again, assuming that the previous list was mostly - // correct as far as distribution of response times went - - synchronized (responseTimes) { - System.arraycopy(responseTimes, 0, localResponseTimes, 0, responseTimes.length); - } - - continue; - } - String bestHost = (String) hostList.get(bestHostIndex); - - Connection conn = (Connection) liveConnections.get(bestHost); - - if (conn == null) { - try { - conn = createConnectionForHost(bestHost); - } catch (SQLException sqlEx) { - ex = sqlEx; - - if (sqlEx instanceof CommunicationsException || "08S01".equals(sqlEx.getSQLState())) { - localResponseTimes[bestHostIndex] = Long.MAX_VALUE; - - try { - Thread.sleep(250); - } catch (InterruptedException e) { - } - - continue; - } else { - throw sqlEx; - } - } - } - - return conn; - } - - if (ex != null) { - throw ex; - } - - return null; // we won't get here, compiler can't tell - } - } - // Lifted from C/J 5.1's JDBC-2.0 connection pool classes, let's merge this // if/when this gets into 5.1 protected class ConnectionErrorFiringInvocationHandler implements @@ -178,76 +117,68 @@ } } - class RandomBalanceStrategy implements BalanceStrategy { + protected MySQLConnection currentConn; - public Connection pickConnection() throws SQLException { - int random = (int) (Math.random() * hostList.size()); + protected List hostList; - if (random == hostList.size()) { - random--; - } + protected Map liveConnections; - String hostPortSpec = (String) hostList.get(random); + private Map connectionsToHostsMap; - SQLException ex = null; - - for (int attempts = 0; attempts < 1200 /* 5 minutes */; attempts++) { - Connection conn = (Connection) liveConnections.get(hostPortSpec); - - if (conn == null) { - try { - conn = createConnectionForHost(hostPortSpec); - } catch (SQLException sqlEx) { - ex = sqlEx; - - if (sqlEx instanceof CommunicationsException || "08S01".equals(sqlEx.getSQLState())) { - - try { - Thread.sleep(250); - } catch (InterruptedException e) { - } - - continue; - } else { - throw sqlEx; - } - } - } - - return conn; - } - - if (ex != null) { - throw ex; - } - - return null; // we won't get here, compiler can't tell - } + private long[] responseTimes; - } + private Map hostsToListIndexMap; - private Connection currentConn; + private boolean inTransaction = false; - private List hostList; + private long transactionStartTime = 0; - private Map liveConnections; + private Properties localProps; - private Map connectionsToHostsMap; + protected boolean isClosed = false; - private long[] responseTimes; + private BalanceStrategy balancer; - private Map hostsToListIndexMap; + private int retriesAllDown; - boolean inTransaction = false; + private static Map globalBlacklist = new HashMap(); - long transactionStartTime = 0; + private int globalBlacklistTimeout = 0; + + private long connectionGroupProxyID = 0; - Properties localProps; + private LoadBalanceExceptionChecker exceptionChecker; - boolean isClosed = false; + private Map, Boolean> jdbcInterfacesForProxyCache = new HashMap, Boolean>(); + + private MySQLConnection thisAsConnection = null; - BalanceStrategy balancer; + private int autoCommitSwapThreshold = 0; + + private static Constructor JDBC_4_LB_CONNECTION_CTOR; + + static { + if(Util.isJdbc4()){ + try { + JDBC_4_LB_CONNECTION_CTOR = Class.forName( + "com.mysql.jdbc.JDBC4LoadBalancedMySQLConnection").getConstructor( + new Class[] { LoadBalancingConnectionProxy.class}); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + } + + + + + + /** * Creates a proxy for java.sql.Connection that routes requests between the * given list of host:port and uses the given properties when creating @@ -257,40 +188,153 @@ * @param props * @throws SQLException */ - LoadBalancingConnectionProxy(List hosts, Properties props) + LoadBalancingConnectionProxy(List hosts, Properties props) throws SQLException { + String group = props.getProperty("loadBalanceConnectionGroup", + null); + boolean enableJMX = false; + String enableJMXAsString = props.getProperty("loadBalanceEnableJMX", + "false"); + try{ + enableJMX = Boolean.parseBoolean(enableJMXAsString); + } catch (Exception e){ + throw SQLError.createSQLException(Messages.getString( + "LoadBalancingConnectionProxy.badValueForLoadBalanceEnableJMX", + new Object[] { enableJMXAsString }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + } + + if(group != null){ + this.connectionGroup = ConnectionGroupManager.getConnectionGroupInstance(group); + if(enableJMX){ + ConnectionGroupManager.registerJmx(); + } + this.connectionGroupProxyID = this.connectionGroup.registerConnectionProxy(this, hosts); + hosts = new ArrayList(this.connectionGroup.getInitialHosts()); + } + + this.autoReconnect = "true".equalsIgnoreCase(props.getProperty("autoReconnect")) || + "true".equalsIgnoreCase(props.getProperty("autoReconnectForPools")); + this.hostList = hosts; int numHosts = this.hostList.size(); - this.liveConnections = new HashMap(numHosts); - this.connectionsToHostsMap = new HashMap(numHosts); + this.liveConnections = new HashMap(numHosts); + this.connectionsToHostsMap = new HashMap(numHosts); this.responseTimes = new long[numHosts]; - this.hostsToListIndexMap = new HashMap(numHosts); + this.hostsToListIndexMap = new HashMap(numHosts); - for (int i = 0; i < numHosts; i++) { - this.hostsToListIndexMap.put(this.hostList.get(i), new Integer(i)); - } - this.localProps = (Properties) props.clone(); this.localProps.remove(NonRegisteringDriver.HOST_PROPERTY_KEY); this.localProps.remove(NonRegisteringDriver.PORT_PROPERTY_KEY); + + for (int i = 0; i < numHosts; i++) { + this.hostsToListIndexMap.put(this.hostList.get(i), Integer.valueOf(i)); + this.localProps.remove(NonRegisteringDriver.HOST_PROPERTY_KEY + "." + + (i + 1)); + this.localProps.remove(NonRegisteringDriver.PORT_PROPERTY_KEY + "." + + (i + 1)); + } + + this.localProps.remove(NonRegisteringDriver.NUM_HOSTS_PROPERTY_KEY); this.localProps.setProperty("useLocalSessionState", "true"); String strategy = this.localProps.getProperty("loadBalanceStrategy", "random"); + + String lbExceptionChecker = this.localProps.getProperty("loadBalanceExceptionChecker", + "com.mysql.jdbc.StandardLoadBalanceExceptionChecker"); + + String retriesAllDownAsString = this.localProps.getProperty( + "retriesAllDown", "120"); + + try { + this.retriesAllDown = Integer.parseInt(retriesAllDownAsString); + } catch (NumberFormatException nfe) { + throw SQLError.createSQLException(Messages.getString( + "LoadBalancingConnectionProxy.badValueForRetriesAllDown", + new Object[] { retriesAllDownAsString }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + } + String blacklistTimeoutAsString = this.localProps.getProperty( + BLACKLIST_TIMEOUT_PROPERTY_KEY, "0"); + + try { + this.globalBlacklistTimeout = Integer + .parseInt(blacklistTimeoutAsString); + } catch (NumberFormatException nfe) { + throw SQLError + .createSQLException( + Messages + .getString( + "LoadBalancingConnectionProxy.badValueForLoadBalanceBlacklistTimeout", + new Object[] { retriesAllDownAsString }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + } + if ("random".equals(strategy)) { - this.balancer = new RandomBalanceStrategy(); + this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, + "com.mysql.jdbc.RandomBalanceStrategy", + "InvalidLoadBalanceStrategy", null).get(0); } else if ("bestResponseTime".equals(strategy)) { - this.balancer = new BestResponseTimeBalanceStrategy(); + this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, + "com.mysql.jdbc.BestResponseTimeBalanceStrategy", + "InvalidLoadBalanceStrategy", null).get(0); } else { + this.balancer = (BalanceStrategy) Util.loadExtensions(null, props, + strategy, "InvalidLoadBalanceStrategy", null).get(0); + } + + String autoCommitSwapThresholdAsString = props.getProperty("loadBalanceAutoCommitStatementThreshold", + "0"); + try { + this.autoCommitSwapThreshold = Integer.parseInt(autoCommitSwapThresholdAsString); + } catch (NumberFormatException nfe) { throw SQLError.createSQLException(Messages.getString( - "InvalidLoadBalanceStrategy", new Object[] { strategy }), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + "LoadBalancingConnectionProxy.badValueForLoadBalanceAutoCommitStatementThreshold", + new Object[] { autoCommitSwapThresholdAsString }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); } + + String autoCommitSwapRegex = props.getProperty("loadBalanceAutoCommitStatementRegex",""); + if(!("".equals(autoCommitSwapRegex))){ + try{ + "".matches(autoCommitSwapRegex); + } catch (Exception e){ + throw SQLError.createSQLException(Messages.getString( + "LoadBalancingConnectionProxy.badValueForLoadBalanceAutoCommitStatementRegex", + new Object[] { autoCommitSwapRegex }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + } + } + + if(this.autoCommitSwapThreshold > 0){ + String statementInterceptors = this.localProps.getProperty("statementInterceptors"); + if(statementInterceptors == null){ + this.localProps.setProperty("statementInterceptors", "com.mysql.jdbc.LoadBalancedAutoCommitInterceptor"); + } else if(statementInterceptors.length() > 0){ + this.localProps.setProperty("statementInterceptors", statementInterceptors + ",com.mysql.jdbc.LoadBalancedAutoCommitInterceptor"); + } + props.setProperty("statementInterceptors", this.localProps.getProperty("statementInterceptors")); + + } + this.balancer.init(null, props); + + this.exceptionChecker = (LoadBalanceExceptionChecker) Util.loadExtensions(null, props, + lbExceptionChecker, "InvalidLoadBalanceExceptionChecker", null).get(0); + + if(Util.isJdbc4() || JDBC_4_LB_CONNECTION_CTOR != null){ + thisAsConnection = (MySQLConnection) Util.handleNewInstance(JDBC_4_LB_CONNECTION_CTOR, + new Object[] {this}, null); + }else{ + thisAsConnection = new LoadBalancedMySQLConnection(this); + } pickNewConnection(); + + } /** @@ -301,30 +345,56 @@ * @return * @throws SQLException */ - private synchronized Connection createConnectionForHost(String hostPortSpec) - throws SQLException { + public synchronized ConnectionImpl createConnectionForHost( + String hostPortSpec) throws SQLException { Properties connProps = (Properties) this.localProps.clone(); String[] hostPortPair = NonRegisteringDriver .parseHostPortPair(hostPortSpec); + String hostName = hostPortPair[NonRegisteringDriver.HOST_NAME_INDEX]; + String portNumber = hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX]; + String dbName = connProps + .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY); - if (hostPortPair[1] == null) { - hostPortPair[1] = "3306"; + if (hostName == null) { + throw new SQLException( + "Could not find a hostname to start a connection to"); } + if (portNumber == null) { + portNumber = "3306";// use default + } - connProps.setProperty(NonRegisteringDriver.HOST_PROPERTY_KEY, - hostPortSpec); + connProps.setProperty(NonRegisteringDriver.HOST_PROPERTY_KEY, hostName); connProps.setProperty(NonRegisteringDriver.PORT_PROPERTY_KEY, - hostPortPair[1]); + portNumber); + connProps.setProperty(NonRegisteringDriver.HOST_PROPERTY_KEY + ".1", + hostName); + connProps.setProperty(NonRegisteringDriver.PORT_PROPERTY_KEY + ".1", + portNumber); + connProps.setProperty(NonRegisteringDriver.NUM_HOSTS_PROPERTY_KEY, "1"); + connProps.setProperty("roundRobinLoadBalance", "false"); // make sure we + // don't + // pickup + // the + // default + // value - Connection conn = new Connection(hostPortSpec, Integer - .parseInt(hostPortPair[1]), connProps, connProps - .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY), - "jdbc:mysql://" + hostPortPair[0] + ":" + hostPortPair[1] + "/"); + ConnectionImpl conn = (ConnectionImpl) ConnectionImpl.getInstance( + hostName, Integer.parseInt(portNumber), connProps, dbName, + "jdbc:mysql://" + hostName + ":" + portNumber + "/"); + + this.liveConnections.put(hostPortSpec, conn); this.connectionsToHostsMap.put(conn, hostPortSpec); + + this.activePhysicalConnections++; + this.totalPhysicalConnections++; + + conn.setProxy(this.thisAsConnection); + conn.setRealProxy(this); + return conn; } @@ -339,16 +409,9 @@ Throwable t = e.getTargetException(); if (t != null) { - if (t instanceof SQLException) { - String sqlState = ((SQLException) t).getSQLState(); - - if (sqlState != null) { - if (sqlState.startsWith("08")) { - // connection error, close up shop on current - // connection - invalidateCurrentConnection(); - } - } + if (t instanceof SQLException && shouldExceptionTriggerFailover((SQLException) t )) { + invalidateCurrentConnection(); + pickNewConnection(); } throw t; @@ -363,88 +426,251 @@ * @throws SQLException */ synchronized void invalidateCurrentConnection() throws SQLException { + invalidateConnection(this.currentConn); + } + + + /** + * Closes specified connection and removes it from required mappings. + * @param conn + * @throws SQLException + */ + synchronized void invalidateConnection(MySQLConnection conn) throws SQLException { try { - if (!this.currentConn.isClosed()) { - this.currentConn.close(); + if (!conn.isClosed()) { + conn.close(); } - + } catch (SQLException e) { + // we don't really want to throw this Exception } finally { + // add host to the global blacklist, if enabled + if (this.isGlobalBlacklistEnabled()) { + this.addToGlobalBlacklist(this.connectionsToHostsMap + .get(conn)); + + } + // remove from liveConnections this.liveConnections.remove(this.connectionsToHostsMap - .get(this.currentConn)); - this.connectionsToHostsMap.remove(this.currentConn); + .get(conn)); + Object mappedHost = this.connectionsToHostsMap + .remove(conn); + if (mappedHost != null + && this.hostsToListIndexMap.containsKey(mappedHost)) { + int hostIndex = (this.hostsToListIndexMap + .get(mappedHost)).intValue(); + // reset the statistics for the host + synchronized (this.responseTimes) { + this.responseTimes[hostIndex] = 0; + } + } + } + } + + + private void closeAllConnections() { + synchronized (this) { + // close all underlying connections + Iterator allConnections = this.liveConnections.values().iterator(); + + while (allConnections.hasNext()) { + try { + this.activePhysicalConnections--; + allConnections.next().close(); + } catch (SQLException e) { + } + } + + if (!this.isClosed) { + this.balancer.destroy(); + if(this.connectionGroup != null){ + this.connectionGroup.closeConnectionProxy(this); + } + } + + this.liveConnections.clear(); + this.connectionsToHostsMap.clear(); } + } + + private void abortAllConnectionsInternal() { + synchronized (this) { + // abort all underlying connections + Iterator allConnections = this.liveConnections.values().iterator(); + while (allConnections.hasNext()) { + try { + this.activePhysicalConnections--; + allConnections.next().abortInternal(); + } catch (SQLException e) { + } + } + + if (!this.isClosed) { + this.balancer.destroy(); + if(this.connectionGroup != null){ + this.connectionGroup.closeConnectionProxy(this); + } + } + + this.liveConnections.clear(); + this.connectionsToHostsMap.clear(); + } + } + + private void abortAllConnections(Executor executor) { + synchronized (this) { + // close all underlying connections + Iterator allConnections = this.liveConnections.values().iterator(); + + while (allConnections.hasNext()) { + try { + this.activePhysicalConnections--; + allConnections.next().abort(executor); + } catch (SQLException e) { + } + } + + if (!this.isClosed) { + this.balancer.destroy(); + if(this.connectionGroup != null){ + this.connectionGroup.closeConnectionProxy(this); + } + } + + this.liveConnections.clear(); + this.connectionsToHostsMap.clear(); + } + + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return this.invoke(proxy, method, args, true); + } + /** * Proxies method invocation on the java.sql.Connection interface, trapping * "close", "isClosed" and "commit/rollback" (to switch connections for load * balancing). + * + * @param proxy + * @param method + * @param args + * @param swapAtTransactionBoundary + * @return + * @throws Throwable */ - public Object invoke(Object proxy, Method method, Object[] args) + public synchronized Object invoke(Object proxy, Method method, Object[] args, boolean swapAtTransactionBoundary) throws Throwable { String methodName = method.getName(); + + if("getLoadBalanceSafeProxy".equals(methodName)){ + return this.currentConn; + } + if ("equals".equals(methodName) && args.length == 1) { + if (args[0] instanceof Proxy) { + return Boolean.valueOf((((Proxy) args[0]).equals(this))); + } + return Boolean.valueOf(this.equals(args[0])); + } + + if ("hashCode".equals(methodName)) { + return Integer.valueOf(this.hashCode()); + } + if ("close".equals(methodName)) { - synchronized (this.liveConnections) { - // close all underlying connections - Iterator allConnections = this.liveConnections.values() - .iterator(); + closeAllConnections(); - while (allConnections.hasNext()) { - ((Connection) allConnections.next()).close(); - } + this.isClosed = true; + this.closedReason = "Connection explicitly closed."; + this.closedExplicitly = true; - this.liveConnections.clear(); - this.connectionsToHostsMap.clear(); - } + return null; + } + if ("abortInternal".equals(methodName)) { + abortAllConnectionsInternal(); + this.isClosed = true; + this.closedReason = "Connection explicitly closed."; return null; } + if ("abort".equals(methodName) && args.length == 1) { + abortAllConnections((Executor)args[0]); + this.isClosed = true; + this.closedReason = "Connection explicitly closed."; + return null; + } + if ("isClosed".equals(methodName)) { return Boolean.valueOf(this.isClosed); } if (this.isClosed) { - throw SQLError.createSQLException( - "No operations allowed after connection closed.", - SQLError.SQL_STATE_CONNECTION_NOT_OPEN); + if(this.autoReconnect && !this.closedExplicitly){ + // try to reconnect first! + this.currentConn = null; + this.pickNewConnection(); + this.isClosed = false; + this.closedReason = null; + } else { + String reason = "No operations allowed after connection closed."; + if(this.closedReason != null){ + reason += (" " + this.closedReason); + } + throw SQLError.createSQLException( + reason, + SQLError.SQL_STATE_CONNECTION_NOT_OPEN, null /* + * no access to + * a interceptor + * here... + */); + } } if (!inTransaction) { this.inTransaction = true; this.transactionStartTime = getLocalTimeBestResolution(); + this.transactionCount++; } Object result = null; try { - result = method.invoke(this.currentConn, args); + this.lastUsed = System.currentTimeMillis(); + result = method.invoke(thisAsConnection, args); if (result != null) { if (result instanceof com.mysql.jdbc.Statement) { - ((com.mysql.jdbc.Statement)result).setPingTarget(this); + ((com.mysql.jdbc.Statement) result).setPingTarget(this); } - + result = proxyIfInterfaceIsJdbc(result, result.getClass()); } } catch (InvocationTargetException e) { dealWithInvocationException(e); } finally { - if ("commit".equals(methodName) || "rollback".equals(methodName)) { + if (swapAtTransactionBoundary && ("commit".equals(methodName) || "rollback".equals(methodName))) { this.inTransaction = false; // Update stats - int hostIndex = ((Integer) this.hostsToListIndexMap - .get(this.connectionsToHostsMap.get(this.currentConn))) - .intValue(); + String host = this.connectionsToHostsMap.get(this.currentConn); + // avoid NPE if the connection has already been removed from + // connectionsToHostsMap + // in invalidateCurrenctConnection() + if (host != null) { + synchronized (this.responseTimes) { + Integer hostIndex = (this.hostsToListIndexMap + .get(host)); - synchronized (this.responseTimes) { - this.responseTimes[hostIndex] = getLocalTimeBestResolution() - - this.transactionStartTime; + if(hostIndex != null && hostIndex.intValue() < this.responseTimes.length){ + this.responseTimes[hostIndex] = getLocalTimeBestResolution() + - this.transactionStartTime; + } + } } - pickNewConnection(); } } @@ -458,19 +684,63 @@ * * @throws SQLException */ - private synchronized void pickNewConnection() throws SQLException { - if (this.currentConn == null) { - this.currentConn = this.balancer.pickConnection(); + protected synchronized void pickNewConnection() throws SQLException { + if (this.isClosed && this.closedExplicitly) { + return; + } + if (this.currentConn == null) { // startup + this.currentConn = this.balancer.pickConnection(this, Collections + .unmodifiableList(this.hostList), Collections + .unmodifiableMap(this.liveConnections), + this.responseTimes.clone(), this.retriesAllDown); return; } + + if(this.currentConn.isClosed()){ + invalidateCurrentConnection(); + } - Connection newConn = this.balancer.pickConnection(); + int pingTimeout = this.currentConn.getLoadBalancePingTimeout(); + boolean pingBeforeReturn = this.currentConn.getLoadBalanceValidateConnectionOnSwapServer(); + + for(int hostsTried = 0, hostsToTry = this.hostList.size(); hostsTried <= hostsToTry; hostsTried++){ + ConnectionImpl newConn = null; + try{ + newConn = this.balancer.pickConnection( - newConn.setTransactionIsolation(this.currentConn - .getTransactionIsolation()); - newConn.setAutoCommit(this.currentConn.getAutoCommit()); - this.currentConn = newConn; + this, Collections.unmodifiableList(this.hostList), Collections + .unmodifiableMap(this.liveConnections), + this.responseTimes.clone(), this.retriesAllDown); + + if (this.currentConn != null) { + if(pingBeforeReturn){ + if(pingTimeout == 0){ + newConn.ping(); + } else { + newConn.pingInternal(true, pingTimeout); + } + } + + syncSessionState(this.currentConn, newConn); + } + + this.currentConn = newConn; + return; + } catch (SQLException e){ + + if (shouldExceptionTriggerFailover(e) && newConn != null) { + // connection error, close up shop on current + // connection + invalidateConnection(newConn); + } + } + + } + // no hosts available to swap connection to, close up. + this.isClosed = true; + this.closedReason = "Connection closed after inability to pick valid new connection during fail-over."; + } /** @@ -482,33 +752,95 @@ * @param clazz * @return */ - Object proxyIfInterfaceIsJdbc(Object toProxy, Class clazz) { - Class[] interfaces = clazz.getInterfaces(); + Object proxyIfInterfaceIsJdbc(Object toProxy, Class clazz) { + + if(isInterfaceJdbc(clazz)){ + + Class[] interfacesToProxy = getAllInterfacesToProxy(clazz); + + return Proxy.newProxyInstance(toProxy.getClass() + .getClassLoader(), interfacesToProxy, + createConnectionProxy(toProxy)); + } + return toProxy; + } + + private Map, Class[]> allInterfacesToProxy = new HashMap, Class[]>(); + + private Class[] getAllInterfacesToProxy(Class clazz) { + Class[] interfacesToProxy = this.allInterfacesToProxy.get(clazz); + + if (interfacesToProxy != null) { + return interfacesToProxy; + } + + List> interfaces = new LinkedList>(); + + Class superClass = clazz; + + while (!(superClass.equals(Object.class))) { + Class[] declared = superClass.getInterfaces(); + + for (int i = 0; i < declared.length; i++) { + interfaces.add(declared[i]); + } + + superClass = superClass.getSuperclass(); + } + + interfacesToProxy = new Class[interfaces.size()]; + interfaces.toArray(interfacesToProxy); + + this.allInterfacesToProxy.put(clazz, interfacesToProxy); + + return interfacesToProxy; + } + + + private boolean isInterfaceJdbc(Class clazz){ + if(this.jdbcInterfacesForProxyCache.containsKey(clazz)){ + return (this.jdbcInterfacesForProxyCache.get(clazz)).booleanValue(); + } + + Class[] interfaces = clazz.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { String packageName = interfaces[i].getPackage().getName(); if ("java.sql".equals(packageName) - || "javax.sql".equals(packageName)) { - return Proxy.newProxyInstance(toProxy.getClass() - .getClassLoader(), interfaces, - new ConnectionErrorFiringInvocationHandler(toProxy)); + || "javax.sql".equals(packageName) + || "com.mysql.jdbc".equals(packageName)) { + this.jdbcInterfacesForProxyCache.put(clazz, Boolean.valueOf(true)); + + return true; } - return proxyIfInterfaceIsJdbc(toProxy, interfaces[i]); + if(isInterfaceJdbc(interfaces[i])){ + this.jdbcInterfacesForProxyCache.put(clazz, Boolean.valueOf(true)); + + return true; + } } - return toProxy; + this.jdbcInterfacesForProxyCache.put(clazz, Boolean.valueOf(false)); + return false; + } + protected ConnectionErrorFiringInvocationHandler createConnectionProxy( + Object toProxy) { + return new ConnectionErrorFiringInvocationHandler(toProxy); + } + /** * Returns best-resolution representation of local time, using nanoTime() if - * availble, otherwise defaulting to currentTimeMillis(). + * available, otherwise defaulting to currentTimeMillis(). */ private static long getLocalTimeBestResolution() { if (getLocalTimeMethod != null) { try { - return ((Long) getLocalTimeMethod.invoke(null, null)) + return ((Long) getLocalTimeMethod.invoke(null, (Object[])null)) .longValue(); } catch (IllegalArgumentException e) { // ignore - we fall through to currentTimeMillis() @@ -523,10 +855,289 @@ } public synchronized void doPing() throws SQLException { - Iterator allConns = this.liveConnections.values().iterator(); + SQLException se = null; + boolean foundHost = false; + int pingTimeout = this.currentConn.getLoadBalancePingTimeout(); + synchronized (this) { + for (Iterator i = this.hostList.iterator(); i.hasNext();) { + String host = i.next(); + ConnectionImpl conn = this.liveConnections.get(host); + if (conn == null) { + continue; + } + try { + if(pingTimeout == 0){ + conn.ping(); + } else { + conn.pingInternal(true, pingTimeout); + } + 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.currentConn))) { + // clean up underlying connections, since connection + // pool won't do it + closeAllConnections(); + this.isClosed = true; + this.closedReason = "Connection closed because ping of current connection failed."; + throw e; + } + + // if the Exception is caused by ping connection lifetime + // checks, don't add to blacklist + if (e + .getMessage() + .equals( + Messages + .getString("Connection.exceededConnectionLifetime"))) { + // only set the return Exception if it's null + if (se == null) { + se = e; + } + } else { + // overwrite the return Exception no matter what + se = e; + if (this.isGlobalBlacklistEnabled()) { + this.addToGlobalBlacklist(host); + } + } + // take the connection out of the liveConnections Map + this.liveConnections.remove(this.connectionsToHostsMap + .get(conn)); + } + } + } + // if there were no successful pings + if (!foundHost) { + closeAllConnections(); + this.isClosed = true; + this.closedReason = "Connection closed due to inability to ping any active connections."; + // throw the stored Exception, if exists + if (se != null) { + throw se; + } + // or create a new SQLException and throw it, must be no + // liveConnections + ((ConnectionImpl) this.currentConn) + .throwConnectionClosedException(); + } + } + + public void addToGlobalBlacklist(String host, long timeout) { + if (this.isGlobalBlacklistEnabled()) { + synchronized (globalBlacklist) { + globalBlacklist.put(host, Long.valueOf(timeout)); + } + } + } + + public void addToGlobalBlacklist(String host){ + addToGlobalBlacklist(host, System.currentTimeMillis() + + this.globalBlacklistTimeout); - while (allConns.hasNext()) { - ((Connection)allConns.next()).ping(); + } + + public boolean isGlobalBlacklistEnabled() { + return (this.globalBlacklistTimeout > 0); + } + + public synchronized Map getGlobalBlacklist() { + if (!this.isGlobalBlacklistEnabled()) { + String localHostToRemove = this.hostToRemove; + + if(hostToRemove != null){ + HashMap fakedBlacklist = new HashMap(); + fakedBlacklist.put(localHostToRemove, Long.valueOf(System.currentTimeMillis() + 5000)); + return fakedBlacklist; + } + + return new HashMap(1); } + + // Make a local copy of the blacklist + Map blacklistClone = new HashMap(globalBlacklist.size()); + // Copy everything from synchronized global blacklist to local copy for + // manipulation + synchronized (globalBlacklist) { + blacklistClone.putAll(globalBlacklist); + } + Set keys = blacklistClone.keySet(); + + // we're only interested in blacklisted hosts that are in the hostList + keys.retainAll(this.hostList); + + // Don't need to synchronize here as we using a local copy + for (Iterator i = keys.iterator(); i.hasNext();) { + String host = i.next(); + // OK if null is returned because another thread already purged Map + // entry. + Long timeout = globalBlacklist.get(host); + if (timeout != null + && timeout.longValue() < System.currentTimeMillis()) { + // Timeout has expired, remove from blacklist + synchronized (globalBlacklist) { + globalBlacklist.remove(host); + } + i.remove(); + } + + } + if (keys.size() == this.hostList.size()) { + // return an empty blacklist, let the BalanceStrategy + // implementations try to connect to everything + // since it appears that all hosts are unavailable - we don't want + // to wait for + // loadBalanceBlacklistTimeout to expire. + return new HashMap(1); + } + + return blacklistClone; } + + public boolean shouldExceptionTriggerFailover(SQLException ex){ + return this.exceptionChecker.shouldExceptionTriggerFailover(ex); + + } + + public void removeHostWhenNotInUse(String host) + throws SQLException { + int timeBetweenChecks = 1000; + long timeBeforeHardFail = 15000; + + synchronized (this) { + addToGlobalBlacklist(host, timeBeforeHardFail + 1000); + + long cur = System.currentTimeMillis(); + + while (System.currentTimeMillis() - timeBeforeHardFail < cur) { + + this.hostToRemove = host; + + if (!host.equals(this.currentConn.getHost())) { + removeHost(host); + return; + } + } + } + + try { + Thread.sleep(timeBetweenChecks); + } catch (InterruptedException e) { + // better to swallow this and retry. + } + + removeHost(host); + } + + public synchronized void removeHost(String host) throws SQLException { + + if (this.connectionGroup != null) { + if (this.connectionGroup.getInitialHosts().size() == 1 + && this.connectionGroup.getInitialHosts().contains(host)) { + throw SQLError.createSQLException( + "Cannot remove only configured host.", null); + } + + this.hostToRemove = host; + + if (host.equals(this.currentConn.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(); + if (idx != null + && idx.intValue() < this.responseTimes.length) { + newResponseTimes[newIdx] = this.responseTimes[idx + .intValue()]; + this.hostsToListIndexMap.put(copyHost, + Integer.valueOf(newIdx)); + } + } + this.responseTimes = newResponseTimes; + } + } + + } + + public synchronized boolean addHost(String host) { + + if (this.hostsToListIndexMap.containsKey(host)) { + 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, + Integer.valueOf(this.responseTimes.length - 1)); + + return true; + } + + public synchronized long getLastUsed(){ + return this.lastUsed; + } + + public synchronized boolean inTransaction(){ + return this.inTransaction; + } + + public synchronized long getTransactionCount(){ + return this.transactionCount; + } + + public synchronized long getActivePhysicalConnectionCount(){ + return this.activePhysicalConnections; + } + + public synchronized long getTotalPhysicalConnectionCount(){ + return this.totalPhysicalConnections; + } + + public synchronized long getConnectionGroupProxyID(){ + return this.connectionGroupProxyID; + } + + public synchronized String getCurrentActiveHost() { + MySQLConnection c = this.currentConn; + if(c != null){ + Object o = this.connectionsToHostsMap.get(c); + if(o != null){ + return o.toString(); + } + } + return null; + } + + public synchronized long getCurrentTransactionDuration(){ + + if (this.inTransaction && this.transactionStartTime > 0) { + return getLocalTimeBestResolution() - this.transactionStartTime; + } + + return 0; + } + + protected void syncSessionState(Connection initial, Connection target) + throws SQLException { + if (initial == null || target == null) { + return; + } + target.setAutoCommit(initial.getAutoCommit()); + target.setCatalog(initial.getCatalog()); + target.setTransactionIsolation(initial.getTransactionIsolation()); + target.setReadOnly(initial.isReadOnly()); + target.setSessionMaxRows(initial.getSessionMaxRows()); + } } \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/LocalizedErrorMessages.properties =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/LocalizedErrorMessages.properties,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/LocalizedErrorMessages.properties 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/LocalizedErrorMessages.properties 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -37,7 +37,8 @@ Statement.61=Can not issue empty query. Statement.63=Statement not closed explicitly. You should call close() on created Statement.64=Statement instances from your code to be more efficient. - +Statement.GeneratedKeysNotRequested=Generated keys not requested. You need to specify Statement.RETURN_GENERATED_KEYS to Statement.executeUpdate() or Connection.prepareStatement(). +Statement.ConnectionKilledDueToTimeout=Connection closed to due to statement timeout being reached and "queryTimeoutKillsConnection" being set to "true". UpdatableResultSet.1=Can not call deleteRow() when on insert row. UpdatableResultSet.2=Can not call deleteRow() on empty result set. UpdatableResultSet.3=Before start of result set. Can not call deleteRow(). @@ -51,6 +52,7 @@ UpdatableResultSet.34=Updatable result set created, but never updated. You should only create updatable result sets when you want to update/insert/delete values using the updateRow(), deleteRow() and insertRow() methods. UpdatableResultSet.39=Unsupported character encoding ''{0}''. UpdatableResultSet.43=Can not create updatable result sets when there is no currently selected database and MySQL server version < 4.1. +UpdatableResultSet.44=Can not call updateRow() when on insert row. # # Possible re-names @@ -60,7 +62,6 @@ ResultSet.Illegal_value_for_fetch_direction_64=Illegal value for fetch direction ResultSet.Value_must_be_between_0_and_getMaxRows()_66=Value must be between 0 and getMaxRows() ResultSet.Query_generated_no_fields_for_ResultSet_99=Query generated no fields for ResultSet -ResultSet.Cannot_absolute_position_to_row_0_110=Cannot absolute position to row 0 ResultSet.Operation_not_allowed_after_ResultSet_closed_144=Operation not allowed after ResultSet closed ResultSet.Before_start_of_result_set_146=Before start of result set ResultSet.After_end_of_result_set_148=After end of result set @@ -108,7 +109,7 @@ ResultSet.Possible_incomplete_traversal_of_result_set=Possible incomplete traversal of result set. Cursor was left on row {0} of {1} rows when it was closed.\n\nYou should consider re-formulating your query to return only the rows you are interested in using. ResultSet.The_following_columns_were_never_referenced=The following columns were part of the SELECT statement for this result set, but were never referenced: ResultSet.Too_Large_Result_Set=Result set size of {0} rows is larger than \"resultSetSizeThreshold\" of {1} rows. Application may be requesting more data than it is using. Consider reformulating the query. -ResultSet.CostlyConversion=ResultSet type conversion via parsing detected when calling {0} for column {1} (column named '{2}') in table '{3}'{4}\n\nJava class of column type is '{5}', MySQL field type is '{6}'.\n\nTypes that could be converted directly without parsing are:\n{7} +ResultSet.CostlyConversion=ResultSet type conversion via parsing detected when calling {0} for column {1} (column named ''{2}'') in table ''{3}''{4}\n\nJava class of column type is ''{5}'', MySQL field type is ''{6}''.\n\nTypes that could be converted directly without parsing are:\n{7} ResultSet.CostlyConversionCreatedFromQuery= created from query:\n\n ResultSet.Value____173=Value \' @@ -136,7 +137,6 @@ ResultSet.Cannot_convert_value____283=Cannot convert value \' ResultSet.___from_column__284=\' from column ResultSet._)_to_TIMESTAMP._286=\ ) to TIMESTAMP. - CallableStatement.2=Parameter name can not be NULL or zero-length. CallableStatement.3=No parameter named ' CallableStatement.4=' @@ -156,29 +156,24 @@ CallableStatement.16=empty. CallableStatement.21=Parameter CallableStatement.22=\ is not registered as an output parameter - CommunicationsException.2=\ is longer than the server configured value of CommunicationsException.3='wait_timeout' CommunicationsException.4='interactive_timeout' CommunicationsException.5=may or may not be greater than the server-side timeout CommunicationsException.6=(the driver was unable to determine the value of either the CommunicationsException.7='wait_timeout' or 'interactive_timeout' configuration values from CommunicationsException.8=the server. -CommunicationsException.9=The last communications with the server was -CommunicationsException.10=\ seconds ago, which CommunicationsException.11=. You should consider either expiring and/or testing connection validity CommunicationsException.12=before use in your application, increasing the server configured values for client timeouts, CommunicationsException.13=or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. -CommunicationsException.14=The driver was unable to create a connection due to -CommunicationsException.15=an inability to establish the client portion of a socket.\n\n -CommunicationsException.16=This is usually caused by a limit on the number of sockets imposed by -CommunicationsException.17=the operating system. This limit is usually configurable. \n\n -CommunicationsException.18=For Unix-based platforms, see the manual page for the 'ulimit' command. Kernel or system reconfiguration may also be required. -CommunicationsException.19=\n\nFor Windows-based platforms, see Microsoft Knowledge Base Article 196271 (Q196271). -CommunicationsException.19a=The configuration parameter \"localSocketAddress\" has been set to a network interface not available for use by the JVM. +CommunicationsException.TooManyClientConnections=The driver was unable to create a connection due to an inability to establish the client portion of a socket.\n\nThis is usually caused by a limit on the number of sockets imposed by the operating system. This limit is usually configurable. \n\nFor Unix-based platforms, see the manual page for the 'ulimit' command. Kernel or system reconfiguration may also be required.\n\nFor Windows-based platforms, see Microsoft Knowledge Base Article 196271 (Q196271). +CommunicationsException.LocalSocketAddressNotAvailable=The configuration parameter \"localSocketAddress\" has been set to a network interface not available for use by the JVM. CommunicationsException.20=Communications link failure CommunicationsException.21=\ due to underlying exception: CommunicationsException.ClientWasStreaming=Application was streaming results when the connection failed. Consider raising value of 'net_write_timeout' on the server. +CommunicationsException.ServerPacketTimingInfoNoRecv=The last packet sent successfully to the server was {0} milliseconds ago. The driver has not received any packets from the server. +CommunicationsException.ServerPacketTimingInfo=The last packet successfully received from the server was {0} milliseconds ago. The last packet sent successfully to the server was {1} milliseconds ago. +CommunicationsException.TooManyAuthenticationPluginNegotiations=Too many authentication plugin negotiations. NonRegisteringDriver.3=Hostname of MySQL Server NonRegisteringDriver.7=Port number of MySQL Server NonRegisteringDriver.13=Username to authenticate as @@ -225,9 +220,13 @@ ChannelBuffer.1=' Field.12=Unsupported character encoding ' Field.13=' + Blob.0=indexToWriteAt must be >= 1 Blob.1=IO Error while writing bytes to blob Blob.2=Position 'pos' can not be < 1 +Blob.invalidStreamLength=Requested stream length of {2} is out of range, given blob length of {0} and starting position of {1}. +Blob.invalidStreamPos=Position 'pos' can not be < 1 or > blob length. + StringUtils.0=Unsupported character encoding ' StringUtils.1='. StringUtils.5=Unsupported character encoding ' @@ -287,7 +286,8 @@ MysqlIO.22=\ any active result sets before attempting more queries. MysqlIO.23=Can not use streaming results with multiple result statements MysqlIO.25=\ ... (truncated) -MysqlIO.SlowQuery=Slow query (exceeded {0} {1}, duration: {2} {1}): +MysqlIO.SlowQuery=Slow query (exceeded {0} {1}, duration: {2} {1}): +MysqlIO.ServerSlowQuery=The server processing the query has indicated that the query was marked "slow". Nanoseconds=ns Milliseconds=ms MysqlIO.28=Not issuing EXPLAIN for query of size > @@ -347,6 +347,7 @@ MysqlIO.99=\ of MysqlIO.100=\ in binary-encoded result set. MysqlIO.102=, underlying cause: +MysqlIO.103=Unexpected packet length MysqlIO.EOF=Can not read response from server. Expected to read {0} bytes, read {1} bytes before connection was unexpectedly lost. MysqlIO.NoInnoDBStatusFound=No InnoDB status output returned by server. MysqlIO.InnoDBStatusFailed=Couldn't retrieve InnoDB status due to underlying exception: @@ -402,9 +403,9 @@ ServerPreparedStatement.25=Error while reading binary stream: ByteArrayBuffer.0=ByteArrayBuffer has no NIO buffers ByteArrayBuffer.1=Unsupported character encoding ' +ByteArrayBuffer.2=Buffer length is less then "expectedLength" value. AssertionFailedException.0=ASSERT FAILS: Exception AssertionFailedException.1=\ that should not be thrown, was thrown - NotUpdatable.0=Result Set not updatable. NotUpdatable.1=This result set must come from a statement NotUpdatable.2=that was created with a result set type of ResultSet.CONCUR_UPDATABLE, @@ -420,5 +421,272 @@ NotUpdatableReason.6=Result Set not updatable (references unknown primary key {0}). NotUpdatableReason.7=Result Set not updatable (does not reference all primary keys). -InvalidLoadBalanceStrategy=Invalid load balancing strategy '{0}'. -Connection.Connection.BadValueInServerVariables=Invalid value '{1}' for server variable named '{0}', falling back to sane default of '{2}'. +JDBC4Connection.ClientInfoNotImplemented=Configured clientInfoProvider class ''{0}'' does not implement com.mysql.jdbc.JDBC4ClientInfoProvider. + +InvalidLoadBalanceStrategy=Invalid load balancing strategy ''{0}''. +Connection.BadValueInServerVariables=Invalid value ''{1}'' for server variable named ''{0}'', falling back to sane default of ''{2}''. +LoadBalancingConnectionProxy.badValueForRetriesAllDown=Bad value ''{0}'' for property "retriesAllDown". +LoadBalancingConnectionProxy.badValueForLoadBalanceBlacklistTimeout=Bad value ''{0}'' for property "loadBalanceBlacklistTimeout". +LoadBalancingConnectionProxy.badValueForLoadBalanceEnableJMX=Bad value ''{0}'' for property "loadBalanceEnableJMX". +LoadBalancingConnectionProxy.badValueForLoadBalanceAutoCommitStatementThreshold=Invalid numeric value ''{0}'' for property "loadBalanceAutoCommitStatementThreshold". +LoadBalancingConnectionProxy.badValueForLoadBalanceAutoCommitStatementRegex=Bad value ''{0}'' for property "loadBalanceAutoCommitStatementRegex". + +ReplicationConnection.badValueForAllowMasterDownConnections=Bad value ''{0}'' for property "allowMasterDownConnections". + + +Connection.UnableToConnect=Could not create connection to database server. +Connection.UnableToConnectWithRetries=Could not create connection to database server. \ +Attempted reconnect {0} times. Giving up. +Connection.UnexpectedException=Unexpected exception encountered during query. +Connection.UnhandledExceptionDuringShutdown=Unexpected exception during server shutdown. + +Sha256PasswordPlugin.0=Unable to read public key {0} +Sha256PasswordPlugin.1=Unable to close public key file +Sha256PasswordPlugin.2=Public Key Retrieval is not allowed + +# +# ConnectionProperty Categories +# + +ConnectionProperties.categoryConnectionAuthentication=Connection/Authentication +ConnectionProperties.categoryNetworking=Networking +ConnectionProperties.categoryDebuggingProfiling=Debugging/Profiling +ConnectionProperties.categorryHA=High Availability and Clustering +ConnectionProperties.categoryMisc=Miscellaneous +ConnectionProperties.categoryPerformance=Performance Extensions +ConnectionProperties.categorySecurity=Security + +# +# ConnectionProperty Descriptions +# + +ConnectionProperties.loadDataLocal=Should the driver allow use of 'LOAD DATA LOCAL INFILE...' (defaults to 'true'). +ConnectionProperties.allowMasterDownConnections=Should replication-aware driver establish connections to slaves when connection to master servers cannot be established at initial connection? Defaults to 'false', which will cause SQLException when configured master hosts are all unavailable when establishing a new replication-aware Connection. +ConnectionProperties.allowMultiQueries=Allow the use of ';' to delimit multiple queries during one statement (true/false), defaults to 'false', and does not affect the addBatch() and executeBatch() methods, which instead rely on rewriteBatchStatements. +ConnectionProperties.allowNANandINF=Should the driver allow NaN or +/- INF values in PreparedStatement.setDouble()? +ConnectionProperties.allowUrlInLoadLocal=Should the driver allow URLs in 'LOAD DATA LOCAL INFILE' statements? +ConnectionProperties.alwaysSendSetIsolation=Should the driver always communicate with the database when Connection.setTransactionIsolation() is called? If set to false, the driver will only communicate with the database when the requested transaction isolation is different than the whichever is newer, the last value that was set via Connection.setTransactionIsolation(), or the value that was read from the server when the connection was established. Note that useLocalSessionState=true will force the same behavior as alwaysSendSetIsolation=false, regardless of how alwaysSendSetIsolation is set. +ConnectionProperties.autoClosePstmtStreams=Should the driver automatically call .close() on streams/readers passed as arguments via set*() methods? +ConnectionProperties.autoDeserialize=Should the driver automatically detect and de-serialize objects stored in BLOB fields? +ConnectionProperties.autoGenerateTestcaseScript=Should the driver dump the SQL it is executing, including server-side prepared statements to STDERR? +ConnectionProperties.autoReconnect=Should the driver try to re-establish stale and/or dead connections? If enabled the driver will throw an exception for a queries issued on a stale or dead connection, which belong to the current transaction, but will attempt reconnect before the next query issued on the connection in a new transaction. The use of this feature is not recommended, because it has side effects related to session state and data consistency when applications don't handle SQLExceptions properly, and is only designed to be used when you are unable to configure your application to handle SQLExceptions resulting from dead and stale connections properly. Alternatively, as a last option, investigate setting the MySQL server variable "wait_timeout" to a high value, rather than the default of 8 hours. +ConnectionProperties.autoReconnectForPools=Use a reconnection strategy appropriate for connection pools (defaults to 'false') +ConnectionProperties.autoSlowLog=Instead of using slowQueryThreshold* to determine if a query is slow enough to be logged, maintain statistics that allow the driver to determine queries that are outside the 99th percentile? +ConnectionProperties.blobsAreStrings=Should the driver always treat BLOBs as Strings - specifically to work around dubious metadata returned by the server for GROUP BY clauses? +ConnectionProperties.functionsNeverReturnBlobs=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? +ConnectionProperties.blobSendChunkSize=Chunk size to use when sending BLOB/CLOBs via ServerPreparedStatements. Note that this value cannot exceed the value of "maxAllowedPacket" and, if that is the case, then this value will be corrected automatically. +ConnectionProperties.cacheCallableStatements=Should the driver cache the parsing stage of CallableStatements +ConnectionProperties.cachePrepStmts=Should the driver cache the parsing stage of PreparedStatements of client-side prepared statements, the "check" for suitability of server-side prepared and server-side prepared statements themselves? +ConnectionProperties.cacheRSMetadata=Should the driver cache ResultSetMetaData for Statements and PreparedStatements? (Req. JDK-1.4+, true/false, default 'false') +ConnectionProperties.cacheServerConfiguration=Should the driver cache the results of 'SHOW VARIABLES' and 'SHOW COLLATION' on a per-URL basis? +ConnectionProperties.callableStmtCacheSize=If 'cacheCallableStmts' is enabled, how many callable statements should be cached? +ConnectionProperties.capitalizeTypeNames=Capitalize type names in DatabaseMetaData? (usually only useful when using WebObjects, true/false, defaults to 'false') +ConnectionProperties.characterEncoding=If 'useUnicode' is set to true, what character encoding should the driver use when dealing with strings? (defaults is to 'autodetect') +ConnectionProperties.characterSetResults=Character set to tell the server to return results as. +ConnectionProperties.clientInfoProvider=The name of a class that implements the com.mysql.jdbc.JDBC4ClientInfoProvider interface in order to support JDBC-4.0's Connection.get/setClientInfo() methods +ConnectionProperties.clobberStreamingResults=This will cause a 'streaming' ResultSet to be automatically closed, and any outstanding data still streaming from the server to be discarded if another query is executed before all the data has been read from the server. +ConnectionProperties.clobCharacterEncoding=The character encoding to use for sending and retrieving TEXT, MEDIUMTEXT and LONGTEXT values instead of the configured connection characterEncoding +ConnectionProperties.compensateOnDuplicateKeyUpdateCounts=Should the driver compensate for the update counts of "ON DUPLICATE KEY" INSERT statements (2 = 1, 0 = 1) when using prepared statements? +ConnectionProperties.connectionCollation=If set, tells the server to use this collation via 'set collation_connection' +ConnectionProperties.connectionLifecycleInterceptors=A comma-delimited list of classes that implement "com.mysql.jdbc.ConnectionLifecycleInterceptor" that should notified of connection lifecycle events (creation, destruction, commit, rollback, setCatalog and setAutoCommit) and potentially alter the execution of these commands. ConnectionLifecycleInterceptors are "stackable", more than one interceptor may be specified via the configuration property as a comma-delimited list, with the interceptors executed in order from left to right. +ConnectionProperties.connectTimeout=Timeout for socket connect (in milliseconds), with 0 being no timeout. Only works on JDK-1.4 or newer. Defaults to '0'. +ConnectionProperties.continueBatchOnError=Should the driver continue processing batch commands if one statement fails. The JDBC spec allows either way (defaults to 'true'). +ConnectionProperties.createDatabaseIfNotExist=Creates the database given in the URL if it doesn't yet exist. Assumes the configured user has permissions to create databases. +ConnectionProperties.defaultFetchSize=The driver will call setFetchSize(n) with this value on all newly-created Statements +ConnectionProperties.useServerPrepStmts=Use server-side prepared statements if the server supports them? +ConnectionProperties.dontTrackOpenResources=The JDBC specification requires the driver to automatically track and close resources, however if your application doesn't do a good job of explicitly calling close() on statements or result sets, this can cause memory leakage. Setting this property to true relaxes this constraint, and can be more memory efficient for some applications. Also the automatic closing of the Statement and current ResultSet in Statement.closeOnCompletion() and Statement.getMoreResults ([Statement.CLOSE_CURRENT_RESULT | Statement.CLOSE_ALL_RESULTS]), respectively, ceases to happen. This property automatically sets holdResultsOpenOverStatementClose=true. +ConnectionProperties.dumpQueriesOnException=Should the driver dump the contents of the query sent to the server in the message for SQLExceptions? +ConnectionProperties.dynamicCalendars=Should the driver retrieve the default calendar when required, or cache it per connection/session? +ConnectionProperties.eliseSetAutoCommit=If using MySQL-4.1 or newer, should the driver only issue 'set autocommit=n' queries when the server's state doesn't match the requested state by Connection.setAutoCommit(boolean)? +ConnectionProperties.emptyStringsConvertToZero=Should the driver allow conversions from empty string fields to numeric values of '0'? +ConnectionProperties.emulateLocators=Should the driver emulate java.sql.Blobs with locators? With this feature enabled, the driver will delay loading the actual Blob data until the one of the retrieval methods (getInputStream(), getBytes(), and so forth) on the blob data stream has been accessed. For this to work, you must use a column alias with the value of the column to the actual name of the Blob. The feature also has the following restrictions: The SELECT that created the result set must reference only one table, the table must have a primary key; the SELECT must alias the original blob column name, specified as a string, to an alternate name; the SELECT must cover all columns that make up the primary key. +ConnectionProperties.emulateUnsupportedPstmts=Should the driver detect prepared statements that are not supported by the server, and replace them with client-side emulated versions? +ConnectionProperties.enablePacketDebug=When enabled, a ring-buffer of 'packetDebugBufferSize' packets will be kept, and dumped when exceptions are thrown in key areas in the driver's code +ConnectionProperties.enableQueryTimeouts=When enabled, query timeouts set via Statement.setQueryTimeout() use a shared java.util.Timer instance for scheduling. Even if the timeout doesn't expire before the query is processed, there will be memory used by the TimerTask for the given timeout which won't be reclaimed until the time the timeout would have expired if it hadn't been cancelled by the driver. High-load environments might want to consider disabling this functionality. +ConnectionProperties.explainSlowQueries=If 'logSlowQueries' is enabled, should the driver automatically issue an 'EXPLAIN' on the server and send the results to the configured log at a WARN level? +ConnectionProperties.failoverReadOnly=When failing over in autoReconnect mode, should the connection be set to 'read-only'? +ConnectionProperties.gatherPerfMetrics=Should the driver gather performance metrics, and report them via the configured logger every 'reportMetricsIntervalMillis' milliseconds? +ConnectionProperties.generateSimpleParameterMetadata=Should the driver generate simplified parameter metadata for PreparedStatements when no metadata is available either because the server couldn't support preparing the statement, or server-side prepared statements are disabled? +ConnectionProperties.holdRSOpenOverStmtClose=Should the driver close result sets on Statement.close() as required by the JDBC specification? +ConnectionProperties.ignoreNonTxTables=Ignore non-transactional table warning for rollback? (defaults to 'false'). +ConnectionProperties.includeInnodbStatusInDeadlockExceptions=Include the output of "SHOW ENGINE INNODB STATUS" in exception messages when deadlock exceptions are detected? +ConnectionProperties.includeThreadDumpInDeadlockExceptions=Include a current Java thread dump in exception messages when deadlock exceptions are detected? +ConnectionProperties.includeThreadNamesAsStatementComment=Include the name of the current thread as a comment visible in "SHOW PROCESSLIST", or in Innodb deadlock dumps, useful in correlation with "includeInnodbStatusInDeadlockExceptions=true" and "includeThreadDumpInDeadlockExceptions=true". +ConnectionProperties.initialTimeout=If autoReconnect is enabled, the initial time to wait between re-connect attempts (in seconds, defaults to '2'). +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.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.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.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. +ConnectionProperties.locatorFetchBufferSize=If 'emulateLocators' is configured to 'true', what size buffer should be used when fetching BLOB data for getBinaryInputStream? +ConnectionProperties.logger=The name of a class that implements \"{0}\" that will be used to log messages to. (default is \"{1}\", which logs to STDERR) +ConnectionProperties.logSlowQueries=Should queries that take longer than 'slowQueryThresholdMillis' be logged? +ConnectionProperties.logXaCommands=Should the driver log XA commands sent by MysqlXaConnection to the server, at the DEBUG level of logging? +ConnectionProperties.maintainTimeStats=Should the driver maintain various internal timers to enable idle time calculations as well as more verbose error messages when the connection to the server fails? Setting this property to false removes at least two calls to System.getCurrentTimeMillis() per query. +ConnectionProperties.maxQuerySizeToLog=Controls the maximum length/size of a query that will get logged when profiling or tracing +ConnectionProperties.maxReconnects=Maximum number of reconnects to attempt if autoReconnect is true, default is '3'. +ConnectionProperties.maxRows=The maximum number of rows to return (0, the default means return all rows). +ConnectionProperties.allVersions=all versions +ConnectionProperties.metadataCacheSize=The number of queries to cache ResultSetMetadata for if cacheResultSetMetaData is set to 'true' (default 50) +ConnectionProperties.netTimeoutForStreamingResults=What value should the driver automatically set the server setting 'net_write_timeout' to when the streaming result sets feature is in use? (value has unit of seconds, the value '0' means the driver will not try and adjust this value) +ConnectionProperties.noAccessToProcedureBodies=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 INOUT VARCHARs) instead of throwing an exception? +ConnectionProperties.noDatetimeStringSync=Don't ensure that ResultSet.getDatetimeType().toString().equals(ResultSet.getString()) +ConnectionProperties.noTzConversionForTimeType=Don't convert TIME values using the server timezone if 'useTimezone'='true' +ConnectionProperties.nullCatalogMeansCurrent=When DatabaseMetadataMethods ask for a 'catalog' parameter, does the value null mean use the current catalog? (this is not JDBC-compliant, but follows legacy behavior from earlier versions of the driver) +ConnectionProperties.nullNamePatternMatchesAll=Should DatabaseMetaData methods that accept *pattern parameters treat null the same as '%' (this is not JDBC-compliant, however older versions of the driver accepted this departure from the specification) +ConnectionProperties.packetDebugBufferSize=The maximum number of packets to retain when 'enablePacketDebug' is true +ConnectionProperties.padCharsWithSpace=If a result set column has the CHAR type and the value does not fill the amount of characters specified in the DDL for the column, should the driver pad the remaining characters with space (for ANSI compliance)? +ConnectionProperties.paranoid=Take measures to prevent exposure sensitive information in error messages and clear data structures holding sensitive data when possible? (defaults to 'false') +ConnectionProperties.pedantic=Follow the JDBC spec to the letter. +ConnectionProperties.pinGlobalTxToPhysicalConnection=When using XAConnections, should the driver ensure that operations on a given XID are always routed to the same physical connection? This allows the XAConnection to support "XA START ... JOIN" after "XA END" has been called +ConnectionProperties.populateInsertRowWithDefaultValues=When using ResultSets that are CONCUR_UPDATABLE, should the driver pre-populate the "insert" row with default values from the DDL for the table used in the query so those values are immediately available for ResultSet accessors? This functionality requires a call to the database for metadata each time a result set of this type is created. If disabled (the default), the default values will be populated by the an internal call to refreshRow() which pulls back default values and/or values changed by triggers. +ConnectionProperties.prepStmtCacheSize=If prepared statement caching is enabled, how many prepared statements should be cached? +ConnectionProperties.prepStmtCacheSqlLimit=If prepared statement caching is enabled, what's the largest SQL the driver will cache the parsing for? +ConnectionProperties.processEscapeCodesForPrepStmts=Should the driver process escape codes in queries that are prepared? +ConnectionProperties.profilerEventHandler=Name of a class that implements the interface com.mysql.jdbc.profiler.ProfilerEventHandler that will be used to handle profiling/tracing events. +ConnectionProperties.profileSqlDeprecated=Deprecated, use 'profileSQL' instead. Trace queries and their execution/fetch times on STDERR (true/false) defaults to 'false' +ConnectionProperties.profileSQL=Trace queries and their execution/fetch times to the configured logger (true/false) defaults to 'false' +ConnectionProperties.connectionPropertiesTransform=An implementation of com.mysql.jdbc.ConnectionPropertiesTransform that the driver will use to modify URL properties passed to the driver before attempting a connection +ConnectionProperties.queriesBeforeRetryMaster=Number of queries to issue before falling back to master when failed over (when using multi-host failover). Whichever condition is met first, 'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an attempt to be made to reconnect to the master. Defaults to 50. +ConnectionProperties.reconnectAtTxEnd=If autoReconnect is set to true, should the driver attempt reconnections at the end of every transaction? +ConnectionProperties.relaxAutoCommit=If the version of MySQL the driver connects to does not support transactions, still allow calls to commit(), rollback() and setAutoCommit() (true/false, defaults to 'false')? +ConnectionProperties.reportMetricsIntervalMillis=If 'gatherPerfMetrics' is enabled, how often should they be logged (in ms)? +ConnectionProperties.requireSSL=Require server support of SSL connection if useSSL=true? (defaults to 'false'). +ConnectionProperties.resourceId=A globally unique name that identifies the resource that this datasource or connection is connected to, used for XAResource.isSameRM() when the driver can't determine this value based on hostnames used in the URL +ConnectionProperties.resultSetSizeThreshold=If the usage advisor is enabled, how many rows should a result set contain before the driver warns that it is suspiciously large? +ConnectionProperties.retainStatementAfterResultSetClose=Should the driver retain the Statement reference in a ResultSet after ResultSet.close() has been called. This is not JDBC-compliant after JDBC-4.0. +ConnectionProperties.retriesAllDown=When using loadbalancing, the number of times the driver should cycle through available hosts, attempting to connect. Between cycles, the driver will pause for 250ms if no servers are available. +ConnectionProperties.rewriteBatchedStatements=Should the driver use multiqueries (irregardless of the setting of "allowMultiQueries") as well as rewriting of prepared statements for INSERT into multi-value inserts when executeBatch() is called? Notice that this has the potential for SQL injection if using plain java.sql.Statements and your code doesn't sanitize input correctly. Notice that for prepared statements, server-side prepared statements can not currently take advantage of this rewrite option, and that if you don't specify stream lengths when using PreparedStatement.set*Stream(), the driver won't be able to determine the optimum number of parameters per batch and you might receive an error from the driver that the resultant packet is too large. Statement.getGeneratedKeys() for these rewritten statements only works when the entire batch includes INSERT statements. Please be aware using rewriteBatchedStatements=true with INSERT .. ON DUPLICATE KEY UPDATE that for rewritten statement server returns only one value as sum of all affected (or found) rows in batch and it isn't possible to map it correctly to initial statements; in this case driver returns 0 as a result of each batch statement if total count was 0, and the Statement.SUCCESS_NO_INFO as a result of each batch statement if total count was > 0. +ConnectionProperties.rollbackOnPooledClose=Should the driver issue a rollback() when the logical connection in a pool is closed? +ConnectionProperties.roundRobinLoadBalance=When autoReconnect is enabled, and failoverReadonly is false, should we pick hosts to connect to on a round-robin basis? +ConnectionProperties.runningCTS13=Enables workarounds for bugs in Sun's JDBC compliance testsuite version 1.3 +ConnectionProperties.secondsBeforeRetryMaster=How long should the driver wait, when failed over, before attempting +ConnectionProperties.secondsBeforeRetryMaster.1=to reconnect to the master server? Whichever condition is met first, +ConnectionProperties.secondsBeforeRetryMaster.2='queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an +ConnectionProperties.secondsBeforeRetryMaster.3=attempt to be made to reconnect to the master. Time in seconds, defaults to 30 +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 timezone. Used when timezone from server doesn't map to Java timezone +ConnectionProperties.sessionVariables=A comma-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. +ConnectionProperties.socketTimeout=Timeout on network socket operations (0, the default means no timeout). +ConnectionProperties.statementInterceptors=A comma-delimited list of classes that implement "com.mysql.jdbc.StatementInterceptor" that should be placed "in between" query execution to influence the results. StatementInterceptors are "chainable", the results returned by the "current" interceptor will be passed on to the next in in the chain, from left-to-right order, as specified in this property. +ConnectionProperties.strictFloatingPoint=Used only in older versions of compliance test +ConnectionProperties.strictUpdates=Should the driver do strict checking (all primary keys selected) of updatable result sets (true, false, defaults to 'true')? +ConnectionProperties.overrideSupportsIEF=Should the driver return "true" for DatabaseMetaData.supportsIntegrityEnhancementFacility() even if the database doesn't support it to workaround applications that require this method to return "true" to signal support of foreign keys, even though the SQL specification states that this facility contains much more than just foreign key support (one such application being OpenOffice)? +ConnectionProperties.tcpNoDelay=If connecting using TCP/IP, should the driver set SO_TCP_NODELAY (disabling the Nagle Algorithm)? +ConnectionProperties.tcpKeepAlive=If connecting using TCP/IP, should the driver set SO_KEEPALIVE? +ConnectionProperties.tcpSoRcvBuf=If connecting using TCP/IP, should the driver set SO_RCV_BUF to the given value? The default value of '0', means use the platform default value for this property) +ConnectionProperties.tcpSoSndBuf=If connecting using TCP/IP, should the driver set SO_SND_BUF to the given value? The default value of '0', means use the platform default value for this property) +ConnectionProperties.tcpTrafficClass=If connecting using TCP/IP, should the driver set traffic class or type-of-service fields ?See the documentation for java.net.Socket.setTrafficClass() for more information. +ConnectionProperties.tinyInt1isBit=Should the driver treat the datatype TINYINT(1) as the BIT type (because the server silently converts BIT -> TINYINT(1) when creating tables)? +ConnectionProperties.traceProtocol=Should trace-level network protocol be logged? +ConnectionProperties.treatUtilDateAsTimestamp=Should the driver treat java.util.Date as a TIMESTAMP for the purposes of PreparedStatement.setObject()? +ConnectionProperties.transformedBitIsBoolean=If the driver converts TINYINT(1) to a different type, should it use BOOLEAN instead of BIT for future compatibility with MySQL-5.0, as MySQL-5.0 has a BIT type? +ConnectionProperties.useCompression=Use zlib compression when communicating with the server (true/false)? Defaults to 'false'. +ConnectionProperties.useConfigs=Load the comma-delimited list of configuration properties before parsing the URL or applying user-specified properties. These configurations are explained in the 'Configurations' of the documentation. +ConnectionProperties.useCursorFetch=If connected to MySQL > 5.0.2, and setFetchSize() > 0 on a statement, should that statement use cursor-based fetching to retrieve rows? +ConnectionProperties.useDynamicCharsetInfo=Should the driver use a per-connection cache of character set information queried from the server when necessary, or use a built-in static mapping that is more efficient, but isn't aware of custom character sets or character sets implemented after the release of the JDBC driver? +ConnectionProperties.useFastIntParsing=Use internal String->Integer conversion routines to avoid excessive object creation? +ConnectionProperties.useFastDateParsing=Use internal String->Date/Time/Timestamp conversion routines to avoid excessive object creation? +ConnectionProperties.useHostsInPrivileges=Add '@hostname' to users in DatabaseMetaData.getColumn/TablePrivileges() (true/false), defaults to 'true'. +ConnectionProperties.useInformationSchema=When connected to MySQL-5.0.7 or newer, should the driver use the INFORMATION_SCHEMA to derive information used by DatabaseMetaData? +ConnectionProperties.useJDBCCompliantTimezoneShift=Should the driver use JDBC-compliant rules when converting TIME/TIMESTAMP/DATETIME values' timezone information for those JDBC arguments which take a java.util.Calendar argument? (Notice that this option is exclusive of the "useTimezone=true" configuration option.) +ConnectionProperties.useLocalSessionState=Should the driver refer to the internal values of autocommit and transaction isolation that are set by Connection.setAutoCommit() and Connection.setTransactionIsolation() and transaction state as maintained by the protocol, rather than querying the database or blindly sending commands to the database for commit() or rollback() method calls? +ConnectionProperties.useLocalTransactionState=Should the driver use the in-transaction state provided by the MySQL protocol to determine if a commit() or rollback() should actually be sent to the database? +ConnectionProperties.useNanosForElapsedTime=For profiling/debugging functionality that measures elapsed time, should the driver try to use nanoseconds resolution if available (JDK >= 1.5)? +ConnectionProperties.useOldAliasMetadataBehavior=Should the driver use the legacy behavior for "AS" clauses on columns and tables, and only return aliases (if any) for ResultSetMetaData.getColumnName() or ResultSetMetaData.getTableName() rather than the original column/table name? In 5.0.x, the default value was true. +ConnectionProperties.useOldUtf8Behavior=Use the UTF-8 behavior the driver did when communicating with 4.0 and older servers +ConnectionProperties.useOnlyServerErrorMessages=Don't prepend 'standard' SQLState error messages to error messages returned by the server. +ConnectionProperties.useReadAheadInput=Use newer, optimized non-blocking, buffered input stream when reading from the server? +ConnectionProperties.useSqlStateCodes=Use SQL Standard state codes instead of 'legacy' X/Open/SQL state codes (true/false), default is 'true' +ConnectionProperties.useSSL=Use SSL when communicating with the server (true/false), defaults to 'false' +ConnectionProperties.useSSPSCompatibleTimezoneShift=If migrating from an environment that was using server-side prepared statements, and the configuration property "useJDBCCompliantTimeZoneShift" set to "true", use compatible behavior when not using server-side prepared statements when sending TIMESTAMP values to the MySQL server. +ConnectionProperties.useStreamLengthsInPrepStmts=Honor stream length parameter in PreparedStatement/ResultSet.setXXXStream() method calls (true/false, defaults to 'true')? +ConnectionProperties.useTimezone=Convert time/date types between client and server timezones (true/false, defaults to 'false')? +ConnectionProperties.ultraDevHack=Create PreparedStatements for prepareCall() when required, because UltraDev is broken and issues a prepareCall() for _all_ statements? (true/false, defaults to 'false') +ConnectionProperties.useUnbufferedInput=Don't use BufferedInputStream for reading data from the server +ConnectionProperties.useUnicode=Should the driver use Unicode character encodings when handling strings? Should only be used when the driver can't determine the character set mapping, or you are trying to 'force' the driver to use a character set that MySQL either doesn't natively support (such as UTF-8), true/false, defaults to 'true' +ConnectionProperties.useUsageAdvisor=Should the driver issue 'usage' warnings advising proper and efficient usage of JDBC and MySQL Connector/J to the log (true/false, defaults to 'false')? +ConnectionProperties.verifyServerCertificate=If "useSSL" is set to "true", should the driver verify the server's certificate? When using this feature, the keystore parameters should be specified by the "clientCertificateKeyStore*" properties, rather than system properties. +ConnectionProperties.yearIsDateType=Should the JDBC driver treat the MySQL type "YEAR" as a java.sql.Date, or as a SHORT? +ConnectionProperties.zeroDateTimeBehavior=What should happen when the driver encounters DATETIME values that are composed entirely of zeros (used by MySQL to represent invalid dates)? Valid values are \"{0}\", \"{1}\" and \"{2}\". +ConnectionProperties.useJvmCharsetConverters=Always use the character encoding routines built into the JVM, rather than using lookup tables for single-byte character sets? +ConnectionProperties.useGmtMillisForDatetimes=Convert between session timezone and GMT before creating Date and Timestamp instances (value of "false" is legacy behavior, "true" leads to more JDBC-compliant behavior. +ConnectionProperties.dumpMetadataOnColumnNotFound=Should the driver dump the field-level metadata of a result set into the exception message when ResultSet.findColumn() fails? +ConnectionProperties.clientCertificateKeyStoreUrl=URL to the client certificate KeyStore (if not specified, use defaults) +ConnectionProperties.trustCertificateKeyStoreUrl=URL to the trusted root certificate KeyStore (if not specified, use defaults) +ConnectionProperties.clientCertificateKeyStoreType=KeyStore type for client certificates (NULL or empty means use the default, which is "JKS". Standard keystore types supported by the JVM are "JKS" and "PKCS12", your environment may have more available depending on what security products are installed and available to the JVM. +ConnectionProperties.clientCertificateKeyStorePassword=Password for the client certificates KeyStore +ConnectionProperties.trustCertificateKeyStoreType=KeyStore type for trusted root certificates (NULL or empty means use the default, which is "JKS". Standard keystore types supported by the JVM are "JKS" and "PKCS12", your environment may have more available depending on what security products are installed and available to the JVM. +ConnectionProperties.trustCertificateKeyStorePassword=Password for the trusted root certificates KeyStore +ConnectionProperties.serverRSAPublicKeyFile=File path to the server RSA public key file for sha256_password authentication. If not specified, the public key will be retrieved from the server. +ConnectionProperties.allowPublicKeyRetrieval=Allows special handshake roundtrip to get server RSA public key directly from server. +ConnectionProperties.Username=The user to connect as +ConnectionProperties.Password=The password to use when connecting +ConnectionProperties.useBlobToStoreUTF8OutsideBMP=Tells the driver to treat [MEDIUM/LONG]BLOB columns as [LONG]VARCHAR columns holding text encoded in UTF-8 that has characters outside the BMP (4-byte encodings), which MySQL server can't handle natively. +ConnectionProperties.utf8OutsideBmpExcludedColumnNamePattern=When "useBlobToStoreUTF8OutsideBMP" is set to "true", column names matching the given regex will still be treated as BLOBs unless they match the regex specified for "utf8OutsideBmpIncludedColumnNamePattern". The regex must follow the patterns used for the java.util.regex package. +ConnectionProperties.utf8OutsideBmpIncludedColumnNamePattern=Used to specify exclusion rules to "utf8OutsideBmpExcludedColumnNamePattern". The regex must follow the patterns used for the java.util.regex package. +ConnectionProperties.useLegacyDatetimeCode=Use code for DATE/TIME/DATETIME/TIMESTAMP handling in result sets and statements that consistently handles timezone conversions from client to server and back again, or use the legacy code for these datatypes that has been in the driver for backwards-compatibility? +ConnectionProperties.useColumnNamesInFindColumn=Prior to JDBC-4.0, the JDBC specification had a bug related to what could be given as a "column name" to ResultSet methods like findColumn(), or getters that took a String property. JDBC-4.0 clarified "column name" to mean the label, as given in an "AS" clause and returned by ResultSetMetaData.getColumnLabel(), and if no AS clause, the column name. Setting this property to "true" will give behavior that is congruent to JDBC-3.0 and earlier versions of the JDBC specification, but which because of the specification bug could give unexpected results. This property is preferred over "useOldAliasMetadataBehavior" unless you need the specific behavior that it provides with respect to ResultSetMetadata. +ConnectionProperties.useAffectedRows=Don't set the CLIENT_FOUND_ROWS flag when connecting to the server (not JDBC-compliant, will break most applications that rely on "found" rows vs. "affected rows" for DML statements), but does cause "correct" update counts from "INSERT ... ON DUPLICATE KEY UPDATE" statements to be returned by the server. +ConnectionProperties.passwordCharacterEncoding=What character encoding is used for passwords? Leaving this set to the default value (null), uses the platform character set, which works for ISO8859_1 (i.e. "latin1") passwords. For passwords in other character encodings, the encoding will have to be specified with this property, as it's not possible for the driver to auto-detect this. +ConnectionProperties.exceptionInterceptors=Comma-delimited list of classes that implement com.mysql.jdbc.ExceptionInterceptor. These classes will be instantiated one per Connection instance, and all SQLExceptions thrown by the driver will be allowed to be intercepted by these interceptors, in a chained fashion, with the first class listed as the head of the chain. +ConnectionProperties.maxAllowedPacket=Maximum allowed packet size to send to server. If not set, the value of system variable 'max_allowed_packet' will be used to initialize this upon connecting. This value will not take effect if set larger than the value of 'max_allowed_packet'. Also, due to an internal dependency with the property "blobSendChunkSize", this setting has a minimum value of "8203" if "useServerPrepStmts" is set to "true". +ConnectionProperties.queryTimeoutKillsConnection=If the timeout given in Statement.setQueryTimeout() expires, should the driver forcibly abort the Connection instead of attempting to abort the query? +ConnectionProperties.authenticationPlugins=Comma-delimited list of classes that implement com.mysql.jdbc.AuthenticationPlugin and which will be used for authentication unless disabled by "disabledAuthenticationPlugins" property. +ConnectionProperties.disabledAuthenticationPlugins=Comma-delimited list of classes implementing com.mysql.jdbc.AuthenticationPlugin or mechanisms, i.e. "mysql_native_password". The authentication plugins or mechanisms listed will not be used for authentication which will fail if it requires one of them. It is an error to disable the default authentication plugin (either the one named by "defaultAuthenticationPlugin" property or the hard-coded one if "defaultAuthenticationPlugin" property is not set). +ConnectionProperties.defaultAuthenticationPlugin=Name of a class implementing com.mysql.jdbc.AuthenticationPlugin which will be used as the default authentication plugin (see below). It is an error to use a class which is not listed in "authenticationPlugins" nor it is one of the built-in plugins. It is an error to set as default a plugin which was disabled with "disabledAuthenticationPlugins" property. It is an error to set this value to null or the empty string (i.e. there must be at least a valid default authentication plugin specified for the connection, meeting all constraints listed above). +ConnectionProperties.parseInfoCacheFactory=Name of a class implementing com.mysql.jdbc.CacheAdapterFactory, which will be used to create caches for the parsed representation of client-side prepared statements. +ConnectionProperties.serverConfigCacheFactory=Name of a class implementing com.mysql.jdbc.CacheAdapterFactory>, which will be used to create caches for MySQL server configuration values +ConnectionProperties.disconnectOnExpiredPasswords=If "disconnectOnExpiredPasswords" is set to "false" and password is expired then server enters "sandbox" mode and sends ERR(08001, ER_MUST_CHANGE_PASSWORD) for all commands that are not needed to set a new password until a new password is set. +ConnectionProperties.connectionAttributes=A comma-delimited list of user-defined key:value pairs (in addition to standard MySQL-defined key:value pairs) to be passed to MySQL Server for display as connection attributes in the PERFORMANCE_SCHEMA.SESSION_CONNECT_ATTRS table. Example usage: connectionAttributes=key1:value1,key2:value2 This functionality is available for use with MySQL Server version 5.6 or later only. Earlier versions of MySQL Server do not support connection attributes, causing this configuration option will be ignored. Setting connectionAttributes=none will cause connection attribute processing to be bypassed, for situations where Connection creation/initialization speed is critical. +ConnectionProperties.getProceduresReturnsFunctions=Pre-JDBC4 DatabaseMetaData API has only the getProcedures() and getProcedureColumns() methods, so they return metadata info for both stored procedures and functions. JDBC4 was extended with the getFunctions() and getFunctionColumns() methods and the expected behaviours of previous methods are not well defined. For JDBC4 and higher, default 'true' value of the option means that calls of DatabaseMetaData.getProcedures() and DatabaseMetaData.getProcedureColumns() return metadata for both procedures and functions as before, keeping backward compatibility. Setting this property to 'false' decouples Connector/J from its pre-JDBC4 behaviours for DatabaseMetaData.getProcedures() and DatabaseMetaData.getProcedureColumns(), forcing them to return metadata for procedures only. +ConnectionProperties.detectCustomCollations=Should the driver detect custom charsets/collations installed on server (true/false, defaults to 'false'). If this option set to 'true' driver gets actual charsets/collations from server each time connection establishes. This could slow down connection initialization significantly. +# +# Error Messages for Connection Properties +# + +ConnectionProperties.unableToInitDriverProperties=Unable to initialize driver properties due to +ConnectionProperties.unsupportedCharacterEncoding=Unsupported character encoding ''{0}''. +ConnectionProperties.errorNotExpected=Huh? +ConnectionProperties.InternalPropertiesFailure=Internal properties failure +ConnectionProperties.dynamicChangeIsNotAllowed=Dynamic change of ''{0}'' is not allowed. + +TimeUtil.TooGenericTimezoneId=The server timezone value ''{0}'' represents more than one timezone. You must \ +configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a \ +more specifc timezone value if you want to utilize timezone support. The timezones that ''{0}'' maps to are: {1}. + +Connection.exceededConnectionLifetime=Ping or validation failed because configured connection lifetime exceeded. +Connection.badLifecycleInterceptor=Unable to load connection lifecycle interceptor ''{0}''. +MysqlIo.BadStatementInterceptor=Unable to load statement interceptor ''{0}''. +Connection.BadExceptionInterceptor=Unable to load exception interceptor ''{0}''. +Connection.CantDetectLocalConnect=Unable to determine if hostname ''{0}'' is local to this box because of exception, assuming it's not. +Connection.NoMetadataOnSocketFactory=Configured socket factory does not implement SocketMetadata, can not determine whether server is locally-connected, assuming not" +Connection.BadAuthenticationPlugin=Unable to load authentication plugin ''{0}''. +Connection.BadDefaultAuthenticationPlugin=Bad value ''{0}'' for property "defaultAuthenticationPlugin". +Connection.DefaultAuthenticationPluginIsNotListed=defaultAuthenticationPlugin ''{0}'' is not listed in "authenticationPlugins" nor it is one of the built-in plugins. +Connection.BadDisabledAuthenticationPlugin=Can''t disable the default plugin, either remove ''{0}'' from the disabled authentication plugins list, or choose a different default authentication plugin. +Connection.AuthenticationPluginRequiresSSL=SSL connection required for plugin ''{0}''. Check if "useSSL" is set to "true". +Connection.UnexpectedAuthenticationApproval=Unexpected authentication approval: ''{0}'' plugin did not reported "done" state but server has approved connection. +Connection.CantFindCacheFactory=Can not find class ''{0}'' specified by the ''{1}'' configuration property. +Connection.CantLoadCacheFactory=Can not load the cache factory ''{0}'' specified by the ''{1}'' configuration property. +Connection.LoginTimeout=Connection attempt exceeded defined timeout. + +ReplicationConnection.badValueForReplicationEnableJMX=Bad value ''{0}'' for property "replicationEnableJMX". + + Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Messages.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Messages.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Messages.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Messages.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.text.MessageFormat; @@ -57,9 +56,12 @@ try { temp = ResourceBundle.getBundle(BUNDLE_NAME); } catch (Throwable t2) { - throw new RuntimeException( + RuntimeException rt = new RuntimeException( "Can't load resource bundle due to underlying exception " + t.toString()); + rt.initCause(t2); + + throw rt; } } finally { RESOURCE_BUNDLE = temp; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MiniAdmin.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/MiniAdmin.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MiniAdmin.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MiniAdmin.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,31 +1,29 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.SQLException; - import java.util.Properties; /** @@ -54,12 +52,12 @@ public MiniAdmin(java.sql.Connection conn) throws SQLException { if (conn == null) { throw SQLError.createSQLException( - Messages.getString("MiniAdmin.0"), SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$ + Messages.getString("MiniAdmin.0"), SQLError.SQL_STATE_GENERAL_ERROR, null); //$NON-NLS-1$ } if (!(conn instanceof Connection)) { throw SQLError.createSQLException(Messages.getString("MiniAdmin.1"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, ((com.mysql.jdbc.ConnectionImpl)conn).getExceptionInterceptor()); } this.conn = (Connection) conn; Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/MySQLConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDataTruncation.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDataTruncation.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDataTruncation.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDataTruncation.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.DataTruncation; @@ -37,8 +36,12 @@ */ public class MysqlDataTruncation extends DataTruncation { + static final long serialVersionUID = 3263928195256986226L; + private String message; + private int vendorErrorCode; + /** * Creates a new MysqlDataTruncation exception/warning. * @@ -56,19 +59,23 @@ * size actually used */ public MysqlDataTruncation(String message, int index, boolean parameter, - boolean read, int dataSize, int transferSize) { + boolean read, int dataSize, int transferSize, int vendorErrorCode) { super(index, parameter, read, dataSize, transferSize); this.message = message; + this.vendorErrorCode = vendorErrorCode; } + public int getErrorCode() { + return this.vendorErrorCode; + } + /* * (non-Javadoc) * * @see java.lang.Throwable#getMessage() */ public String getMessage() { - // TODO Auto-generated method stub return super.getMessage() + ": " + this.message; //$NON-NLS-1$ } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDefs.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDefs.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDefs.java 17 Aug 2012 14:57:08 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlDefs.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,31 +1,29 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.Types; -import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -37,7 +35,7 @@ * @author Mark Matthews * @version $Id$ */ -final class MysqlDefs { +public final class MysqlDefs { // ~ Static fields/initializers // --------------------------------------------- @@ -81,7 +79,7 @@ static final int FIELD_TYPE_BIT = 16; - static final int FIELD_TYPE_BLOB = 252; + public static final int FIELD_TYPE_BLOB = 252; static final int FIELD_TYPE_DATE = 10; @@ -485,85 +483,85 @@ } } - private static Map mysqlToJdbcTypesMap = new HashMap(); + private static Map mysqlToJdbcTypesMap = new HashMap(); static { - mysqlToJdbcTypesMap.put("BIT", new Integer( + mysqlToJdbcTypesMap.put("BIT", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_BIT))); - mysqlToJdbcTypesMap.put("TINYINT", new Integer( + mysqlToJdbcTypesMap.put("TINYINT", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_TINY))); - mysqlToJdbcTypesMap.put("SMALLINT", new Integer( + mysqlToJdbcTypesMap.put("SMALLINT", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_SHORT))); - mysqlToJdbcTypesMap.put("MEDIUMINT", new Integer( + mysqlToJdbcTypesMap.put("MEDIUMINT", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_INT24))); - mysqlToJdbcTypesMap.put("INT", new Integer( + mysqlToJdbcTypesMap.put("INT", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_LONG))); - mysqlToJdbcTypesMap.put("INTEGER", new Integer( + mysqlToJdbcTypesMap.put("INTEGER", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_LONG))); - mysqlToJdbcTypesMap.put("BIGINT", new Integer( + mysqlToJdbcTypesMap.put("BIGINT", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_LONGLONG))); - mysqlToJdbcTypesMap.put("INT24", new Integer( + mysqlToJdbcTypesMap.put("INT24", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_INT24))); - mysqlToJdbcTypesMap.put("REAL", new Integer( + mysqlToJdbcTypesMap.put("REAL", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_DOUBLE))); - mysqlToJdbcTypesMap.put("FLOAT", new Integer( + mysqlToJdbcTypesMap.put("FLOAT", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_FLOAT))); - mysqlToJdbcTypesMap.put("DECIMAL", new Integer( + mysqlToJdbcTypesMap.put("DECIMAL", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_DECIMAL))); - mysqlToJdbcTypesMap.put("NUMERIC", new Integer( + mysqlToJdbcTypesMap.put("NUMERIC", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_DECIMAL))); - mysqlToJdbcTypesMap.put("DOUBLE", new Integer( + mysqlToJdbcTypesMap.put("DOUBLE", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_DOUBLE))); - mysqlToJdbcTypesMap.put("CHAR", new Integer( + mysqlToJdbcTypesMap.put("CHAR", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_STRING))); - mysqlToJdbcTypesMap.put("VARCHAR", new Integer( + mysqlToJdbcTypesMap.put("VARCHAR", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_VAR_STRING))); - mysqlToJdbcTypesMap.put("DATE", new Integer( + mysqlToJdbcTypesMap.put("DATE", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_DATE))); - mysqlToJdbcTypesMap.put("TIME", new Integer( + mysqlToJdbcTypesMap.put("TIME", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_TIME))); - mysqlToJdbcTypesMap.put("YEAR", new Integer( + mysqlToJdbcTypesMap.put("YEAR", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_YEAR))); - mysqlToJdbcTypesMap.put("TIMESTAMP", new Integer( + mysqlToJdbcTypesMap.put("TIMESTAMP", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_TIMESTAMP))); - mysqlToJdbcTypesMap.put("DATETIME", new Integer( + mysqlToJdbcTypesMap.put("DATETIME", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_DATETIME))); - mysqlToJdbcTypesMap.put("TINYBLOB", new Integer(java.sql.Types.BINARY)); - mysqlToJdbcTypesMap.put("BLOB", new Integer( + mysqlToJdbcTypesMap.put("TINYBLOB", Integer.valueOf(java.sql.Types.BINARY)); + mysqlToJdbcTypesMap.put("BLOB", Integer.valueOf( java.sql.Types.LONGVARBINARY)); - mysqlToJdbcTypesMap.put("MEDIUMBLOB", new Integer( + mysqlToJdbcTypesMap.put("MEDIUMBLOB", Integer.valueOf( java.sql.Types.LONGVARBINARY)); - mysqlToJdbcTypesMap.put("LONGBLOB", new Integer( + mysqlToJdbcTypesMap.put("LONGBLOB", Integer.valueOf( java.sql.Types.LONGVARBINARY)); mysqlToJdbcTypesMap - .put("TINYTEXT", new Integer(java.sql.Types.VARCHAR)); + .put("TINYTEXT", Integer.valueOf(java.sql.Types.VARCHAR)); mysqlToJdbcTypesMap - .put("TEXT", new Integer(java.sql.Types.LONGVARCHAR)); - mysqlToJdbcTypesMap.put("MEDIUMTEXT", new Integer( + .put("TEXT", Integer.valueOf(java.sql.Types.LONGVARCHAR)); + mysqlToJdbcTypesMap.put("MEDIUMTEXT", Integer.valueOf( java.sql.Types.LONGVARCHAR)); - mysqlToJdbcTypesMap.put("LONGTEXT", new Integer( + mysqlToJdbcTypesMap.put("LONGTEXT", Integer.valueOf( java.sql.Types.LONGVARCHAR)); - mysqlToJdbcTypesMap.put("ENUM", new Integer( + mysqlToJdbcTypesMap.put("ENUM", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_ENUM))); - mysqlToJdbcTypesMap.put("SET", new Integer( + mysqlToJdbcTypesMap.put("SET", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_SET))); - mysqlToJdbcTypesMap.put("GEOMETRY", new Integer( + mysqlToJdbcTypesMap.put("GEOMETRY", Integer.valueOf( mysqlToJavaType(FIELD_TYPE_GEOMETRY))); } static final void appendJdbcTypeMappingQuery(StringBuffer buf, String mysqlTypeColumnName) { buf.append("CASE "); - Map typesMap = new HashMap(); + Map typesMap = new HashMap(); typesMap.putAll(mysqlToJdbcTypesMap); - typesMap.put("BINARY", new Integer(Types.BINARY)); - typesMap.put("VARBINARY", new Integer(Types.VARBINARY)); + typesMap.put("BINARY", Integer.valueOf(Types.BINARY)); + typesMap.put("VARBINARY", Integer.valueOf(Types.VARBINARY)); - Iterator mysqlTypes = typesMap.keySet().iterator(); + Iterator mysqlTypes = typesMap.keySet().iterator(); while (mysqlTypes.hasNext()) { - String mysqlTypeName = (String)mysqlTypes.next(); + String mysqlTypeName = mysqlTypes.next(); buf.append(" WHEN "); buf.append(mysqlTypeColumnName); buf.append("='"); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlErrorNumbers.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlErrorNumbers.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlErrorNumbers.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlErrorNumbers.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; /** @@ -30,611 +29,963 @@ * * @author Mark Matthews * - * @version $Id: MysqlErrorNumbers.java,v 1.1.2.1 2005/05/13 18:58:38 mmatthews - * Exp $ + * @see http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html + * */ public final class MysqlErrorNumbers { - public final static int ER_ABORTING_CONNECTION = 1152; + public final static int ER_ERROR_MESSAGES = 298; + public final static int ER_HASHCHK = 1000; //SQLSTATE: HY000 Message: hashchk + public final static int ER_NISAMCHK = 1001; //SQLSTATE: HY000 Message: isamchk + public final static int ER_NO = 1002; //SQLSTATE: HY000 Message: NO; Used in the construction of other messages. + public final static int ER_YES = 1003; //SQLSTATE: HY000 Message: YES + public final static int ER_CANT_CREATE_FILE = 1004; //SQLSTATE: HY000 Message: Can't create file '%s' (errno: %d - %s) + public final static int ER_CANT_CREATE_TABLE = 1005; //SQLSTATE: HY000 Message: Can't create table '%s' (errno: %d) + public final static int ER_CANT_CREATE_DB = 1006; //SQLSTATE: HY000 Message: Can't create database '%s' (errno: %d) + public final static int ER_DB_CREATE_EXISTS = 1007; //SQLSTATE: HY000 Message: Can't create database '%s'; database exists... + public final static int ER_DB_DROP_EXISTS = 1008; //SQLSTATE: HY000 Message: Can't drop database '%s'; database doesn't exist + public final static int ER_DB_DROP_DELETE = 1009; //SQLSTATE: HY000 Message: Error dropping database (can't delete '%s', errno: %d) + public final static int ER_DB_DROP_RMDIR = 1010; //SQLSTATE: HY000 Message: Error dropping database (can't rmdir '%s', errno: %d) + public final static int ER_CANT_DELETE_FILE = 1011; //SQLSTATE: HY000 Message: Error on delete of '%s' (errno: %d - %s) + public final static int ER_CANT_FIND_SYSTEM_REC = 1012; //SQLSTATE: HY000 Message: Can't read record in system table + public final static int ER_CANT_GET_STAT = 1013; //SQLSTATE: HY000 Message: Can't get status of '%s' (errno: %d - %s) + public final static int ER_CANT_GET_WD = 1014; //SQLSTATE: HY000 Message: Can't get working directory (errno: %d - %s) + public final static int ER_CANT_LOCK = 1015; //SQLSTATE: HY000 Message: Can't lock file (errno: %d - %s) + public final static int ER_CANT_OPEN_FILE = 1016; //SQLSTATE: HY000 Message: Can't open file: '%s' (errno: %d - %s) + public final static int ER_FILE_NOT_FOUND = 1017; //SQLSTATE: HY000 Message: Can't find file: '%s' (errno: %d - %s) + public final static int ER_CANT_READ_DIR = 1018; //SQLSTATE: HY000 Message: Can't read dir of '%s' (errno: %d - %s) + public final static int ER_CANT_SET_WD = 1019; //SQLSTATE: HY000 Message: Can't change dir to '%s' (errno: %d - %s) + public final static int ER_CHECKREAD = 1020; //SQLSTATE: HY000 Message: Record has changed since last read in table '%s' + public final static int ER_DISK_FULL = 1021; //SQLSTATE: HY000 Message: Disk full (%s); waiting for someone to free some space... (errno: %d - %s) + public final static int ER_DUP_KEY = 1022; //SQLSTATE: 23000 Message: Can't write; duplicate key in table '%s' + public final static int ER_ERROR_ON_CLOSE = 1023; //SQLSTATE: HY000 Message: Error on close of '%s' (errno: %d - %s) + public final static int ER_ERROR_ON_READ = 1024; //SQLSTATE: HY000 Message: Error reading file '%s' (errno: %d - %s) + public final static int ER_ERROR_ON_RENAME = 1025; //SQLSTATE: HY000 Message: Error on rename of '%s' to '%s' (errno: %d - %s) + public final static int ER_ERROR_ON_WRITE = 1026; //SQLSTATE: HY000 Message: Error writing file '%s' (errno: %d - %s) + public final static int ER_FILE_USED = 1027; //SQLSTATE: HY000 Message: '%s' is locked against change + public final static int ER_FILSORT_ABORT = 1028; //SQLSTATE: HY000 Message: Sort aborted + public final static int ER_FORM_NOT_FOUND = 1029; //SQLSTATE: HY000 Message: View '%s' doesn't exist for '%s' + public final static int ER_GET_ERRNO = 1030; //SQLSTATE: HY000 Message: Got error %d from storage engine... + public final static int ER_ILLEGAL_HA = 1031; //SQLSTATE: HY000 Message: Table storage engine for '%s' doesn't have this option + public final static int ER_KEY_NOT_FOUND = 1032; //SQLSTATE: HY000 Message: Can't find record in '%s' + public final static int ER_NOT_FORM_FILE = 1033; //SQLSTATE: HY000 Message: Incorrect information in file: '%s' + public final static int ER_NOT_KEYFILE = 1034; //SQLSTATE: HY000 Message: Incorrect key file for table '%s'; try to repair it + public final static int ER_OLD_KEYFILE = 1035; //SQLSTATE: HY000 Message: Old key file for table '%s'; repair it! + public final static int ER_OPEN_AS_READONLY = 1036; //SQLSTATE: HY000 Message: Table '%s' is read only + public final static int ER_OUTOFMEMORY = 1037; //SQLSTATE: HY001 Message: Out of memory; restart server and try again (needed %d bytes) + public final static int ER_OUT_OF_SORTMEMORY = 1038; //SQLSTATE: HY001 Message: Out of sort memory, consider increasing server sort buffer size + public final static int ER_UNEXPECTED_EOF = 1039; //SQLSTATE: HY000 Message: Unexpected EOF found when reading file '%s' (errno: %d - %s) + public final static int ER_CON_COUNT_ERROR = 1040; //SQLSTATE: 08004 Message: Too many connections + public final static int ER_OUT_OF_RESOURCES = 1041; //SQLSTATE: HY000 Message: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space + public final static int ER_BAD_HOST_ERROR = 1042; //SQLSTATE: 08S01 Message: Can't get hostname for your address + public final static int ER_HANDSHAKE_ERROR = 1043; //SQLSTATE: 08S01 Message: Bad handshake + public final static int ER_DBACCESS_DENIED_ERROR = 1044; //SQLSTATE: 42000 Message: Access denied for user '%s'@'%s' to database '%s' + public final static int ER_ACCESS_DENIED_ERROR = 1045; //SQLSTATE: 28000 Message: Access denied for user '%s'@'%s' (using password: %s) + public final static int ER_NO_DB_ERROR = 1046; //SQLSTATE: 3D000 Message: No database selected + public final static int ER_UNKNOWN_COM_ERROR = 1047; //SQLSTATE: 08S01 Message: Unknown command + public final static int ER_BAD_NULL_ERROR = 1048; //SQLSTATE: 23000 Message: Column '%s' cannot be null + public final static int ER_BAD_DB_ERROR = 1049; //SQLSTATE: 42000 Message: Unknown database '%s' + public final static int ER_TABLE_EXISTS_ERROR = 1050; //SQLSTATE: 42S01 Message: Table '%s' already exists + public final static int ER_BAD_TABLE_ERROR = 1051; //SQLSTATE: 42S02 Message: Unknown table '%s' + public final static int ER_NON_UNIQ_ERROR = 1052; //SQLSTATE: 23000 Message: Column '%s' in %s is ambiguous + public final static int ER_SERVER_SHUTDOWN = 1053; //SQLSTATE: 08S01 Message: Server shutdown in progress + public final static int ER_BAD_FIELD_ERROR = 1054; //SQLSTATE: 42S22 Message: Unknown column '%s' in '%s' + public final static int ER_WRONG_FIELD_WITH_GROUP = 1055; //SQLSTATE: 42000 Message: '%s' isn't in GROUP BY + public final static int ER_WRONG_GROUP_FIELD = 1056; //SQLSTATE: 42000 Message: Can't group on '%s' + public final static int ER_WRONG_SUM_SELECT = 1057; //SQLSTATE: 42000 Message: Statement has sum functions and columns in same statement + public final static int ER_WRONG_VALUE_COUNT = 1058; //SQLSTATE: 21S01 Message: Column count doesn't match value count + public final static int ER_TOO_LONG_IDENT = 1059; //SQLSTATE: 42000 Message: Identifier name '%s' is too long + public final static int ER_DUP_FIELDNAME = 1060; //SQLSTATE: 42S21 Message: Duplicate column name '%s' + public final static int ER_DUP_KEYNAME = 1061; //SQLSTATE: 42000 Message: Duplicate key name '%s' + public final static int ER_DUP_ENTRY = 1062; //SQLSTATE: 23000 Message: Duplicate entry '%s' for key %d + public final static int ER_WRONG_FIELD_SPEC = 1063; //SQLSTATE: 42000 Message: Incorrect column specifier for column '%s' + public final static int ER_PARSE_ERROR = 1064; //SQLSTATE: 42000 Message: %s near '%s' at line %d + public final static int ER_EMPTY_QUERY = 1065; //SQLSTATE: 42000 Message: Query was empty + public final static int ER_NONUNIQ_TABLE = 1066; //SQLSTATE: 42000 Message: Not unique table/alias: '%s' + public final static int ER_INVALID_DEFAULT = 1067; //SQLSTATE: 42000 Message: Invalid default value for '%s' + public final static int ER_MULTIPLE_PRI_KEY = 1068; //SQLSTATE: 42000 Message: Multiple primary key defined + public final static int ER_TOO_MANY_KEYS = 1069; //SQLSTATE: 42000 Message: Too many keys specified; max %d keys allowed + public final static int ER_TOO_MANY_KEY_PARTS = 1070; //SQLSTATE: 42000 Message: Too many key parts specified; max %d parts allowed + public final static int ER_TOO_LONG_KEY = 1071; //SQLSTATE: 42000 Message: Specified key was too long; max key length is %d bytes + public final static int ER_KEY_COLUMN_DOES_NOT_EXITS = 1072; //SQLSTATE: 42000 Message: Key column '%s' doesn't exist in table + public final static int ER_BLOB_USED_AS_KEY = 1073; //SQLSTATE: 42000 Message: BLOB column '%s' can't be used in key specification with the used table type + public final static int ER_TOO_BIG_FIELDLENGTH = 1074; //SQLSTATE: 42000 Message: Column length too big for column '%s' (max = %lu); use BLOB or TEXT instead + public final static int ER_WRONG_AUTO_KEY = 1075; //SQLSTATE: 42000 Message: Incorrect table definition; there can be only one auto column and it must be defined as a key + public final static int ER_READY = 1076; //SQLSTATE: HY000 Message: %s: ready for connections. Version: '%s' socket: '%s' port: %d + public final static int ER_NORMAL_SHUTDOWN = 1077; //SQLSTATE: HY000 Message: %s: Normal shutdown + public final static int ER_GOT_SIGNAL = 1078; //SQLSTATE: HY000 Message: %s: Got signal %d. Aborting! + public final static int ER_SHUTDOWN_COMPLETE = 1079; //SQLSTATE: HY000 Message: %s: Shutdown complete + public final static int ER_FORCING_CLOSE = 1080; //SQLSTATE: 08S01 Message: %s: Forcing close of thread %ld user: '%s' + public final static int ER_IPSOCK_ERROR = 1081; //SQLSTATE: 08S01 Message: Can't create IP socket + public final static int ER_NO_SUCH_INDEX = 1082; //SQLSTATE: 42S12 Message: Table '%s' has no index like the one used in CREATE INDEX; recreate the table + public final static int ER_WRONG_FIELD_TERMINATORS = 1083; //SQLSTATE: 42000 Message: Field separator argument is not what is expected; check the manual + public final static int ER_BLOBS_AND_NO_TERMINATED = 1084; //SQLSTATE: 42000 Message: You can't use fixed rowlength with BLOBs; please use 'fields terminated by' + public final static int ER_TEXTFILE_NOT_READABLE = 1085; //SQLSTATE: HY000 Message: The file '%s' must be in the database directory or be readable by all + public final static int ER_FILE_EXISTS_ERROR = 1086; //SQLSTATE: HY000 Message: File '%s' already exists + public final static int ER_LOAD_INFO = 1087; //SQLSTATE: HY000 Message: Records: %ld Deleted: %ld Skipped: %ld Warnings: %ld + public final static int ER_ALTER_INFO = 1088; //SQLSTATE: HY000 Message: Records: %ld Duplicates: %ld + public final static int ER_WRONG_SUB_KEY = 1089; //SQLSTATE: HY000 Message: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys + public final static int ER_CANT_REMOVE_ALL_FIELDS = 1090; //SQLSTATE: 42000 Message: You can't delete all columns with ALTER TABLE; use DROP TABLE instead + public final static int ER_CANT_DROP_FIELD_OR_KEY = 1091; //SQLSTATE: 42000 Message: Can't DROP '%s'; check that column/key exists + public final static int ER_INSERT_INFO = 1092; //SQLSTATE: HY000 Message: Records: %ld Duplicates: %ld Warnings: %ld + public final static int ER_UPDATE_TABLE_USED = 1093; //SQLSTATE: HY000 Message: You can't specify target table '%s' for update in FROM clause + public final static int ER_NO_SUCH_THREAD = 1094; //SQLSTATE: HY000 Message: Unknown thread id: %lu + public final static int ER_KILL_DENIED_ERROR = 1095; //SQLSTATE: HY000 Message: You are not owner of thread %lu + public final static int ER_NO_TABLES_USED = 1096; //SQLSTATE: HY000 Message: No tables used + public final static int ER_TOO_BIG_SET = 1097; //SQLSTATE: HY000 Message: Too many strings for column %s and SET + public final static int ER_NO_UNIQUE_LOGFILE = 1098; //SQLSTATE: HY000 Message: Can't generate a unique log-filename %s.(1-999) + public final static int ER_TABLE_NOT_LOCKED_FOR_WRITE = 1099; //SQLSTATE: HY000 Message: Table '%s' was locked with a READ lock and can't be updated + public final static int ER_TABLE_NOT_LOCKED = 1100; //SQLSTATE: HY000 Message: Table '%s' was not locked with LOCK TABLES + public final static int ER_BLOB_CANT_HAVE_DEFAULT = 1101; //SQLSTATE: 42000 Message: BLOB/TEXT column '%s' can't have a default value + public final static int ER_WRONG_DB_NAME = 1102; //SQLSTATE: 42000 Message: Incorrect database name '%s' + public final static int ER_WRONG_TABLE_NAME = 1103; //SQLSTATE: 42000 Message: Incorrect table name '%s' + public final static int ER_TOO_BIG_SELECT = 1104; //SQLSTATE: 42000 Message: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay + public final static int ER_UNKNOWN_ERROR = 1105; //SQLSTATE: HY000 Message: Unknown error + public final static int ER_UNKNOWN_PROCEDURE = 1106; //SQLSTATE: 42000 Message: Unknown procedure '%s' + public final static int ER_WRONG_PARAMCOUNT_TO_PROCEDURE = 1107; //SQLSTATE: 42000 Message: Incorrect parameter count to procedure '%s' + public final static int ER_WRONG_PARAMETERS_TO_PROCEDURE = 1108; //SQLSTATE: HY000 Message: Incorrect parameters to procedure '%s' + public final static int ER_UNKNOWN_TABLE = 1109; //SQLSTATE: 42S02 Message: Unknown table '%s' in %s + public final static int ER_FIELD_SPECIFIED_TWICE = 1110; //SQLSTATE: 42000 Message: Column '%s' specified twice + public final static int ER_INVALID_GROUP_FUNC_USE = 1111; //SQLSTATE: HY000 Message: Invalid use of group function + public final static int ER_UNSUPPORTED_EXTENSION = 1112; //SQLSTATE: 42000 Message: Table '%s' uses an extension that doesn't exist in this MySQL version + public final static int ER_TABLE_MUST_HAVE_COLUMNS = 1113; //SQLSTATE: 42000 Message: A table must have at least 1 column + public final static int ER_RECORD_FILE_FULL = 1114; //SQLSTATE: HY000 Message: The table '%s' is full + public final static int ER_UNKNOWN_CHARACTER_SET = 1115; //SQLSTATE: 42000 Message: Unknown character set: '%s' + public final static int ER_TOO_MANY_TABLES = 1116; //SQLSTATE: HY000 Message: Too many tables; MySQL can only use %d tables in a join + public final static int ER_TOO_MANY_FIELDS = 1117; //SQLSTATE: HY000 Message: Too many columns + public final static int ER_TOO_BIG_ROWSIZE = 1118; //SQLSTATE: 42000 Message: Row size too large. The maximum row size for the used table type, not counting BLOBs, is %ld. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs + public final static int ER_STACK_OVERRUN = 1119; //SQLSTATE: HY000 Message: Thread stack overrun: Used: %ld of a %ld stack. Use 'mysqld --thread_stack=#' to specify a bigger stack if needed + public final static int ER_WRONG_OUTER_JOIN = 1120; //SQLSTATE: 42000 Message: Cross dependency found in OUTER JOIN; examine your ON conditions + public final static int ER_NULL_COLUMN_IN_INDEX = 1121; //SQLSTATE: 42000 Message: Table handler doesn't support NULL in given index. Please change column '%s' to be NOT NULL or use another handler + public final static int ER_CANT_FIND_UDF = 1122; //SQLSTATE: HY000 Message: Can't load function '%s' + public final static int ER_CANT_INITIALIZE_UDF = 1123; //SQLSTATE: HY000 Message: Can't initialize function '%s'; %s + public final static int ER_UDF_NO_PATHS = 1124; //SQLSTATE: HY000 Message: No paths allowed for shared library + public final static int ER_UDF_EXISTS = 1125; //SQLSTATE: HY000 Message: Function '%s' already exists + public final static int ER_CANT_OPEN_LIBRARY = 1126; //SQLSTATE: HY000 Message: Can't open shared library '%s' (errno: %d %s) + public final static int ER_CANT_FIND_DL_ENTRY = 1127; //SQLSTATE: HY000 Message: Can't find symbol '%s' in library + public final static int ER_FUNCTION_NOT_DEFINED = 1128; //SQLSTATE: HY000 Message: Function '%s' is not defined + public final static int ER_HOST_IS_BLOCKED = 1129; //SQLSTATE: HY000 Message: Host '%s' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts' + public final static int ER_HOST_NOT_PRIVILEGED = 1130; //SQLSTATE: HY000 Message: Host '%s' is not allowed to connect to this MySQL server + public final static int ER_PASSWORD_ANONYMOUS_USER = 1131; //SQLSTATE: 42000 Message: You are using MySQL as an anonymous user and anonymous users are not allowed to change passwords + public final static int ER_PASSWORD_NOT_ALLOWED = 1132; //SQLSTATE: 42000 Message: You must have privileges to update tables in the mysql database to be able to change passwords for others + public final static int ER_PASSWORD_NO_MATCH = 1133; //SQLSTATE: 42000 Message: Can't find any matching row in the user table + public final static int ER_UPDATE_INFO = 1134; //SQLSTATE: HY000 Message: Rows matched: %ld Changed: %ld Warnings: %ld + public final static int ER_CANT_CREATE_THREAD = 1135; //SQLSTATE: HY000 Message: Can't create a new thread (errno %d); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug + public final static int ER_WRONG_VALUE_COUNT_ON_ROW = 1136; //SQLSTATE: 21S01 Message: Column count doesn't match value count at row %ld + public final static int ER_CANT_REOPEN_TABLE = 1137; //SQLSTATE: HY000 Message: Can't reopen table: '%s' + public final static int ER_INVALID_USE_OF_NULL = 1138; //SQLSTATE: 22004 Message: Invalid use of NULL value + public final static int ER_REGEXP_ERROR = 1139; //SQLSTATE: 42000 Message: Got error '%s' from regexp + public final static int ER_MIX_OF_GROUP_FUNC_AND_FIELDS = 1140; //SQLSTATE: 42000 Message: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause + public final static int ER_NONEXISTING_GRANT = 1141; //SQLSTATE: 42000 Message: There is no such grant defined for user '%s' on host '%s' + public final static int ER_TABLEACCESS_DENIED_ERROR = 1142; //SQLSTATE: 42000 Message: %s command denied to user '%s'@'%s' for table '%s' + public final static int ER_COLUMNACCESS_DENIED_ERROR = 1143; //SQLSTATE: 42000 Message: %s command denied to user '%s'@'%s' for column '%s' in table '%s' + public final static int ER_ILLEGAL_GRANT_FOR_TABLE = 1144; //SQLSTATE: 42000 Message: Illegal GRANT/REVOKE command; please consult the manual to see which privileges can be used + public final static int ER_GRANT_WRONG_HOST_OR_USER = 1145; //SQLSTATE: 42000 Message: The host or user argument to GRANT is too long + public final static int ER_NO_SUCH_TABLE = 1146; //SQLSTATE: 42S02 Message: Table '%s.%s' doesn't exist + public final static int ER_NONEXISTING_TABLE_GRANT = 1147; //SQLSTATE: 42000 Message: There is no such grant defined for user '%s' on host '%s' on table '%s' + public final static int ER_NOT_ALLOWED_COMMAND = 1148; //SQLSTATE: 42000 Message: The used command is not allowed with this MySQL version + public final static int ER_SYNTAX_ERROR = 1149; //SQLSTATE: 42000 Message: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use + public final static int ER_DELAYED_CANT_CHANGE_LOCK = 1150; //SQLSTATE: HY000 Message: Delayed insert thread couldn't get requested lock for table %s + public final static int ER_TOO_MANY_DELAYED_THREADS = 1151; //SQLSTATE: HY000 Message: Too many delayed threads in use + public final static int ER_ABORTING_CONNECTION = 1152; //SQLSTATE: 08S01 Message: Aborted connection %ld to db: '%s' user: '%s' (%s) + public final static int ER_NET_PACKET_TOO_LARGE = 1153; //SQLSTATE: 08S01 Message: Got a packet bigger than 'max_allowed_packet' bytes + public final static int ER_NET_READ_ERROR_FROM_PIPE = 1154; //SQLSTATE: 08S01 Message: Got a read error from the connection pipe + public final static int ER_NET_FCNTL_ERROR = 1155; //SQLSTATE: 08S01 Message: Got an error from fcntl() + public final static int ER_NET_PACKETS_OUT_OF_ORDER = 1156; //SQLSTATE: 08S01 Message: Got packets out of order + public final static int ER_NET_UNCOMPRESS_ERROR = 1157; //SQLSTATE: 08S01 Message: Couldn't uncompress communication packet + public final static int ER_NET_READ_ERROR = 1158; //SQLSTATE: 08S01 Message: Got an error reading communication packets + public final static int ER_NET_READ_INTERRUPTED = 1159; //SQLSTATE: 08S01 Message: Got timeout reading communication packets + public final static int ER_NET_ERROR_ON_WRITE = 1160; //SQLSTATE: 08S01 Message: Got an error writing communication packets + public final static int ER_NET_WRITE_INTERRUPTED = 1161; //SQLSTATE: 08S01 Message: Got timeout writing communication packets + public final static int ER_TOO_LONG_STRING = 1162; //SQLSTATE: 42000 Message: Result string is longer than 'max_allowed_packet' bytes + public final static int ER_TABLE_CANT_HANDLE_BLOB = 1163; //SQLSTATE: 42000 Message: The used table type doesn't support BLOB/TEXT columns + public final static int ER_TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164; //SQLSTATE: 42000 Message: The used table type doesn't support AUTO_INCREMENT columns + public final static int ER_DELAYED_INSERT_TABLE_LOCKED = 1165; //SQLSTATE: HY000 Message: INSERT DELAYED can't be used with table '%s' because it is locked with LOCK TABLES + public final static int ER_WRONG_COLUMN_NAME = 1166; //SQLSTATE: 42000 Message: Incorrect column name '%s' + public final static int ER_WRONG_KEY_COLUMN = 1167; //SQLSTATE: 42000 Message: The used storage engine can't index column '%s' + public final static int ER_WRONG_MRG_TABLE = 1168; //SQLSTATE: HY000 Message: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist + public final static int ER_DUP_UNIQUE = 1169; //SQLSTATE: 23000 Message: Can't write, because of unique constraint, to table '%s' + public final static int ER_BLOB_KEY_WITHOUT_LENGTH = 1170; //SQLSTATE: 42000 Message: BLOB/TEXT column '%s' used in key specification without a key length + public final static int ER_PRIMARY_CANT_HAVE_NULL = 1171; //SQLSTATE: 42000 Message: All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead + public final static int ER_TOO_MANY_ROWS = 1172; //SQLSTATE: 42000 Message: Result consisted of more than one row + public final static int ER_REQUIRES_PRIMARY_KEY = 1173; //SQLSTATE: 42000 Message: This table type requires a primary key + public final static int ER_NO_RAID_COMPILED = 1174; //SQLSTATE: HY000 Message: This version of MySQL is not compiled with RAID support + public final static int ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175; //SQLSTATE: HY000 Message: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column + public final static int ER_KEY_DOES_NOT_EXITS = 1176; //SQLSTATE: 42000 Message: Key '%s' doesn't exist in table '%s' + public final static int ER_CHECK_NO_SUCH_TABLE = 1177; //SQLSTATE: 42000 Message: Can't open table + public final static int ER_CHECK_NOT_IMPLEMENTED = 1178; //SQLSTATE: 42000 Message: The storage engine for the table doesn't support %s + public final static int ER_CANT_DO_THIS_DURING_AN_TRANSACTION = 1179; //SQLSTATE: 25000 Message: You are not allowed to execute this command in a transaction + public final static int ER_ERROR_DURING_COMMIT = 1180; //SQLSTATE: HY000 Message: Got error %d during COMMIT + public final static int ER_ERROR_DURING_ROLLBACK = 1181; //SQLSTATE: HY000 Message: Got error %d during ROLLBACK + public final static int ER_ERROR_DURING_FLUSH_LOGS = 1182; //SQLSTATE: HY000 Message: Got error %d during FLUSH_LOGS + public final static int ER_ERROR_DURING_CHECKPOINT = 1183; //SQLSTATE: HY000 Message: Got error %d during CHECKPOINT + public final static int ER_NEW_ABORTING_CONNECTION = 1184; //SQLSTATE: 08S01 Message: Aborted connection %ld to db: '%s' user: '%s' host: '%s' (%s) + public final static int ER_DUMP_NOT_IMPLEMENTED = 1185; //SQLSTATE: HY000 Message: The storage engine for the table does not support binary table dump + public final static int ER_FLUSH_MASTER_BINLOG_CLOSED = 1186; //SQLSTATE: HY000 Message: Binlog closed, cannot RESET MASTER + public final static int ER_INDEX_REBUILD = 1187; //SQLSTATE: HY000 Message: Failed rebuilding the index of dumped table '%s' + public final static int ER_MASTER = 1188; //SQLSTATE: HY000 Message: Error from master: '%s' + public final static int ER_MASTER_NET_READ = 1189; //SQLSTATE: 08S01 Message: Net error reading from master + public final static int ER_MASTER_NET_WRITE = 1190; //SQLSTATE: 08S01 Message: Net error writing to master + public final static int ER_FT_MATCHING_KEY_NOT_FOUND = 1191; //SQLSTATE: HY000 Message: Can't find FULLTEXT index matching the column list + public final static int ER_LOCK_OR_ACTIVE_TRANSACTION = 1192; //SQLSTATE: HY000 Message: Can't execute the given command because you have active locked tables or an active transaction + public final static int ER_UNKNOWN_SYSTEM_VARIABLE = 1193; //SQLSTATE: HY000 Message: Unknown system variable '%s' + public final static int ER_CRASHED_ON_USAGE = 1194; //SQLSTATE: HY000 Message: Table '%s' is marked as crashed and should be repaired + public final static int ER_CRASHED_ON_REPAIR = 1195; //SQLSTATE: HY000 Message: Table '%s' is marked as crashed and last (automatic?) repair failed + public final static int ER_WARNING_NOT_COMPLETE_ROLLBACK = 1196; //SQLSTATE: HY000 Message: Some non-transactional changed tables couldn't be rolled back + public final static int ER_TRANS_CACHE_FULL = 1197; //SQLSTATE: HY000 Message: Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage; increase this mysqld variable and try again + public final static int ER_SLAVE_MUST_STOP = 1198; //SQLSTATE: HY000 Message: This operation cannot be performed with a running slave; run STOP SLAVE first + public final static int ER_SLAVE_NOT_RUNNING = 1199; //SQLSTATE: HY000 Message: This operation requires a running slave; configure slave and do START SLAVE + public final static int ER_BAD_SLAVE = 1200; //SQLSTATE: HY000 Message: The server is not configured as slave; fix in config file or with CHANGE MASTER TO + public final static int ER_MASTER_INFO = 1201; //SQLSTATE: HY000 Message: Could not initialize master info structure; more error messages can be found in the MySQL error log + public final static int ER_SLAVE_THREAD = 1202; //SQLSTATE: HY000 Message: Could not create slave thread; check system resources + public final static int ER_TOO_MANY_USER_CONNECTIONS = 1203; //SQLSTATE: 42000 Message: User %s already has more than 'max_user_connections' active connections + public final static int ER_SET_CONSTANTS_ONLY = 1204; //SQLSTATE: HY000 Message: You may only use constant expressions with SET + public final static int ER_LOCK_WAIT_TIMEOUT = 1205; //SQLSTATE: HY000 Message: Lock wait timeout exceeded; try restarting transaction + public final static int ER_LOCK_TABLE_FULL = 1206; //SQLSTATE: HY000 Message: The total number of locks exceeds the lock table size + public final static int ER_READ_ONLY_TRANSACTION = 1207; //SQLSTATE: 25000 Message: Update locks cannot be acquired during a READ UNCOMMITTED transaction + public final static int ER_DROP_DB_WITH_READ_LOCK = 1208; //SQLSTATE: HY000 Message: DROP DATABASE not allowed while thread is holding global read lock + public final static int ER_CREATE_DB_WITH_READ_LOCK = 1209; //SQLSTATE: HY000 Message: CREATE DATABASE not allowed while thread is holding global read lock + public final static int ER_WRONG_ARGUMENTS = 1210; //SQLSTATE: HY000 Message: Incorrect arguments to %s + public final static int ER_NO_PERMISSION_TO_CREATE_USER = 1211; //SQLSTATE: 42000 Message: '%s'@'%s' is not allowed to create new users + public final static int ER_UNION_TABLES_IN_DIFFERENT_DIR = 1212; //SQLSTATE: HY000 Message: Incorrect table definition; all MERGE tables must be in the same database + public final static int ER_LOCK_DEADLOCK = 1213; //SQLSTATE: 40001 Message: Deadlock found when trying to get lock; try restarting transaction + public final static int ER_TABLE_CANT_HANDLE_FT = 1214; //SQLSTATE: HY000 Message: The used table type doesn't support FULLTEXT indexes + public final static int ER_CANNOT_ADD_FOREIGN = 1215; //SQLSTATE: HY000 Message: Cannot add foreign key constraint + public final static int ER_NO_REFERENCED_ROW = 1216; //SQLSTATE: 23000 Message: Cannot add or update a child row: a foreign key constraint fails + public final static int ER_ROW_IS_REFERENCED = 1217; //SQLSTATE: 23000 Message: Cannot delete or update a parent row: a foreign key constraint fails + public final static int ER_CONNECT_TO_MASTER = 1218; //SQLSTATE: 08S01 Message: Error connecting to master: %s + public final static int ER_QUERY_ON_MASTER = 1219; //SQLSTATE: HY000 Message: Error running query on master: %s + public final static int ER_ERROR_WHEN_EXECUTING_COMMAND = 1220; //SQLSTATE: HY000 Message: Error when executing command %s: %s + public final static int ER_WRONG_USAGE = 1221; //SQLSTATE: HY000 Message: Incorrect usage of %s and %s + public final static int ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222; //SQLSTATE: 21000 Message: The used SELECT statements have a different number of columns + public final static int ER_CANT_UPDATE_WITH_READLOCK = 1223; //SQLSTATE: HY000 Message: Can't execute the query because you have a conflicting read lock + public final static int ER_MIXING_NOT_ALLOWED = 1224; //SQLSTATE: HY000 Message: Mixing of transactional and non-transactional tables is disabled + public final static int ER_DUP_ARGUMENT = 1225; //SQLSTATE: HY000 Message: Option '%s' used twice in statement + public final static int ER_USER_LIMIT_REACHED = 1226; //SQLSTATE: 42000 Message: User '%s' has exceeded the '%s' resource (current value: %ld) + public final static int ER_SPECIFIC_ACCESS_DENIED_ERROR = 1227; //SQLSTATE: 42000 Message: Access denied; you need (at least one of) the %s privilege(s) for this operation + public final static int ER_LOCAL_VARIABLE = 1228; //SQLSTATE: HY000 Message: Variable '%s' is a SESSION variable and can't be used with SET GLOBAL + public final static int ER_GLOBAL_VARIABLE = 1229; //SQLSTATE: HY000 Message: Variable '%s' is a GLOBAL variable and should be set with SET GLOBAL + public final static int ER_NO_DEFAULT = 1230; //SQLSTATE: 42000 Message: Variable '%s' doesn't have a default value + public final static int ER_WRONG_VALUE_FOR_VAR = 1231; //SQLSTATE: 42000 Message: Variable '%s' can't be set to the value of '%s' + public final static int ER_WRONG_TYPE_FOR_VAR = 1232; //SQLSTATE: 42000 Message: Incorrect argument type to variable '%s' + public final static int ER_VAR_CANT_BE_READ = 1233; //SQLSTATE: HY000 Message: Variable '%s' can only be set, not read + public final static int ER_CANT_USE_OPTION_HERE = 1234; //SQLSTATE: 42000 Message: Incorrect usage/placement of '%s' + public final static int ER_NOT_SUPPORTED_YET = 1235; //SQLSTATE: 42000 Message: This version of MySQL doesn't yet support '%s' + public final static int ER_MASTER_FATAL_ERROR_READING_BINLOG = 1236; //SQLSTATE: HY000 Message: Got fatal error %d from master when reading data from binary log: '%s' + public final static int ER_SLAVE_IGNORED_TABLE = 1237; //SQLSTATE: HY000 Message: Slave SQL thread ignored the query because of replicate-*-table rules + public final static int ER_INCORRECT_GLOBAL_LOCAL_VAR = 1238; //SQLSTATE: HY000 Message: Variable '%s' is a %s variable + public final static int ER_WRONG_FK_DEF = 1239; //SQLSTATE: 42000 Message: Incorrect foreign key definition for '%s': %s + public final static int ER_KEY_REF_DO_NOT_MATCH_TABLE_REF = 1240; //SQLSTATE: HY000 Message: Key reference and table reference don't match + public final static int ER_OPERAND_COLUMNS = 1241; //SQLSTATE: 21000 Message: Operand should contain %d column(s) + public final static int ER_SUBQUERY_NO_1_ROW = 1242; //SQLSTATE: 21000 Message: Subquery returns more than 1 row + public final static int ER_UNKNOWN_STMT_HANDLER = 1243; //SQLSTATE: HY000 Message: Unknown prepared statement handler (%.*s) given to %s + public final static int ER_CORRUPT_HELP_DB = 1244; //SQLSTATE: HY000 Message: Help database is corrupt or does not exist + public final static int ER_CYCLIC_REFERENCE = 1245; //SQLSTATE: HY000 Message: Cyclic reference on subqueries + public final static int ER_AUTO_CONVERT = 1246; //SQLSTATE: HY000 Message: Converting column '%s' from %s to %s + public final static int ER_ILLEGAL_REFERENCE = 1247; //SQLSTATE: 42S22 Message: Reference '%s' not supported (%s) + public final static int ER_DERIVED_MUST_HAVE_ALIAS = 1248; //SQLSTATE: 42000 Message: Every derived table must have its own alias + public final static int ER_SELECT_REDUCED = 1249; //SQLSTATE: 01000 Message: Select %u was reduced during optimization + public final static int ER_TABLENAME_NOT_ALLOWED_HERE = 1250; //SQLSTATE: 42000 Message: Table '%s' from one of the SELECTs cannot be used in %s + public final static int ER_NOT_SUPPORTED_AUTH_MODE = 1251; //SQLSTATE: 08004 Message: Client does not support authentication protocol requested by server; consider upgrading MySQL client + public final static int ER_SPATIAL_CANT_HAVE_NULL = 1252; //SQLSTATE: 42000 Message: All parts of a SPATIAL index must be NOT NULL + public final static int ER_COLLATION_CHARSET_MISMATCH = 1253; //SQLSTATE: 42000 Message: COLLATION '%s' is not valid for CHARACTER SET '%s' + public final static int ER_SLAVE_WAS_RUNNING = 1254; //SQLSTATE: HY000 Message: Slave is already running + public final static int ER_SLAVE_WAS_NOT_RUNNING = 1255; //SQLSTATE: HY000 Message: Slave already has been stopped + public final static int ER_TOO_BIG_FOR_UNCOMPRESS = 1256; //SQLSTATE: HY000 Message: Uncompressed data size too large; the maximum size is %d (probably, length of uncompressed data was corrupted) + public final static int ER_ZLIB_Z_MEM_ERROR = 1257; //SQLSTATE: HY000 Message: ZLIB: Not enough memory + public final static int ER_ZLIB_Z_BUF_ERROR = 1258; //SQLSTATE: HY000 Message: ZLIB: Not enough room in the output buffer (probably, length of uncompressed data was corrupted) + public final static int ER_ZLIB_Z_DATA_ERROR = 1259; //SQLSTATE: HY000 Message: ZLIB: Input data corrupted + public final static int ER_CUT_VALUE_GROUP_CONCAT = 1260; //SQLSTATE: HY000 Message: Row %u was cut by GROUP_CONCAT() + public final static int ER_WARN_TOO_FEW_RECORDS = 1261; //SQLSTATE: 01000 Message: Row %ld doesn't contain data for all columns + public final static int ER_WARN_TOO_MANY_RECORDS = 1262; //SQLSTATE: 01000 Message: Row %ld was truncated; it contained more data than there were input columns + public final static int ER_WARN_NULL_TO_NOTNULL = 1263; //SQLSTATE: 22004 Message: Column set to default value; NULL supplied to NOT NULL column '%s' at row %ld + public final static int ER_WARN_DATA_OUT_OF_RANGE = 1264; //SQLSTATE: 22003 Message: Out of range value for column '%s' at row %ld + public final static int ER_WARN_DATA_TRUNCATED = 1265; //SQLSTATE: 01000 Message: Data truncated for column '%s' at row %ld + public final static int ER_WARN_USING_OTHER_HANDLER = 1266; //SQLSTATE: HY000 Message: Using storage engine %s for table '%s' + public final static int ER_CANT_AGGREGATE_2COLLATIONS = 1267; //SQLSTATE: HY000 Message: Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s' + public final static int ER_DROP_USER = 1268; //SQLSTATE: HY000 Message: Cannot drop one or more of the requested users + public final static int ER_REVOKE_GRANTS = 1269; //SQLSTATE: HY000 Message: Can't revoke all privileges for one or more of the requested users + public final static int ER_CANT_AGGREGATE_3COLLATIONS = 1270; //SQLSTATE: HY000 Message: Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s' + public final static int ER_CANT_AGGREGATE_NCOLLATIONS = 1271; //SQLSTATE: HY000 Message: Illegal mix of collations for operation '%s' + public final static int ER_VARIABLE_IS_NOT_STRUCT = 1272; //SQLSTATE: HY000 Message: Variable '%s' is not a variable component (can't be used as XXXX.variable_name) + public final static int ER_UNKNOWN_COLLATION = 1273; //SQLSTATE: HY000 Message: Unknown collation: '%s' + public final static int ER_SLAVE_IGNORED_SSL_PARAMS = 1274; //SQLSTATE: HY000 Message: SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support; they can be used later if MySQL slave with SSL is started + public final static int ER_SERVER_IS_IN_SECURE_AUTH_MODE = 1275; //SQLSTATE: HY000 Message: Server is running in --secure-auth mode, but '%s'@'%s' has a password in the old format; please change the password to the new format + public final static int ER_WARN_FIELD_RESOLVED = 1276; //SQLSTATE: HY000 Message: Field or reference '%s%s%s%s%s' of SELECT #%d was resolved in SELECT #%d + public final static int ER_BAD_SLAVE_UNTIL_COND = 1277; //SQLSTATE: HY000 Message: Incorrect parameter or combination of parameters for START SLAVE UNTIL + public final static int ER_MISSING_SKIP_SLAVE = 1278; //SQLSTATE: HY000 Message: It is recommended to use --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL; otherwise, you will get problems if you get an unexpected slave's mysqld restart + public final static int ER_UNTIL_COND_IGNORED = 1279; //SQLSTATE: HY000 Message: SQL thread is not to be started so UNTIL options are ignored + public final static int ER_WRONG_NAME_FOR_INDEX = 1280; //SQLSTATE: 42000 Message: Incorrect index name '%s' + public final static int ER_WRONG_NAME_FOR_CATALOG = 1281; //SQLSTATE: 42000 Message: Incorrect catalog name '%s' + public final static int ER_WARN_QC_RESIZE = 1282; //SQLSTATE: HY000 Message: Query cache failed to set size %lu; new query cache size is %lu + public final static int ER_BAD_FT_COLUMN = 1283; //SQLSTATE: HY000 Message: Column '%s' cannot be part of FULLTEXT index + public final static int ER_UNKNOWN_KEY_CACHE = 1284; //SQLSTATE: HY000 Message: Unknown key cache '%s' + public final static int ER_WARN_HOSTNAME_WONT_WORK = 1285; //SQLSTATE: HY000 Message: MySQL is started in --skip-name-resolve mode; you must restart it without this switch for this grant to work + public final static int ER_UNKNOWN_STORAGE_ENGINE = 1286; //SQLSTATE: 42000 Message: Unknown storage engine '%s' + public final static int ER_WARN_DEPRECATED_SYNTAX = 1287; //SQLSTATE: HY000 Message: '%s' is deprecated and will be removed in a future release. Please use %s instead + public final static int ER_NON_UPDATABLE_TABLE = 1288; //SQLSTATE: HY000 Message: The target table %s of the %s is not updatable + public final static int ER_FEATURE_DISABLED = 1289; //SQLSTATE: HY000 Message: The '%s' feature is disabled; you need MySQL built with '%s' to have it working + public final static int ER_OPTION_PREVENTS_STATEMENT = 1290; //SQLSTATE: HY000 Message: The MySQL server is running with the %s option so it cannot execute this statement + public final static int ER_DUPLICATED_VALUE_IN_TYPE = 1291; //SQLSTATE: HY000 Message: Column '%s' has duplicated value '%s' in %s + public final static int ER_TRUNCATED_WRONG_VALUE = 1292; //SQLSTATE: 22007 Message: Truncated incorrect %s value: '%s' + public final static int ER_TOO_MUCH_AUTO_TIMESTAMP_COLS = 1293; //SQLSTATE: HY000 Message: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause + public final static int ER_INVALID_ON_UPDATE = 1294; //SQLSTATE: HY000 Message: Invalid ON UPDATE clause for '%s' column + public final static int ER_UNSUPPORTED_PS = 1295; //SQLSTATE: HY000 Message: This command is not supported in the prepared statement protocol yet + public final static int ER_GET_ERRMSG = 1296; //SQLSTATE: HY000 Message: Got error %d '%s' from %s + public final static int ER_GET_TEMPORARY_ERRMSG = 1297; //SQLSTATE: HY000 Message: Got temporary error %d '%s' from %s + public final static int ER_UNKNOWN_TIME_ZONE = 1298; //SQLSTATE: HY000 Message: Unknown or incorrect time zone: '%s' + public final static int ER_WARN_INVALID_TIMESTAMP = 1299; //SQLSTATE: HY000 Message: Invalid TIMESTAMP value in column '%s' at row %ld + public final static int ER_INVALID_CHARACTER_STRING = 1300; //SQLSTATE: HY000 Message: Invalid %s character string: '%s' + public final static int ER_WARN_ALLOWED_PACKET_OVERFLOWED = 1301; //SQLSTATE: HY000 Message: Result of %s() was larger than max_allowed_packet (%ld) - truncated + public final static int ER_CONFLICTING_DECLARATIONS = 1302; //SQLSTATE: HY000 Message: Conflicting declarations: '%s%s' and '%s%s' + public final static int ER_SP_NO_RECURSIVE_CREATE = 1303; //SQLSTATE: 2F003 Message: Can't create a %s from within another stored routine + public final static int ER_SP_ALREADY_EXISTS = 1304; //SQLSTATE: 42000 Message: %s %s already exists + public final static int ER_SP_DOES_NOT_EXIST = 1305; //SQLSTATE: 42000 Message: %s %s does not exist + public final static int ER_SP_DROP_FAILED = 1306; //SQLSTATE: HY000 Message: Failed to DROP %s %s + public final static int ER_SP_STORE_FAILED = 1307; //SQLSTATE: HY000 Message: Failed to CREATE %s %s + public final static int ER_SP_LILABEL_MISMATCH = 1308; //SQLSTATE: 42000 Message: %s with no matching label: %s + public final static int ER_SP_LABEL_REDEFINE = 1309; //SQLSTATE: 42000 Message: Redefining label %s + public final static int ER_SP_LABEL_MISMATCH = 1310; //SQLSTATE: 42000 Message: End-label %s without match + public final static int ER_SP_UNINIT_VAR = 1311; //SQLSTATE: 01000 Message: Referring to uninitialized variable %s + public final static int ER_SP_BADSELECT = 1312; //SQLSTATE: 0A000 Message: PROCEDURE %s can't return a result set in the given context + public final static int ER_SP_BADRETURN = 1313; //SQLSTATE: 42000 Message: RETURN is only allowed in a FUNCTION + public final static int ER_SP_BADSTATEMENT = 1314; //SQLSTATE: 0A000 Message: %s is not allowed in stored procedures + public final static int ER_UPDATE_LOG_DEPRECATED_IGNORED = 1315; //SQLSTATE: 42000 Message: The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored. This option will be removed in MySQL 5.6. + public final static int ER_UPDATE_LOG_DEPRECATED_TRANSLATED = 1316; //SQLSTATE: 42000 Message: The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN. This option will be removed in MySQL 5.6. + public final static int ER_QUERY_INTERRUPTED = 1317; //SQLSTATE: 70100 Message: Query execution was interrupted + public final static int ER_SP_WRONG_NO_OF_ARGS = 1318; //SQLSTATE: 42000 Message: Incorrect number of arguments for %s %s; expected %u, got %u + public final static int ER_SP_COND_MISMATCH = 1319; //SQLSTATE: 42000 Message: Undefined CONDITION: %s + public final static int ER_SP_NORETURN = 1320; //SQLSTATE: 42000 Message: No RETURN found in FUNCTION %s + public final static int ER_SP_NORETURNEND = 1321; //SQLSTATE: 2F005 Message: FUNCTION %s ended without RETURN + public final static int ER_SP_BAD_CURSOR_QUERY = 1322; //SQLSTATE: 42000 Message: Cursor statement must be a SELECT + public final static int ER_SP_BAD_CURSOR_SELECT = 1323; //SQLSTATE: 42000 Message: Cursor SELECT must not have INTO + public final static int ER_SP_CURSOR_MISMATCH = 1324; //SQLSTATE: 42000 Message: Undefined CURSOR: %s + public final static int ER_SP_CURSOR_ALREADY_OPEN = 1325; //SQLSTATE: 24000 Message: Cursor is already open + public final static int ER_SP_CURSOR_NOT_OPEN = 1326; //SQLSTATE: 24000 Message: Cursor is not open + public final static int ER_SP_UNDECLARED_VAR = 1327; //SQLSTATE: 42000 Message: Undeclared variable: %s + public final static int ER_SP_WRONG_NO_OF_FETCH_ARGS = 1328; //SQLSTATE: HY000 Message: Incorrect number of FETCH variables + public final static int ER_SP_FETCH_NO_DATA = 1329; //SQLSTATE: 02000 Message: No data - zero rows fetched, selected, or processed + public final static int ER_SP_DUP_PARAM = 1330; //SQLSTATE: 42000 Message: Duplicate parameter: %s + public final static int ER_SP_DUP_VAR = 1331; //SQLSTATE: 42000 Message: Duplicate variable: %s + public final static int ER_SP_DUP_COND = 1332; //SQLSTATE: 42000 Message: Duplicate condition: %s + public final static int ER_SP_DUP_CURS = 1333; //SQLSTATE: 42000 Message: Duplicate cursor: %s + public final static int ER_SP_CANT_ALTER = 1334; //SQLSTATE: HY000 Message: Failed to ALTER %s %s + public final static int ER_SP_SUBSELECT_NYI = 1335; //SQLSTATE: 0A000 Message: Subquery value not supported + public final static int ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG = 1336; //SQLSTATE: 0A000 Message: %s is not allowed in stored function or trigger + public final static int ER_SP_VARCOND_AFTER_CURSHNDLR = 1337; //SQLSTATE: 42000 Message: Variable or condition declaration after cursor or handler declaration + public final static int ER_SP_CURSOR_AFTER_HANDLER = 1338; //SQLSTATE: 42000 Message: Cursor declaration after handler declaration + public final static int ER_SP_CASE_NOT_FOUND = 1339; //SQLSTATE: 20000 Message: Case not found for CASE statement + public final static int ER_FPARSER_TOO_BIG_FILE = 1340; //SQLSTATE: HY000 Message: Configuration file '%s' is too big + public final static int ER_FPARSER_BAD_HEADER = 1341; //SQLSTATE: HY000 Message: Malformed file type header in file '%s' + public final static int ER_FPARSER_EOF_IN_COMMENT = 1342; //SQLSTATE: HY000 Message: Unexpected end of file while parsing comment '%s' + public final static int ER_FPARSER_ERROR_IN_PARAMETER = 1343; //SQLSTATE: HY000 Message: Error while parsing parameter '%s' (line: '%s') + public final static int ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER = 1344; //SQLSTATE: HY000 Message: Unexpected end of file while skipping unknown parameter '%s' + public final static int ER_VIEW_NO_EXPLAIN = 1345; //SQLSTATE: HY000 Message: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table + public final static int ER_FRM_UNKNOWN_TYPE = 1346; //SQLSTATE: HY000 Message: File '%s' has unknown type '%s' in its header + public final static int ER_WRONG_OBJECT = 1347; //SQLSTATE: HY000 Message: '%s.%s' is not %s + public final static int ER_NONUPDATEABLE_COLUMN = 1348; //SQLSTATE: HY000 Message: Column '%s' is not updatable + public final static int ER_VIEW_SELECT_DERIVED = 1349; //SQLSTATE: HY000 Message: View's SELECT contains a subquery in the FROM clause + public final static int ER_VIEW_SELECT_CLAUSE = 1350; //SQLSTATE: HY000 Message: View's SELECT contains a '%s' clause + public final static int ER_VIEW_SELECT_VARIABLE = 1351; //SQLSTATE: HY000 Message: View's SELECT contains a variable or parameter + public final static int ER_VIEW_SELECT_TMPTABLE = 1352; //SQLSTATE: HY000 Message: View's SELECT refers to a temporary table '%s' + public final static int ER_VIEW_WRONG_LIST = 1353; //SQLSTATE: HY000 Message: View's SELECT and view's field list have different column counts + public final static int ER_WARN_VIEW_MERGE = 1354; //SQLSTATE: HY000 Message: View merge algorithm can't be used here for now (assumed undefined algorithm) + public final static int ER_WARN_VIEW_WITHOUT_KEY = 1355; //SQLSTATE: HY000 Message: View being updated does not have complete key of underlying table in it + public final static int ER_VIEW_INVALID = 1356; //SQLSTATE: HY000 Message: View '%s.%s' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them + public final static int ER_SP_NO_DROP_SP = 1357; //SQLSTATE: HY000 Message: Can't drop or alter a %s from within another stored routine + public final static int ER_SP_GOTO_IN_HNDLR = 1358; //SQLSTATE: HY000 Message: GOTO is not allowed in a stored procedure handler + public final static int ER_TRG_ALREADY_EXISTS = 1359; //SQLSTATE: HY000 Message: Trigger already exists + public final static int ER_TRG_DOES_NOT_EXIST = 1360; //SQLSTATE: HY000 Message: Trigger does not exist + public final static int ER_TRG_ON_VIEW_OR_TEMP_TABLE = 1361; //SQLSTATE: HY000 Message: Trigger's '%s' is view or temporary table + public final static int ER_TRG_CANT_CHANGE_ROW = 1362; //SQLSTATE: HY000 Message: Updating of %s row is not allowed in %strigger + public final static int ER_TRG_NO_SUCH_ROW_IN_TRG = 1363; //SQLSTATE: HY000 Message: There is no %s row in %s trigger + public final static int ER_NO_DEFAULT_FOR_FIELD = 1364; //SQLSTATE: HY000 Message: Field '%s' doesn't have a default value + public final static int ER_DIVISION_BY_ZERO = 1365; //SQLSTATE: 22012 Message: Division by 0 + public final static int ER_TRUNCATED_WRONG_VALUE_FOR_FIELD = 1366; //SQLSTATE: HY000 Message: Incorrect %s value: '%s' for column '%s' at row %ld + public final static int ER_ILLEGAL_VALUE_FOR_TYPE = 1367; //SQLSTATE: 22007 Message: Illegal %s '%s' value found during parsing + public final static int ER_VIEW_NONUPD_CHECK = 1368; //SQLSTATE: HY000 Message: CHECK OPTION on non-updatable view '%s.%s' + public final static int ER_VIEW_CHECK_FAILED = 1369; //SQLSTATE: HY000 Message: CHECK OPTION failed '%s.%s' + public final static int ER_PROCACCESS_DENIED_ERROR = 1370; //SQLSTATE: 42000 Message: %s command denied to user '%s'@'%s' for routine '%s' + public final static int ER_RELAY_LOG_FAIL = 1371; //SQLSTATE: HY000 Message: Failed purging old relay logs: %s + public final static int ER_PASSWD_LENGTH = 1372; //SQLSTATE: HY000 Message: Password hash should be a %d-digit hexadecimal number + public final static int ER_UNKNOWN_TARGET_BINLOG = 1373; //SQLSTATE: HY000 Message: Target log not found in binlog index + public final static int ER_IO_ERR_LOG_INDEX_READ = 1374; //SQLSTATE: HY000 Message: I/O error reading log index file + public final static int ER_BINLOG_PURGE_PROHIBITED = 1375; //SQLSTATE: HY000 Message: Server configuration does not permit binlog purge + public final static int ER_FSEEK_FAIL = 1376; //SQLSTATE: HY000 Message: Failed on fseek() + public final static int ER_BINLOG_PURGE_FATAL_ERR = 1377; //SQLSTATE: HY000 Message: Fatal error during log purge + public final static int ER_LOG_IN_USE = 1378; //SQLSTATE: HY000 Message: A purgeable log is in use, will not purge + public final static int ER_LOG_PURGE_UNKNOWN_ERR = 1379; //SQLSTATE: HY000 Message: Unknown error during log purge + public final static int ER_RELAY_LOG_INIT = 1380; //SQLSTATE: HY000 Message: Failed initializing relay log position: %s + public final static int ER_NO_BINARY_LOGGING = 1381; //SQLSTATE: HY000 Message: You are not using binary logging + public final static int ER_RESERVED_SYNTAX = 1382; //SQLSTATE: HY000 Message: The '%s' syntax is reserved for purposes internal to the MySQL server + public final static int ER_WSAS_FAILED = 1383; //SQLSTATE: HY000 Message: WSAStartup Failed + public final static int ER_DIFF_GROUPS_PROC = 1384; //SQLSTATE: HY000 Message: Can't handle procedures with different groups yet + public final static int ER_NO_GROUP_FOR_PROC = 1385; //SQLSTATE: HY000 Message: Select must have a group with this procedure + public final static int ER_ORDER_WITH_PROC = 1386; //SQLSTATE: HY000 Message: Can't use ORDER clause with this procedure + public final static int ER_LOGGING_PROHIBIT_CHANGING_OF = 1387; //SQLSTATE: HY000 Message: Binary logging and replication forbid changing the global server %s + public final static int ER_NO_FILE_MAPPING = 1388; //SQLSTATE: HY000 Message: Can't map file: %s, errno: %d + public final static int ER_WRONG_MAGIC = 1389; //SQLSTATE: HY000 Message: Wrong magic in %s + public final static int ER_PS_MANY_PARAM = 1390; //SQLSTATE: HY000 Message: Prepared statement contains too many placeholders + public final static int ER_KEY_PART_0 = 1391; //SQLSTATE: HY000 Message: Key part '%s' length cannot be 0 + public final static int ER_VIEW_CHECKSUM = 1392; //SQLSTATE: HY000 Message: View text checksum failed + public final static int ER_VIEW_MULTIUPDATE = 1393; //SQLSTATE: HY000 Message: Can not modify more than one base table through a join view '%s.%s' + public final static int ER_VIEW_NO_INSERT_FIELD_LIST = 1394; //SQLSTATE: HY000 Message: Can not insert into join view '%s.%s' without fields list + public final static int ER_VIEW_DELETE_MERGE_VIEW = 1395; //SQLSTATE: HY000 Message: Can not delete from join view '%s.%s' + public final static int ER_CANNOT_USER = 1396; //SQLSTATE: HY000 Message: Operation %s failed for %s + public final static int ER_XAER_NOTA = 1397; //SQLSTATE: XAE04 Message: XAER_NOTA: Unknown XID + public final static int ER_XAER_INVAL = 1398; //SQLSTATE: XAE05 Message: XAER_INVAL: Invalid arguments (or unsupported command) + public final static int ER_XAER_RMFAIL = 1399; //SQLSTATE: XAE07 Message: XAER_RMFAIL: The command cannot be executed when global transaction is in the %s state + public final static int ER_XAER_OUTSIDE = 1400; //SQLSTATE: XAE09 Message: XAER_OUTSIDE: Some work is done outside global transaction + public final static int ER_XA_RMERR = 1401; + public final static int ER_XA_RBROLLBACK = 1402; //SQLSTATE: XA100 Message: XA_RBROLLBACK: Transaction branch was rolled back + public final static int ER_NONEXISTING_PROC_GRANT = 1403; //SQLSTATE: 42000 Message: There is no such grant defined for user '%s' on host '%s' on routine '%s' + public final static int ER_PROC_AUTO_GRANT_FAIL = 1404; //SQLSTATE: HY000 Message: Failed to grant EXECUTE and ALTER ROUTINE privileges + public final static int ER_PROC_AUTO_REVOKE_FAIL = 1405; //SQLSTATE: HY000 Message: Failed to revoke all privileges to dropped routine + public final static int ER_DATA_TOO_LONG = 1406; //SQLSTATE: 22001 Message: Data too long for column '%s' at row %ld + public final static int ER_SP_BAD_SQLSTATE = 1407; //SQLSTATE: 42000 Message: Bad; //SQLSTATE: '%s' + public final static int ER_STARTUP = 1408; //SQLSTATE: HY000 Message: %s: ready for connections. Version: '%s' socket: '%s' port: %d %s + public final static int ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR = 1409; //SQLSTATE: HY000 Message: Can't load value from file with fixed size rows to variable + public final static int ER_CANT_CREATE_USER_WITH_GRANT = 1410; //SQLSTATE: 42000 Message: You are not allowed to create a user with GRANT + public final static int ER_WRONG_VALUE_FOR_TYPE = 1411; //SQLSTATE: HY000 Message: Incorrect %s value: '%s' for function %s + public final static int ER_TABLE_DEF_CHANGED = 1412; //SQLSTATE: HY000 Message: Table definition has changed, please retry transaction + public final static int ER_SP_DUP_HANDLER = 1413; //SQLSTATE: 42000 Message: Duplicate handler declared in the same block + public final static int ER_SP_NOT_VAR_ARG = 1414; //SQLSTATE: 42000 Message: OUT or INOUT argument %d for routine %s is not a variable or NEW pseudo-variable in BEFORE trigger + public final static int ER_SP_NO_RETSET = 1415; //SQLSTATE: 0A000 Message: Not allowed to return a result set from a %s + public final static int ER_CANT_CREATE_GEOMETRY_OBJECT = 1416; //SQLSTATE: 22003 Message: Cannot get geometry object from data you send to the GEOMETRY field + public final static int ER_FAILED_ROUTINE_BREAK_BINLOG = 1417; //SQLSTATE: HY000 Message: A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes + public final static int ER_BINLOG_UNSAFE_ROUTINE = 1418; //SQLSTATE: HY000 Message: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) + public final static int ER_BINLOG_CREATE_ROUTINE_NEED_SUPER = 1419; //SQLSTATE: HY000 Message: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) + public final static int ER_EXEC_STMT_WITH_OPEN_CURSOR = 1420; //SQLSTATE: HY000 Message: You can't execute a prepared statement which has an open cursor associated with it. Reset the statement to re-execute it. + public final static int ER_STMT_HAS_NO_OPEN_CURSOR = 1421; //SQLSTATE: HY000 Message: The statement (%lu) has no open cursor. + public final static int ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG = 1422; //SQLSTATE: HY000 Message: Explicit or implicit commit is not allowed in stored function or trigger. + public final static int ER_NO_DEFAULT_FOR_VIEW_FIELD = 1423; //SQLSTATE: HY000 Message: Field of view '%s.%s' underlying table doesn't have a default value + public final static int ER_SP_NO_RECURSION = 1424; //SQLSTATE: HY000 Message: Recursive stored functions and triggers are not allowed. + public final static int ER_TOO_BIG_SCALE = 1425; //SQLSTATE: 42000 Message: Too big scale %d specified for column '%s'. Maximum is %lu. + public final static int ER_TOO_BIG_PRECISION = 1426; //SQLSTATE: 42000 Message: Too big precision %d specified for column '%s'. Maximum is %lu. + public final static int ER_M_BIGGER_THAN_D = 1427; //SQLSTATE: 42000 Message: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%s'). + public final static int ER_WRONG_LOCK_OF_SYSTEM_TABLE = 1428; //SQLSTATE: HY000 Message: You can't combine write-locking of system tables with other tables or lock types + public final static int ER_CONNECT_TO_FOREIGN_DATA_SOURCE = 1429; //SQLSTATE: HY000 Message: Unable to connect to foreign data source: %s + public final static int ER_QUERY_ON_FOREIGN_DATA_SOURCE = 1430; //SQLSTATE: HY000 Message: There was a problem processing the query on the foreign data source. Data source error: %s + public final static int ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST = 1431; //SQLSTATE: HY000 Message: The foreign data source you are trying to reference does not exist. Data source error: %s + public final static int ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE = 1432; //SQLSTATE: HY000 Message: Can't create federated table. The data source connection string '%s' is not in the correct format + public final static int ER_FOREIGN_DATA_STRING_INVALID = 1433; //SQLSTATE: HY000 Message: The data source connection string '%s' is not in the correct format + public final static int ER_CANT_CREATE_FEDERATED_TABLE = 1434; //SQLSTATE: HY000 Message: Can't create federated table. Foreign data src error: %s + public final static int ER_TRG_IN_WRONG_SCHEMA = 1435; //SQLSTATE: HY000 Message: Trigger in wrong schema + public final static int ER_STACK_OVERRUN_NEED_MORE = 1436; //SQLSTATE: HY000 Message: Thread stack overrun: %ld bytes used of a %ld byte stack, and %ld bytes needed. Use 'mysqld --thread_stack=#' to specify a bigger stack. + public final static int ER_TOO_LONG_BODY = 1437; //SQLSTATE: 42000 Message: Routine body for '%s' is too long + public final static int ER_WARN_CANT_DROP_DEFAULT_KEYCACHE = 1438; //SQLSTATE: HY000 Message: Cannot drop default keycache + public final static int ER_TOO_BIG_DISPLAYWIDTH = 1439; //SQLSTATE: 42000 Message: Display width out of range for column '%s' (max = %lu) + public final static int ER_XAER_DUPID = 1440; //SQLSTATE: XAE08 Message: XAER_DUPID: The XID already exists + public final static int ER_DATETIME_FUNCTION_OVERFLOW = 1441; //SQLSTATE: 22008 Message: Datetime function: %s field overflow + public final static int ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG = 1442; //SQLSTATE: HY000 Message: Can't update table '%s' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. + public final static int ER_VIEW_PREVENT_UPDATE = 1443; //SQLSTATE: HY000 Message: The definition of table '%s' prevents operation %s on table '%s'. + public final static int ER_PS_NO_RECURSION = 1444; //SQLSTATE: HY000 Message: The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner + public final static int ER_SP_CANT_SET_AUTOCOMMIT = 1445; //SQLSTATE: HY000 Message: Not allowed to set autocommit from a stored function or trigger + public final static int ER_MALFORMED_DEFINER = 1446; //SQLSTATE: HY000 Message: Definer is not fully qualified + public final static int ER_VIEW_FRM_NO_USER = 1447; //SQLSTATE: HY000 Message: View '%s'.'%s' has no definer information (old table format). Current user is used as definer. Please recreate the view! + public final static int ER_VIEW_OTHER_USER = 1448; //SQLSTATE: HY000 Message: You need the SUPER privilege for creation view with '%s'@'%s' definer + public final static int ER_NO_SUCH_USER = 1449; //SQLSTATE: HY000 Message: The user specified as a definer ('%s'@'%s') does not exist + public final static int ER_FORBID_SCHEMA_CHANGE = 1450; //SQLSTATE: HY000 Message: Changing schema from '%s' to '%s' is not allowed. + public final static int ER_ROW_IS_REFERENCED_2 = 1451; //SQLSTATE: 23000 Message: Cannot delete or update a parent row: a foreign key constraint fails (%s) + public final static int ER_NO_REFERENCED_ROW_2 = 1452; //SQLSTATE: 23000 Message: Cannot add or update a child row: a foreign key constraint fails (%s) + public final static int ER_SP_BAD_VAR_SHADOW = 1453; //SQLSTATE: 42000 Message: Variable '%s' must be quoted with `...`, or renamed + public final static int ER_TRG_NO_DEFINER = 1454; //SQLSTATE: HY000 Message: No definer attribute for trigger '%s'.'%s'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger. + public final static int ER_OLD_FILE_FORMAT = 1455; //SQLSTATE: HY000 Message: '%s' has an old format, you should re-create the '%s' object(s) + public final static int ER_SP_RECURSION_LIMIT = 1456; //SQLSTATE: HY000 Message: Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %s + public final static int ER_SP_PROC_TABLE_CORRUPT = 1457; //SQLSTATE: HY000 Message: Failed to load routine %s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d) + public final static int ER_SP_WRONG_NAME = 1458; //SQLSTATE: 42000 Message: Incorrect routine name '%s' + public final static int ER_TABLE_NEEDS_UPGRADE = 1459; //SQLSTATE: HY000 Message: Table upgrade required. Please do "REPAIR TABLE `%s`" or dump/reload to fix it! + public final static int ER_SP_NO_AGGREGATE = 1460; //SQLSTATE: 42000 Message: AGGREGATE is not supported for stored functions + public final static int ER_MAX_PREPARED_STMT_COUNT_REACHED = 1461; //SQLSTATE: 42000 Message: Can't create more than max_prepared_stmt_count statements (current value: %lu) + public final static int ER_VIEW_RECURSIVE = 1462; //SQLSTATE: HY000 Message: `%s`.`%s` contains view recursion + public final static int ER_NON_GROUPING_FIELD_USED = 1463; //SQLSTATE: 42000 Message: non-grouping field '%s' is used in %s clause + public final static int ER_TABLE_CANT_HANDLE_SPKEYS = 1464; //SQLSTATE: HY000 Message: The used table type doesn't support SPATIAL indexes + public final static int ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA = 1465; //SQLSTATE: HY000 Message: Triggers can not be created on system tables + public final static int ER_REMOVED_SPACES = 1466; //SQLSTATE: HY000 Message: Leading spaces are removed from name '%s' + public final static int ER_AUTOINC_READ_FAILED = 1467; //SQLSTATE: HY000 Message: Failed to read auto-increment value from storage engine + public final static int ER_USERNAME = 1468; //SQLSTATE: HY000 Message: user name + public final static int ER_HOSTNAME = 1469; //SQLSTATE: HY000 Message: host name + public final static int ER_WRONG_STRING_LENGTH = 1470; //SQLSTATE: HY000 Message: String '%s' is too long for %s (should be no longer than %d) + public final static int ER_NON_INSERTABLE_TABLE = 1471; //SQLSTATE: HY000 Message: The target table %s of the %s is not insertable-into + public final static int ER_ADMIN_WRONG_MRG_TABLE = 1472; //SQLSTATE: HY000 Message: Table '%s' is differently defined or of non-MyISAM type or doesn't exist + public final static int ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT = 1473; //SQLSTATE: HY000 Message: Too high level of nesting for select + public final static int ER_NAME_BECOMES_EMPTY = 1474; //SQLSTATE: HY000 Message: Name '%s' has become '' + public final static int ER_AMBIGUOUS_FIELD_TERM = 1475; //SQLSTATE: HY000 Message: First character of the FIELDS TERMINATED string is ambiguous; please use non-optional and non-empty FIELDS ENCLOSED BY + public final static int ER_FOREIGN_SERVER_EXISTS = 1476; //SQLSTATE: HY000 Message: The foreign server, %s, you are trying to create already exists. + public final static int ER_FOREIGN_SERVER_DOESNT_EXIST = 1477; //SQLSTATE: HY000 Message: The foreign server name you are trying to reference does not exist. Data source error: %s + public final static int ER_ILLEGAL_HA_CREATE_OPTION = 1478; //SQLSTATE: HY000 Message: Table storage engine '%s' does not support the create option '%s' + public final static int ER_PARTITION_REQUIRES_VALUES_ERROR = 1479; //SQLSTATE: HY000 Message: Syntax error: %s PARTITIONING requires definition of VALUES %s for each partition + public final static int ER_PARTITION_WRONG_VALUES_ERROR = 1480; //SQLSTATE: HY000 Message: Only %s PARTITIONING can use VALUES %s in partition definition + public final static int ER_PARTITION_MAXVALUE_ERROR = 1481; //SQLSTATE: HY000 Message: MAXVALUE can only be used in last partition definition + public final static int ER_PARTITION_SUBPARTITION_ERROR = 1482; //SQLSTATE: HY000 Message: Subpartitions can only be hash partitions and by key + public final static int ER_PARTITION_SUBPART_MIX_ERROR = 1483; //SQLSTATE: HY000 Message: Must define subpartitions on all partitions if on one partition + public final static int ER_PARTITION_WRONG_NO_PART_ERROR = 1484; //SQLSTATE: HY000 Message: Wrong number of partitions defined, mismatch with previous setting + public final static int ER_PARTITION_WRONG_NO_SUBPART_ERROR = 1485; //SQLSTATE: HY000 Message: Wrong number of subpartitions defined, mismatch with previous setting + public final static int ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR = 1486; //SQLSTATE: HY000 Message: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed + public final static int ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR = 1487; //SQLSTATE: HY000 Message: Expression in RANGE/LIST VALUES must be constant + public final static int ER_FIELD_NOT_FOUND_PART_ERROR = 1488; //SQLSTATE: HY000 Message: Field in list of fields for partition function not found in table + public final static int ER_LIST_OF_FIELDS_ONLY_IN_HASH_ERROR = 1489; //SQLSTATE: HY000 Message: List of fields is only allowed in KEY partitions + public final static int ER_INCONSISTENT_PARTITION_INFO_ERROR = 1490; //SQLSTATE: HY000 Message: The partition info in the frm file is not consistent with what can be written into the frm file + public final static int ER_PARTITION_FUNC_NOT_ALLOWED_ERROR = 1491; //SQLSTATE: HY000 Message: The %s function returns the wrong type + public final static int ER_PARTITIONS_MUST_BE_DEFINED_ERROR = 1492; //SQLSTATE: HY000 Message: For %s partitions each partition must be defined + public final static int ER_RANGE_NOT_INCREASING_ERROR = 1493; //SQLSTATE: HY000 Message: VALUES LESS THAN value must be strictly increasing for each partition + public final static int ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR = 1494; //SQLSTATE: HY000 Message: VALUES value must be of same type as partition function + public final static int ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR = 1495; //SQLSTATE: HY000 Message: Multiple definition of same constant in list partitioning + public final static int ER_PARTITION_ENTRY_ERROR = 1496; //SQLSTATE: HY000 Message: Partitioning can not be used stand-alone in query + public final static int ER_MIX_HANDLER_ERROR = 1497; //SQLSTATE: HY000 Message: The mix of handlers in the partitions is not allowed in this version of MySQL + public final static int ER_PARTITION_NOT_DEFINED_ERROR = 1498; //SQLSTATE: HY000 Message: For the partitioned engine it is necessary to define all %s + public final static int ER_TOO_MANY_PARTITIONS_ERROR = 1499; //SQLSTATE: HY000 Message: Too many partitions (including subpartitions) were defined + public final static int ER_SUBPARTITION_ERROR = 1500; //SQLSTATE: HY000 Message: It is only possible to mix RANGE/LIST partitioning with HASH/KEY partitioning for subpartitioning + public final static int ER_CANT_CREATE_HANDLER_FILE = 1501; //SQLSTATE: HY000 Message: Failed to create specific handler file + public final static int ER_BLOB_FIELD_IN_PART_FUNC_ERROR = 1502; //SQLSTATE: HY000 Message: A BLOB field is not allowed in partition function + public final static int ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF = 1503; //SQLSTATE: HY000 Message: A %s must include all columns in the table's partitioning function + public final static int ER_NO_PARTS_ERROR = 1504; //SQLSTATE: HY000 Message: Number of %s = 0 is not an allowed value + public final static int ER_PARTITION_MGMT_ON_NONPARTITIONED = 1505; //SQLSTATE: HY000 Message: Partition management on a not partitioned table is not possible + public final static int ER_FOREIGN_KEY_ON_PARTITIONED = 1506; //SQLSTATE: HY000 Message: Foreign key clause is not yet supported in conjunction with partitioning + public final static int ER_DROP_PARTITION_NON_EXISTENT = 1507; //SQLSTATE: HY000 Message: Error in list of partitions to %s + public final static int ER_DROP_LAST_PARTITION = 1508; //SQLSTATE: HY000 Message: Cannot remove all partitions, use DROP TABLE instead + public final static int ER_COALESCE_ONLY_ON_HASH_PARTITION = 1509; //SQLSTATE: HY000 Message: COALESCE PARTITION can only be used on HASH/KEY partitions + public final static int ER_REORG_HASH_ONLY_ON_SAME_NO = 1510; //SQLSTATE: HY000 Message: REORGANIZE PARTITION can only be used to reorganize partitions not to change their numbers + public final static int ER_REORG_NO_PARAM_ERROR = 1511; //SQLSTATE: HY000 Message: REORGANIZE PARTITION without parameters can only be used on auto-partitioned tables using HASH PARTITIONs + public final static int ER_ONLY_ON_RANGE_LIST_PARTITION = 1512; //SQLSTATE: HY000 Message: %s PARTITION can only be used on RANGE/LIST partitions + public final static int ER_ADD_PARTITION_SUBPART_ERROR = 1513; //SQLSTATE: HY000 Message: Trying to Add partition(s) with wrong number of subpartitions + public final static int ER_ADD_PARTITION_NO_NEW_PARTITION = 1514; //SQLSTATE: HY000 Message: At least one partition must be added + public final static int ER_COALESCE_PARTITION_NO_PARTITION = 1515; //SQLSTATE: HY000 Message: At least one partition must be coalesced + public final static int ER_REORG_PARTITION_NOT_EXIST = 1516; //SQLSTATE: HY000 Message: More partitions to reorganize than there are partitions + public final static int ER_SAME_NAME_PARTITION = 1517; //SQLSTATE: HY000 Message: Duplicate partition name %s + public final static int ER_NO_BINLOG_ERROR = 1518; //SQLSTATE: HY000 Message: It is not allowed to shut off binlog on this command + public final static int ER_CONSECUTIVE_REORG_PARTITIONS = 1519; //SQLSTATE: HY000 Message: When reorganizing a set of partitions they must be in consecutive order + public final static int ER_REORG_OUTSIDE_RANGE = 1520; //SQLSTATE: HY000 Message: Reorganize of range partitions cannot change total ranges except for last partition where it can extend the range + public final static int ER_PARTITION_FUNCTION_FAILURE = 1521; //SQLSTATE: HY000 Message: Partition function not supported in this version for this handler + public final static int ER_PART_STATE_ERROR = 1522; //SQLSTATE: HY000 Message: Partition state cannot be defined from CREATE/ALTER TABLE + public final static int ER_LIMITED_PART_RANGE = 1523; //SQLSTATE: HY000 Message: The %s handler only supports 32 bit integers in VALUES + public final static int ER_PLUGIN_IS_NOT_LOADED = 1524; //SQLSTATE: HY000 Message: Plugin '%s' is not loaded + public final static int ER_WRONG_VALUE = 1525; //SQLSTATE: HY000 Message: Incorrect %s value: '%s' + public final static int ER_NO_PARTITION_FOR_GIVEN_VALUE = 1526; //SQLSTATE: HY000 Message: Table has no partition for value %s + public final static int ER_FILEGROUP_OPTION_ONLY_ONCE = 1527; //SQLSTATE: HY000 Message: It is not allowed to specify %s more than once + public final static int ER_CREATE_FILEGROUP_FAILED = 1528; //SQLSTATE: HY000 Message: Failed to create %s + public final static int ER_DROP_FILEGROUP_FAILED = 1529; //SQLSTATE: HY000 Message: Failed to drop %s + public final static int ER_TABLESPACE_AUTO_EXTEND_ERROR = 1530; //SQLSTATE: HY000 Message: The handler doesn't support autoextend of tablespaces + public final static int ER_WRONG_SIZE_NUMBER = 1531; //SQLSTATE: HY000 Message: A size parameter was incorrectly specified, either number or on the form 10M + public final static int ER_SIZE_OVERFLOW_ERROR = 1532; //SQLSTATE: HY000 Message: The size number was correct but we don't allow the digit part to be more than 2 billion + public final static int ER_ALTER_FILEGROUP_FAILED = 1533; //SQLSTATE: HY000 Message: Failed to alter: %s + public final static int ER_BINLOG_ROW_LOGGING_FAILED = 1534; //SQLSTATE: HY000 Message: Writing one row to the row-based binary log failed + public final static int ER_BINLOG_ROW_WRONG_TABLE_DEF = 1535; //SQLSTATE: HY000 Message: Table definition on master and slave does not match: %s + public final static int ER_BINLOG_ROW_RBR_TO_SBR = 1536; //SQLSTATE: HY000 Message: Slave running with --log-slave-updates must use row-based binary logging to be able to replicate row-based binary log events + public final static int ER_EVENT_ALREADY_EXISTS = 1537; //SQLSTATE: HY000 Message: Event '%s' already exists + public final static int ER_EVENT_STORE_FAILED = 1538; //SQLSTATE: HY000 Message: Failed to store event %s. Error code %d from storage engine. + public final static int ER_EVENT_DOES_NOT_EXIST = 1539; //SQLSTATE: HY000 Message: Unknown event '%s' + public final static int ER_EVENT_CANT_ALTER = 1540; //SQLSTATE: HY000 Message: Failed to alter event '%s' + public final static int ER_EVENT_DROP_FAILED = 1541; //SQLSTATE: HY000 Message: Failed to drop %s + public final static int ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG = 1542; //SQLSTATE: HY000 Message: INTERVAL is either not positive or too big + public final static int ER_EVENT_ENDS_BEFORE_STARTS = 1543; //SQLSTATE: HY000 Message: ENDS is either invalid or before STARTS + public final static int ER_EVENT_EXEC_TIME_IN_THE_PAST = 1544; //SQLSTATE: HY000 Message: Event execution time is in the past. Event has been disabled + public final static int ER_EVENT_OPEN_TABLE_FAILED = 1545; //SQLSTATE: HY000 Message: Failed to open mysql.event + public final static int ER_EVENT_NEITHER_M_EXPR_NOR_M_AT = 1546; //SQLSTATE: HY000 Message: No datetime expression provided + public final static int ER_COL_COUNT_DOESNT_MATCH_CORRUPTED = 1547; //SQLSTATE: HY000 Message: Column count of mysql.%s is wrong. Expected %d, found %d. The table is probably corrupted + public final static int ER_CANNOT_LOAD_FROM_TABLE = 1548; //SQLSTATE: HY000 Message: Cannot load from mysql.%s. The table is probably corrupted + public final static int ER_EVENT_CANNOT_DELETE = 1549; //SQLSTATE: HY000 Message: Failed to delete the event from mysql.event + public final static int ER_EVENT_COMPILE_ERROR = 1550; //SQLSTATE: HY000 Message: Error during compilation of event's body + public final static int ER_EVENT_SAME_NAME = 1551; //SQLSTATE: HY000 Message: Same old and new event name + public final static int ER_EVENT_DATA_TOO_LONG = 1552; //SQLSTATE: HY000 Message: Data for column '%s' too long + public final static int ER_DROP_INDEX_FK = 1553; //SQLSTATE: HY000 Message: Cannot drop index '%s': needed in a foreign key constraint + public final static int ER_WARN_DEPRECATED_SYNTAX_WITH_VER = 1554; //SQLSTATE: HY000 Message: The syntax '%s' is deprecated and will be removed in MySQL %s. Please use %s instead + public final static int ER_CANT_WRITE_LOCK_LOG_TABLE = 1555; //SQLSTATE: HY000 Message: You can't write-lock a log table. Only read access is possible + public final static int ER_CANT_LOCK_LOG_TABLE = 1556; //SQLSTATE: HY000 Message: You can't use locks with log tables. + public final static int ER_FOREIGN_DUPLICATE_KEY = 1557; //SQLSTATE: 23000 Message: Upholding foreign key constraints for table '%s', entry '%s', key %d would lead to a duplicate entry + public final static int ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE = 1558; //SQLSTATE: HY000 Message: Column count of mysql.%s is wrong. Expected %d, found %d. Created with MySQL %d, now running %d. Please use mysql_upgrade to fix this error. + public final static int ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR = 1559; //SQLSTATE: HY000 Message: Cannot switch out of the row-based binary log format when the session has open temporary tables + public final static int ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT + = 1560; //SQLSTATE: HY000 Message: Cannot change the binary logging format inside a stored function or trigger + public final static int ER_NDB_CANT_SWITCH_BINLOG_FORMAT = 1561; //SQLSTATE: HY000 Message: The NDB cluster engine does not support changing the binlog format on the fly yet + public final static int ER_PARTITION_NO_TEMPORARY = 1562; //SQLSTATE: HY000 Message: Cannot create temporary table with partitions + public final static int ER_PARTITION_CONST_DOMAIN_ERROR = 1563; //SQLSTATE: HY000 Message: Partition constant is out of partition function domain + public final static int ER_PARTITION_FUNCTION_IS_NOT_ALLOWED = 1564; //SQLSTATE: HY000 Message: This partition function is not allowed + public final static int ER_DDL_LOG_ERROR = 1565; //SQLSTATE: HY000 Message: Error in DDL log + public final static int ER_NULL_IN_VALUES_LESS_THAN = 1566; //SQLSTATE: HY000 Message: Not allowed to use NULL value in VALUES LESS THAN + public final static int ER_WRONG_PARTITION_NAME = 1567; //SQLSTATE: HY000 Message: Incorrect partition name + public final static int ER_CANT_CHANGE_TX_ISOLATION = 1568; //SQLSTATE: 25001 Message: Transaction isolation level can't be changed while a transaction is in progress + public final static int ER_DUP_ENTRY_AUTOINCREMENT_CASE = 1569; //SQLSTATE: HY000 Message: ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '%s' for key '%s' + public final static int ER_EVENT_MODIFY_QUEUE_ERROR = 1570; //SQLSTATE: HY000 Message: Internal scheduler error %d + public final static int ER_EVENT_SET_VAR_ERROR = 1571; //SQLSTATE: HY000 Message: Error during starting/stopping of the scheduler. Error code %u + public final static int ER_PARTITION_MERGE_ERROR = 1572; //SQLSTATE: HY000 Message: Engine cannot be used in partitioned tables + public final static int ER_CANT_ACTIVATE_LOG = 1573; //SQLSTATE: HY000 Message: Cannot activate '%s' log + public final static int ER_RBR_NOT_AVAILABLE = 1574; //SQLSTATE: HY000 Message: The server was not built with row-based replication + public final static int ER_BASE64_DECODE_ERROR = 1575; //SQLSTATE: HY000 Message: Decoding of base64 string failed + public final static int ER_EVENT_RECURSION_FORBIDDEN = 1576; //SQLSTATE: HY000 Message: Recursion of EVENT DDL statements is forbidden when body is present + public final static int ER_EVENTS_DB_ERROR = 1577; //SQLSTATE: HY000 Message: Cannot proceed because system tables used by Event Scheduler were found damaged at server start + public final static int ER_ONLY_INTEGERS_ALLOWED = 1578; //SQLSTATE: HY000 Message: Only integers allowed as number here + public final static int ER_UNSUPORTED_LOG_ENGINE = 1579; //SQLSTATE: HY000 Message: This storage engine cannot be used for log tables" + public final static int ER_BAD_LOG_STATEMENT = 1580; //SQLSTATE: HY000 Message: You cannot '%s' a log table if logging is enabled + public final static int ER_CANT_RENAME_LOG_TABLE = 1581; //SQLSTATE: HY000 Message: Cannot rename '%s'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to '%s' + public final static int ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT = 1582; //SQLSTATE: 42000 Message: Incorrect parameter count in the call to native function '%s' + public final static int ER_WRONG_PARAMETERS_TO_NATIVE_FCT = 1583; //SQLSTATE: 42000 Message: Incorrect parameters in the call to native function '%s' + public final static int ER_WRONG_PARAMETERS_TO_STORED_FCT = 1584; //SQLSTATE: 42000 Message: Incorrect parameters in the call to stored function '%s' + public final static int ER_NATIVE_FCT_NAME_COLLISION = 1585; //SQLSTATE: HY000 Message: This function '%s' has the same name as a native function + public final static int ER_DUP_ENTRY_WITH_KEY_NAME = 1586; //SQLSTATE: 23000 Message: Duplicate entry '%s' for key '%s' + public final static int ER_BINLOG_PURGE_EMFILE = 1587; //SQLSTATE: HY000 Message: Too many files opened, please execute the command again + public final static int ER_EVENT_CANNOT_CREATE_IN_THE_PAST = 1588; //SQLSTATE: HY000 Message: Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. + public final static int ER_EVENT_CANNOT_ALTER_IN_THE_PAST = 1589; //SQLSTATE: HY000 Message: Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. + public final static int ER_SLAVE_INCIDENT = 1590; //SQLSTATE: HY000 Message: The incident %s occured on the master. Message: %s + public final static int ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT = 1591; //SQLSTATE: HY000 Message: Table has no partition for some existing values + public final static int ER_BINLOG_UNSAFE_STATEMENT = 1592; //SQLSTATE: HY000 Message: Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. %s + public final static int ER_SLAVE_FATAL_ERROR = 1593; //SQLSTATE: HY000 Message: Fatal error: %s + public final static int ER_SLAVE_RELAY_LOG_READ_FAILURE = 1594; //SQLSTATE: HY000 Message: Relay log read failure: %s + public final static int ER_SLAVE_RELAY_LOG_WRITE_FAILURE = 1595; //SQLSTATE: HY000 Message: Relay log write failure: %s + public final static int ER_SLAVE_CREATE_EVENT_FAILURE = 1596; //SQLSTATE: HY000 Message: Failed to create %s + public final static int ER_SLAVE_MASTER_COM_FAILURE = 1597; //SQLSTATE: HY000 Message: Master command %s failed: %s + public final static int ER_BINLOG_LOGGING_IMPOSSIBLE = 1598; //SQLSTATE: HY000 Message: Binary logging not possible. Message: %s + public final static int ER_VIEW_NO_CREATION_CTX = 1599; //SQLSTATE: HY000 Message: View `%s`.`%s` has no creation context + public final static int ER_VIEW_INVALID_CREATION_CTX = 1600; //SQLSTATE: HY000 Message: Creation context of view `%s`.`%s' is invalid + public final static int ER_SR_INVALID_CREATION_CTX = 1601; //SQLSTATE: HY000 Message: Creation context of stored routine `%s`.`%s` is invalid + public final static int ER_TRG_CORRUPTED_FILE = 1602; //SQLSTATE: HY000 Message: Corrupted TRG file for table `%s`.`%s` + public final static int ER_TRG_NO_CREATION_CTX = 1603; //SQLSTATE: HY000 Message: Triggers for table `%s`.`%s` have no creation context + public final static int ER_TRG_INVALID_CREATION_CTX = 1604; //SQLSTATE: HY000 Message: Trigger creation context of table `%s`.`%s` is invalid + public final static int ER_EVENT_INVALID_CREATION_CTX = 1605; //SQLSTATE: HY000 Message: Creation context of event `%s`.`%s` is invalid + public final static int ER_TRG_CANT_OPEN_TABLE = 1606; //SQLSTATE: HY000 Message: Cannot open table for trigger `%s`.`%s` + public final static int ER_CANT_CREATE_SROUTINE = 1607; //SQLSTATE: HY000 Message: Cannot create stored routine `%s`. Check warnings + public final static int ER_NEVER_USED = 1608; //SQLSTATE: HY000 Message: Ambiguous slave modes combination. %s + public final static int ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT + = 1609; //SQLSTATE: HY000 Message: The BINLOG statement of type `%s` was not preceded by a format description BINLOG statement. + public final static int ER_SLAVE_CORRUPT_EVENT = 1610; //SQLSTATE: HY000 Message: Corrupted replication event was detected + public final static int ER_LOAD_DATA_INVALID_COLUMN = 1611; //SQLSTATE: HY000 Message: Invalid column reference (%s) in LOAD DATA + public final static int ER_LOG_PURGE_NO_FILE = 1612; //SQLSTATE: HY000 Message: Being purged log %s was not found + public final static int ER_XA_RBTIMEOUT = 1613; //SQLSTATE: XA106 Message: XA_RBTIMEOUT: Transaction branch was rolled back: took too long + public final static int ER_XA_RBDEADLOCK = 1614; //SQLSTATE: XA102 Message: XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected + public final static int ER_NEED_REPREPARE = 1615; //SQLSTATE: HY000 Message: Prepared statement needs to be re-prepared + public final static int ER_DELAYED_NOT_SUPPORTED = 1616; //SQLSTATE: HY000 Message: DELAYED option not supported for table '%s' + public final static int WARN_NO_MASTER_INFO = 1617; //SQLSTATE: HY000 Message: The master info structure does not exist + public final static int WARN_OPTION_IGNORED = 1618; //SQLSTATE: HY000 Message: <%s> option ignored + public final static int WARN_PLUGIN_DELETE_BUILTIN = 1619; //SQLSTATE: HY000 Message: Built-in plugins cannot be deleted + public final static int WARN_PLUGIN_BUSY = 1620; //SQLSTATE: HY000 Message: Plugin is busy and will be uninstalled on shutdown + public final static int ER_VARIABLE_IS_READONLY = 1621; //SQLSTATE: HY000 Message: %s variable '%s' is read-only. Use SET %s to assign the value + public final static int ER_WARN_ENGINE_TRANSACTION_ROLLBACK = 1622; //SQLSTATE: HY000 Message: Storage engine %s does not support rollback for this statement. Transaction rolled back and must be restarted + public final static int ER_SLAVE_HEARTBEAT_FAILURE = 1623; //SQLSTATE: HY000 Message: Unexpected master's heartbeat data: %s + public final static int ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE = 1624; //SQLSTATE: HY000 Message: The requested value for the heartbeat period is either negative or exceeds the maximum allowed (%s seconds). + public final static int ER_NDB_REPLICATION_SCHEMA_ERROR = 1625; //SQLSTATE: HY000 Message: Bad schema for mysql.ndb_replication table. Message: %s + public final static int ER_CONFLICT_FN_PARSE_ERROR = 1626; //SQLSTATE: HY000 Message: Error in parsing conflict function. Message: %s + public final static int ER_EXCEPTIONS_WRITE_ERROR = 1627; //SQLSTATE: HY000 Message: Write to exceptions table failed. Message: %s" + public final static int ER_TOO_LONG_TABLE_COMMENT = 1628; //SQLSTATE: HY000 Message: Comment for table '%s' is too long (max = %lu) + public final static int ER_TOO_LONG_FIELD_COMMENT = 1629; //SQLSTATE: HY000 Message: Comment for field '%s' is too long (max = %lu) + public final static int ER_FUNC_INEXISTENT_NAME_COLLISION = 1630; //SQLSTATE: 42000 Message: FUNCTION %s does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual + public final static int ER_DATABASE_NAME = 1631; //SQLSTATE: HY000 Message: Database + public final static int ER_TABLE_NAME = 1632; //SQLSTATE: HY000 Message: Table + public final static int ER_PARTITION_NAME = 1633; //SQLSTATE: HY000 Message: Partition + public final static int ER_SUBPARTITION_NAME = 1634; //SQLSTATE: HY000 Message: Subpartition + public final static int ER_TEMPORARY_NAME = 1635; //SQLSTATE: HY000 Message: Temporary + public final static int ER_RENAMED_NAME = 1636; //SQLSTATE: HY000 Message: Renamed + public final static int ER_TOO_MANY_CONCURRENT_TRXS = 1637; //SQLSTATE: HY000 Message: Too many active concurrent transactions + public final static int WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED = 1638; //SQLSTATE: HY000 Message: Non-ASCII separator arguments are not fully supported + public final static int ER_DEBUG_SYNC_TIMEOUT = 1639; //SQLSTATE: HY000 Message: debug sync point wait timed out + public final static int ER_DEBUG_SYNC_HIT_LIMIT = 1640; //SQLSTATE: HY000 Message: debug sync point hit limit reached + public final static int ER_DUP_SIGNAL_SET = 1641; //SQLSTATE: 42000 Message: Duplicate condition information item '%s' + public final static int ER_SIGNAL_WARN = 1642; //SQLSTATE: 01000 Message: Unhandled user-defined warning condition + public final static int ER_SIGNAL_NOT_FOUND = 1643; //SQLSTATE: 02000 Message: Unhandled user-defined not found condition + public final static int ER_SIGNAL_EXCEPTION = 1644; //SQLSTATE: HY000 Message: Unhandled user-defined exception condition + public final static int ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER = 1645; //SQLSTATE: 0K000 Message: RESIGNAL when handler not active + public final static int ER_SIGNAL_BAD_CONDITION_TYPE = 1646; //SQLSTATE: HY000 Message: SIGNAL/RESIGNAL can only use a CONDITION defined with; //SQLSTATE + public final static int WARN_COND_ITEM_TRUNCATED = 1647; //SQLSTATE: HY000 Message: Data truncated for condition item '%s' + public final static int ER_COND_ITEM_TOO_LONG = 1648; //SQLSTATE: HY000 Message: Data too long for condition item '%s' + public final static int ER_UNKNOWN_LOCALE = 1649; //SQLSTATE: HY000 Message: Unknown locale: '%s' + public final static int ER_SLAVE_IGNORE_SERVER_IDS = 1650; //SQLSTATE: HY000 Message: The requested server id %d clashes with the slave startup option --replicate-same-server-id + public final static int ER_QUERY_CACHE_DISABLED = 1651; //SQLSTATE: HY000 Message: Query cache is disabled; restart the server with query_cache_type=1 to enable it + public final static int ER_SAME_NAME_PARTITION_FIELD = 1652; //SQLSTATE: HY000 Message: Duplicate partition field name '%s' + public final static int ER_PARTITION_COLUMN_LIST_ERROR = 1653; //SQLSTATE: HY000 Message: Inconsistency in usage of column lists for partitioning + public final static int ER_WRONG_TYPE_COLUMN_VALUE_ERROR = 1654; //SQLSTATE: HY000 Message: Partition column values of incorrect type + public final static int ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR = 1655; //SQLSTATE: HY000 Message: Too many fields in '%s' + public final static int ER_MAXVALUE_IN_VALUES_IN = 1656; //SQLSTATE: HY000 Message: Cannot use MAXVALUE as value in VALUES IN + public final static int ER_TOO_MANY_VALUES_ERROR = 1657; //SQLSTATE: HY000 Message: Cannot have more than one value for this type of %s partitioning + public final static int ER_ROW_SINGLE_PARTITION_FIELD_ERROR = 1658; //SQLSTATE: HY000 Message: Row expressions in VALUES IN only allowed for multi-field column partitioning + public final static int ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD + = 1659; //SQLSTATE: HY000 Message: Field '%s' is of a not allowed type for this type of partitioning + public final static int ER_PARTITION_FIELDS_TOO_LONG = 1660; //SQLSTATE: HY000 Message: The total length of the partitioning fields is too large + public final static int ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE = 1661; //SQLSTATE: HY000 Message: Cannot execute statement: impossible to write to binary log since both row-incapable engines and statement-incapable engines are involved. + public final static int ER_BINLOG_ROW_MODE_AND_STMT_ENGINE = 1662; //SQLSTATE: HY000 Message: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-based logging. + public final static int ER_BINLOG_UNSAFE_AND_STMT_ENGINE = 1663; //SQLSTATE: HY000 Message: Cannot execute statement: impossible to write to binary log since statement is unsafe, storage engine is limited to statement-based logging, and BINLOG_FORMAT = MIXED. %s + public final static int ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE = 1664; //SQLSTATE: HY000 Message: Cannot execute statement: impossible to write to binary log since statement is in row format and at least one table uses a storage engine limited to statement-based logging. + public final static int ER_BINLOG_STMT_MODE_AND_ROW_ENGINE = 1665; //SQLSTATE: HY000 Message: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging.%s + public final static int ER_BINLOG_ROW_INJECTION_AND_STMT_MODE = 1666; //SQLSTATE: HY000 Message: Cannot execute statement: impossible to write to binary log since statement is in row format and BINLOG_FORMAT = STATEMENT. + public final static int ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE + = 1667; //SQLSTATE: HY000 Message: Cannot execute statement: impossible to write to binary log since more than one engine is involved and at least one engine is self-logging. + public final static int ER_BINLOG_UNSAFE_LIMIT = 1668; //SQLSTATE: HY000 Message: The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted. + public final static int ER_BINLOG_UNSAFE_INSERT_DELAYED = 1669; //SQLSTATE: HY000 Message: The statement is unsafe because it uses INSERT DELAYED. This is unsafe because the times when rows are inserted cannot be predicted. + public final static int ER_BINLOG_UNSAFE_SYSTEM_TABLE = 1670; //SQLSTATE: HY000 Message: The statement is unsafe because it uses the general log, slow query log, or performance_schema table(s). This is unsafe because system tables may differ on slaves. + public final static int ER_BINLOG_UNSAFE_AUTOINC_COLUMNS = 1671; //SQLSTATE: HY000 Message: Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly. + public final static int ER_BINLOG_UNSAFE_UDF = 1672; //SQLSTATE: HY000 Message: Statement is unsafe because it uses a UDF which may not return the same value on the slave. + public final static int ER_BINLOG_UNSAFE_SYSTEM_VARIABLE = 1673; //SQLSTATE: HY000 Message: Statement is unsafe because it uses a system variable that may have a different value on the slave. + public final static int ER_BINLOG_UNSAFE_SYSTEM_FUNCTION = 1674; //SQLSTATE: HY000 Message: Statement is unsafe because it uses a system function that may return a different value on the slave. + public final static int ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS = 1675; //SQLSTATE: HY000 Message: Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction. + public final static int ER_MESSAGE_AND_STATEMENT = 1676; //SQLSTATE: HY000 Message: %s Statement: %s + public final static int ER_SLAVE_CONVERSION_FAILED = 1677; //SQLSTATE: HY000 Message: Column %d of table '%s.%s' cannot be converted from type '%s' to type '%s' + public final static int ER_SLAVE_CANT_CREATE_CONVERSION = 1678; //SQLSTATE: HY000 Message: Can't create conversion table for table '%s.%s' + public final static int ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT + = 1679; //SQLSTATE: HY000 Message: Cannot modify @@session.binlog_format inside a transaction + public final static int ER_PATH_LENGTH = 1680; //SQLSTATE: HY000 Message: The path specified for %s is too long. + public final static int ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT = 1681; //SQLSTATE: HY000 Message: The syntax '%s' is deprecated and will be removed in MySQL %s. + public final static int ER_WRONG_NATIVE_TABLE_STRUCTURE = 1682; //SQLSTATE: HY000 Message: Native table '%s'.'%s' has the wrong structure + public final static int ER_WRONG_PERFSCHEMA_USAGE = 1683; //SQLSTATE: HY000 Message: Invalid performance_schema usage. + public final static int ER_WARN_I_S_SKIPPED_TABLE = 1684; //SQLSTATE: HY000 Message: Table '%s'.'%s' was skipped since its definition is being modified by concurrent DDL statement + public final static int ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT + = 1685; //SQLSTATE: HY000 Message: Cannot modify @@session.binlog_direct_non_transactional_updates inside a transaction + public final static int ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT + = 1686; //SQLSTATE: HY000 Message: Cannot change the binlog direct flag inside a stored function or trigger + public final static int ER_SPATIAL_MUST_HAVE_GEOM_COL = 1687; //SQLSTATE: 42000 Message: A SPATIAL index may only contain a geometrical type column + public final static int ER_TOO_LONG_INDEX_COMMENT = 1688; //SQLSTATE: HY000 Message: Comment for index '%s' is too long (max = %lu) + public final static int ER_LOCK_ABORTED = 1689; //SQLSTATE: HY000 Message: Wait on a lock was aborted due to a pending exclusive lock + public final static int ER_DATA_OUT_OF_RANGE = 1690; //SQLSTATE: 22003 Message: %s value is out of range in '%s' + public final static int ER_WRONG_SPVAR_TYPE_IN_LIMIT = 1691; //SQLSTATE: HY000 Message: A variable of a non-integer type in LIMIT clause + public final static int ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE + = 1692; //SQLSTATE: HY000 Message: Mixing self-logging and non-self-logging engines in a statement is unsafe. + public final static int ER_BINLOG_UNSAFE_MIXED_STATEMENT = 1693; //SQLSTATE: HY000 Message: Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them. + public final static int ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN + = 1694; //SQLSTATE: HY000 Message: Cannot modify @@session.sql_log_bin inside a transaction + public final static int ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN + = 1695; //SQLSTATE: HY000 Message: Cannot change the sql_log_bin inside a stored function or trigger + public final static int ER_FAILED_READ_FROM_PAR_FILE = 1696; //SQLSTATE: HY000 Message: Failed to read from the .par file + public final static int ER_VALUES_IS_NOT_INT_TYPE_ERROR = 1697; //SQLSTATE: HY000 Message: VALUES value for partition '%s' must have type INT + public final static int ER_ACCESS_DENIED_NO_PASSWORD_ERROR = 1698; //SQLSTATE: 28000 Message: Access denied for user '%s'@'%s' + public final static int ER_SET_PASSWORD_AUTH_PLUGIN = 1699; //SQLSTATE: HY000 Message: SET PASSWORD has no significance for users authenticating via plugins + public final static int ER_GRANT_PLUGIN_USER_EXISTS = 1700; //SQLSTATE: HY000 Message: GRANT with IDENTIFIED WITH is illegal because the user %-.*s already exists + public final static int ER_TRUNCATE_ILLEGAL_FK = 1701; //SQLSTATE: 42000 Message: Cannot truncate a table referenced in a foreign key constraint (%s) + public final static int ER_PLUGIN_IS_PERMANENT = 1702; //SQLSTATE: HY000 Message: Plugin '%s' is force_plus_permanent and can not be unloaded + public final static int ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN = 1703; //SQLSTATE: HY000 Message: The requested value for the heartbeat period is less than 1 millisecond. The value is reset to 0, meaning that heartbeating will effectively be disabled. + public final static int ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX = 1704; //SQLSTATE: HY000 Message: The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout. + public final static int ER_STMT_CACHE_FULL = 1705; //SQLSTATE: HY000 Message: Multi-row statements required more than 'max_binlog_stmt_cache_size' bytes of storage; increase this mysqld variable and try again - public final static int ER_ACCESS_DENIED_ERROR = 1045; + public final static int ER_MULTI_UPDATE_KEY_CONFLICT = 1706; //SQLSTATE: HY000 Message: Primary key/partition key update is not allowed since the table is updated both as '%s' and '%s'. + public final static int ER_TABLE_NEEDS_REBUILD = 1707; //SQLSTATE: HY000 Message: Table rebuild required. Please do "ALTER TABLE `%s` FORCE" or dump/reload to fix it! + public final static int WARN_OPTION_BELOW_LIMIT = 1708; //SQLSTATE: HY000 Message: The value of '%s' should be no less than the value of '%s' + public final static int ER_INDEX_COLUMN_TOO_LONG = 1709; //SQLSTATE: HY000 Message: Index column size too large. The maximum column size is %lu bytes. + public final static int ER_ERROR_IN_TRIGGER_BODY = 1710; //SQLSTATE: HY000 Message: Trigger '%s' has an error in its body: '%s' + public final static int ER_ERROR_IN_UNKNOWN_TRIGGER_BODY = 1711; //SQLSTATE: HY000 Message: Unknown trigger has an error in its body: '%s' + public final static int ER_INDEX_CORRUPT = 1712; //SQLSTATE: HY000 Message: Index %s is corrupted + public final static int ER_UNDO_RECORD_TOO_BIG = 1713; //SQLSTATE: HY000 Message: Undo log record is too big. + public final static int ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT = 1714; //SQLSTATE: HY000 Message: INSERT IGNORE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave. + public final static int ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE = 1715; //SQLSTATE: HY000 Message: INSERT... SELECT... ON DUPLICATE KEY UPDATE is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are updated. This order cannot be predicted and may differ on master and the slave. + public final static int ER_BINLOG_UNSAFE_REPLACE_SELECT = 1716; //SQLSTATE: HY000 Message: REPLACE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave. + public final static int ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT = 1717; //SQLSTATE: HY000 Message: CREATE... IGNORE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave. + public final static int ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT = 1718; //SQLSTATE: HY000 Message: CREATE... REPLACE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave. + public final static int ER_BINLOG_UNSAFE_UPDATE_IGNORE = 1719; //SQLSTATE: HY000 Message: UPDATE IGNORE is unsafe because the order in which rows are updated determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave. + public final static int ER_PLUGIN_NO_UNINSTALL = 1720; //SQLSTATE: HY000 Message: Plugin '%s' is marked as not dynamically uninstallable. You have to stop the server to uninstall it. + public final static int ER_PLUGIN_NO_INSTALL = 1721; //SQLSTATE: HY000 Message: Plugin '%s' is marked as not dynamically installable. You have to stop the server to install it. + public final static int ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT = 1722; //SQLSTATE: HY000 Message: Statements writing to a table with an auto-increment column after selecting from another table are unsafe because the order in which rows are retrieved determines what (if any) rows will be written. This order cannot be predicted and may differ on master and the slave. + public final static int ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC = 1723; //SQLSTATE: HY000 Message: CREATE TABLE... SELECT... on a table with an auto-increment column is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are inserted. This order cannot be predicted and may differ on master and the slave. + public final static int ER_BINLOG_UNSAFE_INSERT_TWO_KEYS = 1724; //SQLSTATE: HY000 Message: INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe + public final static int ER_TABLE_IN_FK_CHECK = 1725; //SQLSTATE: HY000 Message: Table is being used in foreign key check. + public final static int ER_UNSUPPORTED_ENGINE = 1726; //SQLSTATE: HY000 Message: Storage engine '%s' does not support system tables. [%s.%s] + public final static int ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST = 1727; //SQLSTATE: HY000 Message: INSERT into autoincrement field which is not the first part in the composed primary key is unsafe. + public final static int ER_CANNOT_LOAD_FROM_TABLE_V2 = 1728; //SQLSTATE: HY000 Message: Cannot load from %s.%s. The table is probably corrupted + public final static int ER_MASTER_DELAY_VALUE_OUT_OF_RANGE = 1729; //SQLSTATE: HY000 Message: The requested value %u for the master delay exceeds the maximum %u + public final static int ER_ONLY_FD_AND_RBR_EVENTS_ALLOWED_IN_BINLOG_STATEMENT + = 1730; //SQLSTATE: HY000 Message: Only Format_description_log_event and row events are allowed in BINLOG statements (but %s was provided) + public final static int ER_PARTITION_EXCHANGE_DIFFERENT_OPTION = 1731; //SQLSTATE: HY000 Message: Non matching attribute '%s' between partition and table + public final static int ER_PARTITION_EXCHANGE_PART_TABLE = 1732; //SQLSTATE: HY000 Message: Table to exchange with partition is partitioned: '%s' + public final static int ER_PARTITION_EXCHANGE_TEMP_TABLE = 1733; //SQLSTATE: HY000 Message: Table to exchange with partition is temporary: '%s' + public final static int ER_PARTITION_INSTEAD_OF_SUBPARTITION = 1734; //SQLSTATE: HY000 Message: Subpartitioned table, use subpartition instead of partition + public final static int ER_UNKNOWN_PARTITION = 1735; //SQLSTATE: HY000 Message: Unknown partition '%s' in table '%s' + public final static int ER_TABLES_DIFFERENT_METADATA = 1736; //SQLSTATE: HY000 Message: Tables have different definitions + public final static int ER_ROW_DOES_NOT_MATCH_PARTITION = 1737; //SQLSTATE: HY000 Message: Found a row that does not match the partition + public final static int ER_BINLOG_CACHE_SIZE_GREATER_THAN_MAX = 1738; //SQLSTATE: HY000 Message: Option binlog_cache_size (%lu) is greater than max_binlog_cache_size (%lu); setting binlog_cache_size equal to max_binlog_cache_size. + public final static int ER_WARN_INDEX_NOT_APPLICABLE = 1739; //SQLSTATE: HY000 Message: Cannot use %s access on index '%s' due to type or collation conversion on field '%s' + public final static int ER_PARTITION_EXCHANGE_FOREIGN_KEY = 1740; //SQLSTATE: HY000 Message: Table to exchange with partition has foreign key references: '%s' + public final static int ER_NO_SUCH_KEY_VALUE = 1741; //SQLSTATE: HY000 Message: Key value '%s' was not found in table '%s.%s' + public final static int ER_RPL_INFO_DATA_TOO_LONG = 1742; //SQLSTATE: HY000 Message: Data for column '%s' too long + public final static int ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE = 1743; //SQLSTATE: HY000 Message: Replication event checksum verification failed while reading from network. + public final static int ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE = 1744; //SQLSTATE: HY000 Message: Replication event checksum verification failed while reading from a log file. + public final static int ER_BINLOG_STMT_CACHE_SIZE_GREATER_THAN_MAX = 1745; //SQLSTATE: HY000 Message: Option binlog_stmt_cache_size (%lu) is greater than max_binlog_stmt_cache_size (%lu); setting binlog_stmt_cache_size equal to max_binlog_stmt_cache_size. + public final static int ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT = 1746; //SQLSTATE: HY000 Message: Can't update table '%s' while '%s' is being created. + public final static int ER_PARTITION_CLAUSE_ON_NONPARTITIONED = 1747; //SQLSTATE: HY000 Message: PARTITION () clause on non partitioned table + public final static int ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET = 1748; //SQLSTATE: HY000 Message: Found a row not matching the given partition set + public final static int ER_NO_SUCH_PARTITION__UNUSED = 1749; //SQLSTATE: HY000 Message: partition '%s' doesn't exist + public final static int ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE = 1750; //SQLSTATE: HY000 Message: Failure while changing the type of replication repository: %s. + public final static int ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE + = 1751; //SQLSTATE: HY000 Message: The creation of some temporary tables could not be rolled back. + public final static int ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE + = 1752; //SQLSTATE: HY000 Message: Some temporary tables were dropped, but these operations could not be rolled back. + public final static int ER_MTS_FEATURE_IS_NOT_SUPPORTED = 1753; //SQLSTATE: HY000 Message: %s is not supported in multi-threaded slave mode. %s + public final static int ER_MTS_UPDATED_DBS_GREATER_MAX = 1754; //SQLSTATE: HY000 Message: The number of modified databases exceeds the maximum %d; the database names will not be included in the replication event metadata. + public final static int ER_MTS_CANT_PARALLEL = 1755; //SQLSTATE: HY000 Message: Cannot execute the current event group in the parallel mode. Encountered event %s, relay-log name %s, position %s which prevents execution of this event group in parallel mode. Reason: %s. + public final static int ER_MTS_INCONSISTENT_DATA = 1756; //SQLSTATE: HY000 Message: %s + public final static int ER_FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING = 1757; //SQLSTATE: HY000 Message: FULLTEXT index is not supported for partitioned tables. + public final static int ER_DA_INVALID_CONDITION_NUMBER = 1758; //SQLSTATE: 35000 Message: Invalid condition number + public final static int ER_INSECURE_PLAIN_TEXT = 1759; //SQLSTATE: HY000 Message: Sending passwords in plain text without SSL/TLS is extremely insecure. + public final static int ER_INSECURE_CHANGE_MASTER = 1760; //SQLSTATE: HY000 Message: Storing MySQL user name or password information in the master.info repository is not secure and is therefore not recommended. Please see the MySQL Manual for more about this issue and possible alternatives. + public final static int ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO = 1761; //SQLSTATE: 23000 Message: Foreign key constraint for table '%s', record '%s' would lead to a duplicate entry in table '%s', key '%s' + public final static int ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO = 1762; //SQLSTATE: 23000 Message: Foreign key constraint for table '%s', record '%s' would lead to a duplicate entry in a child table + public final static int ER_SQLTHREAD_WITH_SECURE_SLAVE = 1763; //SQLSTATE: HY000 Message: Setting authentication options is not possible when only the Slave SQL Thread is being started. + public final static int ER_TABLE_HAS_NO_FT = 1764; //SQLSTATE: HY000 Message: The table does not have FULLTEXT index to support this query + public final static int ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER = 1765; //SQLSTATE: HY000 Message: The system variable %s cannot be set in stored functions or triggers. + public final static int ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION = 1766; //SQLSTATE: HY000 Message: The system variable %s cannot be set when there is an ongoing transaction. + public final static int ER_GTID_NEXT_IS_NOT_IN_GTID_NEXT_LIST = 1767; //SQLSTATE: HY000 Message: The system variable @@SESSION.GTID_NEXT has the value %s, which is not listed in @@SESSION.GTID_NEXT_LIST. + public final static int ER_CANT_CHANGE_GTID_NEXT_IN_TRANSACTION_WHEN_GTID_NEXT_LIST_IS_NULL + = 1768; //SQLSTATE: HY000 Message: When @@SESSION.GTID_NEXT_LIST == NULL, the system variable @@SESSION.GTID_NEXT cannot change inside a transaction. + public final static int ER_SET_STATEMENT_CANNOT_INVOKE_FUNCTION = 1769; //SQLSTATE: HY000 Message: The statement 'SET %s' cannot invoke a stored function. + public final static int ER_GTID_NEXT_CANT_BE_AUTOMATIC_IF_GTID_NEXT_LIST_IS_NON_NULL + = 1770; //SQLSTATE: HY000 Message: The system variable @@SESSION.GTID_NEXT cannot be 'AUTOMATIC' when @@SESSION.GTID_NEXT_LIST is non-NULL. + public final static int ER_SKIPPING_LOGGED_TRANSACTION = 1771; //SQLSTATE: HY000 Message: Skipping transaction %s because it has already been executed and logged. + public final static int ER_MALFORMED_GTID_SET_SPECIFICATION = 1772; //SQLSTATE: HY000 Message: Malformed GTID set specification '%s'. + public final static int ER_MALFORMED_GTID_SET_ENCODING = 1773; //SQLSTATE: HY000 Message: Malformed GTID set encoding. + public final static int ER_MALFORMED_GTID_SPECIFICATION = 1774; //SQLSTATE: HY000 Message: Malformed GTID specification '%s'. + public final static int ER_GNO_EXHAUSTED = 1775; //SQLSTATE: HY000 Message: Impossible to generate Global Transaction Identifier: the integer component reached the maximal value. Restart the server with a new server_uuid. + public final static int ER_BAD_SLAVE_AUTO_POSITION = 1776; //SQLSTATE: HY000 Message: Parameters MASTER_LOG_FILE, MASTER_LOG_POS, RELAY_LOG_FILE and RELAY_LOG_POS cannot be set when MASTER_AUTO_POSITION is active. + public final static int ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON = 1777; //SQLSTATE: HY000 Message: CHANGE MASTER TO MASTER_AUTO_POSITION = 1 can only be executed when GTID_MODE = ON. + public final static int ER_CANT_DO_IMPLICIT_COMMIT_IN_TRX_WHEN_GTID_NEXT_IS_SET + = 1778; //SQLSTATE: HY000 Message: Cannot execute statements with implicit commit inside a transaction when GTID_NEXT != AUTOMATIC or GTID_NEXT_LIST != NULL. + public final static int ER_GTID_MODE_2_OR_3_REQUIRES_ENFORCE_GTID_CONSISTENCY_ON + = 1779; //SQLSTATE: HY000 Message: GTID_MODE = ON or GTID_MODE = UPGRADE_STEP_2 requires ENFORCE_GTID_CONSISTENCY = 1. + public final static int ER_GTID_MODE_REQUIRES_BINLOG = 1780; //SQLSTATE: HY000 Message: GTID_MODE = ON or UPGRADE_STEP_1 or UPGRADE_STEP_2 requires --log-bin and --log-slave-updates. + public final static int ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF + = 1781; //SQLSTATE: HY000 Message: GTID_NEXT cannot be set to UUID:NUMBER when GTID_MODE = OFF. + public final static int ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON + = 1782; //SQLSTATE: HY000 Message: GTID_NEXT cannot be set to ANONYMOUS when GTID_MODE = ON. + public final static int ER_CANT_SET_GTID_NEXT_LIST_TO_NON_NULL_WHEN_GTID_MODE_IS_OFF + = 1783; //SQLSTATE: HY000 Message: GTID_NEXT_LIST cannot be set to a non-NULL value when GTID_MODE = OFF. + public final static int ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF = 1784; //SQLSTATE: HY000 Message: Found a Gtid_log_event or Previous_gtids_log_event when GTID_MODE = OFF. + public final static int ER_GTID_UNSAFE_NON_TRANSACTIONAL_TABLE = 1785; //SQLSTATE: HY000 Message: When ENFORCE_GTID_CONSISTENCY = 1, updates to non-transactional tables can only be done in either autocommitted statements or single-statement transactions, and never in the same statement as updates to transactional tables. + public final static int ER_GTID_UNSAFE_CREATE_SELECT = 1786; //SQLSTATE: HY000 Message: CREATE TABLE ... SELECT is forbidden when ENFORCE_GTID_CONSISTENCY = 1. + public final static int ER_GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION + = 1787; //SQLSTATE: HY000 Message: When ENFORCE_GTID_CONSISTENCY = 1, the statements CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE can be executed in a non-transactional context only, and require that AUTOCOMMIT = 1. + public final static int ER_GTID_MODE_CAN_ONLY_CHANGE_ONE_STEP_AT_A_TIME + = 1788; //SQLSTATE: HY000 Message: The value of GTID_MODE can only change one step at a time: OFF <-> UPGRADE_STEP_1 <-> UPGRADE_STEP_2 <-> ON. Also note that this value must be stepped up or down simultaneously on all servers; see the Manual for instructions. + public final static int ER_MASTER_HAS_PURGED_REQUIRED_GTIDS = 1789; //SQLSTATE: HY000 Message: The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires. + public final static int ER_CANT_SET_GTID_NEXT_WHEN_OWNING_GTID = 1790; //SQLSTATE: HY000 Message: GTID_NEXT cannot be changed by a client that owns a GTID. The client owns %s. Ownership is released on COMMIT or ROLLBACK. + public final static int ER_UNKNOWN_EXPLAIN_FORMAT = 1791; //SQLSTATE: HY000 Message: Unknown EXPLAIN format name: '%s' + public final static int ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION = 1792; //SQLSTATE: 25006 Message: Cannot execute statement in a READ ONLY transaction. + public final static int ER_TOO_LONG_TABLE_PARTITION_COMMENT = 1793; //SQLSTATE: HY000 Message: Comment for table partition '%s' is too long (max = %lu) + public final static int ER_SLAVE_CONFIGURATION = 1794; //SQLSTATE: HY000 Message: Slave is not configured or failed to initialize properly. You must at least set --server-id to enable either a master or a slave. Additional error messages can be found in the MySQL error log. + public final static int ER_INNODB_FT_LIMIT = 1795; //SQLSTATE: HY000 Message: InnoDB presently supports one FULLTEXT index creation at a time + public final static int ER_INNODB_NO_FT_TEMP_TABLE = 1796; //SQLSTATE: HY000 Message: Cannot create FULLTEXT index on temporary InnoDB table + public final static int ER_INNODB_FT_WRONG_DOCID_COLUMN = 1797; //SQLSTATE: HY000 Message: Column '%s' is of wrong type for an InnoDB FULLTEXT index + public final static int ER_INNODB_FT_WRONG_DOCID_INDEX = 1798; //SQLSTATE: HY000 Message: Index '%s' is of wrong type for an InnoDB FULLTEXT index + public final static int ER_INNODB_ONLINE_LOG_TOO_BIG = 1799; //SQLSTATE: HY000 Message: Creating index '%s' required more than 'innodb_online_alter_log_max_size' bytes of modification log. Please try again. + public final static int ER_UNKNOWN_ALTER_ALGORITHM = 1800; //SQLSTATE: HY000 Message: Unknown ALGORITHM '%s' + public final static int ER_UNKNOWN_ALTER_LOCK = 1801; //SQLSTATE: HY000 Message: Unknown LOCK type '%s' + public final static int ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS = 1802; //SQLSTATE: HY000 Message: CHANGE MASTER cannot be executed when the slave was stopped with an error or killed in MTS mode. Consider using RESET SLAVE or START SLAVE UNTIL. + public final static int ER_MTS_RECOVERY_FAILURE = 1803; //SQLSTATE: HY000 Message: Cannot recover after SLAVE errored out in parallel execution mode. Additional error messages can be found in the MySQL error log. + public final static int ER_MTS_RESET_WORKERS = 1804; //SQLSTATE: HY000 Message: Cannot clean up worker info tables. Additional error messages can be found in the MySQL error log. + public final static int ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2 = 1805; //SQLSTATE: HY000 Message: Column count of %s.%s is wrong. Expected %d, found %d. The table is probably corrupted + public final static int ER_SLAVE_SILENT_RETRY_TRANSACTION = 1806; //SQLSTATE: HY000 Message: Slave must silently retry current transaction + public final static int ER_DISCARD_FK_CHECKS_RUNNING = 1807; //SQLSTATE: HY000 Message: There is a foreign key check running on table '%s'. Cannot discard the table. + public final static int ER_TABLE_SCHEMA_MISMATCH = 1808; //SQLSTATE: HY000 Message: Schema mismatch (%s) + public final static int ER_TABLE_IN_SYSTEM_TABLESPACE = 1809; //SQLSTATE: HY000 Message: Table '%s' in system tablespace + public final static int ER_IO_READ_ERROR = 1810; //SQLSTATE: HY000 Message: IO Read error: (%lu, %s) %s + public final static int ER_IO_WRITE_ERROR = 1811; //SQLSTATE: HY000 Message: IO Write error: (%lu, %s) %s + public final static int ER_TABLESPACE_MISSING = 1812; //SQLSTATE: HY000 Message: Tablespace is missing for table '%s' + public final static int ER_TABLESPACE_EXISTS = 1813; //SQLSTATE: HY000 Message: Tablespace for table '%s' exists. Please DISCARD the tablespace before IMPORT. + public final static int ER_TABLESPACE_DISCARDED = 1814; //SQLSTATE: HY000 Message: Tablespace has been discarded for table '%s' + public final static int ER_INTERNAL_ERROR = 1815; //SQLSTATE: HY000 Message: Internal error: %s + public final static int ER_INNODB_IMPORT_ERROR = 1816; //SQLSTATE: HY000 Message: ALTER TABLE '%s' IMPORT TABLESPACE failed with error %lu : '%s' + public final static int ER_INNODB_INDEX_CORRUPT = 1817; //SQLSTATE: HY000 Message: Index corrupt: %s + public final static int ER_INVALID_YEAR_COLUMN_LENGTH = 1818; //SQLSTATE: HY000 Message: YEAR(%lu) column type is deprecated. Creating YEAR(4) column instead. + public final static int ER_NOT_VALID_PASSWORD = 1819; //SQLSTATE: HY000 Message: Your password does not satisfy the current policy requirements + public final static int ER_MUST_CHANGE_PASSWORD = 1820; //SQLSTATE: HY000 Message: You must SET PASSWORD before executing this statement + public final static int ER_FK_NO_INDEX_CHILD = 1821; //SQLSTATE: HY000 Message: Failed to add the foreign key constaint. Missing index for constraint '%s' in the foreign table '%s' + public final static int ER_FK_NO_INDEX_PARENT = 1822; //SQLSTATE: HY000 Message: Failed to add the foreign key constaint. Missing index for constraint '%s' in the referenced table '%s' + public final static int ER_FK_FAIL_ADD_SYSTEM = 1823; //SQLSTATE: HY000 Message: Failed to add the foreign key constraint '%s' to system tables + public final static int ER_FK_CANNOT_OPEN_PARENT = 1824; //SQLSTATE: HY000 Message: Failed to open the referenced table '%s' + public final static int ER_FK_INCORRECT_OPTION = 1825; //SQLSTATE: HY000 Message: Failed to add the foreign key constraint on table '%s'. Incorrect options in FOREIGN KEY constraint '%s' + public final static int ER_FK_DUP_NAME = 1826; //SQLSTATE: HY000 Message: Duplicate foreign key constraint name '%s' + public final static int ER_PASSWORD_FORMAT = 1827; //SQLSTATE: HY000 Message: The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function. + public final static int ER_FK_COLUMN_CANNOT_DROP = 1828; //SQLSTATE: HY000 Message: Cannot drop column '%s': needed in a foreign key constraint '%s' + public final static int ER_FK_COLUMN_CANNOT_DROP_CHILD = 1829; //SQLSTATE: HY000 Message: Cannot drop column '%s': needed in a foreign key constraint '%s' of table '%s' + public final static int ER_FK_COLUMN_NOT_NULL = 1830; //SQLSTATE: HY000 Message: Column '%s' cannot be NOT NULL: needed in a foreign key constraint '%s' SET NULL + public final static int ER_DUP_INDEX = 1831; //SQLSTATE: HY000 Message: Duplicate index '%s' defined on the table '%s.%s'. This is deprecated and will be disallowed in a future release. + public final static int ER_FK_COLUMN_CANNOT_CHANGE = 1832; //SQLSTATE: HY000 Message: Cannot change column '%s': used in a foreign key constraint '%s' + public final static int ER_FK_COLUMN_CANNOT_CHANGE_CHILD = 1833; //SQLSTATE: HY000 Message: Cannot change column '%s': used in a foreign key constraint '%s' of table '%s' + public final static int ER_FK_CANNOT_DELETE_PARENT = 1834; //SQLSTATE: HY000 Message: Cannot delete rows from table which is parent in a foreign key constraint '%s' of table '%s' + public final static int ER_MALFORMED_PACKET = 1835; //SQLSTATE: HY000 Message: Malformed communication packet. + public final static int ER_READ_ONLY_MODE = 1836; //SQLSTATE: HY000 Message: Running in read-only mode + public final static int ER_GTID_NEXT_TYPE_UNDEFINED_GROUP = 1837; //SQLSTATE: HY000 Message: When GTID_NEXT is set to a GTID, you must explicitly set it again after a COMMIT or ROLLBACK. If you see this error message in the slave SQL thread, it means that a table in the current transaction is transactional on the master and non-transactional on the slave. In a client connection, it means that you executed SET GTID_NEXT before a transaction and forgot to set GTID_NEXT to a different identifier or to 'AUTOMATIC' after COMMIT or ROLLBACK. Current GTID_NEXT is '%s'. + public final static int ER_VARIABLE_NOT_SETTABLE_IN_SP = 1838; //SQLSTATE: HY000 Message: The system variable %s cannot be set in stored procedures. + public final static int ER_CANT_SET_GTID_PURGED_WHEN_GTID_MODE_IS_OFF + = 1839; //SQLSTATE: HY000 Message: GTID_PURGED can only be set when GTID_MODE = ON. + public final static int ER_CANT_SET_GTID_PURGED_WHEN_GTID_EXECUTED_IS_NOT_EMPTY + = 1840; //SQLSTATE: HY000 Message: GTID_PURGED can only be set when GTID_EXECUTED is empty. + public final static int ER_CANT_SET_GTID_PURGED_WHEN_OWNED_GTIDS_IS_NOT_EMPTY + = 1841; //SQLSTATE: HY000 Message: GTID_PURGED can only be set when there are no ongoing transactions (not even in other clients). + public final static int ER_GTID_PURGED_WAS_CHANGED = 1842; //SQLSTATE: HY000 Message: GTID_PURGED was changed from '%s' to '%s'. + public final static int ER_GTID_EXECUTED_WAS_CHANGED = 1843; //SQLSTATE: HY000 Message: GTID_EXECUTED was changed from '%s' to '%s'. + public final static int ER_BINLOG_STMT_MODE_AND_NO_REPL_TABLES = 1844; //SQLSTATE: HY000 Message: Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT, and both replicated and non replicated tables are written to. + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED = 1845; //SQLSTATE: 0A000 Message: %s is not supported for this operation. Try %s. + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON = 1846; //SQLSTATE: 0A000 Message: %s is not supported. Reason: %s. Try %s. + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COPY + = 1847; //SQLSTATE: HY000 Message: COPY algorithm requires a lock + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION + = 1848; //SQLSTATE: HY000 Message: Partition specific operations do not yet support LOCK/ALGORITHM + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME + = 1849; //SQLSTATE: HY000 Message: Columns participating in a foreign key are renamed + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE + = 1850; //SQLSTATE: HY000 Message: Cannot change column type INPLACE + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_CHECK + = 1851; //SQLSTATE: HY000 Message: Adding foreign keys needs foreign_key_checks=OFF + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_IGNORE + = 1852; //SQLSTATE: HY000 Message: Creating unique indexes with IGNORE requires COPY algorithm to remove duplicate rows + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOPK + = 1853; //SQLSTATE: HY000 Message: Dropping a primary key is not allowed without also adding a new primary key + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_AUTOINC + = 1854; //SQLSTATE: HY000 Message: Adding an auto-increment column requires a lock + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_HIDDEN_FTS + = 1855; //SQLSTATE: HY000 Message: Cannot replace hidden FTS_DOC_ID with a user-visible one + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS + = 1856; //SQLSTATE: HY000 Message: Cannot drop or rename FTS_DOC_ID + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS = 1857; //SQLSTATE: HY000 Message: Fulltext index creation requires a lock + public final static int ER_SQL_SLAVE_SKIP_COUNTER_NOT_SETTABLE_IN_GTID_MODE + = 1858; //SQLSTATE: HY000 Message: sql_slave_skip_counter can not be set when the server is running with GTID_MODE = ON. Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction + public final static int ER_DUP_UNKNOWN_IN_INDEX = 1859; //SQLSTATE: 23000 Message: Duplicate entry for key '%s' + public final static int ER_IDENT_CAUSES_TOO_LONG_PATH = 1860; //SQLSTATE: HY000 Message: Long database name and identifier for object resulted in path length exceeding %d characters. Path: '%s'. + public final static int ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL + = 1861; //SQLSTATE: HY000 Message: cannot silently convert NULL values, as required in this SQL_MODE; was introduced in 5.7.1. + public final static int ER_MUST_CHANGE_PASSWORD_LOGIN = 1862; //SQLSTATE: HY000 Message: Your password has expired. To log in you must change it using a client that supports expired passwords. was introduced in 5.7.1. + public final static int ER_ROW_IN_WRONG_PARTITION = 1863; //SQLSTATE: HY000 Message: Found a row in wrong partition %s; was introduced in 5.7.1. + public final static int ER_MTS_EVENT_BIGGER_PENDING_JOBS_SIZE_MAX = 1864; //SQLSTATE: HY000 Message: Cannot schedule event %s, relay-log name %s, position %s to Worker thread because its size %lu exceeds %lu of slave_pending_jobs_size_max.; was introduced in 5.7.2. - public final static int ER_ALTER_INFO = 1088; + public final static int ER_INNODB_NO_FT_USES_PARSER = 1865; //SQLSTATE: HY000 Message: Cannot CREATE FULLTEXT INDEX WITH PARSER on InnoDB table; was introduced in 5.7.2. + public final static int ER_BINLOG_LOGICAL_CORRUPTION = 1866; //SQLSTATE: HY000 Message: The binary log file '%s' is logically corrupted: %s; was introduced in 5.7.2. + public final static int ER_WARN_PURGE_LOG_IN_USE = 1867; //SQLSTATE: HY000 Message: file %s was not purged because it was being read by %d thread(s), purged only %d out of %d files. was introduced in 5.7.2. + public final static int ER_WARN_PURGE_LOG_IS_ACTIVE = 1868; //SQLSTATE: HY000 Message: file %s was not purged because it is the active log file.; was introduced in 5.7.2. + public final static int ER_AUTO_INCREMENT_CONFLICT = 1869; //SQLSTATE: HY000 Message: Auto-increment value in UPDATE conflicts with internally generated values; was introduced in 5.7.2. + public final static int WARN_ON_BLOCKHOLE_IN_RBR = 1870; //SQLSTATE: HY000 Message: Row events are not logged for %s statements that modify BLACKHOLE tables in row format. Table(s): '%s'; was introduced in 5.7.2. + public final static int ER_SLAVE_MI_INIT_REPOSITORY = 1871; //SQLSTATE: HY000 Message: Slave failed to initialize master info structure from the repository; was introduced in 5.7.2. + public final static int ER_SLAVE_RLI_INIT_REPOSITORY = 1872; //SQLSTATE: HY000 Message: Slave failed to initialize relay log info structure from the repository; was introduced in 5.7.2. + public final static int ER_ACCESS_DENIED_CHANGE_USER_ERROR = 1873; //SQLSTATE: 28000 Message: Access denied trying to change to user '%s'@'%s' (using password: %s). Disconnecting. was introduced in 5.7.2. + public final static int ER_INNODB_READ_ONLY = 1874; //SQLSTATE: HY000 Message: InnoDB is in read only mode.; was introduced in 5.7.2. + public final static int ER_STOP_SLAVE_SQL_THREAD_TIMEOUT = 1875; //SQLSTATE: HY000 Message: STOP SLAVE command execution is incomplete: Slave SQL thread got the stop signal, thread is busy, SQL thread will stop once the current task is complete.; was introduced in 5.7.2. + public final static int ER_STOP_SLAVE_IO_THREAD_TIMEOUT = 1876; //SQLSTATE: HY000 Message: STOP SLAVE command execution is incomplete: Slave IO thread got the stop signal, thread is busy, IO thread will stop once the current task is complete.; was introduced in 5.7.2. + public final static int ER_TABLE_CORRUPT = 1877; //SQLSTATE: HY000 Message: Operation cannot be performed. The table '%s.%s' is missing, corrupt or contains bad data.; was introduced in 5.7.2. + public final static int ER_TEMP_FILE_WRITE_FAILURE = 1878; //SQLSTATE: HY000 Message: Temporary file write failure.; was introduced in 5.7.3. + public final static int ER_INNODB_FT_AUX_NOT_HEX_ID = 1879; //SQLSTATE: HY000 Message: Upgrade index name failed, please use create index(alter table) algorithm copy to rebuild index.; was introduced in 5.7.4. + public final static int ER_OLD_TEMPORALS_UPGRADED = 1880; //SQLSTATE: HY000 Message: TIME/TIMESTAMP/DATETIME columns of old format have been upgraded to the new format.; was introduced in 5.7.4. + public final static int ER_INNODB_FORCED_RECOVERY = 1881; //SQLSTATE: HY000 Message: Operation not allowed when innodb_forced_recovery > 0.; was introduced in 5.7.4. + public final static int ER_AES_INVALID_IV = 1882; //SQLSTATE: HY000 Message: The initialization vector supplied to %s is too short. Must be at least %d bytes long; was introduced in 5.7.4. + public final static int ER_FILE_CORRUPT = 1883; //SQLSTATE: HY000 Message: File %s is corrupted + public final static int ER_ERROR_ON_MASTER = 1884; //SQLSTATE: HY000 Message: Query partially completed on the master (error on master: %d) and was aborted. There is a chance that your master is inconsistent at this point. If you are sure that your master is ok, run this query manually on the slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE;. Query:'%s' + public final static int ER_INCONSISTENT_ERROR = 1885; //SQLSTATE: HY000 Message: Query caused different errors on master and slave. Error on master: message (format)='%s' error code=%d; Error on slave:actual message='%s', error code=%d. Default database:'%s'. Query:'%s' + public final static int ER_STORAGE_ENGINE_NOT_LOADED = 1886; //SQLSTATE: HY000 Message: Storage engine for table '%s'.'%s' is not loaded. + public final static int ER_GET_STACKED_DA_WITHOUT_ACTIVE_HANDLER = 1887; //SQLSTATE: 0Z002 Message: GET STACKED DIAGNOSTICS when handler not active + public final static int ER_WARN_LEGACY_SYNTAX_CONVERTED = 1888; //SQLSTATE: HY000 Message: %s is no longer supported. The statement was converted to %s. + public final static int ER_BINLOG_UNSAFE_FULLTEXT_PLUGIN = 1889; //SQLSTATE: HY000 Message: Statement is unsafe because it uses a fulltext parser plugin which may not return the same value on the slave.; was introduced in 5.7.1. + public final static int ER_CANNOT_DISCARD_TEMPORARY_TABLE = 1890; //SQLSTATE: HY000 Message: Cannot DISCARD/IMPORT tablespace associated with temporary table; was introduced in 5.7.1. + public final static int ER_FK_DEPTH_EXCEEDED = 1891; //SQLSTATE: HY000 Message: Foreign key cascade delete/update exceeds max depth of %d.; was introduced in 5.7.2. + public final static int ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE_V2 = 1892; //SQLSTATE: HY000 Message: Column count of %s.%s is wrong. Expected %d, found %d. Created with MySQL %d, now running %d. Please use mysql_upgrade to fix this error.; was introduced in 5.7.2. + public final static int ER_WARN_TRIGGER_DOESNT_HAVE_CREATED = 1893; //SQLSTATE: HY000 Message: Trigger %s.%s.%s does not have CREATED attribute.; was introduced in 5.7.2. + public final static int ER_REFERENCED_TRG_DOES_NOT_EXIST = 1894; //SQLSTATE: HY000 Message: Referenced trigger '%s' for the given action time and event type does not exist.; was introduced in 5.7.2. + public final static int ER_EXPLAIN_NOT_SUPPORTED = 1895; //SQLSTATE: HY000 Message: EXPLAIN FOR CONNECTION command is supported only for SELECT/UPDATE/INSERT/DELETE/REPLACE; was introduced in 5.7.2. + public final static int ER_INVALID_FIELD_SIZE = 1896; //SQLSTATE: HY000 Message: Invalid size for column '%s'.; was introduced in 5.7.2. + public final static int ER_MISSING_HA_CREATE_OPTION = 1897; //SQLSTATE: HY000 Message: Table storage engine '%s' found required create option missing; was introduced in 5.7.2. + public final static int ER_ENGINE_OUT_OF_MEMORY = 1898; //SQLSTATE: HY000 Message: Out of memory in storage engine '%s'.; was introduced in 5.7.3. + public final static int ER_PASSWORD_EXPIRE_ANONYMOUS_USER = 1899; //SQLSTATE: HY000 Message: The password for anonymous user cannot be expired.; was introduced in 5.7.3. + public final static int ER_SLAVE_SQL_THREAD_MUST_STOP = 1900; //SQLSTATE: HY000 Message: This operation cannot be performed with a running slave sql thread; run STOP SLAVE SQL_THREAD first; was introduced in 5.7.3. + public final static int ER_NO_FT_MATERIALIZED_SUBQUERY = 1901; //SQLSTATE: HY000 Message: Cannot create FULLTEXT index on materialized subquery; was introduced in 5.7.4. + public final static int ER_INNODB_UNDO_LOG_FULL = 1902; //SQLSTATE: HY000 Message: Undo Log error: %s; was introduced in 5.7.4. + public final static int ER_INVALID_ARGUMENT_FOR_LOGARITHM = 1903; //SQLSTATE: 2201E Message: Invalid argument for logarithm; was introduced in 5.7.4. + public final static int ER_SLAVE_IO_THREAD_MUST_STOP = 1904; //SQLSTATE: HY000 Message: This operation cannot be performed with a running slave io thread; run STOP SLAVE IO_THREAD first.; was introduced in 5.7.4. + public final static int ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO = 1905; //SQLSTATE: HY000 Message: This operation may not be safe when the slave has temporary tables. The tables will be kept open until the server restarts or until the tables are deleted by any replicated DROP statement. Suggest to wait until slave_open_temp_tables = 0.; was introduced in 5.7.4. + public final static int ER_WARN_ONLY_MASTER_LOG_FILE_NO_POS = 1906; //SQLSTATE: HY000 Message: CHANGE MASTER TO with a MASTER_LOG_FILE clause but no MASTER_LOG_POS clause may not be safe. The old position value may not be valid for the new binary log file.; was introduced in 5.7.4. + public final static int ER_QUERY_TIMEOUT = 1907; //SQLSTATE: HY000 Message: Query execution was interrupted, max_statement_time exceeded; was introduced in 5.7.4. + public final static int ER_NON_RO_SELECT_DISABLE_TIMER = 1908; //SQLSTATE: HY000 Message: Select is not a read only statement, disabling timer; was introduced in 5.7.4. + 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. - public final static int ER_AUTO_CONVERT = 1246; - - public final static int ER_BAD_DB_ERROR = 1049; - - public final static int ER_BAD_FIELD_ERROR = 1054; - - public final static int ER_BAD_FT_COLUMN = 1283; - - public final static int ER_BAD_HOST_ERROR = 1042; - - public final static int ER_BAD_NULL_ERROR = 1048; - - public final static int ER_BAD_SLAVE = 1200; - - public final static int ER_BAD_SLAVE_UNTIL_COND = 1277; - - public final static int ER_BAD_TABLE_ERROR = 1051; - - public final static int ER_BLOB_CANT_HAVE_DEFAULT = 1101; - - public final static int ER_BLOB_KEY_WITHOUT_LENGTH = 1170; - - public final static int ER_BLOB_USED_AS_KEY = 1073; - - public final static int ER_BLOBS_AND_NO_TERMINATED = 1084; - - public final static int ER_CANNOT_ADD_FOREIGN = 1215; - - public final static int ER_CANT_AGGREGATE_2COLLATIONS = 1267; - - public final static int ER_CANT_AGGREGATE_3COLLATIONS = 1270; - - public final static int ER_CANT_AGGREGATE_NCOLLATIONS = 1271; - - public final static int ER_CANT_CREATE_DB = 1006; - - public final static int ER_CANT_CREATE_FILE = 1004; - - public final static int ER_CANT_CREATE_TABLE = 1005; - - public final static int ER_CANT_CREATE_THREAD = 1135; - - public final static int ER_CANT_DELETE_FILE = 1011; - - public final static int ER_CANT_DO_THIS_DURING_AN_TRANSACTION = 1179; - - public final static int ER_CANT_DROP_FIELD_OR_KEY = 1091; - - public final static int ER_CANT_FIND_DL_ENTRY = 1127; - - public final static int ER_CANT_FIND_SYSTEM_REC = 1012; - - public final static int ER_CANT_FIND_UDF = 1122; - - public final static int ER_CANT_GET_STAT = 1013; - - public final static int ER_CANT_GET_WD = 1014; - - public final static int ER_CANT_INITIALIZE_UDF = 1123; - - public final static int ER_CANT_LOCK = 1015; - - public final static int ER_CANT_OPEN_FILE = 1016; - - public final static int ER_CANT_OPEN_LIBRARY = 1126; - - public final static int ER_CANT_READ_DIR = 1018; - - public final static int ER_CANT_REMOVE_ALL_FIELDS = 1090; - - public final static int ER_CANT_REOPEN_TABLE = 1137; - - public final static int ER_CANT_SET_WD = 1019; - - public final static int ER_CANT_UPDATE_WITH_READLOCK = 1223; - - public final static int ER_CANT_USE_OPTION_HERE = 1234; - - public final static int ER_CHECK_NO_SUCH_TABLE = 1177; - - public final static int ER_CHECK_NOT_IMPLEMENTED = 1178; - - public final static int ER_CHECKREAD = 1020; - - public final static int ER_COLLATION_CHARSET_MISMATCH = 1253; - - public final static int ER_COLUMNACCESS_DENIED_ERROR = 1143; - - public final static int ER_CON_COUNT_ERROR = 1040; - - public final static int ER_CONNECT_TO_MASTER = 1218; - - public final static int ER_CORRUPT_HELP_DB = 1244; - - public final static int ER_CRASHED_ON_REPAIR = 1195; - - public final static int ER_CRASHED_ON_USAGE = 1194; - - public final static int ER_CREATE_DB_WITH_READ_LOCK = 1209; - - public final static int ER_CUT_VALUE_GROUP_CONCAT = 1260; - - public final static int ER_CYCLIC_REFERENCE = 1245; - - public final static int ER_DB_CREATE_EXISTS = 1007; - - public final static int ER_DB_DROP_DELETE = 1009; - - public final static int ER_DB_DROP_EXISTS = 1008; - - public final static int ER_DB_DROP_RMDIR = 1010; - - public final static int ER_DBACCESS_DENIED_ERROR = 1044; - - public final static int ER_DELAYED_CANT_CHANGE_LOCK = 1150; - - public final static int ER_DELAYED_INSERT_TABLE_LOCKED = 1165; - - public final static int ER_DERIVED_MUST_HAVE_ALIAS = 1248; - - public final static int ER_DISK_FULL = 1021; - - public final static int ER_DROP_DB_WITH_READ_LOCK = 1208; - - public final static int ER_DROP_USER = 1268; - - public final static int ER_DUMP_NOT_IMPLEMENTED = 1185; - - public final static int ER_DUP_ARGUMENT = 1225; - - public final static int ER_DUP_ENTRY = 1062; - - public final static int ER_DUP_FIELDNAME = 1060; - - public final static int ER_DUP_KEY = 1022; - - public final static int ER_DUP_KEYNAME = 1061; - - public final static int ER_DUP_UNIQUE = 1169; - - public final static int ER_DUPLICATED_VALUE_IN_TYPE = 1291; - - public final static int ER_EMPTY_QUERY = 1065; - - public final static int ER_ERROR_DURING_CHECKPOINT = 1183; - - public final static int ER_ERROR_DURING_COMMIT = 1180; - - public final static int ER_ERROR_DURING_FLUSH_LOGS = 1182; - - public final static int ER_ERROR_DURING_ROLLBACK = 1181; - - public final static int ER_ERROR_MESSAGES = 298; - - public final static int ER_ERROR_ON_CLOSE = 1023; - - public final static int ER_ERROR_ON_READ = 1024; - - public final static int ER_ERROR_ON_RENAME = 1025; - - public final static int ER_ERROR_ON_WRITE = 1026; - - public final static int ER_ERROR_WHEN_EXECUTING_COMMAND = 1220; - - public final static int ER_FEATURE_DISABLED = 1289; - - public final static int ER_FIELD_SPECIFIED_TWICE = 1110; - - public final static int ER_FILE_EXISTS_ERROR = 1086; - - public final static int ER_FILE_NOT_FOUND = 1017; - - public final static int ER_FILE_USED = 1027; - - public final static int ER_FILSORT_ABORT = 1028; - - public final static int ER_FLUSH_MASTER_BINLOG_CLOSED = 1186; - - public final static int ER_FORCING_CLOSE = 1080; - - public final static int ER_FORM_NOT_FOUND = 1029; - - public final static int ER_FT_MATCHING_KEY_NOT_FOUND = 1191; - - public final static int ER_FUNCTION_NOT_DEFINED = 1128; - - public final static int ER_GET_ERRMSG = 1296; - - public final static int ER_GET_ERRNO = 1030; - - public final static int ER_GET_TEMPORARY_ERRMSG = 1297; - - public final static int ER_GLOBAL_VARIABLE = 1229; - - public final static int ER_GOT_SIGNAL = 1078; - - public final static int ER_GRANT_WRONG_HOST_OR_USER = 1145; - - public final static int ER_HANDSHAKE_ERROR = 1043; - - public final static int ER_HASHCHK = 1000; - - public final static int ER_HOST_IS_BLOCKED = 1129; - - public final static int ER_HOST_NOT_PRIVILEGED = 1130; - - public final static int ER_ILLEGAL_GRANT_FOR_TABLE = 1144; - - public final static int ER_ILLEGAL_HA = 1031; - - public final static int ER_ILLEGAL_REFERENCE = 1247; - - public final static int ER_INCORRECT_GLOBAL_LOCAL_VAR = 1238; - - public final static int ER_INDEX_REBUILD = 1187; - - public final static int ER_INSERT_INFO = 1092; - - public final static int ER_INVALID_DEFAULT = 1067; - - public final static int ER_INVALID_GROUP_FUNC_USE = 1111; - - public final static int ER_INVALID_ON_UPDATE = 1294; - - public final static int ER_INVALID_USE_OF_NULL = 1138; - - public final static int ER_IPSOCK_ERROR = 1081; - - public final static int ER_KEY_COLUMN_DOES_NOT_EXITS = 1072; - - public final static int ER_KEY_DOES_NOT_EXITS = 1176; - - public final static int ER_KEY_NOT_FOUND = 1032; - - public final static int ER_KEY_REF_DO_NOT_MATCH_TABLE_REF = 1240; - - public final static int ER_KILL_DENIED_ERROR = 1095; - - public final static int ER_LOAD_INFO = 1087; - - public final static int ER_LOCAL_VARIABLE = 1228; - - public final static int ER_LOCK_DEADLOCK = 1213; - - public final static int ER_LOCK_OR_ACTIVE_TRANSACTION = 1192; - - public final static int ER_LOCK_TABLE_FULL = 1206; - - public final static int ER_LOCK_WAIT_TIMEOUT = 1205; - - public final static int ER_MASTER = 1188; - - public final static int ER_MASTER_FATAL_ERROR_READING_BINLOG = 1236; - - public final static int ER_MASTER_INFO = 1201; - - public final static int ER_MASTER_NET_READ = 1189; - - public final static int ER_MASTER_NET_WRITE = 1190; - - public final static int ER_MISSING_SKIP_SLAVE = 1278; - - public final static int ER_MIX_OF_GROUP_FUNC_AND_FIELDS = 1140; - - public final static int ER_MIXING_NOT_ALLOWED = 1224; - - public final static int ER_MULTIPLE_PRI_KEY = 1068; - - public final static int ER_NET_ERROR_ON_WRITE = 1160; - - public final static int ER_NET_FCNTL_ERROR = 1155; - - public final static int ER_NET_PACKET_TOO_LARGE = 1153; - - public final static int ER_NET_PACKETS_OUT_OF_ORDER = 1156; - - public final static int ER_NET_READ_ERROR = 1158; - - public final static int ER_NET_READ_ERROR_FROM_PIPE = 1154; - - public final static int ER_NET_READ_INTERRUPTED = 1159; - - public final static int ER_NET_UNCOMPRESS_ERROR = 1157; - - public final static int ER_NET_WRITE_INTERRUPTED = 1161; - - public final static int ER_NEW_ABORTING_CONNECTION = 1184; - - public final static int ER_NISAMCHK = 1001; - - public final static int ER_NO = 1002; - - public final static int ER_NO_DB_ERROR = 1046; - - public final static int ER_NO_DEFAULT = 1230; - - public final static int ER_NO_PERMISSION_TO_CREATE_USER = 1211; - - public final static int ER_NO_RAID_COMPILED = 1174; - - public final static int ER_NO_REFERENCED_ROW = 1216; - - public final static int ER_NO_SUCH_INDEX = 1082; - - public final static int ER_NO_SUCH_TABLE = 1146; - - public final static int ER_NO_SUCH_THREAD = 1094; - - public final static int ER_NO_TABLES_USED = 1096; - - public final static int ER_NO_UNIQUE_LOGFILE = 1098; - - public final static int ER_NON_UNIQ_ERROR = 1052; - - public final static int ER_NON_UPDATABLE_TABLE = 1288; - - public final static int ER_NONEXISTING_GRANT = 1141; - - public final static int ER_NONEXISTING_TABLE_GRANT = 1147; - - public final static int ER_NONUNIQ_TABLE = 1066; - - public final static int ER_NORMAL_SHUTDOWN = 1077; - - public final static int ER_NOT_ALLOWED_COMMAND = 1148; - - public final static int ER_NOT_FORM_FILE = 1033; - - public final static int ER_NOT_KEYFILE = 1034; - - public final static int ER_NOT_SUPPORTED_AUTH_MODE = 1251; - - public final static int ER_NOT_SUPPORTED_YET = 1235; - - public final static int ER_NULL_COLUMN_IN_INDEX = 1121; - - public final static int ER_OLD_KEYFILE = 1035; - - public final static int ER_OPEN_AS_READONLY = 1036; - - public final static int ER_OPERAND_COLUMNS = 1241; - - public final static int ER_OPTION_PREVENTS_STATEMENT = 1290; - - public final static int ER_OUT_OF_RESOURCES = 1041; - - public final static int ER_OUT_OF_SORTMEMORY = 1038; - - public final static int ER_OUTOFMEMORY = 1037; - - public final static int ER_PARSE_ERROR = 1064; - - public final static int ER_PASSWORD_ANONYMOUS_USER = 1131; - - public final static int ER_PASSWORD_NO_MATCH = 1133; - - public final static int ER_PASSWORD_NOT_ALLOWED = 1132; - - public final static int ER_PRIMARY_CANT_HAVE_NULL = 1171; - - public final static int ER_QUERY_ON_MASTER = 1219; - - public final static int ER_READ_ONLY_TRANSACTION = 1207; - - public final static int ER_READY = 1076; - - public final static int ER_RECORD_FILE_FULL = 1114; - - public final static int ER_REGEXP_ERROR = 1139; - - public final static int ER_REQUIRES_PRIMARY_KEY = 1173; - - public final static int ER_REVOKE_GRANTS = 1269; - - public final static int ER_ROW_IS_REFERENCED = 1217; - - public final static int ER_SELECT_REDUCED = 1249; - - public final static int ER_SERVER_IS_IN_SECURE_AUTH_MODE = 1275; - - public final static int ER_SERVER_SHUTDOWN = 1053; - - public final static int ER_SET_CONSTANTS_ONLY = 1204; - - public final static int ER_SHUTDOWN_COMPLETE = 1079; - - public final static int ER_SLAVE_IGNORED_SSL_PARAMS = 1274; - - public final static int ER_SLAVE_IGNORED_TABLE = 1237; - - public final static int ER_SLAVE_MUST_STOP = 1198; - - public final static int ER_SLAVE_NOT_RUNNING = 1199; - - public final static int ER_SLAVE_THREAD = 1202; - - public final static int ER_SLAVE_WAS_NOT_RUNNING = 1255; - - public final static int ER_SLAVE_WAS_RUNNING = 1254; - - public final static int ER_SPATIAL_CANT_HAVE_NULL = 1252; - - public final static int ER_SPECIFIC_ACCESS_DENIED_ERROR = 1227; - - public final static int ER_STACK_OVERRUN = 1119; - - public final static int ER_SUBQUERY_NO_1_ROW = 1242; - - public final static int ER_SYNTAX_ERROR = 1149; - - public final static int ER_TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164; - - public final static int ER_TABLE_CANT_HANDLE_BLOB = 1163; - - public final static int ER_TABLE_CANT_HANDLE_FT = 1214; - - public final static int ER_TABLE_EXISTS_ERROR = 1050; - - public final static int ER_TABLE_MUST_HAVE_COLUMNS = 1113; - - public final static int ER_TABLE_NOT_LOCKED = 1100; - - public final static int ER_TABLE_NOT_LOCKED_FOR_WRITE = 1099; - - public final static int ER_TABLEACCESS_DENIED_ERROR = 1142; - - public final static int ER_TABLENAME_NOT_ALLOWED_HERE = 1250; - - public final static int ER_TEXTFILE_NOT_READABLE = 1085; - - public final static int ER_TOO_BIG_FIELDLENGTH = 1074; - - public final static int ER_TOO_BIG_FOR_UNCOMPRESS = 1256; - - public final static int ER_TOO_BIG_ROWSIZE = 1118; - - public final static int ER_TOO_BIG_SELECT = 1104; - - public final static int ER_TOO_BIG_SET = 1097; - - public final static int ER_TOO_LONG_IDENT = 1059; - - public final static int ER_TOO_LONG_KEY = 1071; - - public final static int ER_TOO_LONG_STRING = 1162; - - public final static int ER_TOO_MANY_DELAYED_THREADS = 1151; - - public final static int ER_TOO_MANY_FIELDS = 1117; - - public final static int ER_TOO_MANY_KEY_PARTS = 1070; - - public final static int ER_TOO_MANY_KEYS = 1069; - - public final static int ER_TOO_MANY_ROWS = 1172; - - public final static int ER_TOO_MANY_TABLES = 1116; - - public final static int ER_TOO_MANY_USER_CONNECTIONS = 1203; - - public final static int ER_TOO_MUCH_AUTO_TIMESTAMP_COLS = 1293; - - public final static int ER_TRANS_CACHE_FULL = 1197; - - public final static int ER_TRUNCATED_WRONG_VALUE = 1292; - - public final static int ER_UDF_EXISTS = 1125; - - public final static int ER_UDF_NO_PATHS = 1124; - - public final static int ER_UNEXPECTED_EOF = 1039; - - public final static int ER_UNION_TABLES_IN_DIFFERENT_DIR = 1212; - - public final static int ER_UNKNOWN_CHARACTER_SET = 1115; - - public final static int ER_UNKNOWN_COLLATION = 1273; - - public final static int ER_UNKNOWN_COM_ERROR = 1047; - - public final static int ER_UNKNOWN_ERROR = 1105; - - public final static int ER_UNKNOWN_KEY_CACHE = 1284; - - public final static int ER_UNKNOWN_PROCEDURE = 1106; - - public final static int ER_UNKNOWN_STMT_HANDLER = 1243; - - public final static int ER_UNKNOWN_STORAGE_ENGINE = 1286; - - public final static int ER_UNKNOWN_SYSTEM_VARIABLE = 1193; - - public final static int ER_UNKNOWN_TABLE = 1109; - - public final static int ER_UNSUPPORTED_EXTENSION = 1112; - - public final static int ER_UNSUPPORTED_PS = 1295; - - public final static int ER_UNTIL_COND_IGNORED = 1279; - - public final static int ER_UPDATE_INFO = 1134; - - public final static int ER_UPDATE_TABLE_USED = 1093; - - public final static int ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175; - - public final static int ER_USER_LIMIT_REACHED = 1226; - - public final static int ER_VAR_CANT_BE_READ = 1233; - - public final static int ER_VARIABLE_IS_NOT_STRUCT = 1272; - - public final static int ER_WARN_DATA_OUT_OF_RANGE = 1264; - - public final static int ER_WARN_DATA_TRUNCATED = 1265; - - public final static int ER_WARN_DEPRECATED_SYNTAX = 1287; - - public final static int ER_WARN_FIELD_RESOLVED = 1276; - - public final static int ER_WARN_HOSTNAME_WONT_WORK = 1285; - - public final static int ER_WARN_NULL_TO_NOTNULL = 1263; - - public final static int ER_WARN_QC_RESIZE = 1282; - - public final static int ER_WARN_TOO_FEW_RECORDS = 1261; - - public final static int ER_WARN_TOO_MANY_RECORDS = 1262; - - public final static int ER_WARN_USING_OTHER_HANDLER = 1266; - - public final static int ER_WARNING_NOT_COMPLETE_ROLLBACK = 1196; - - public final static int ER_WRONG_ARGUMENTS = 1210; - - public final static int ER_WRONG_AUTO_KEY = 1075; - - public final static int ER_WRONG_COLUMN_NAME = 1166; - - public final static int ER_WRONG_DB_NAME = 1102; - - public final static int ER_WRONG_FIELD_SPEC = 1063; - - public final static int ER_WRONG_FIELD_TERMINATORS = 1083; - - public final static int ER_WRONG_FIELD_WITH_GROUP = 1055; - - public final static int ER_WRONG_FK_DEF = 1239; - - public final static int ER_WRONG_GROUP_FIELD = 1056; - - public final static int ER_WRONG_KEY_COLUMN = 1167; - - public final static int ER_WRONG_MRG_TABLE = 1168; - - public final static int ER_WRONG_NAME_FOR_CATALOG = 1281; - - public final static int ER_WRONG_NAME_FOR_INDEX = 1280; - - public final static int ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222; - - public final static int ER_WRONG_OUTER_JOIN = 1120; - - public final static int ER_WRONG_PARAMCOUNT_TO_PROCEDURE = 1107; - - public final static int ER_WRONG_PARAMETERS_TO_PROCEDURE = 1108; - - public final static int ER_WRONG_SUB_KEY = 1089; - - public final static int ER_WRONG_SUM_SELECT = 1057; - - public final static int ER_WRONG_TABLE_NAME = 1103; - - public final static int ER_WRONG_TYPE_FOR_VAR = 1232; - - public final static int ER_WRONG_USAGE = 1221; - - public final static int ER_WRONG_VALUE_COUNT = 1058; - - public final static int ER_WRONG_VALUE_COUNT_ON_ROW = 1136; - - public final static int ER_WRONG_VALUE_FOR_VAR = 1231; - - public final static int ER_XA_RMERR = 1401; - - public final static int ER_YES = 1003; - - public final static int ER_ZLIB_Z_BUF_ERROR = 1258; - - public final static int ER_ZLIB_Z_DATA_ERROR = 1259; - - public final static int ER_ZLIB_Z_MEM_ERROR = 1257; - private MysqlErrorNumbers() { // prevent instantiation } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlIO.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlIO.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlIO.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlIO.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.BufferedInputStream; @@ -32,25 +31,38 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; import java.lang.ref.SoftReference; -import java.lang.reflect.Method; import java.math.BigInteger; import java.net.MalformedURLException; import java.net.Socket; +import java.net.SocketException; import java.net.URL; -import java.nio.ByteBuffer; import java.security.NoSuchAlgorithmException; +import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Types; import java.util.ArrayList; -import java.util.Calendar; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.zip.Deflater; -import com.mysql.jdbc.profiler.ProfileEventSink; +import com.mysql.jdbc.authentication.MysqlClearPasswordPlugin; +import com.mysql.jdbc.authentication.MysqlNativePasswordPlugin; +import com.mysql.jdbc.authentication.MysqlOldPasswordPlugin; +import com.mysql.jdbc.authentication.Sha256PasswordPlugin; +import com.mysql.jdbc.exceptions.MySQLStatementCancelledException; +import com.mysql.jdbc.exceptions.MySQLTimeoutException; +import com.mysql.jdbc.log.LogUtils; import com.mysql.jdbc.profiler.ProfilerEvent; +import com.mysql.jdbc.profiler.ProfilerEventHandler; import com.mysql.jdbc.util.ReadAheadInputStream; import com.mysql.jdbc.util.ResultSetUtil; @@ -63,38 +75,43 @@ * * @see java.sql.Connection */ -class MysqlIO { - protected static final int NULL_LENGTH = ~0; +public class MysqlIO { + private static final int UTF8_CHARSET_INDEX = 33; + private static final String CODE_PAGE_1252 = "Cp1252"; + protected static final int NULL_LENGTH = ~0; protected static final int COMP_HEADER_LENGTH = 3; protected static final int MIN_COMPRESS_LEN = 50; protected static final int HEADER_LENGTH = 4; protected static final int AUTH_411_OVERHEAD = 33; private static int maxBufferSize = 65535; - private static final int CLIENT_COMPRESS = 32; /* Can use compression - protcol */ - protected static final int CLIENT_CONNECT_WITH_DB = 8; - private static final int CLIENT_FOUND_ROWS = 2; - private static final int CLIENT_LOCAL_FILES = 128; /* Can use LOAD DATA - LOCAL */ - /* Found instead of - affected rows */ - private static final int CLIENT_LONG_FLAG = 4; /* Get all column flags */ - private static final int CLIENT_LONG_PASSWORD = 1; /* new more secure - passwords */ - private static final int CLIENT_PROTOCOL_41 = 512; // for > 4.1.1 - private static final int CLIENT_INTERACTIVE = 1024; - protected static final int CLIENT_SSL = 2048; - private static final int CLIENT_TRANSACTIONS = 8192; // Client knows about transactions - protected static final int CLIENT_RESERVED = 16384; // for 4.1.0 only - protected static final int CLIENT_SECURE_CONNECTION = 32768; - private static final int CLIENT_MULTI_QUERIES = 65536; // Enable/disable multiquery support - private static final int CLIENT_MULTI_RESULTS = 131072; // Enable/disable multi-results - private static final int SERVER_STATUS_IN_TRANS = 1; + private static final String NONE = "none"; + + private static final int CLIENT_LONG_PASSWORD = 0x00000001; /* new more secure passwords */ + private static final int CLIENT_FOUND_ROWS = 0x00000002; + private static final int CLIENT_LONG_FLAG = 0x00000004; /* Get all column flags */ + protected static final int CLIENT_CONNECT_WITH_DB = 0x00000008; + private static final int CLIENT_COMPRESS = 0x00000020; /* Can use compression protcol */ + private static final int CLIENT_LOCAL_FILES = 0x00000080; /* Can use LOAD DATA LOCAL */ + private static final int CLIENT_PROTOCOL_41 = 0x00000200; // for > 4.1.1 + private static final int CLIENT_INTERACTIVE = 0x00000400; + protected static final int CLIENT_SSL = 0x00000800; + private static final int CLIENT_TRANSACTIONS = 0x00002000; // Client knows about transactions + protected static final int CLIENT_RESERVED = 0x00004000; // for 4.1.0 only + protected static final int CLIENT_SECURE_CONNECTION = 0x00008000; + private static final int CLIENT_MULTI_STATEMENTS = 0x00010000; // Enable/disable multiquery support + private static final int CLIENT_MULTI_RESULTS = 0x00020000; // Enable/disable multi-results + private static final int CLIENT_PLUGIN_AUTH = 0x00080000; + 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 SERVER_STATUS_IN_TRANS = 1; private static final int SERVER_STATUS_AUTOCOMMIT = 2; // Server in auto_commit mode - private static final int SERVER_MORE_RESULTS_EXISTS = 8; // Multi query - next query exists + static final int SERVER_MORE_RESULTS_EXISTS = 8; // Multi query - next query exists private static final int SERVER_QUERY_NO_GOOD_INDEX_USED = 16; private static final int SERVER_QUERY_NO_INDEX_USED = 32; + private static final int SERVER_QUERY_WAS_SLOW = 2048; private static final int SERVER_STATUS_CURSOR_EXISTS = 64; private static final String FALSE_SCRAMBLE = "xxxxxxxx"; //$NON-NLS-1$ protected static final int MAX_QUERY_SIZE_TO_LOG = 1024; // truncate logging of queries at 1K @@ -105,11 +122,6 @@ * filenames for LOAD DATA LOCAL INFILE... */ private static String jvmPlatformCharset = null; - - /** - * Are we using packed or unpacked binary result set rows? - */ - private boolean binaryResultsAreUnpacked = true; /** * We need to have a 'marker' for all-zero datetimes so that ResultSet @@ -118,7 +130,11 @@ protected final static String ZERO_DATE_VALUE_MARKER = "0000-00-00"; protected final static String ZERO_DATETIME_VALUE_MARKER = "0000-00-00 00:00:00"; - static { + private static final String EXPLAINABLE_STATEMENT = "SELECT"; + private static final String[] EXPLAINABLE_STATEMENT_EXTENSION = new String[] { "INSERT", "UPDATE", "REPLACE", + "DELETE" }; + + static { OutputStreamWriter outWriter = null; // @@ -156,30 +172,31 @@ /** Data to the server */ protected BufferedOutputStream mysqlOutput = null; - protected com.mysql.jdbc.Connection connection; + protected MySQLConnection connection; private Deflater deflater = null; protected InputStream mysqlInput = null; - private LinkedList packetDebugRingBuffer = null; + private LinkedList packetDebugRingBuffer = null; private RowData streamingData = null; /** The connection to the server */ - protected Socket mysqlConnection = null; - private SocketFactory socketFactory = null; + public Socket mysqlConnection = null; + protected SocketFactory socketFactory = null; // // Packet used for 'LOAD DATA LOCAL INFILE' // // We use a SoftReference, so that we don't penalize intermittent // use of this feature // - private SoftReference loadFileBufRef; + private SoftReference loadFileBufRef; // // Used to send large packets to the server versions 4+ // We use a SoftReference, so that we don't penalize intermittent // use of this feature // - private SoftReference splitBufRef; + private SoftReference splitBufRef; + private SoftReference compressBufRef; protected String host = null; protected String seed; private String serverVersion = null; @@ -202,37 +219,46 @@ private boolean profileSql = false; private boolean queryBadIndexUsed = false; private boolean queryNoIndexUsed = false; + private boolean serverQueryWasSlow = false; /** Should we use 4.1 protocol extensions? */ private boolean use41Extensions = false; private boolean useCompression = false; private boolean useNewLargePackets = false; private boolean useNewUpdateCounts = false; // should we use the new larger update counts? private byte packetSequence = 0; + private byte compressedPacketSequence = 0; private byte readPacketSequence = -1; private boolean checkPacketSequence = false; - byte protocolVersion = 0; + private byte protocolVersion = 0; private int maxAllowedPacket = 1024 * 1024; protected int maxThreeBytes = 255 * 255 * 255; protected int port = 3306; protected int serverCapabilities; private int serverMajorVersion = 0; private int serverMinorVersion = 0; + private int oldServerStatus = 0; private int serverStatus = 0; private int serverSubMinorVersion = 0; private int warningCount = 0; protected long clientParam = 0; protected long lastPacketSentTimeMs = 0; + protected long lastPacketReceivedTimeMs = 0; private boolean traceProtocol = false; private boolean enablePacketDebug = false; - private Calendar sessionCalendar; private boolean useConnectWithDb; private boolean needToGrabQueryFromPacket; private boolean autoGenerateTestcaseScript; private long threadId; private boolean useNanosForElapsedTime; private long slowQueryThreshold; private String queryTimingUnits; + private boolean useDirectRowUnpack = true; + private int useBufferRowSizeThreshold; + private int commandCount = 0; + private List statementInterceptors; + private ExceptionInterceptor exceptionInterceptor; + private int authPluginDataLength = 0; /** * Constructor: Connect to the MySQL server and setup a stream connection. @@ -249,76 +275,88 @@ * @throws SQLException if a database access error occurs. */ public MysqlIO(String host, int port, Properties props, - String socketFactoryClassName, com.mysql.jdbc.Connection conn, - int socketTimeout) throws IOException, SQLException { - this.connection = conn; + String socketFactoryClassName, MySQLConnection conn, + int socketTimeout, int useBufferRowSizeThreshold) throws IOException, SQLException { + this.connection = conn; + + if (this.connection.getEnablePacketDebug()) { + this.packetDebugRingBuffer = new LinkedList(); + } + this.traceProtocol = this.connection.getTraceProtocol(); + - if (this.connection.getEnablePacketDebug()) { - this.packetDebugRingBuffer = new LinkedList(); - } + this.useAutoSlowLog = this.connection.getAutoSlowLog(); + + this.useBufferRowSizeThreshold = useBufferRowSizeThreshold; + this.useDirectRowUnpack = this.connection.getUseDirectRowUnpack(); - this.logSlowQueries = this.connection.getLogSlowQueries(); + this.logSlowQueries = this.connection.getLogSlowQueries(); - this.reusablePacket = new Buffer(INITIAL_PACKET_SIZE); - this.sendPacket = new Buffer(INITIAL_PACKET_SIZE); + this.reusablePacket = new Buffer(INITIAL_PACKET_SIZE); + this.sendPacket = new Buffer(INITIAL_PACKET_SIZE); - this.port = port; - this.host = host; + this.port = port; + this.host = host; - this.socketFactoryClassName = socketFactoryClassName; - this.socketFactory = createSocketFactory(); - - this.mysqlConnection = this.socketFactory.connect(this.host, this.port, - props); - - if (socketTimeout != 0) { - try { - this.mysqlConnection.setSoTimeout(socketTimeout); - } catch (Exception ex) { - /* Ignore if the platform does not support it */ - ; + this.socketFactoryClassName = socketFactoryClassName; + this.socketFactory = createSocketFactory(); + this.exceptionInterceptor = this.connection.getExceptionInterceptor(); + + try { + this.mysqlConnection = this.socketFactory.connect(this.host, + this.port, props); + + + if (socketTimeout != 0) { + try { + this.mysqlConnection.setSoTimeout(socketTimeout); + } catch (Exception ex) { + /* Ignore if the platform does not support it */ + } + } + + this.mysqlConnection = this.socketFactory.beforeHandshake(); + + if (this.connection.getUseReadAheadInput()) { + this.mysqlInput = new ReadAheadInputStream(this.mysqlConnection.getInputStream(), 16384, + this.connection.getTraceProtocol(), + this.connection.getLog()); + } else if (this.connection.useUnbufferedInput()) { + this.mysqlInput = this.mysqlConnection.getInputStream(); + } else { + this.mysqlInput = new BufferedInputStream(this.mysqlConnection.getInputStream(), + 16384); + } + + this.mysqlOutput = new BufferedOutputStream(this.mysqlConnection.getOutputStream(), + 16384); + + + this.isInteractiveClient = this.connection.getInteractiveClient(); + this.profileSql = this.connection.getProfileSql(); + this.autoGenerateTestcaseScript = this.connection.getAutoGenerateTestcaseScript(); + + this.needToGrabQueryFromPacket = (this.profileSql || + this.logSlowQueries || + this.autoGenerateTestcaseScript); + + if (this.connection.getUseNanosForElapsedTime() + && Util.nanoTimeAvailable()) { + this.useNanosForElapsedTime = true; + + this.queryTimingUnits = Messages.getString("Nanoseconds"); + } else { + this.queryTimingUnits = Messages.getString("Milliseconds"); } - } + + if (this.connection.getLogSlowQueries()) { + calculateSlowQueryThreshold(); + } + } catch (IOException ioEx) { + throw SQLError.createCommunicationsException(this.connection, 0, 0, ioEx, getExceptionInterceptor()); + } + } - this.mysqlConnection = this.socketFactory.beforeHandshake(); - - if (this.connection.getUseReadAheadInput()) { - this.mysqlInput = new ReadAheadInputStream(this.mysqlConnection - .getInputStream(), 16384, this.connection - .getTraceProtocol(), this.connection.getLog()); - } else if (this.connection.useUnbufferedInput()) { - this.mysqlInput = this.mysqlConnection.getInputStream(); - } else { - this.mysqlInput = new BufferedInputStream(this.mysqlConnection - .getInputStream(), 16384); - } - - this.mysqlOutput = new BufferedOutputStream(this.mysqlConnection - .getOutputStream(), 16384); - - this.isInteractiveClient = this.connection.getInteractiveClient(); - this.profileSql = this.connection.getProfileSql(); - this.sessionCalendar = Calendar.getInstance(); - this.autoGenerateTestcaseScript = this.connection - .getAutoGenerateTestcaseScript(); - - this.needToGrabQueryFromPacket = (this.profileSql - || this.logSlowQueries || this.autoGenerateTestcaseScript); - - if (this.connection.getUseNanosForElapsedTime() - && Util.nanoTimeAvailable()) { - this.useNanosForElapsedTime = true; - - this.queryTimingUnits = Messages.getString("Nanoseconds"); - } else { - this.queryTimingUnits = Messages.getString("Milliseconds"); - } - - if (this.connection.getLogSlowQueries()) { - calculateSlowQueryThreshold(); - } - } - /** * Does the server send back extra column info? * @@ -332,8 +370,8 @@ try { return this.mysqlInput.available() > 0; } catch (IOException ioEx) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, ioEx); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); } } @@ -345,6 +383,10 @@ protected long getLastPacketSentTimeMs() { return this.lastPacketSentTimeMs; } + + protected long getLastPacketReceivedTimeMs() { + return this.lastPacketReceivedTimeMs; + } /** * Build a result set. Delegates to buildResultSetWithRows() to build a @@ -367,142 +409,127 @@ * * @throws SQLException if a database access error occurs */ - protected ResultSet getResultSet(Statement callingStatement, + protected ResultSetImpl getResultSet(StatementImpl callingStatement, long columnCount, int maxRows, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, - boolean isBinaryEncoded, boolean unpackFieldInfo, Field[] metadataFromCache) + boolean isBinaryEncoded, Field[] metadataFromCache) throws SQLException { Buffer packet; // The packet from the server Field[] fields = null; // Read in the column information - - if (unpackFieldInfo) { + + if (metadataFromCache == null /* we want the metadata from the server */) { fields = new Field[(int) columnCount]; - + for (int i = 0; i < columnCount; i++) { Buffer fieldPacket = null; - + fieldPacket = readPacket(); fields[i] = unpackField(fieldPacket, false); } } else { for (int i = 0; i < columnCount; i++) { skipPacket(); } - - //this.reusablePacket.clear(); } packet = reuseAndReadPacket(this.reusablePacket); - + readServerStatusForResultSets(packet); - + // // Handle cursor-based fetch first // - + if (this.connection.versionMeetsMinimum(5, 0, 2) && this.connection.getUseCursorFetch() && isBinaryEncoded && callingStatement != null && callingStatement.getFetchSize() != 0 && callingStatement.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) { ServerPreparedStatement prepStmt = (com.mysql.jdbc.ServerPreparedStatement) callingStatement; - - Field[] fieldMetadata = ((com.mysql.jdbc.ResultSetMetaData) prepStmt.getMetaData()).fields; boolean usingCursor = true; - + // // Server versions 5.0.5 or newer will only open // a cursor and set this flag if they can, otherwise // they punt and go back to mysql_store_results() behavior // - + if (this.connection.versionMeetsMinimum(5, 0, 5)) { - usingCursor = (this.serverStatus & + usingCursor = (this.serverStatus & SERVER_STATUS_CURSOR_EXISTS) != 0; } - + if (usingCursor) { - RowData rows = new CursorRowProvider( + RowData rows = new RowDataCursor( this, prepStmt, fields); - ResultSet rs = buildResultSetWithRows( + ResultSetImpl rs = buildResultSetWithRows( callingStatement, catalog, fields, rows, resultSetType, resultSetConcurrency, isBinaryEncoded); - + if (usingCursor) { rs.setFetchSize(callingStatement.getFetchSize()); } - + return rs; } } - + RowData rowData = null; - + if (!streamResults) { rowData = readSingleRowSet(columnCount, maxRows, - resultSetConcurrency, isBinaryEncoded, unpackFieldInfo ? fields : metadataFromCache); + resultSetConcurrency, isBinaryEncoded, + (metadataFromCache == null) ? fields : metadataFromCache); } else { - rowData = new RowDataDynamic(this, (int) columnCount, unpackFieldInfo ? fields : metadataFromCache, + rowData = new RowDataDynamic(this, (int) columnCount, + (metadataFromCache == null) ? fields : metadataFromCache, isBinaryEncoded); this.streamingData = rowData; } - ResultSet rs = buildResultSetWithRows(callingStatement, catalog, fields, + ResultSetImpl rs = buildResultSetWithRows(callingStatement, catalog, + (metadataFromCache == null) ? fields : metadataFromCache, rowData, resultSetType, resultSetConcurrency, isBinaryEncoded); - - - + + + return rs; } + // We do this to break the chain between MysqlIO and Connection, so that + // we can have PhantomReferences on connections that let the driver + // clean up the socket connection without having to use finalize() somewhere + // (which although more straightforward, is horribly inefficent). + protected NetworkResources getNetworkResources() { + return new NetworkResources(this.mysqlConnection, this.mysqlInput, this.mysqlOutput); + } + /** * Forcibly closes the underlying socket to MySQL. */ - protected final void forceClose() { + protected final void forceClose() { try { - if (this.mysqlInput != null) { - this.mysqlInput.close(); - } - } catch (IOException ioEx) { - // we can't do anything constructive about this - // Let the JVM clean it up later - this.mysqlInput = null; + getNetworkResources().forceClose(); + } finally { + this.mysqlConnection = null; + this.mysqlInput = null; + this.mysqlOutput = null; } - - try { - if (this.mysqlOutput != null) { - this.mysqlOutput.close(); - } - } catch (IOException ioEx) { - // we can't do anything constructive about this - // Let the JVM clean it up later - this.mysqlOutput = null; - } - - try { - if (this.mysqlConnection != null) { - this.mysqlConnection.close(); - } - } catch (IOException ioEx) { - // we can't do anything constructive about this - // Let the JVM clean it up later - this.mysqlConnection = null; - } } /** * Reads and discards a single MySQL packet from the input stream. - * - * @throws SQLException if the network fails while skipping the + * + * @throws SQLException if the network fails while skipping the * packet. */ protected final void skipPacket() throws SQLException { @@ -546,30 +573,28 @@ skipFully(this.mysqlInput, packetLength); } catch (IOException ioEx) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, ioEx); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); } catch (OutOfMemoryError oom) { try { this.connection.realClose(false, false, true, oom); - } finally { - throw oom; - } + } catch (Exception ex) { + } + throw oom; } } - + /** - * Read one packet from the MySQL server - * - * @return the packet from the server. - * - * @throws SQLException - * DOCUMENT ME! - * @throws CommunicationsException - * DOCUMENT ME! - */ + * Read one packet from the MySQL server + * + * @return the packet from the server. + * + * @throws SQLException DOCUMENT ME! + * @throws CommunicationsException DOCUMENT ME! + */ protected final Buffer readPacket() throws SQLException { try { - + int lengthRead = readFully(this.mysqlInput, this.packetHeaderBuf, 0, 4); @@ -581,6 +606,10 @@ int packetLength = (this.packetHeaderBuf[0] & 0xff) + ((this.packetHeaderBuf[1] & 0xff) << 8) + ((this.packetHeaderBuf[2] & 0xff) << 16); + + if (packetLength > this.maxAllowedPacket) { + throw new PacketTooBigException(packetLength, this.maxAllowedPacket); + } if (this.traceProtocol) { StringBuffer traceMessageBuf = new StringBuffer(); @@ -636,16 +665,20 @@ this.packetHeaderBuf, packet); } + if (this.connection.getMaintainTimeStats()) { + this.lastPacketReceivedTimeMs = System.currentTimeMillis(); + } + return packet; } catch (IOException ioEx) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, ioEx); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); } catch (OutOfMemoryError oom) { try { this.connection.realClose(false, false, true, oom); - } finally { - throw oom; + } catch (Exception ex) { } + throw oom; } } @@ -679,7 +712,7 @@ int tableNameStart = packet.getPosition() + 1; int tableNameLength = packet.fastSkipLenString(); tableNameStart = adjustStartForFieldLength(tableNameStart, tableNameLength); - + // orgTableName is never used so skip int originalTableNameStart = packet.getPosition() + 1; int originalTableNameLength = packet.fastSkipLenString(); @@ -688,7 +721,7 @@ // we only store the position again... int nameStart = packet.getPosition() + 1; int nameLength = packet.fastSkipLenString(); - + nameStart = adjustStartForFieldLength(nameStart, nameLength); // orgColName is not required so skip... @@ -742,11 +775,11 @@ int tableNameStart = packet.getPosition() + 1; int tableNameLength = packet.fastSkipLenString(); tableNameStart = adjustStartForFieldLength(tableNameStart, tableNameLength); - + int nameStart = packet.getPosition() + 1; int nameLength = packet.fastSkipLenString(); nameStart = adjustStartForFieldLength(nameStart, nameLength); - + int colLength = packet.readnBytes(); int colType = packet.readnBytes(); packet.readByte(); // We know it's currently 2 @@ -776,15 +809,15 @@ if (nameLength < 251) { return nameStart; } - + if (nameLength >= 251 && nameLength < 65536) { return nameStart + 2; } - + if (nameLength >= 65536 && nameLength < 16777216) { return nameStart + 3; } - + return nameStart + 8; } @@ -808,7 +841,7 @@ return true; } - + protected boolean inTransactionOnServer() { return (this.serverStatus & SERVER_STATUS_IN_TRANS) != 0; } @@ -825,14 +858,19 @@ protected void changeUser(String userName, String password, String database) throws SQLException { this.packetSequence = -1; + this.compressedPacketSequence = -1; int passwordLength = 16; int userLength = (userName != null) ? userName.length() : 0; int databaseLength = (database != null) ? database.length() : 0; - - int packLength = ((userLength + passwordLength + databaseLength) * 2) + 7 + HEADER_LENGTH + AUTH_411_OVERHEAD; - if ((this.serverCapabilities & CLIENT_SECURE_CONNECTION) != 0) { + int packLength = ((userLength + passwordLength + databaseLength) * 3) + 7 + HEADER_LENGTH + AUTH_411_OVERHEAD; + + if ((this.serverCapabilities & CLIENT_PLUGIN_AUTH) != 0) { + + proceedHandshakeWithPluggableAuthentication(userName, password, database, null); + + } else if ((this.serverCapabilities & CLIENT_SECURE_CONNECTION) != 0) { Buffer changeUserPacket = new Buffer(packLength + 1); changeUserPacket.writeByte((byte) MysqlDefs.COM_CHANGE_USER); @@ -857,16 +895,19 @@ packet.writeString(Util.oldCrypt(password, this.seed)); } - boolean localUseConnectWithDb = this.useConnectWithDb && + boolean localUseConnectWithDb = this.useConnectWithDb && (database != null && database.length() > 0); - + if (localUseConnectWithDb) { packet.writeString(database); + } else { + //Not needed, old server does not require \0 + //packet.writeString(""); } send(packet, packet.getPosition()); checkErrorPacket(); - + if (!localUseConnectWithDb) { changeDatabaseTo(database); } @@ -906,7 +947,7 @@ } protected void clearInputStream() throws SQLException { - + try { int len = this.mysqlInput.available(); @@ -915,8 +956,8 @@ len = this.mysqlInput.available(); } } catch (IOException ioEx) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, ioEx); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); } } @@ -933,9 +974,9 @@ " packets received from server, from oldest->newest:\n"); dumpBuffer.append("\n"); - for (Iterator ringBufIter = this.packetDebugRingBuffer.iterator(); + for (Iterator ringBufIter = this.packetDebugRingBuffer.iterator(); ringBufIter.hasNext();) { - dumpBuffer.append((StringBuffer) ringBufIter.next()); + dumpBuffer.append(ringBufIter.next()); dumpBuffer.append("\n"); } @@ -953,13 +994,15 @@ */ protected void explainSlowQuery(byte[] querySQL, String truncatedQuery) throws SQLException { - if (StringUtils.startsWithIgnoreCaseAndWs(truncatedQuery, "SELECT")) { //$NON-NLS-1$ + if (StringUtils.startsWithIgnoreCaseAndWs(truncatedQuery, EXPLAINABLE_STATEMENT) + || (versionMeetsMinimum(5, 6, 3) && StringUtils.startsWithIgnoreCaseAndWs(truncatedQuery, + EXPLAINABLE_STATEMENT_EXTENSION) != -1)) { PreparedStatement stmt = null; java.sql.ResultSet rs = null; try { - stmt = this.connection.clientPrepareStatement("EXPLAIN ?"); //$NON-NLS-1$ + stmt = (PreparedStatement) this.connection.clientPrepareStatement("EXPLAIN ?"); //$NON-NLS-1$ stmt.setBytesNoEscapeNoQuotes(1, querySQL); rs = stmt.executeQuery(); @@ -980,7 +1023,6 @@ stmt.close(); } } - } else { } } @@ -1050,14 +1092,14 @@ try { this.mysqlConnection.close(); } catch (Exception e) { - ; // ignore + // ignore } int errno = 2000; errno = buf.readInt(); - String serverErrorMessage = buf.readString(); + String serverErrorMessage = buf.readString("ASCII", getExceptionInterceptor()); StringBuffer errorBuf = new StringBuffer(Messages.getString( "MysqlIO.10")); //$NON-NLS-1$ @@ -1068,32 +1110,32 @@ this.connection.getUseSqlStateCodes()); throw SQLError.createSQLException(SQLError.get(xOpen) + ", " //$NON-NLS-1$ - +errorBuf.toString(), xOpen, errno); + +errorBuf.toString(), xOpen, errno, getExceptionInterceptor()); } - this.serverVersion = buf.readString(); + this.serverVersion = buf.readString("ASCII", getExceptionInterceptor()); // Parse the server version into major/minor/subminor - int point = this.serverVersion.indexOf("."); //$NON-NLS-1$ + int point = this.serverVersion.indexOf('.'); //$NON-NLS-1$ if (point != -1) { try { int n = Integer.parseInt(this.serverVersion.substring(0, point)); this.serverMajorVersion = n; } catch (NumberFormatException NFE1) { - ; + // ignore } String remaining = this.serverVersion.substring(point + 1, this.serverVersion.length()); - point = remaining.indexOf("."); //$NON-NLS-1$ + point = remaining.indexOf('.'); //$NON-NLS-1$ if (point != -1) { try { int n = Integer.parseInt(remaining.substring(0, point)); this.serverMinorVersion = n; } catch (NumberFormatException nfe) { - ; + // ignore } remaining = remaining.substring(point + 1, remaining.length()); @@ -1113,7 +1155,7 @@ int n = Integer.parseInt(remaining.substring(0, pos)); this.serverSubMinorVersion = n; } catch (NumberFormatException nfe) { - ; + // ignore } } } @@ -1129,40 +1171,81 @@ this.colDecimalNeedsBump = versionMeetsMinimum(3, 23, 0); this.colDecimalNeedsBump = !versionMeetsMinimum(3, 23, 15); // guess? Not noted in changelog this.useNewUpdateCounts = versionMeetsMinimum(3, 22, 5); + + // read connection id + threadId = buf.readLong(); + + if (this.protocolVersion > 9) { + // read auth-plugin-data-part-1 (string[8]) + this.seed = buf.readString("ASCII", getExceptionInterceptor(), 8); + // read filler ([00]) + buf.readByte(); + } else { + // read scramble (string[NUL]) + this.seed = buf.readString("ASCII", getExceptionInterceptor()); + } - threadId = buf.readLong(); - this.seed = buf.readString(); - this.serverCapabilities = 0; + // read capability flags (lower 2 bytes) if (buf.getPosition() < buf.getBufLength()) { this.serverCapabilities = buf.readInt(); } - if (versionMeetsMinimum(4, 1, 1)) { - int position = buf.getPosition(); + if ((versionMeetsMinimum(4, 1, 1) || ((this.protocolVersion > 9) && (this.serverCapabilities & CLIENT_PROTOCOL_41) != 0))) { /* New protocol with 16 bytes to describe server characteristics */ + // read character set (1 byte) this.serverCharsetIndex = buf.readByte() & 0xff; + // read status flags (2 bytes) this.serverStatus = buf.readInt(); - buf.setPosition(position + 16); + checkTransactionState(0); + + // read capability flags (upper 2 bytes) + this.serverCapabilities |= buf.readInt() << 16; + + if ((this.serverCapabilities & CLIENT_PLUGIN_AUTH) != 0) { + // read length of auth-plugin-data (1 byte) + this.authPluginDataLength = buf.readByte() & 0xff; + } else { + // read filler ([00]) + buf.readByte(); + } + // next 10 bytes are reserved (all [00]) + buf.setPosition(buf.getPosition() + 10); - String seedPart2 = buf.readString(); - StringBuffer newSeed = new StringBuffer(20); - newSeed.append(this.seed); - newSeed.append(seedPart2); - this.seed = newSeed.toString(); + if ((this.serverCapabilities & CLIENT_SECURE_CONNECTION) != 0) { + String seedPart2; + StringBuffer newSeed; + // read string[$len] auth-plugin-data-part-2 ($len=MAX(13, length of auth-plugin-data - 8)) + if (this.authPluginDataLength > 0) { +// TODO: disabled the following check for further clarification +// if (this.authPluginDataLength < 21) { +// forceClose(); +// throw SQLError.createSQLException(Messages.getString("MysqlIO.103"), //$NON-NLS-1$ +// SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, getExceptionInterceptor()); +// } + seedPart2 = buf.readString("ASCII", getExceptionInterceptor(), this.authPluginDataLength - 8); + newSeed = new StringBuffer(this.authPluginDataLength); + } else { + seedPart2 = buf.readString("ASCII", getExceptionInterceptor()); + newSeed = new StringBuffer(20); + } + newSeed.append(this.seed); + newSeed.append(seedPart2); + this.seed = newSeed.toString(); + } } if (((this.serverCapabilities & CLIENT_COMPRESS) != 0) && this.connection.getUseCompression()) { this.clientParam |= CLIENT_COMPRESS; } - this.useConnectWithDb = (database != null) && + this.useConnectWithDb = (database != null) && (database.length() > 0) && !this.connection.getCreateDatabaseIfNotExist(); - + if (this.useConnectWithDb) { this.clientParam |= CLIENT_CONNECT_WITH_DB; } @@ -1173,7 +1256,7 @@ this.connection.close(); forceClose(); throw SQLError.createSQLException(Messages.getString("MysqlIO.15"), //$NON-NLS-1$ - SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE); + SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, getExceptionInterceptor()); } this.connection.setUseSSL(false); @@ -1186,7 +1269,9 @@ } // return FOUND rows - this.clientParam |= CLIENT_FOUND_ROWS; + if (!this.connection.getUseAffectedRows()) { + this.clientParam |= CLIENT_FOUND_ROWS; + } if (this.connection.getAllowLoadLocalInfile()) { this.clientParam |= CLIENT_LOCAL_FILES; @@ -1196,6 +1281,14 @@ this.clientParam |= CLIENT_INTERACTIVE; } + // + // switch to pluggable authentication if available + // + if ((this.serverCapabilities & CLIENT_PLUGIN_AUTH) != 0) { + proceedHandshakeWithPluggableAuthentication(user, password, database, buf); + return; + } + // Authenticate if (this.protocolVersion > 9) { this.clientParam |= CLIENT_LONG_PASSWORD; // for long passwords @@ -1206,8 +1299,8 @@ // // 4.1 has some differences in the protocol // - if (versionMeetsMinimum(4, 1, 0)) { - if (versionMeetsMinimum(4, 1, 1)) { + if ((versionMeetsMinimum(4, 1, 0) || ((this.protocolVersion > 9) && (this.serverCapabilities & CLIENT_RESERVED) != 0))) { + if ((versionMeetsMinimum(4, 1, 1) || ((this.protocolVersion > 9) && (this.serverCapabilities & CLIENT_PROTOCOL_41) != 0))) { this.clientParam |= CLIENT_PROTOCOL_41; this.has41NewNewProt = true; @@ -1221,7 +1314,7 @@ // or not they want to support multiple queries // (by default, this is disabled). if (this.connection.getAllowMultiQueries()) { - this.clientParam |= CLIENT_MULTI_QUERIES; + this.clientParam |= CLIENT_MULTI_STATEMENTS; } } else { this.clientParam |= CLIENT_RESERVED; @@ -1234,16 +1327,16 @@ int passwordLength = 16; int userLength = (user != null) ? user.length() : 0; int databaseLength = (database != null) ? database.length() : 0; - - int packLength = ((userLength + passwordLength + databaseLength) * 2) + 7 + HEADER_LENGTH + AUTH_411_OVERHEAD; - + + int packLength = ((userLength + passwordLength + databaseLength) * 3) + 7 + HEADER_LENGTH + AUTH_411_OVERHEAD; + Buffer packet = null; if (!this.connection.getUseSSL()) { if ((this.serverCapabilities & CLIENT_SECURE_CONNECTION) != 0) { this.clientParam |= CLIENT_SECURE_CONNECTION; - if (versionMeetsMinimum(4, 1, 1)) { + if ((versionMeetsMinimum(4, 1, 1) || ((this.protocolVersion > 9) && (this.serverCapabilities & CLIENT_PROTOCOL_41) != 0))) { secureAuth411(null, packLength, user, password, database, true); } else { @@ -1254,7 +1347,7 @@ packet = new Buffer(packLength); if ((this.clientParam & CLIENT_RESERVED) != 0) { - if (versionMeetsMinimum(4, 1, 1)) { + if ((versionMeetsMinimum(4, 1, 1) || ((this.protocolVersion > 9) && (this.serverCapabilities & CLIENT_PROTOCOL_41) != 0))) { packet.writeLong(this.clientParam); packet.writeLong(this.maxThreeBytes); @@ -1275,28 +1368,64 @@ } // User/Password data - packet.writeString(user, "Cp1252", this.connection); + packet.writeString(user, CODE_PAGE_1252, this.connection); if (this.protocolVersion > 9) { - packet.writeString(Util.newCrypt(password, this.seed), "Cp1252", this.connection); + packet.writeString(Util.newCrypt(password, this.seed), CODE_PAGE_1252, this.connection); } else { - packet.writeString(Util.oldCrypt(password, this.seed), "Cp1252", this.connection); + packet.writeString(Util.oldCrypt(password, this.seed), CODE_PAGE_1252, this.connection); } if (this.useConnectWithDb) { - packet.writeString(database, "Cp1252", this.connection); + packet.writeString(database, CODE_PAGE_1252, this.connection); } send(packet, packet.getPosition()); } } else { negotiateSSLConnection(user, password, database, packLength); + + if ((this.serverCapabilities & CLIENT_SECURE_CONNECTION) != 0) { + if (versionMeetsMinimum(4, 1, 1)) { + secureAuth411(null, packLength, user, password, database, true); + } else { + secureAuth411(null, packLength, user, password, database, true); + } + } else { + + packet = new Buffer(packLength); + + if (this.use41Extensions) { + packet.writeLong(this.clientParam); + packet.writeLong(this.maxThreeBytes); + } else { + packet.writeInt((int) this.clientParam); + packet.writeLongInt(this.maxThreeBytes); + } + + // User/Password data + packet.writeString(user); + + if (this.protocolVersion > 9) { + packet.writeString(Util.newCrypt(password, this.seed)); + } else { + packet.writeString(Util.oldCrypt(password, this.seed)); + } + + if (((this.serverCapabilities & CLIENT_CONNECT_WITH_DB) != 0) && + (database != null) && (database.length() > 0)) { + packet.writeString(database); + } + + send(packet, packet.getPosition()); + } } // 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)) { + if (!(versionMeetsMinimum(4, 1, 1) || !((this.protocolVersion > 9) && (this.serverCapabilities & CLIENT_PROTOCOL_41) != 0))) { checkErrorPacket(); } @@ -1316,24 +1445,573 @@ if (!this.useConnectWithDb) { changeDatabaseTo(database); } + + try { + this.mysqlConnection = this.socketFactory.afterHandshake(); + } catch (IOException ioEx) { + throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); + } } - private void changeDatabaseTo(String database) throws SQLException, CommunicationsException { + + /** + * Contains instances of authentication plugins which implements + * {@link AuthenticationPlugin} interface. Key values are mysql + * protocol plugin names, for example "mysql_native_password" and + * "mysql_old_password" for built-in plugins. + */ + private Map authenticationPlugins = null; + /** + * Contains names of classes or mechanisms ("mysql_native_password" + * for example) of authentication plugins which must be disabled. + */ + private List disabledAuthenticationPlugins = null; + /** + * Name of class for default authentication plugin + */ + private String defaultAuthenticationPlugin = null; + /** + * Protocol name of default authentication plugin + */ + private String defaultAuthenticationPluginProtocolName = null; + + /** + * Fill the {@link MysqlIO#authenticationPlugins} map. + * First this method fill the map with instances of {@link MysqlOldPasswordPlugin}, {@link MysqlNativePasswordPlugin}, + * {@link MysqlClearPasswordPlugin} and {@link Sha256PasswordPlugin}. + * Then it gets instances of plugins listed in "authenticationPlugins" connection property by + * {@link Util#loadExtensions(Connection, Properties, String, String, ExceptionInterceptor)} call and adds them to the map too. + * + * The key for the map entry is getted by {@link AuthenticationPlugin#getProtocolPluginName()}. + * Thus it is possible to replace built-in plugin with custom one, to do it custom plugin should return value + * "mysql_native_password", "mysql_old_password", "mysql_clear_password" or "sha256_password" from it's own getProtocolPluginName() method. + * + * All plugin instances in the map are initialized by {@link Extension#init(Connection, Properties)} call + * with this.connection and this.connection.getProperties() values. + * + * @throws SQLException + */ + private void loadAuthenticationPlugins() throws SQLException { + + // default plugin + this.defaultAuthenticationPlugin = this.connection.getDefaultAuthenticationPlugin(); + if (this.defaultAuthenticationPlugin == null || "".equals(defaultAuthenticationPlugin.trim())) { + throw SQLError.createSQLException( + Messages.getString("Connection.BadDefaultAuthenticationPlugin", + new Object[] { this.defaultAuthenticationPlugin }), + getExceptionInterceptor()); + } + + // disabled plugins + String disabledPlugins = this.connection.getDisabledAuthenticationPlugins(); + if (disabledPlugins != null && !"".equals(disabledPlugins)) { + this.disabledAuthenticationPlugins = new ArrayList(); + List pluginsToDisable = StringUtils.split(disabledPlugins, ",", true); + Iterator iter = pluginsToDisable.iterator(); + while (iter.hasNext()) { + this.disabledAuthenticationPlugins.add(iter.next()); + } + } + + this.authenticationPlugins = new HashMap(); + + // embedded plugins + AuthenticationPlugin plugin = new MysqlOldPasswordPlugin(); + plugin.init(this.connection, this.connection.getProperties()); + boolean defaultIsFound = addAuthenticationPlugin(plugin); + + plugin = new MysqlNativePasswordPlugin(); + plugin.init(this.connection, this.connection.getProperties()); + if (addAuthenticationPlugin(plugin)) defaultIsFound = true; + + plugin = new MysqlClearPasswordPlugin(); + plugin.init(this.connection, this.connection.getProperties()); + if (addAuthenticationPlugin(plugin)) defaultIsFound = true; + + plugin = new Sha256PasswordPlugin(); + plugin.init(this.connection, this.connection.getProperties()); + if (addAuthenticationPlugin(plugin)) defaultIsFound = true; + + // plugins from authenticationPluginClasses connection parameter + String authenticationPluginClasses = this.connection.getAuthenticationPlugins(); + if (authenticationPluginClasses != null && !"".equals(authenticationPluginClasses)) { + + List plugins = Util.loadExtensions( + this.connection, this.connection.getProperties(), authenticationPluginClasses, + "Connection.BadAuthenticationPlugin", getExceptionInterceptor()); + + for (Extension object : plugins) { + plugin = (AuthenticationPlugin) object; + if (addAuthenticationPlugin(plugin)) defaultIsFound = true; + } + } + + // check if default plugin is listed + if (!defaultIsFound) { + throw SQLError.createSQLException( + Messages.getString("Connection.DefaultAuthenticationPluginIsNotListed", + new Object[] { this.defaultAuthenticationPlugin }), + getExceptionInterceptor()); + } + + } + + /** + * Add plugin to {@link MysqlIO#authenticationPlugins} if it is not disabled by + * "disabledAuthenticationPlugins" property, check is it a default plugin. + * @param plugin Instance of AuthenticationPlugin + * @return True if plugin is default, false if plugin is not default. + * @throws SQLException if plugin is default but disabled. + */ + private boolean addAuthenticationPlugin(AuthenticationPlugin plugin) throws SQLException { + boolean isDefault = false; + String pluginClassName = plugin.getClass().getName(); + String pluginProtocolName = plugin.getProtocolPluginName(); + boolean disabledByClassName = + this.disabledAuthenticationPlugins != null && + this.disabledAuthenticationPlugins.contains(pluginClassName); + boolean disabledByMechanism = + this.disabledAuthenticationPlugins != null && + this.disabledAuthenticationPlugins.contains(pluginProtocolName); + + if (disabledByClassName || disabledByMechanism) { + // if disabled then check is it default + if (this.defaultAuthenticationPlugin.equals(pluginClassName)) { + throw SQLError.createSQLException( + Messages.getString("Connection.BadDisabledAuthenticationPlugin", + new Object[] { disabledByClassName ? pluginClassName : pluginProtocolName}), + getExceptionInterceptor()); + } + } else { + this.authenticationPlugins.put(pluginProtocolName , plugin); + if (this.defaultAuthenticationPlugin.equals(pluginClassName)) { + this.defaultAuthenticationPluginProtocolName = pluginProtocolName; + isDefault = true; + } + } + return isDefault; + } + + /** + * Get authentication plugin instance from {@link MysqlIO#authenticationPlugins} map by + * pluginName key. If such plugin is found it's {@link AuthenticationPlugin#isReusable()} method + * is checked, when it's false this method returns a new instance of plugin + * and the same instance otherwise. + * + * If plugin is not found method returns null, in such case the subsequent behavior + * of handshake process depends on type of last packet received from server: + * if it was Auth Challenge Packet then handshake will proceed with default plugin, + * if it was Auth Method Switch Request Packet then handshake will be interrupted with exception. + * + * @param pluginName mysql protocol plugin names, for example "mysql_native_password" and "mysql_old_password" for built-in plugins + * @return null if plugin is not found or authentication plugin instance initialized with current connection properties + * @throws SQLException + */ + private AuthenticationPlugin getAuthenticationPlugin(String pluginName) throws SQLException { + + AuthenticationPlugin plugin = this.authenticationPlugins.get(pluginName); + + if (plugin != null && !plugin.isReusable()) { + try { + plugin = plugin.getClass().newInstance(); + plugin.init(this.connection, this.connection.getProperties()); + } catch (Throwable t) { + SQLException sqlEx = SQLError.createSQLException(Messages + .getString("Connection.BadAuthenticationPlugin", new Object[] { plugin.getClass().getName() }), getExceptionInterceptor()); + sqlEx.initCause(t); + throw sqlEx; + } + } + + return plugin; + } + + /** + * Check if given plugin requires confidentiality, but connection is without SSL + * @param plugin + * @throws SQLException + */ + private void checkConfidentiality(AuthenticationPlugin plugin) throws SQLException { + if (plugin.requiresConfidentiality() && !isSSLEstablished()) { + throw SQLError.createSQLException( + Messages.getString("Connection.AuthenticationPluginRequiresSSL", new Object[] {plugin.getProtocolPluginName()}), getExceptionInterceptor()); + } + } + + /** + * Performs an authentication handshake to authorize connection to a + * given database as a given MySQL user. This can happen upon initial + * connection to the server, after receiving Auth Challenge Packet, or + * at any moment during the connection life-time via a Change User + * request. + * + * This method is aware of pluggable authentication and will use + * registered authentication plugins as requested by the server. + * + * @param user the MySQL user account to log into + * @param password authentication data for the user account (depends + * on authentication method used - can be empty) + * @param database database to connect to (can be empty) + * @param challenge the Auth Challenge Packet received from server if + * this method is used during the initial connection. + * Otherwise null. + * + * @throws SQLException + */ + private void proceedHandshakeWithPluggableAuthentication(String user, String password, String database, Buffer challenge) throws SQLException { + if (this.authenticationPlugins == null) { + loadAuthenticationPlugins(); + } + + int passwordLength = 16; + int userLength = (user != null) ? user.length() : 0; + int databaseLength = (database != null) ? database.length() : 0; + + int packLength = ((userLength + passwordLength + databaseLength) * 3) + 7 + HEADER_LENGTH + AUTH_411_OVERHEAD; + + AuthenticationPlugin plugin = null; + Buffer fromServer = null; + ArrayList toServer = new ArrayList(); + Boolean done = null; + Buffer last_sent = null; + + boolean old_raw_challenge = false; + + int counter = 100; + + while (0 < counter--) { + + if (done == null) { + + if (challenge != null) { + // read Auth Challenge Packet + + this.clientParam |= + CLIENT_PLUGIN_AUTH + | CLIENT_LONG_PASSWORD + | CLIENT_PROTOCOL_41 + | CLIENT_TRANSACTIONS // Need this to get server status values + | CLIENT_MULTI_RESULTS // We always allow multiple result sets + | CLIENT_SECURE_CONNECTION // protocol with pluggable authentication always support this + ; + + // We allow the user to configure whether + // or not they want to support multiple queries + // (by default, this is disabled). + if (this.connection.getAllowMultiQueries()) { + this.clientParam |= CLIENT_MULTI_STATEMENTS; + } + + if (((this.serverCapabilities & CLIENT_CAN_HANDLE_EXPIRED_PASSWORD) != 0) && !this.connection.getDisconnectOnExpiredPasswords()) { + this.clientParam |= CLIENT_CAN_HANDLE_EXPIRED_PASSWORD; + } + if (((this.serverCapabilities & CLIENT_CONNECT_ATTRS) != 0 ) && + !NONE.equals(this.connection.getConnectionAttributes())) { + this.clientParam |= CLIENT_CONNECT_ATTRS; + } + if ((this.serverCapabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) != 0 ) { + this.clientParam |= CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA; + } + + this.has41NewNewProt = true; + this.use41Extensions = true; + + if (this.connection.getUseSSL()) { + negotiateSSLConnection(user, password, database, packLength); + } + + String pluginName = null; + // Due to Bug#59453 the auth-plugin-name is missing the terminating NUL-char in versions prior to 5.5.10 and 5.6.2. + if ((this.serverCapabilities & CLIENT_PLUGIN_AUTH) != 0) { + if (!versionMeetsMinimum(5, 5, 10) || versionMeetsMinimum(5, 6, 0) && !versionMeetsMinimum(5, 6, 2)) { + pluginName = challenge.readString("ASCII", getExceptionInterceptor(), this.authPluginDataLength); + } else { + pluginName = challenge.readString("ASCII", getExceptionInterceptor()); + } + } + + plugin = getAuthenticationPlugin(pluginName); + // if plugin is not found for pluginName get default instead + if (plugin == null) plugin = getAuthenticationPlugin(this.defaultAuthenticationPluginProtocolName); + + checkConfidentiality(plugin); + fromServer = new Buffer(StringUtils.getBytes(this.seed)); + } else { + // no challenge so this is a changeUser call + plugin = getAuthenticationPlugin(this.defaultAuthenticationPluginProtocolName); + checkConfidentiality(plugin); + } + + } else { + + // read packet from server and check if it's an ERROR packet + challenge = checkErrorPacket(); + old_raw_challenge = false; + + if (challenge.isOKPacket()) { + // if OK packet then finish handshake + if (!done) { + throw SQLError.createSQLException(Messages.getString("Connection.UnexpectedAuthenticationApproval", new Object[] {plugin.getProtocolPluginName()}), getExceptionInterceptor()); + } + plugin.destroy(); + break; + + } else if (challenge.isAuthMethodSwitchRequestPacket()) { + // read Auth Method Switch Request Packet + String pluginName = challenge.readString("ASCII", getExceptionInterceptor()); + + // get new plugin + if (plugin != null && !plugin.getProtocolPluginName().equals(pluginName)) { + plugin.destroy(); + plugin = getAuthenticationPlugin(pluginName); + // if plugin is not found for pluginName throw exception + if (plugin == null) { + throw SQLError.createSQLException(Messages.getString("Connection.BadAuthenticationPlugin", new Object[] {pluginName}), getExceptionInterceptor()); + } + } + + checkConfidentiality(plugin); + fromServer = new Buffer(StringUtils.getBytes(challenge.readString("ASCII", getExceptionInterceptor()))); + + } else { + // read raw packet + if (versionMeetsMinimum(5, 5, 16)) { + fromServer = new Buffer(challenge.getBytes(challenge.getPosition(), challenge.getBufLength()-challenge.getPosition())); + } else { + old_raw_challenge = true; + fromServer = new Buffer(challenge.getBytes(challenge.getPosition()-1, challenge.getBufLength()-challenge.getPosition()+1)); + } + } + + } + + // call plugin + try { + plugin.setAuthenticationParameters(user, password); + done = plugin.nextAuthenticationStep(fromServer, toServer); + } catch (SQLException e) { + throw SQLError.createSQLException(e.getMessage(), e.getSQLState(), e, getExceptionInterceptor()); + } + + // send response + if (toServer.size() > 0) { + if (challenge == null) { + // write COM_CHANGE_USER Packet + + String enc = this.connection.getEncoding(); + int charsetIndex = 0; + if (enc != null) { + charsetIndex = CharsetMapping.getCharsetIndexForMysqlEncodingName(CharsetMapping.getMysqlEncodingForJavaEncoding(enc, this.connection)); + } else { + enc = "utf-8"; + } + if (charsetIndex == 0) { + charsetIndex = UTF8_CHARSET_INDEX; + } + + + last_sent = new Buffer(packLength + 1); + last_sent.writeByte((byte) MysqlDefs.COM_CHANGE_USER); + + // User/Password data + last_sent.writeString(user, enc, this.connection); + + last_sent.writeByte((byte) toServer.get(0).getBufLength()); + last_sent.writeBytesNoNull(toServer.get(0).getByteBuffer(), 0, toServer.get(0).getBufLength()); + + if (this.useConnectWithDb) { + last_sent.writeString(database, enc, this.connection); + } else { + /* For empty database*/ + last_sent.writeByte((byte) 0); + } + + // charset (2 bytes low-endian) + last_sent.writeByte((byte) (charsetIndex % 256)); + if (charsetIndex > 255) { + last_sent.writeByte((byte) (charsetIndex / 256)); + } else { + last_sent.writeByte((byte) 0); + } + + // plugin name + if ((this.serverCapabilities & CLIENT_PLUGIN_AUTH) != 0) { + last_sent.writeString(plugin.getProtocolPluginName(), enc, this.connection); + } + + // connection attributes + if ((this.clientParam & CLIENT_CONNECT_ATTRS) != 0) { + sendConnectionAttributes(last_sent, enc, this.connection); + last_sent.writeByte((byte) 0); + } + + send(last_sent, last_sent.getPosition()); + + } else if (challenge.isAuthMethodSwitchRequestPacket()) { + // write Auth Method Switch Response Packet + + byte savePacketSequence = this.packetSequence++; + this.packetSequence = ++savePacketSequence; + + last_sent = new Buffer(toServer.get(0).getBufLength()+HEADER_LENGTH); + last_sent.writeBytesNoNull(toServer.get(0).getByteBuffer(), 0, toServer.get(0).getBufLength()); + send(last_sent, last_sent.getPosition()); + + } else if (challenge.isRawPacket() || old_raw_challenge) { + // write raw packet(s) + byte savePacketSequence = this.packetSequence++; + + for (Buffer buffer : toServer) { + this.packetSequence = ++savePacketSequence; + + last_sent = new Buffer(buffer.getBufLength()+HEADER_LENGTH); + last_sent.writeBytesNoNull(buffer.getByteBuffer(), 0, toServer.get(0).getBufLength()); + send(last_sent, last_sent.getPosition()); + } + + } else { + // write Auth Response Packet + + last_sent = new Buffer(packLength); + last_sent.writeLong(this.clientParam); + last_sent.writeLong(this.maxThreeBytes); + + // charset, JDBC will connect as 'utf8', + // and use 'SET NAMES' to change to the desired + // charset after the connection is established. + last_sent.writeByte((byte) UTF8_CHARSET_INDEX); + + last_sent.writeBytesNoNull(new byte[23]); // Set of bytes reserved for future use. + + // User/Password data + last_sent.writeString(user, "utf-8", this.connection); + + if ((this.serverCapabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) != 0 ) { + // send lenenc-int length of auth-response and string[n] auth-response + last_sent.writeLenBytes(toServer.get(0).getBytes(toServer.get(0).getBufLength())); + } else { + // send 1 byte length of auth-response and string[n] auth-response + last_sent.writeByte((byte) toServer.get(0).getBufLength()); + last_sent.writeBytesNoNull(toServer.get(0).getByteBuffer(), 0, toServer.get(0).getBufLength()); + } + + if (this.useConnectWithDb) { + last_sent.writeString(database, "utf-8", this.connection); + } else { + /* For empty database*/ + last_sent.writeByte((byte) 0); + } + + if ((this.serverCapabilities & CLIENT_PLUGIN_AUTH) != 0) { + last_sent.writeString(plugin.getProtocolPluginName(), "utf-8", this.connection); + } + + // connection attributes + if (((this.clientParam & CLIENT_CONNECT_ATTRS) != 0) ) { + sendConnectionAttributes(last_sent, "utf-8", this.connection); + } + + send(last_sent, last_sent.getPosition()); + } + + } + + } + + if (counter == 0) { + throw SQLError.createSQLException(Messages.getString("CommunicationsException.TooManyAuthenticationPluginNegotiations"), getExceptionInterceptor()); + } + + // + // Can't enable compression until after handshake + // + if (((this.serverCapabilities & CLIENT_COMPRESS) != 0) && + this.connection.getUseCompression()) { + // The following matches with ZLIB's + // compress() + this.deflater = new Deflater(); + this.useCompression = true; + this.mysqlInput = new CompressedInputStream(this.connection, this.mysqlInput); + } + + if (!this.useConnectWithDb) { + changeDatabaseTo(database); + } + + try { + this.mysqlConnection = this.socketFactory.afterHandshake(); + } catch (IOException ioEx) { + throw SQLError.createCommunicationsException(this.connection, this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); + } + } + + private Properties getConnectionAttributesAsProperties(String atts) throws SQLException { + + Properties props = new Properties(); + + + if(atts != null) { + String[] pairs = atts.split(","); + for(String pair : pairs){ + int keyEnd = pair.indexOf(":"); + if (keyEnd > 0 && (keyEnd + 1) < pair.length()) { + props.setProperty(pair.substring(0,keyEnd), pair.substring(keyEnd + 1)); + } + } + } + +// Leaving disabled until standard values are defined +// props.setProperty("_os", NonRegisteringDriver.OS); +// props.setProperty("_platform", NonRegisteringDriver.PLATFORM); + props.setProperty("_client_name", NonRegisteringDriver.NAME); + props.setProperty("_client_version", NonRegisteringDriver.VERSION); + props.setProperty("_runtime_vendor", NonRegisteringDriver.RUNTIME_VENDOR); + props.setProperty("_runtime_version", NonRegisteringDriver.RUNTIME_VERSION); + props.setProperty("_client_license", NonRegisteringDriver.LICENSE); + + + return props; + } + + private void sendConnectionAttributes(Buffer buf, String enc, MySQLConnection conn) throws SQLException { + String atts = conn.getConnectionAttributes(); + + Buffer lb = new Buffer(100); + try{ + + Properties props = getConnectionAttributesAsProperties(atts); + + for(Object key : props.keySet()) { + lb.writeLenString((String) key, enc, conn.getServerCharacterEncoding(), null, conn.parserKnowsUnicode(), conn); + lb.writeLenString(props.getProperty((String) key), enc, conn.getServerCharacterEncoding(), null, conn.parserKnowsUnicode(), conn); + } + + } catch (UnsupportedEncodingException e){ + + } + + buf.writeByte((byte) (lb.getPosition() - 4)); + buf.writeBytesNoNull(lb.getByteBuffer(), 4 , lb.getBufLength() - 4); + + } + + + private void changeDatabaseTo(String database) throws SQLException { if (database == null || database.length() == 0) { return; } - + try { - sendCommand(MysqlDefs.INIT_DB, database, null, false, null); + sendCommand(MysqlDefs.INIT_DB, database, null, false, null, 0); } catch (Exception ex) { if (this.connection.getCreateDatabaseIfNotExist()) { sendCommand(MysqlDefs.QUERY, "CREATE DATABASE IF NOT EXISTS " + database, - null, false, null); - sendCommand(MysqlDefs.INIT_DB, database, null, false, null); + null, false, null, 0); + sendCommand(MysqlDefs.INIT_DB, database, null, false, null, 0); } else { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, ex); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ex, getExceptionInterceptor()); } } } @@ -1347,18 +2025,44 @@ * @param columnCount DOCUMENT ME! * @param isBinaryEncoded DOCUMENT ME! * @param resultSetConcurrency DOCUMENT ME! + * @param b * * @return DOCUMENT ME! * * @throws SQLException DOCUMENT ME! */ - final Object[] nextRow(Field[] fields, int columnCount, - boolean isBinaryEncoded, int resultSetConcurrency) + final ResultSetRow nextRow(Field[] fields, int columnCount, + boolean isBinaryEncoded, int resultSetConcurrency, + boolean useBufferRowIfPossible, + boolean useBufferRowExplicit, + boolean canReuseRowPacketForBufferRow, Buffer existingRowPacket) throws SQLException { - // Get the next incoming packet, re-using the packet because - // all the data we need gets copied out of it. - Buffer rowPacket = checkErrorPacket(); + if (this.useDirectRowUnpack && existingRowPacket == null + && !isBinaryEncoded && !useBufferRowIfPossible + && !useBufferRowExplicit) { + return nextRowFast(fields, columnCount, isBinaryEncoded, resultSetConcurrency, + useBufferRowIfPossible, useBufferRowExplicit, canReuseRowPacketForBufferRow); + } + + Buffer rowPacket = null; + + if (existingRowPacket == null) { + rowPacket = checkErrorPacket(); + + if (!useBufferRowExplicit && useBufferRowIfPossible) { + if (rowPacket.getBufLength() > this.useBufferRowSizeThreshold) { + useBufferRowExplicit = true; + } + } + } else { + // We attempted to do nextRowFast(), but the packet was a + // multipacket, so we couldn't unpack it directly + rowPacket = existingRowPacket; + checkErrorPacket(existingRowPacket); + } + + if (!isBinaryEncoded) { // // Didn't read an error, so re-position to beginning @@ -1367,29 +2071,47 @@ rowPacket.setPosition(rowPacket.getPosition() - 1); if (!rowPacket.isLastDataPacket()) { - byte[][] rowData = new byte[columnCount][]; + if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE + || (!useBufferRowIfPossible && !useBufferRowExplicit)) { - int offset = 0; + byte[][] rowData = new byte[columnCount][]; - for (int i = 0; i < columnCount; i++) { - rowData[i] = rowPacket.readLenByteArray(offset); - } + for (int i = 0; i < columnCount; i++) { + rowData[i] = rowPacket.readLenByteArray(0); + } - return rowData; + return new ByteArrayRow(rowData, getExceptionInterceptor()); + } + + if (!canReuseRowPacketForBufferRow) { + this.reusablePacket = new Buffer(rowPacket.getBufLength()); + } + + return new BufferRow(rowPacket, fields, false, getExceptionInterceptor()); + } readServerStatusForResultSets(rowPacket); return null; } - // - // Handle binary-encoded data for server-side + // + // Handle binary-encoded data for server-side // PreparedStatements... // if (!rowPacket.isLastDataPacket()) { - return unpackBinaryResultSetRow(fields, rowPacket, - resultSetConcurrency); + if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE + || (!useBufferRowIfPossible && !useBufferRowExplicit)) { + return unpackBinaryResultSetRow(fields, rowPacket, + resultSetConcurrency); + } + + if (!canReuseRowPacketForBufferRow) { + this.reusablePacket = new Buffer(rowPacket.getBufLength()); + } + + return new BufferRow(rowPacket, fields, true, getExceptionInterceptor()); } rowPacket.setPosition(rowPacket.getPosition() - 1); @@ -1398,17 +2120,206 @@ return null; } + final ResultSetRow nextRowFast(Field[] fields, int columnCount, + boolean isBinaryEncoded, int resultSetConcurrency, + boolean useBufferRowIfPossible, + boolean useBufferRowExplicit, boolean canReuseRowPacket) + throws SQLException { + try { + int lengthRead = readFully(this.mysqlInput, this.packetHeaderBuf, + 0, 4); + + if (lengthRead < 4) { + forceClose(); + throw new RuntimeException(Messages.getString("MysqlIO.43")); //$NON-NLS-1$ + } + + int packetLength = (this.packetHeaderBuf[0] & 0xff) + + ((this.packetHeaderBuf[1] & 0xff) << 8) + + ((this.packetHeaderBuf[2] & 0xff) << 16); + + // Have we stumbled upon a multi-packet? + if (packetLength == this.maxThreeBytes) { + reuseAndReadPacket(this.reusablePacket, packetLength); + + // Go back to "old" way which uses packets + return nextRow(fields, columnCount, isBinaryEncoded, resultSetConcurrency, + useBufferRowIfPossible, useBufferRowExplicit, + canReuseRowPacket, this.reusablePacket); + } + + // Does this go over the threshold where we should use a BufferRow? + + if (packetLength > this.useBufferRowSizeThreshold) { + reuseAndReadPacket(this.reusablePacket, packetLength); + + // Go back to "old" way which uses packets + return nextRow(fields, columnCount, isBinaryEncoded, resultSetConcurrency, + true, true, + false, this.reusablePacket); + } + + int remaining = packetLength; + + boolean firstTime = true; + + byte[][] rowData = null; + + for (int i = 0; i < columnCount; i++) { + + int sw = this.mysqlInput.read() & 0xff; + remaining--; + + if (firstTime) { + if (sw == 255) { + // 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); + errorPacket.setPosition(0); + errorPacket.writeByte(this.packetHeaderBuf[0]); + errorPacket.writeByte(this.packetHeaderBuf[1]); + errorPacket.writeByte(this.packetHeaderBuf[2]); + errorPacket.writeByte((byte) 1); + errorPacket.writeByte((byte)sw); + readFully(this.mysqlInput, errorPacket.getByteBuffer(), 5, packetLength - 1); + errorPacket.setPosition(4); + checkErrorPacket(errorPacket); + } + + if (sw == 254 && packetLength < 9) { + if (this.use41Extensions) { + 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(oldServerStatus); + + remaining -= 2; + + if (remaining > 0) { + skipFully(this.mysqlInput, remaining); + } + } + + return null; // last data packet + } + + rowData = new byte[columnCount][]; + + firstTime = false; + } + + int len = 0; + + switch (sw) { + case 251: + len = NULL_LENGTH; + break; + + case 252: + len = (this.mysqlInput.read() & 0xff) + | ((this.mysqlInput.read() & 0xff) << 8); + remaining -= 2; + break; + + case 253: + len = (this.mysqlInput.read() & 0xff) + | ((this.mysqlInput.read() & 0xff) << 8) + | ((this.mysqlInput.read() & 0xff) << 16); + + remaining -= 3; + break; + + case 254: + len = (int) ((this.mysqlInput.read() & 0xff) + | ((long) (this.mysqlInput.read() & 0xff) << 8) + | ((long) (this.mysqlInput.read() & 0xff) << 16) + | ((long) (this.mysqlInput.read() & 0xff) << 24) + | ((long) (this.mysqlInput.read() & 0xff) << 32) + | ((long) (this.mysqlInput.read() & 0xff) << 40) + | ((long) (this.mysqlInput.read() & 0xff) << 48) + | ((long) (this.mysqlInput.read() & 0xff) << 56)); + remaining -= 8; + break; + + default: + len = sw; + } + + if (len == NULL_LENGTH) { + rowData[i] = null; + } else if (len == 0) { + rowData[i] = Constants.EMPTY_BYTE_ARRAY; + } else { + rowData[i] = new byte[len]; + + int bytesRead = readFully(this.mysqlInput, rowData[i], 0, + len); + + if (bytesRead != len) { + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, + new IOException(Messages.getString("MysqlIO.43")), getExceptionInterceptor()); + } + + remaining -= bytesRead; + } + } + + if (remaining > 0) { + skipFully(this.mysqlInput, remaining); + } + + return new ByteArrayRow(rowData, getExceptionInterceptor()); + } catch (IOException ioEx) { + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); + } + } + /** * Log-off of the MySQL server and close the socket. * * @throws SQLException DOCUMENT ME! */ final void quit() throws SQLException { - Buffer packet = new Buffer(6); - this.packetSequence = -1; - packet.writeByte((byte) MysqlDefs.QUIT); - send(packet, packet.getPosition()); - forceClose(); + try { + // we're not going to read the response, fixes BUG#56979 Improper connection closing logic + // leads to TIME_WAIT sockets on server + + try { + if (!this.mysqlConnection.isClosed()) { + try { + this.mysqlConnection.shutdownInput(); + } catch (UnsupportedOperationException ex) { + // ignore, some sockets do not support this method + } + } + } catch (IOException ioEx) { + this.connection.getLog().logWarn("Caught while disconnecting...", ioEx); + } + + Buffer packet = new Buffer(6); + this.packetSequence = -1; + this.compressedPacketSequence = -1; + packet.writeByte((byte) MysqlDefs.QUIT); + send(packet, packet.getPosition()); + } finally { + forceClose(); + } } /** @@ -1428,32 +2339,81 @@ void closeStreamer(RowData streamer) throws SQLException { if (this.streamingData == null) { throw SQLError.createSQLException(Messages.getString("MysqlIO.17") //$NON-NLS-1$ - +streamer + Messages.getString("MysqlIO.18")); //$NON-NLS-1$ + +streamer + Messages.getString("MysqlIO.18"), getExceptionInterceptor()); //$NON-NLS-1$ } if (streamer != this.streamingData) { throw SQLError.createSQLException(Messages.getString("MysqlIO.19") //$NON-NLS-1$ +streamer + Messages.getString("MysqlIO.20") //$NON-NLS-1$ +Messages.getString("MysqlIO.21") //$NON-NLS-1$ - +Messages.getString("MysqlIO.22")); //$NON-NLS-1$ + +Messages.getString("MysqlIO.22"), getExceptionInterceptor()); //$NON-NLS-1$ } this.streamingData = null; } - ResultSet readAllResults(Statement callingStatement, int maxRows, + boolean tackOnMoreStreamingResults(ResultSetImpl addingTo) throws SQLException { + if ((this.serverStatus & SERVER_MORE_RESULTS_EXISTS) != 0) { + + boolean moreRowSetsExist = true; + ResultSetImpl currentResultSet = addingTo; + boolean firstTime = true; + + while (moreRowSetsExist) { + if (!firstTime && currentResultSet.reallyResult()) { + break; + } + + firstTime = false; + + Buffer fieldPacket = checkErrorPacket(); + fieldPacket.setPosition(0); + + java.sql.Statement owningStatement = addingTo.getStatement(); + + int maxRows = owningStatement.getMaxRows(); + + // fixme for catalog, isBinary + + ResultSetImpl newResultSet = readResultsForQueryOrUpdate( + (StatementImpl)owningStatement, + maxRows, owningStatement.getResultSetType(), + owningStatement.getResultSetConcurrency(), + true, owningStatement.getConnection().getCatalog(), fieldPacket, + addingTo.isBinaryEncoded, + -1L, null); + + currentResultSet.setNextResultSet(newResultSet); + + currentResultSet = newResultSet; + + moreRowSetsExist = (this.serverStatus & MysqlIO.SERVER_MORE_RESULTS_EXISTS) != 0; + + if (!currentResultSet.reallyResult() && !moreRowSetsExist) { + // special case, we can stop "streaming" + return false; + } + } + + return true; + } + + return false; + } + + ResultSetImpl readAllResults(StatementImpl callingStatement, int maxRows, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Buffer resultPacket, boolean isBinaryEncoded, - long preSentColumnCount, boolean unpackFieldInfo, Field[] metadataFromCache) + long preSentColumnCount, Field[] metadataFromCache) throws SQLException { resultPacket.setPosition(resultPacket.getPosition() - 1); - ResultSet topLevelResultSet = readResultsForQueryOrUpdate(callingStatement, + ResultSetImpl topLevelResultSet = readResultsForQueryOrUpdate(callingStatement, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, resultPacket, isBinaryEncoded, preSentColumnCount, - unpackFieldInfo, metadataFromCache); + metadataFromCache); - ResultSet currentResultSet = topLevelResultSet; + ResultSetImpl currentResultSet = topLevelResultSet; boolean checkForMoreResults = ((this.clientParam & CLIENT_MULTI_RESULTS) != 0); @@ -1465,22 +2425,29 @@ // TODO: We need to support streaming of multiple result sets // if (serverHasMoreResults && streamResults) { - clearInputStream(); - - throw SQLError.createSQLException(Messages.getString("MysqlIO.23"), //$NON-NLS-1$ - SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); + //clearInputStream(); +// + //throw SQLError.createSQLException(Messages.getString("MysqlIO.23"), //$NON-NLS-1$ + //SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); + if (topLevelResultSet.getUpdateCount() != -1) { + tackOnMoreStreamingResults(topLevelResultSet); + } + + reclaimLargeReusablePacket(); + + return topLevelResultSet; } boolean moreRowSetsExist = checkForMoreResults & serverHasMoreResults; while (moreRowSetsExist) { Buffer fieldPacket = checkErrorPacket(); fieldPacket.setPosition(0); - - ResultSet newResultSet = readResultsForQueryOrUpdate(callingStatement, + + ResultSetImpl newResultSet = readResultsForQueryOrUpdate(callingStatement, maxRows, resultSetType, resultSetConcurrency, streamResults, catalog, fieldPacket, isBinaryEncoded, - preSentColumnCount, unpackFieldInfo, metadataFromCache); + preSentColumnCount, metadataFromCache); currentResultSet.setNextResultSet(newResultSet); @@ -1524,33 +2491,48 @@ * * @throws SQLException if an I/O error or SQL error occurs */ - + final Buffer sendCommand(int command, String extraData, Buffer queryPacket, - boolean skipCheck, String extraDataCharEncoding) + boolean skipCheck, String extraDataCharEncoding, int timeoutMillis) throws SQLException { + this.commandCount++; + // // We cache these locally, per-command, as the checks // for them are in very 'hot' sections of the I/O code // and we save 10-15% in overall performance by doing this... // this.enablePacketDebug = this.connection.getEnablePacketDebug(); - this.traceProtocol = this.connection.getTraceProtocol(); this.readPacketSequence = 0; + int oldTimeout = 0; + + if (timeoutMillis != 0) { + try { + oldTimeout = this.mysqlConnection.getSoTimeout(); + this.mysqlConnection.setSoTimeout(timeoutMillis); + } catch (SocketException e) { + throw SQLError.createCommunicationsException(this.connection, lastPacketSentTimeMs, + lastPacketReceivedTimeMs, e, getExceptionInterceptor()); + } + } + try { - + checkForOutstandingStreamingData(); - + // Clear serverStatus...this value is guarded by an - // external mutex, as you can only ever be processing + // external mutex, as you can only ever be processing // one command at a time + this.oldServerStatus = this.serverStatus; this.serverStatus = 0; this.hadWarnings = false; this.warningCount = 0; this.queryNoIndexUsed = false; this.queryBadIndexUsed = false; - + this.serverQueryWasSlow = false; + // // Compressed input stream needs cleared at beginning // of each command execution... @@ -1582,6 +2564,7 @@ } this.packetSequence = -1; + this.compressedPacketSequence = -1; this.readPacketSequence = 0; this.checkPacketSequence = true; this.sendPacket.clear(); @@ -1602,21 +2585,22 @@ this.connection.parserKnowsUnicode(), this.connection); } } else if (command == MysqlDefs.PROCESS_KILL) { - long id = new Long(extraData).longValue(); + long id = Long.parseLong(extraData); this.sendPacket.writeLong(id); } send(this.sendPacket, this.sendPacket.getPosition()); } else { this.packetSequence = -1; + this.compressedPacketSequence = -1; send(queryPacket, queryPacket.getPosition()); // packet passed by PreparedStatement } } catch (SQLException sqlEx) { // don't wrap SQLExceptions throw sqlEx; } catch (Exception ex) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, ex); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ex, getExceptionInterceptor()); } Buffer returnPacket = null; @@ -1633,11 +2617,27 @@ return returnPacket; } catch (IOException ioEx) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, ioEx); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); + } finally { + if (timeoutMillis != 0) { + try { + this.mysqlConnection.setSoTimeout(oldTimeout); + } catch (SocketException e) { + throw SQLError.createCommunicationsException(this.connection, lastPacketSentTimeMs, + lastPacketReceivedTimeMs, e, getExceptionInterceptor()); + } + } } } + private int statementExecutionDepth = 0; + private boolean useAutoSlowLog; + + protected boolean shouldIntercept() { + return this.statementInterceptors != null; + } + /** * Send a query stored in a packet directly to the server. * @@ -1657,232 +2657,396 @@ * * @throws Exception DOCUMENT ME! */ - final ResultSet sqlQueryDirect(Statement callingStatement, String query, - String characterEncoding, Buffer queryPacket, int maxRows, - Connection conn, int resultSetType, int resultSetConcurrency, - boolean streamResults, String catalog, boolean unpackFieldInfo) - throws Exception { - long queryStartTime = 0; - long queryEndTime = 0; + final ResultSetInternalMethods sqlQueryDirect(StatementImpl callingStatement, String query, + String characterEncoding, Buffer queryPacket, int maxRows, + int resultSetType, int resultSetConcurrency, + boolean streamResults, String catalog, Field[] cachedMetadata) + throws Exception { + this.statementExecutionDepth++; - if (query != null) { - - - // We don't know exactly how many bytes we're going to get - // from the query. Since we're dealing with Unicode, the - // max is 2, so pad it (2 * query) + space for headers - int packLength = HEADER_LENGTH + 1 + (query.length() * 2) + 2; + try { + if (this.statementInterceptors != null) { + ResultSetInternalMethods interceptedResults = + invokeStatementInterceptorsPre(query, callingStatement, false); - if (this.sendPacket == null) { - this.sendPacket = new Buffer(packLength); - } else { - this.sendPacket.clear(); - } + if (interceptedResults != null) { + return interceptedResults; + } + } - this.sendPacket.writeByte((byte) MysqlDefs.QUERY); + long queryStartTime = 0; + long queryEndTime = 0; - if (characterEncoding != null) { - if (this.platformDbCharsetMatches) { - this.sendPacket.writeStringNoNull(query, characterEncoding, - this.connection.getServerCharacterEncoding(), - this.connection.parserKnowsUnicode(), - this.connection); - } else { - if (StringUtils.startsWithIgnoreCaseAndWs(query, "LOAD DATA")) { //$NON-NLS-1$ - this.sendPacket.writeBytesNoNull(query.getBytes()); - } else { - this.sendPacket.writeStringNoNull(query, - characterEncoding, - this.connection.getServerCharacterEncoding(), - this.connection.parserKnowsUnicode(), - this.connection); - } - } - } else { - this.sendPacket.writeStringNoNull(query); - } + String statementComment = this.connection.getStatementComment(); + + if (this.connection.getIncludeThreadNamesAsStatementComment()) { + statementComment = (statementComment != null ? statementComment + ", " : "") + "java thread: " + Thread.currentThread().getName(); + } + + if (query != null) { + // We don't know exactly how many bytes we're going to get + // from the query. Since we're dealing with Unicode, the + // max is 2, so pad it (2 * query) + space for headers + int packLength = HEADER_LENGTH + 1 + (query.length() * 3) + 2; - queryPacket = this.sendPacket; - } + byte[] commentAsBytes = null; - byte[] queryBuf = null; - int oldPacketPosition = 0; + if (statementComment != null) { + commentAsBytes = StringUtils.getBytes(statementComment, null, + characterEncoding, this.connection + .getServerCharacterEncoding(), + this.connection.parserKnowsUnicode(), getExceptionInterceptor()); - - - if (needToGrabQueryFromPacket) { - queryBuf = queryPacket.getByteBuffer(); + packLength += commentAsBytes.length; + packLength += 6; // for /*[space] [space]*/ + } - // save the packet position - oldPacketPosition = queryPacket.getPosition(); + if (this.sendPacket == null) { + this.sendPacket = new Buffer(packLength); + } else { + this.sendPacket.clear(); + } - queryStartTime = getCurrentTimeNanosOrMillis(); - } - - // Send query command and sql query string - Buffer resultPacket = sendCommand(MysqlDefs.QUERY, null, queryPacket, - false, null); + this.sendPacket.writeByte((byte) MysqlDefs.QUERY); - long fetchBeginTime = 0; - long fetchEndTime = 0; + if (commentAsBytes != null) { + this.sendPacket.writeBytesNoNull(Constants.SLASH_STAR_SPACE_AS_BYTES); + this.sendPacket.writeBytesNoNull(commentAsBytes); + this.sendPacket.writeBytesNoNull(Constants.SPACE_STAR_SLASH_SPACE_AS_BYTES); + } - String profileQueryToLog = null; + if (characterEncoding != null) { + if (this.platformDbCharsetMatches) { + this.sendPacket.writeStringNoNull(query, characterEncoding, + this.connection.getServerCharacterEncoding(), + this.connection.parserKnowsUnicode(), + this.connection); + } else { + if (StringUtils.startsWithIgnoreCaseAndWs(query, "LOAD DATA")) { //$NON-NLS-1$ + this.sendPacket.writeBytesNoNull(StringUtils.getBytes(query)); + } else { + this.sendPacket.writeStringNoNull(query, + characterEncoding, + this.connection.getServerCharacterEncoding(), + this.connection.parserKnowsUnicode(), + this.connection); + } + } + } else { + this.sendPacket.writeStringNoNull(query); + } - boolean queryWasSlow = false; + queryPacket = this.sendPacket; + } - if (this.profileSql || this.logSlowQueries) { - queryEndTime = getCurrentTimeNanosOrMillis(); + byte[] queryBuf = null; + int oldPacketPosition = 0; - boolean shouldExtractQuery = false; + if (needToGrabQueryFromPacket) { + queryBuf = queryPacket.getByteBuffer(); - if (this.profileSql) { - shouldExtractQuery = true; - } else if (this.logSlowQueries) { + // save the packet position + oldPacketPosition = queryPacket.getPosition(); - if ((queryEndTime - queryStartTime) > this.slowQueryThreshold) { - shouldExtractQuery = true; - queryWasSlow = true; - } - } + queryStartTime = getCurrentTimeNanosOrMillis(); + } + + if (this.autoGenerateTestcaseScript) { + String testcaseQuery = null; - if (shouldExtractQuery) { - // Extract the actual query from the network packet - boolean truncated = false; + if (query != null) { + if (statementComment != null) { + testcaseQuery = "/* " + statementComment + " */ " + query; + } else { + testcaseQuery = query; + } + } else { + testcaseQuery = StringUtils.toString(queryBuf, 5, + (oldPacketPosition - 5)); + } - int extractPosition = oldPacketPosition; + StringBuffer debugBuf = new StringBuffer(testcaseQuery.length() + 32); + this.connection.generateConnectionCommentBlock(debugBuf); + debugBuf.append(testcaseQuery); + debugBuf.append(';'); + this.connection.dumpTestcaseQuery(debugBuf.toString()); + } - if (oldPacketPosition > this.connection.getMaxQuerySizeToLog()) { - extractPosition = this.connection.getMaxQuerySizeToLog() + 5; - truncated = true; - } + // Send query command and sql query string + Buffer resultPacket = sendCommand(MysqlDefs.QUERY, null, queryPacket, + false, null, 0); - profileQueryToLog = new String(queryBuf, 5, - (extractPosition - 5)); + long fetchBeginTime = 0; + long fetchEndTime = 0; - if (truncated) { - profileQueryToLog += Messages.getString("MysqlIO.25"); //$NON-NLS-1$ - } - } + String profileQueryToLog = null; - fetchBeginTime = queryEndTime; - } - - if (this.autoGenerateTestcaseScript) { - String testcaseQuery = null; - - if (query != null) { - testcaseQuery = query; - } else { - testcaseQuery = new String(queryBuf, 5, - (oldPacketPosition - 5)); - } - - StringBuffer debugBuf = new StringBuffer(testcaseQuery.length() + 32); - this.connection.generateConnectionCommentBlock(debugBuf); - debugBuf.append(testcaseQuery); - debugBuf.append(';'); - this.connection.dumpTestcaseQuery(debugBuf.toString()); - } - - ResultSet rs = readAllResults(callingStatement, maxRows, resultSetType, - resultSetConcurrency, streamResults, catalog, resultPacket, - false, -1L, unpackFieldInfo, null /* we don't need metadata for cached MD in this case */); + boolean queryWasSlow = false; - if (queryWasSlow) { - StringBuffer mesgBuf = new StringBuffer(48 + - profileQueryToLog.length()); - - mesgBuf.append(Messages.getString("MysqlIO.SlowQuery", - new Object[] {new Long(this.slowQueryThreshold), - queryTimingUnits, - new Long(queryEndTime - queryStartTime)})); - mesgBuf.append(profileQueryToLog); + if (this.profileSql || this.logSlowQueries) { + queryEndTime = getCurrentTimeNanosOrMillis(); - ProfileEventSink eventSink = ProfileEventSink.getInstance(this.connection); + boolean shouldExtractQuery = false; - eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_SLOW_QUERY, - "", catalog, this.connection.getId(), //$NON-NLS-1$ - (callingStatement != null) ? callingStatement.getId() : 999, - rs.resultId, System.currentTimeMillis(), - (int) (queryEndTime - queryStartTime), queryTimingUnits, null, - new Throwable(), mesgBuf.toString())); + if (this.profileSql) { + shouldExtractQuery = true; + } else if (this.logSlowQueries) { + long queryTime = queryEndTime - queryStartTime; + + boolean logSlow = false; + + if (!this.useAutoSlowLog) { + logSlow = queryTime > this.connection.getSlowQueryThresholdMillis(); + } else { + logSlow = this.connection.isAbonormallyLongQuery(queryTime); + + this.connection.reportQueryTime(queryTime); + } + + if (logSlow) { + shouldExtractQuery = true; + queryWasSlow = true; + } + } - if (this.connection.getExplainSlowQueries()) { - if (oldPacketPosition < MAX_QUERY_SIZE_TO_EXPLAIN) { - explainSlowQuery(queryPacket.getBytes(5, - (oldPacketPosition - 5)), profileQueryToLog); - } else { - this.connection.getLog().logWarn(Messages.getString( - "MysqlIO.28") //$NON-NLS-1$ - +MAX_QUERY_SIZE_TO_EXPLAIN + - Messages.getString("MysqlIO.29")); //$NON-NLS-1$ - } - } - } + if (shouldExtractQuery) { + // Extract the actual query from the network packet + boolean truncated = false; - if (this.profileSql) { - fetchEndTime = getCurrentTimeNanosOrMillis(); + int extractPosition = oldPacketPosition; - ProfileEventSink eventSink = ProfileEventSink.getInstance(this.connection); + if (oldPacketPosition > this.connection.getMaxQuerySizeToLog()) { + extractPosition = this.connection.getMaxQuerySizeToLog() + 5; + truncated = true; + } - eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_QUERY, - "", catalog, this.connection.getId(), //$NON-NLS-1$ - (callingStatement != null) ? callingStatement.getId() : 999, - rs.resultId, System.currentTimeMillis(), - (queryEndTime - queryStartTime), this.queryTimingUnits, - null, - new Throwable(), profileQueryToLog)); + profileQueryToLog = StringUtils.toString(queryBuf, 5, + (extractPosition - 5)); - eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_FETCH, - "", catalog, this.connection.getId(), //$NON-NLS-1$ - (callingStatement != null) ? callingStatement.getId() : 999, - rs.resultId, System.currentTimeMillis(), - (fetchEndTime - fetchBeginTime), this.queryTimingUnits, - null, - new Throwable(), null)); + if (truncated) { + profileQueryToLog += Messages.getString("MysqlIO.25"); //$NON-NLS-1$ + } + } - if (this.queryBadIndexUsed) { - eventSink.consumeEvent(new ProfilerEvent( - ProfilerEvent.TYPE_SLOW_QUERY, "", catalog, //$NON-NLS-1$ - this.connection.getId(), - (callingStatement != null) ? callingStatement.getId() - : 999, rs.resultId, - System.currentTimeMillis(), - (queryEndTime - queryStartTime), this.queryTimingUnits, - null, - new Throwable(), - Messages.getString("MysqlIO.33") //$NON-NLS-1$ - +profileQueryToLog)); - } + fetchBeginTime = queryEndTime; + } - if (this.queryNoIndexUsed) { - eventSink.consumeEvent(new ProfilerEvent( - ProfilerEvent.TYPE_SLOW_QUERY, "", catalog, //$NON-NLS-1$ - this.connection.getId(), - (callingStatement != null) ? callingStatement.getId() - : 999, rs.resultId, - System.currentTimeMillis(), - (queryEndTime - queryStartTime), this.queryTimingUnits, - null, - new Throwable(), - Messages.getString("MysqlIO.35") //$NON-NLS-1$ - +profileQueryToLog)); - } - } + ResultSetInternalMethods rs = readAllResults(callingStatement, maxRows, resultSetType, + resultSetConcurrency, streamResults, catalog, resultPacket, + false, -1L, cachedMetadata); - if (this.hadWarnings) { - scanForAndThrowDataTruncation(); - } + if (queryWasSlow && !this.serverQueryWasSlow /* don't log slow queries twice */) { + StringBuffer mesgBuf = new StringBuffer(48 + + profileQueryToLog.length()); - return rs; + mesgBuf.append(Messages.getString("MysqlIO.SlowQuery", + new Object[] {String.valueOf(this.useAutoSlowLog ? + " 95% of all queries " : this.slowQueryThreshold), + queryTimingUnits, + Long.valueOf(queryEndTime - queryStartTime)})); + mesgBuf.append(profileQueryToLog); + + ProfilerEventHandler eventSink = ProfilerEventHandlerFactory.getInstance(this.connection); + + eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_SLOW_QUERY, + "", catalog, this.connection.getId(), //$NON-NLS-1$ + (callingStatement != null) ? callingStatement.getId() : 999, + ((ResultSetImpl)rs).resultId, System.currentTimeMillis(), + (int) (queryEndTime - queryStartTime), queryTimingUnits, null, + LogUtils.findCallingClassAndMethod(new Throwable()), mesgBuf.toString())); + + if (this.connection.getExplainSlowQueries()) { + if (oldPacketPosition < MAX_QUERY_SIZE_TO_EXPLAIN) { + explainSlowQuery(queryPacket.getBytes(5, + (oldPacketPosition - 5)), profileQueryToLog); + } else { + this.connection.getLog().logWarn(Messages.getString( + "MysqlIO.28") //$NON-NLS-1$ + +MAX_QUERY_SIZE_TO_EXPLAIN + + Messages.getString("MysqlIO.29")); //$NON-NLS-1$ + } + } + } + + if (this.logSlowQueries) { + + ProfilerEventHandler eventSink = ProfilerEventHandlerFactory.getInstance(this.connection); + + if (this.queryBadIndexUsed && this.profileSql) { + eventSink.consumeEvent(new ProfilerEvent( + ProfilerEvent.TYPE_SLOW_QUERY, "", catalog, //$NON-NLS-1$ + 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") //$NON-NLS-1$ + +profileQueryToLog)); + } + + if (this.queryNoIndexUsed && this.profileSql) { + eventSink.consumeEvent(new ProfilerEvent( + ProfilerEvent.TYPE_SLOW_QUERY, "", catalog, //$NON-NLS-1$ + 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") //$NON-NLS-1$ + +profileQueryToLog)); + } + + if (this.serverQueryWasSlow && this.profileSql) { + eventSink.consumeEvent(new ProfilerEvent( + ProfilerEvent.TYPE_SLOW_QUERY, "", catalog, //$NON-NLS-1$ + 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") //$NON-NLS-1$ + +profileQueryToLog)); + } + } + + if (this.profileSql) { + fetchEndTime = getCurrentTimeNanosOrMillis(); + + ProfilerEventHandler eventSink = ProfilerEventHandlerFactory.getInstance(this.connection); + + eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_QUERY, + "", catalog, this.connection.getId(), //$NON-NLS-1$ + (callingStatement != null) ? callingStatement.getId() : 999, + ((ResultSetImpl)rs).resultId, System.currentTimeMillis(), + (queryEndTime - queryStartTime), this.queryTimingUnits, + null, + LogUtils.findCallingClassAndMethod(new Throwable()), profileQueryToLog)); + + eventSink.consumeEvent(new ProfilerEvent(ProfilerEvent.TYPE_FETCH, + "", catalog, this.connection.getId(), //$NON-NLS-1$ + (callingStatement != null) ? callingStatement.getId() : 999, + ((ResultSetImpl)rs).resultId, System.currentTimeMillis(), + (fetchEndTime - fetchBeginTime), this.queryTimingUnits, + null, + LogUtils.findCallingClassAndMethod(new Throwable()), null)); + } + + if (this.hadWarnings) { + scanForAndThrowDataTruncation(); + } + + if (this.statementInterceptors != null) { + ResultSetInternalMethods interceptedResults = invokeStatementInterceptorsPost( + query, callingStatement, rs, false, null); + + if (interceptedResults != null) { + rs = interceptedResults; + } + } + + return rs; + } catch (SQLException sqlEx) { + if (this.statementInterceptors != null) { + invokeStatementInterceptorsPost( + query, callingStatement, null, false, sqlEx); // we don't do anything with the result set in this case + } + + if (callingStatement != null) { + synchronized (callingStatement.cancelTimeoutMutex) { + if (callingStatement.wasCancelled) { + SQLException cause = null; + + if (callingStatement.wasCancelledByTimeout) { + cause = new MySQLTimeoutException(); + } else { + cause = new MySQLStatementCancelledException(); + } + + callingStatement.resetCancelledState(); + + throw cause; + } + } + } + + throw sqlEx; + } finally { + this.statementExecutionDepth--; + } } + ResultSetInternalMethods invokeStatementInterceptorsPre(String sql, + Statement interceptedStatement, boolean forceExecute) throws SQLException { + ResultSetInternalMethods previousResultSet = null; + + for (int i = 0, s = this.statementInterceptors.size(); i < s; i++) { + StatementInterceptorV2 interceptor = this.statementInterceptors.get(i); + + boolean executeTopLevelOnly = interceptor.executeTopLevelOnly(); + boolean shouldExecute = (executeTopLevelOnly && (this.statementExecutionDepth == 1 || forceExecute)) + || (!executeTopLevelOnly); + + if (shouldExecute) { + String sqlToInterceptor = sql; + + //if (interceptedStatement instanceof PreparedStatement) { + // sqlToInterceptor = ((PreparedStatement) interceptedStatement) + // .asSql(); + //} + + ResultSetInternalMethods interceptedResultSet = interceptor + .preProcess(sqlToInterceptor, interceptedStatement, + this.connection); + + if (interceptedResultSet != null) { + previousResultSet = interceptedResultSet; + } + } + } + + return previousResultSet; + } + + ResultSetInternalMethods invokeStatementInterceptorsPost( + String sql, Statement interceptedStatement, + ResultSetInternalMethods originalResultSet, boolean forceExecute, SQLException statementException) throws SQLException { + + for (int i = 0, s = this.statementInterceptors.size(); i < s; i++) { + StatementInterceptorV2 interceptor = this.statementInterceptors.get(i); + + boolean executeTopLevelOnly = interceptor.executeTopLevelOnly(); + boolean shouldExecute = (executeTopLevelOnly && (this.statementExecutionDepth == 1 || forceExecute)) + || (!executeTopLevelOnly); + + if (shouldExecute) { + String sqlToInterceptor = sql; + + ResultSetInternalMethods interceptedResultSet = interceptor + .postProcess(sqlToInterceptor, interceptedStatement, + originalResultSet, this.connection, this.warningCount, + this.queryNoIndexUsed, this.queryBadIndexUsed, statementException); + + if (interceptedResultSet != null) { + originalResultSet = interceptedResultSet; + } + } + } + + return originalResultSet; + } + private void calculateSlowQueryThreshold() { this.slowQueryThreshold = this.connection.getSlowQueryThresholdMillis(); - + if (this.connection.getUseNanosForElapsedTime()) { long nanosThreshold = this.connection.getSlowQueryThresholdNanos(); - + if (nanosThreshold != 0) { this.slowQueryThreshold = nanosThreshold; } else { @@ -1895,11 +3059,11 @@ if (this.useNanosForElapsedTime) { return Util.getCurrentTimeNanosOrMillis(); } - + return System.currentTimeMillis(); } - /** + /** * Returns the host this IO is connected to * * @return DOCUMENT ME! @@ -1951,7 +3115,7 @@ return false; } - // newer than major + // newer than major return true; } @@ -1994,34 +3158,34 @@ int count = in.read(b, off + n, len - n); if (count < 0) { - throw new EOFException(Messages.getString("MysqlIO.EOF", - new Object[] {new Integer(len), new Integer(n)})); + throw new EOFException(Messages.getString("MysqlIO.EOF", + new Object[] {Integer.valueOf(len), Integer.valueOf(n)})); } n += count; } return n; } - + private final long skipFully(InputStream in, long len) throws IOException { if (len < 0) { throw new IOException("Negative skip length not allowed"); } - + long n = 0; - + while (n < len) { long count = in.skip(len - n); - + if (count < 0) { - throw new EOFException(Messages.getString("MysqlIO.EOF", - new Object[] {new Long(len), new Long(n)})); + throw new EOFException(Messages.getString("MysqlIO.EOF", + new Object[] {Long.valueOf(len), Long.valueOf(n)})); } - + n += count; } - + return n; } @@ -2045,11 +3209,11 @@ * * @throws SQLException if an error occurs while reading the rows */ - private final ResultSet readResultsForQueryOrUpdate( - Statement callingStatement, int maxRows, int resultSetType, + protected final ResultSetImpl readResultsForQueryOrUpdate( + StatementImpl callingStatement, int maxRows, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, Buffer resultPacket, boolean isBinaryEncoded, long preSentColumnCount, - boolean unpackFieldInfo, Field[] metadataFromCache) throws SQLException { + Field[] metadataFromCache) throws SQLException { long columnCount = resultPacket.readFieldLength(); if (columnCount == 0) { @@ -2065,17 +3229,17 @@ if (this.platformDbCharsetMatches) { fileName = ((charEncoding != null) - ? resultPacket.readString(charEncoding) + ? resultPacket.readString(charEncoding, getExceptionInterceptor()) : resultPacket.readString()); } else { fileName = resultPacket.readString(); } return sendFileToServer(callingStatement, fileName); } else { - com.mysql.jdbc.ResultSet results = getResultSet(callingStatement, + com.mysql.jdbc.ResultSetImpl results = getResultSet(callingStatement, columnCount, maxRows, resultSetType, resultSetConcurrency, - streamResults, catalog, isBinaryEncoded, unpackFieldInfo, + streamResults, catalog, isBinaryEncoded, metadataFromCache); return results; @@ -2086,17 +3250,17 @@ return ((((a) + (l)) - 1) & ~((l) - 1)); } - private com.mysql.jdbc.ResultSet buildResultSetWithRows( - Statement callingStatement, String catalog, + private com.mysql.jdbc.ResultSetImpl buildResultSetWithRows( + StatementImpl callingStatement, String catalog, com.mysql.jdbc.Field[] fields, RowData rows, int resultSetType, int resultSetConcurrency, boolean isBinaryEncoded) throws SQLException { - ResultSet rs = null; + ResultSetImpl rs = null; switch (resultSetConcurrency) { case java.sql.ResultSet.CONCUR_READ_ONLY: - rs = new com.mysql.jdbc.ResultSet(catalog, fields, rows, - this.connection, callingStatement); + rs = com.mysql.jdbc.ResultSetImpl.getInstance(catalog, fields, rows, + this.connection, callingStatement, false); if (isBinaryEncoded) { rs.setBinaryEncoded(); @@ -2105,14 +3269,14 @@ break; case java.sql.ResultSet.CONCUR_UPDATABLE: - rs = new com.mysql.jdbc.UpdatableResultSet(catalog, fields, rows, - this.connection, callingStatement); + rs = com.mysql.jdbc.ResultSetImpl.getInstance(catalog, fields, rows, + this.connection, callingStatement, true); break; default: - return new com.mysql.jdbc.ResultSet(catalog, fields, rows, - this.connection, callingStatement); + return com.mysql.jdbc.ResultSetImpl.getInstance(catalog, fields, rows, + this.connection, callingStatement, false); } rs.setResultSetType(resultSetType); @@ -2121,8 +3285,8 @@ return rs; } - private com.mysql.jdbc.ResultSet buildResultSetWithUpdates( - Statement callingStatement, Buffer resultPacket) + private com.mysql.jdbc.ResultSetImpl buildResultSetWithUpdates( + StatementImpl callingStatement, Buffer resultPacket) throws SQLException { long updateCount = -1; long updateID = -1; @@ -2138,8 +3302,11 @@ } if (this.use41Extensions) { + // oldStatus set in sendCommand() this.serverStatus = resultPacket.readInt(); + checkTransactionState(oldServerStatus); + this.warningCount = resultPacket.readInt(); if (this.warningCount > 0) { @@ -2148,41 +3315,49 @@ resultPacket.readByte(); // advance pointer - if (this.profileSql) { - this.queryNoIndexUsed = (this.serverStatus & - SERVER_QUERY_NO_GOOD_INDEX_USED) != 0; - this.queryBadIndexUsed = (this.serverStatus & - SERVER_QUERY_NO_INDEX_USED) != 0; - } + setServerSlowQueryFlags(); } if (this.connection.isReadInfoMsgEnabled()) { - info = resultPacket.readString(); + info = resultPacket.readString(this.connection.getErrorMessageEncoding(), getExceptionInterceptor()); } } catch (Exception ex) { - throw SQLError.createSQLException(SQLError.get( - SQLError.SQL_STATE_GENERAL_ERROR) + ": " //$NON-NLS-1$ - +ex.getClass().getName(), SQLError.SQL_STATE_GENERAL_ERROR, -1); + SQLException sqlEx = SQLError.createSQLException(SQLError.get( + SQLError.SQL_STATE_GENERAL_ERROR), SQLError.SQL_STATE_GENERAL_ERROR, -1, getExceptionInterceptor()); + sqlEx.initCause(ex); + + throw sqlEx; } - ResultSet updateRs = new com.mysql.jdbc.ResultSet(updateCount, + ResultSetInternalMethods updateRs = com.mysql.jdbc.ResultSetImpl.getInstance(updateCount, updateID, this.connection, callingStatement); if (info != null) { - updateRs.setServerInfo(info); + ((com.mysql.jdbc.ResultSetImpl)updateRs).setServerInfo(info); } - return updateRs; + return (com.mysql.jdbc.ResultSetImpl)updateRs; } + private void setServerSlowQueryFlags() { + this.queryBadIndexUsed = (this.serverStatus & + SERVER_QUERY_NO_GOOD_INDEX_USED) != 0; + this.queryNoIndexUsed = (this.serverStatus & + SERVER_QUERY_NO_INDEX_USED) != 0; + this.serverQueryWasSlow = (this.serverStatus & + SERVER_QUERY_WAS_SLOW) != 0; + } + private void checkForOutstandingStreamingData() throws SQLException { if (this.streamingData != null) { - if (!this.connection.getClobberStreamingResults()) { + boolean shouldClobber = this.connection.getClobberStreamingResults(); + + if (!shouldClobber) { throw SQLError.createSQLException(Messages.getString("MysqlIO.39") //$NON-NLS-1$ +this.streamingData + Messages.getString("MysqlIO.40") //$NON-NLS-1$ +Messages.getString("MysqlIO.41") //$NON-NLS-1$ - +Messages.getString("MysqlIO.42")); //$NON-NLS-1$ + +Messages.getString("MysqlIO.42"), getExceptionInterceptor()); //$NON-NLS-1$ } // Close the result set @@ -2193,51 +3368,55 @@ } } - private Buffer compressPacket(Buffer packet, int offset, int packetLen, - int headerLength) throws SQLException { - packet.writeLongInt(packetLen - headerLength); - packet.writeByte((byte) 0); // wrapped packet has 0 packet seq. + /** + * + * @param packet original uncompressed MySQL packet + * @param offset begin of MySQL packet header + * @param packetLen real length of packet + * @return compressed packet with header + * @throws SQLException + */ + private Buffer compressPacket(Buffer packet, int offset, int packetLen) throws SQLException { - int lengthToWrite = 0; - int compressedLength = 0; - byte[] bytesToCompress = packet.getByteBuffer(); - byte[] compressedBytes = null; - int offsetWrite = 0; + // uncompressed payload by default + int compressedLength = packetLen; + int uncompressedLength = 0; + byte[] compressedBytes = null; + int offsetWrite = offset; - if (packetLen < MIN_COMPRESS_LEN) { - lengthToWrite = packetLen; - compressedBytes = packet.getByteBuffer(); - compressedLength = 0; - offsetWrite = offset; - } else { - compressedBytes = new byte[bytesToCompress.length * 2]; + if (packetLen < MIN_COMPRESS_LEN) { + compressedBytes = packet.getByteBuffer(); + } else { + byte[] bytesToCompress = packet.getByteBuffer(); + compressedBytes = new byte[bytesToCompress.length * 2]; + + if (this.deflater == null) { + this.deflater = new Deflater(); + } this.deflater.reset(); this.deflater.setInput(bytesToCompress, offset, packetLen); this.deflater.finish(); - int compLen = this.deflater.deflate(compressedBytes); + compressedLength = this.deflater.deflate(compressedBytes); - if (compLen > packetLen) { - lengthToWrite = packetLen; + if (compressedLength > packetLen) { + // if compressed data is greater then uncompressed then send uncompressed compressedBytes = packet.getByteBuffer(); - compressedLength = 0; - offsetWrite = offset; + compressedLength = packetLen; } else { - lengthToWrite = compLen; - headerLength += COMP_HEADER_LENGTH; - compressedLength = packetLen; + uncompressedLength = packetLen; + offsetWrite = 0; } } - Buffer compressedPacket = new Buffer(packetLen + headerLength); + Buffer compressedPacket = new Buffer(HEADER_LENGTH + COMP_HEADER_LENGTH + compressedLength); compressedPacket.setPosition(0); - compressedPacket.writeLongInt(lengthToWrite); - compressedPacket.writeByte(this.packetSequence); compressedPacket.writeLongInt(compressedLength); - compressedPacket.writeBytesNoNull(compressedBytes, offsetWrite, - lengthToWrite); + compressedPacket.writeByte(this.compressedPacketSequence); + compressedPacket.writeLongInt(uncompressedLength); + compressedPacket.writeBytesNoNull(compressedBytes, offsetWrite, compressedLength); return compressedPacket; } @@ -2253,33 +3432,32 @@ this.hadWarnings = true; // this is a 'latch', it's reset by sendCommand() } + this.oldServerStatus = this.serverStatus; this.serverStatus = rowPacket.readInt(); + checkTransactionState(oldServerStatus); - if (this.profileSql) { - this.queryNoIndexUsed = (this.serverStatus & - SERVER_QUERY_NO_GOOD_INDEX_USED) != 0; - this.queryBadIndexUsed = (this.serverStatus & - SERVER_QUERY_NO_INDEX_USED) != 0; - } + setServerSlowQueryFlags(); } } - + private SocketFactory createSocketFactory() throws SQLException { try { if (this.socketFactoryClassName == null) { throw SQLError.createSQLException(Messages.getString("MysqlIO.75"), //$NON-NLS-1$ - SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE); + SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, getExceptionInterceptor()); } return (SocketFactory) (Class.forName(this.socketFactoryClassName) .newInstance()); } catch (Exception ex) { - throw SQLError.createSQLException(Messages.getString("MysqlIO.76") //$NON-NLS-1$ + SQLException sqlEx = SQLError.createSQLException(Messages.getString("MysqlIO.76") //$NON-NLS-1$ +this.socketFactoryClassName + - Messages.getString("MysqlIO.77") + ex.toString() //$NON-NLS-1$ - +(this.connection.getParanoid() ? "" //$NON-NLS-1$ - : Util.stackTraceToString(ex)), - SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE); + Messages.getString("MysqlIO.77"), + SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, getExceptionInterceptor()); + + sqlEx.initCause(ex); + + throw sqlEx; } } @@ -2347,31 +3525,33 @@ this.packetDebugRingBuffer.addLast(packetDump); } - + private RowData readSingleRowSet(long columnCount, int maxRows, int resultSetConcurrency, boolean isBinaryEncoded, Field[] fields) throws SQLException { RowData rowData; - ArrayList rows = new ArrayList(); + ArrayList rows = new ArrayList(); + boolean useBufferRowExplicit = useBufferRowExplicit(fields); + // Now read the data - Object rowBytes = nextRow(fields, (int) columnCount, isBinaryEncoded, - resultSetConcurrency); - + ResultSetRow row = nextRow(fields, (int) columnCount, isBinaryEncoded, + resultSetConcurrency, false, useBufferRowExplicit, false, null); + int rowCount = 0; - if (rowBytes != null) { - rows.add(rowBytes); + if (row != null) { + rows.add(row); rowCount = 1; } - while (rowBytes != null) { - rowBytes = nextRow(fields, (int) columnCount, isBinaryEncoded, - resultSetConcurrency); + while (row != null) { + row = nextRow(fields, (int) columnCount, isBinaryEncoded, + resultSetConcurrency, false, useBufferRowExplicit, false, null); - if (rowBytes != null) { + if (row != null) { if ((maxRows == -1) || (rowCount < maxRows)) { - rows.add(rowBytes); + rows.add(row); rowCount++; } } @@ -2382,7 +3562,25 @@ return rowData; } - /** + public static boolean useBufferRowExplicit(Field[] fields) { + if (fields == null) { + return false; + } + + for (int i = 0; i < fields.length; i++) { + switch (fields[i].getSQLType()) { + case Types.BLOB: + case Types.CLOB: + case Types.LONGVARBINARY: + case Types.LONGVARCHAR: + return true; + } + } + + return false; + } + + /** * Don't hold on to overly-large packets */ private void reclaimLargeReusablePacket() { @@ -2402,51 +3600,60 @@ * @throws SQLException DOCUMENT ME! * @throws SQLException DOCUMENT ME! */ - private final Buffer reuseAndReadPacket(Buffer reuse) + private final Buffer reuseAndReadPacket(Buffer reuse) throws SQLException { + return reuseAndReadPacket(reuse, -1); + } + + private final Buffer reuseAndReadPacket(Buffer reuse, int existingPacketLength) throws SQLException { - + try { reuse.setWasMultiPacket(false); - - int lengthRead = readFully(this.mysqlInput, - this.packetHeaderBuf, 0, 4); - - if (lengthRead < 4) { - forceClose(); - throw new IOException(Messages.getString("MysqlIO.43")); //$NON-NLS-1$ + int packetLength = 0; + + if (existingPacketLength == -1) { + int lengthRead = readFully(this.mysqlInput, + this.packetHeaderBuf, 0, 4); + + if (lengthRead < 4) { + forceClose(); + throw new IOException(Messages.getString("MysqlIO.43")); //$NON-NLS-1$ + } + + packetLength = (this.packetHeaderBuf[0] & 0xff) + + ((this.packetHeaderBuf[1] & 0xff) << 8) + + ((this.packetHeaderBuf[2] & 0xff) << 16); + } else { + packetLength = existingPacketLength; } - - int packetLength = (this.packetHeaderBuf[0] & 0xff) + - ((this.packetHeaderBuf[1] & 0xff) << 8) + - ((this.packetHeaderBuf[2] & 0xff) << 16); - + if (this.traceProtocol) { StringBuffer traceMessageBuf = new StringBuffer(); - + traceMessageBuf.append(Messages.getString("MysqlIO.44")); //$NON-NLS-1$ traceMessageBuf.append(packetLength); traceMessageBuf.append(Messages.getString("MysqlIO.45")); //$NON-NLS-1$ traceMessageBuf.append(StringUtils.dumpAsHex( this.packetHeaderBuf, 4)); - + this.connection.getLog().logTrace(traceMessageBuf.toString()); } - + byte multiPacketSeq = this.packetHeaderBuf[3]; - + if (!this.packetSequenceReset) { if (this.enablePacketDebug && this.checkPacketSequence) { checkPacketSequencing(multiPacketSeq); } } else { this.packetSequenceReset = false; } - + this.readPacketSequence = multiPacketSeq; - + // Set the Buffer to it's original state reuse.setPosition(0); - + // Do we need to re-alloc the byte buffer? // // Note: We actually check the length of the buffer, @@ -2456,260 +3663,272 @@ if (reuse.getByteBuffer().length <= packetLength) { reuse.setByteBuffer(new byte[packetLength + 1]); } - + // Set the new length reuse.setBufLength(packetLength); - + // Read the data from the server int numBytesRead = readFully(this.mysqlInput, reuse.getByteBuffer(), 0, packetLength); - + if (numBytesRead != packetLength) { throw new IOException("Short read, expected " + packetLength + " bytes, only read " + numBytesRead); } - + if (this.traceProtocol) { StringBuffer traceMessageBuf = new StringBuffer(); - + traceMessageBuf.append(Messages.getString("MysqlIO.46")); //$NON-NLS-1$ traceMessageBuf.append(getPacketDumpToLog(reuse, packetLength)); - + this.connection.getLog().logTrace(traceMessageBuf.toString()); } - + if (this.enablePacketDebug) { enqueuePacketForDebugging(false, true, 0, this.packetHeaderBuf, reuse); } - + boolean isMultiPacket = false; - + if (packetLength == this.maxThreeBytes) { reuse.setPosition(this.maxThreeBytes); - - int packetEndPoint = packetLength; - + // it's multi-packet isMultiPacket = true; - - lengthRead = readFully(this.mysqlInput, - this.packetHeaderBuf, 0, 4); - - if (lengthRead < 4) { - forceClose(); - throw new IOException(Messages.getString("MysqlIO.47")); //$NON-NLS-1$ - } - - packetLength = (this.packetHeaderBuf[0] & 0xff) + - ((this.packetHeaderBuf[1] & 0xff) << 8) + - ((this.packetHeaderBuf[2] & 0xff) << 16); - - Buffer multiPacket = new Buffer(packetLength); - boolean firstMultiPkt = true; - - while (true) { - if (!firstMultiPkt) { - lengthRead = readFully(this.mysqlInput, - this.packetHeaderBuf, 0, 4); - - if (lengthRead < 4) { - forceClose(); - throw new IOException(Messages.getString( - "MysqlIO.48")); //$NON-NLS-1$ - } - - packetLength = (this.packetHeaderBuf[0] & 0xff) + - ((this.packetHeaderBuf[1] & 0xff) << 8) + - ((this.packetHeaderBuf[2] & 0xff) << 16); - } else { - firstMultiPkt = false; - } - - if (!this.useNewLargePackets && (packetLength == 1)) { - clearInputStream(); - - break; - } else if (packetLength < this.maxThreeBytes) { - byte newPacketSeq = this.packetHeaderBuf[3]; - - if (newPacketSeq != (multiPacketSeq + 1)) { - throw new IOException(Messages.getString( - "MysqlIO.49")); //$NON-NLS-1$ - } - - multiPacketSeq = newPacketSeq; - - // Set the Buffer to it's original state - multiPacket.setPosition(0); - - // Set the new length - multiPacket.setBufLength(packetLength); - - // Read the data from the server - byte[] byteBuf = multiPacket.getByteBuffer(); - int lengthToWrite = packetLength; - - int bytesRead = readFully(this.mysqlInput, byteBuf, - 0, packetLength); - - if (bytesRead != lengthToWrite) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, - SQLError.createSQLException(Messages.getString( - "MysqlIO.50") //$NON-NLS-1$ - +lengthToWrite + - Messages.getString("MysqlIO.51") + - bytesRead //$NON-NLS-1$ - +".")); //$NON-NLS-1$ - } - - reuse.writeBytesNoNull(byteBuf, 0, lengthToWrite); - - packetEndPoint += lengthToWrite; - - break; // end of multipacket sequence - } - - byte newPacketSeq = this.packetHeaderBuf[3]; - - if (newPacketSeq != (multiPacketSeq + 1)) { - throw new IOException(Messages.getString( - "MysqlIO.53")); //$NON-NLS-1$ - } - - multiPacketSeq = newPacketSeq; - - // Set the Buffer to it's original state - multiPacket.setPosition(0); - - // Set the new length - multiPacket.setBufLength(packetLength); - - // Read the data from the server - byte[] byteBuf = multiPacket.getByteBuffer(); - int lengthToWrite = packetLength; - - int bytesRead = readFully(this.mysqlInput, byteBuf, 0, - packetLength); - - if (bytesRead != lengthToWrite) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, - SQLError.createSQLException(Messages.getString( - "MysqlIO.54") //$NON-NLS-1$ - +lengthToWrite + - Messages.getString("MysqlIO.55") //$NON-NLS-1$ - +bytesRead + ".")); //$NON-NLS-1$ - } - - reuse.writeBytesNoNull(byteBuf, 0, lengthToWrite); - - packetEndPoint += lengthToWrite; - } - - reuse.setPosition(0); - reuse.setWasMultiPacket(true); + + packetLength = readRemainingMultiPackets(reuse, multiPacketSeq); } - + if (!isMultiPacket) { reuse.getByteBuffer()[packetLength] = 0; // Null-termination } - + + if (this.connection.getMaintainTimeStats()) { + this.lastPacketReceivedTimeMs = System.currentTimeMillis(); + } + return reuse; } catch (IOException ioEx) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, ioEx); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); } catch (OutOfMemoryError oom) { try { // _Try_ this clearInputStream(); - } finally { - try { - this.connection.realClose(false, false, true, oom); - } finally { - throw oom; - } - } + } catch (Exception ex) { + } + try { + this.connection.realClose(false, false, true, oom); + } catch (Exception ex) { + } + throw oom; } - + } + private int readRemainingMultiPackets(Buffer reuse, byte multiPacketSeq) + throws IOException, SQLException { + int lengthRead; + int packetLength; + lengthRead = readFully(this.mysqlInput, + this.packetHeaderBuf, 0, 4); + + if (lengthRead < 4) { + forceClose(); + throw new IOException(Messages.getString("MysqlIO.47")); //$NON-NLS-1$ + } + + packetLength = (this.packetHeaderBuf[0] & 0xff) + + ((this.packetHeaderBuf[1] & 0xff) << 8) + + ((this.packetHeaderBuf[2] & 0xff) << 16); + + Buffer multiPacket = new Buffer(packetLength); + boolean firstMultiPkt = true; + + while (true) { + if (!firstMultiPkt) { + lengthRead = readFully(this.mysqlInput, + this.packetHeaderBuf, 0, 4); + + if (lengthRead < 4) { + forceClose(); + throw new IOException(Messages.getString( + "MysqlIO.48")); //$NON-NLS-1$ + } + + packetLength = (this.packetHeaderBuf[0] & 0xff) + + ((this.packetHeaderBuf[1] & 0xff) << 8) + + ((this.packetHeaderBuf[2] & 0xff) << 16); + } else { + firstMultiPkt = false; + } + + if (!this.useNewLargePackets && (packetLength == 1)) { + clearInputStream(); + + break; + } else if (packetLength < this.maxThreeBytes) { + byte newPacketSeq = this.packetHeaderBuf[3]; + + if (newPacketSeq != (multiPacketSeq + 1)) { + throw new IOException(Messages.getString( + "MysqlIO.49")); //$NON-NLS-1$ + } + + multiPacketSeq = newPacketSeq; + + // Set the Buffer to it's original state + multiPacket.setPosition(0); + + // Set the new length + multiPacket.setBufLength(packetLength); + + // Read the data from the server + byte[] byteBuf = multiPacket.getByteBuffer(); + int lengthToWrite = packetLength; + + 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") //$NON-NLS-1$ + +lengthToWrite + + Messages.getString("MysqlIO.51") + + bytesRead //$NON-NLS-1$ + +".", getExceptionInterceptor()), getExceptionInterceptor()); //$NON-NLS-1$ + } + + reuse.writeBytesNoNull(byteBuf, 0, lengthToWrite); + + break; // end of multipacket sequence + } + + byte newPacketSeq = this.packetHeaderBuf[3]; + + if (newPacketSeq != (multiPacketSeq + 1)) { + throw new IOException(Messages.getString( + "MysqlIO.53")); //$NON-NLS-1$ + } + + multiPacketSeq = newPacketSeq; + + // Set the Buffer to it's original state + multiPacket.setPosition(0); + + // Set the new length + multiPacket.setBufLength(packetLength); + + // Read the data from the server + byte[] byteBuf = multiPacket.getByteBuffer(); + int lengthToWrite = packetLength; + + 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.54") //$NON-NLS-1$ + +lengthToWrite + + Messages.getString("MysqlIO.55") //$NON-NLS-1$ + +bytesRead + ".", getExceptionInterceptor()), getExceptionInterceptor()); //$NON-NLS-1$ + } + + reuse.writeBytesNoNull(byteBuf, 0, lengthToWrite); + } + + reuse.setPosition(0); + reuse.setWasMultiPacket(true); + return packetLength; + } + /** * @param multiPacketSeq * @throws CommunicationsException */ private void checkPacketSequencing(byte multiPacketSeq) - throws CommunicationsException { + throws SQLException { if ((multiPacketSeq == -128) && (this.readPacketSequence != 127)) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, new IOException("Packets out of order, expected packet # -128, but received packet # " + - multiPacketSeq)); + multiPacketSeq), getExceptionInterceptor()); } if ((this.readPacketSequence == -1) && (multiPacketSeq != 0)) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, new IOException("Packets out of order, expected packet # -1, but received packet # " + - multiPacketSeq)); + multiPacketSeq), getExceptionInterceptor()); } if ((multiPacketSeq != -128) && (this.readPacketSequence != -1) && (multiPacketSeq != (this.readPacketSequence + 1))) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, new IOException("Packets out of order, expected packet # " + (this.readPacketSequence + 1) + ", but received packet # " + - multiPacketSeq)); + multiPacketSeq), getExceptionInterceptor()); } } void enableMultiQueries() throws SQLException { Buffer buf = getSharedSendPacket(); - + buf.clear(); buf.writeByte((byte)MysqlDefs.COM_SET_OPTION); buf.writeInt(0); - sendCommand(MysqlDefs.COM_SET_OPTION, null, buf, false, null); + sendCommand(MysqlDefs.COM_SET_OPTION, null, buf, false, null, 0); } - + void disableMultiQueries() throws SQLException { Buffer buf = getSharedSendPacket(); - + buf.clear(); buf.writeByte((byte)MysqlDefs.COM_SET_OPTION); buf.writeInt(1); - sendCommand(MysqlDefs.COM_SET_OPTION, null, buf, false, null); + sendCommand(MysqlDefs.COM_SET_OPTION, null, buf, false, null, 0); } - + + /** + * + * @param packet + * @param packetLen length of header + payload + * @throws SQLException + */ private final void send(Buffer packet, int packetLen) throws SQLException { try { - if (packetLen > this.maxAllowedPacket) { + if (this.maxAllowedPacket > 0 && packetLen > this.maxAllowedPacket) { throw new PacketTooBigException(packetLen, this.maxAllowedPacket); } - if (this.connection.getMaintainTimeStats()) { - this.lastPacketSentTimeMs = System.currentTimeMillis(); - } - if ((this.serverMajorVersion >= 4) && - (packetLen >= this.maxThreeBytes)) { - sendSplitPackets(packet); + (packetLen - HEADER_LENGTH >= this.maxThreeBytes || + (this.useCompression && packetLen - HEADER_LENGTH >= this.maxThreeBytes - COMP_HEADER_LENGTH) + )) { + sendSplitPackets(packet, packetLen); + } else { this.packetSequence++; Buffer packetToSend = packet; - packetToSend.setPosition(0); + packetToSend.writeLongInt(packetLen - HEADER_LENGTH); + packetToSend.writeByte(this.packetSequence); if (this.useCompression) { + this.compressedPacketSequence++; int originalPacketLen = packetLen; - packetToSend = compressPacket(packet, 0, packetLen, - HEADER_LENGTH); + packetToSend = compressPacket(packetToSend, 0, packetLen); packetLen = packetToSend.getPosition(); if (this.traceProtocol) { @@ -2725,39 +3944,44 @@ this.connection.getLog().logTrace(traceMessageBuf.toString()); } } else { - packetToSend.writeLongInt(packetLen - HEADER_LENGTH); - packetToSend.writeByte(this.packetSequence); if (this.traceProtocol) { StringBuffer traceMessageBuf = new StringBuffer(); traceMessageBuf.append(Messages.getString("MysqlIO.59")); //$NON-NLS-1$ + traceMessageBuf.append("host: '"); + traceMessageBuf.append(host); + traceMessageBuf.append("' threadId: '"); + traceMessageBuf.append(threadId); + traceMessageBuf.append("'\n"); traceMessageBuf.append(packetToSend.dump(packetLen)); this.connection.getLog().logTrace(traceMessageBuf.toString()); } } - - this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, - packetLen); - this.mysqlOutput.flush(); + this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, packetLen); + this.mysqlOutput.flush(); } if (this.enablePacketDebug) { enqueuePacketForDebugging(true, false, packetLen + 5, this.packetHeaderBuf, packet); } - // + // // Don't hold on to large packets // if (packet == this.sharedSendPacket) { reclaimLargeSharedSendPacket(); } + + if (this.connection.getMaintainTimeStats()) { + this.lastPacketSentTimeMs = System.currentTimeMillis(); + } } catch (IOException ioEx) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, ioEx); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); } } @@ -2771,34 +3995,38 @@ * * @throws SQLException DOCUMENT ME! */ - private final ResultSet sendFileToServer(Statement callingStatement, + private final ResultSetImpl sendFileToServer(StatementImpl callingStatement, String fileName) throws SQLException { - + + if (this.useCompression) { + this.compressedPacketSequence++; + } + Buffer filePacket = (this.loadFileBufRef == null) ? null - : (Buffer) (this.loadFileBufRef.get()); + : this.loadFileBufRef.get(); int bigPacketLength = Math.min(this.connection.getMaxAllowedPacket() - (HEADER_LENGTH * 3), alignPacketSize(this.connection.getMaxAllowedPacket() - 16, 4096) - (HEADER_LENGTH * 3)); - + int oneMeg = 1024 * 1024; - - int smallerPacketSizeAligned = Math.min(oneMeg - (HEADER_LENGTH * 3), + + int smallerPacketSizeAligned = Math.min(oneMeg - (HEADER_LENGTH * 3), alignPacketSize(oneMeg - 16, 4096) - (HEADER_LENGTH * 3)); - + int packetLength = Math.min(smallerPacketSizeAligned, bigPacketLength); if (filePacket == null) { try { filePacket = new Buffer((packetLength + HEADER_LENGTH)); - this.loadFileBufRef = new SoftReference(filePacket); + 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." + 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); - + + "'max_allowed_packet'", SQLError.SQL_STATE_MEMORY_ALLOCATION_FAILURE, getExceptionInterceptor()); + } } @@ -2812,15 +4040,23 @@ try { if (!this.connection.getAllowLoadLocalInfile()) { throw SQLError.createSQLException( - Messages.getString("MysqlIO.LoadDataLocalNotAllowed"), - SQLError.SQL_STATE_GENERAL_ERROR); + Messages.getString("MysqlIO.LoadDataLocalNotAllowed"), + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } - - if (!this.connection.getAllowUrlInLocalInfile()) { + + InputStream hookedStream = null; + + if (callingStatement != null) { + hookedStream = callingStatement.getLocalInfileInputStream(); + } + + if (hookedStream != null) { + fileIn = new BufferedInputStream(hookedStream); + } else if (!this.connection.getAllowUrlInLocalInfile()) { fileIn = new BufferedInputStream(new FileInputStream(fileName)); } else { // First look for ':' - if (fileName.indexOf(":") != -1) { + if (fileName.indexOf(':') != -1) { try { URL urlFromFileName = new URL(fileName); fileIn = new BufferedInputStream(urlFromFileName.openStream()); @@ -2843,17 +4079,12 @@ send(filePacket, filePacket.getPosition()); } } catch (IOException ioEx) { - StringBuffer messageBuf = new StringBuffer(Messages.getString( - "MysqlIO.60")); //$NON-NLS-1$ + StringBuffer messageBuf = new StringBuffer(Messages.getString("MysqlIO.60")); - if (!this.connection.getParanoid()) { - messageBuf.append("'"); //$NON-NLS-1$ - - if (fileName != null) { - messageBuf.append(fileName); - } - - messageBuf.append("'"); //$NON-NLS-1$ + if (fileName != null && !this.connection.getParanoid()) { + messageBuf.append("'"); + messageBuf.append(fileName); + messageBuf.append("'"); } messageBuf.append(Messages.getString("MysqlIO.63")); //$NON-NLS-1$ @@ -2864,14 +4095,16 @@ } throw SQLError.createSQLException(messageBuf.toString(), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } finally { if (fileIn != null) { try { fileIn.close(); } catch (Exception ex) { - throw SQLError.createSQLException(Messages.getString("MysqlIO.65"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + SQLException sqlEx = SQLError.createSQLException(Messages.getString("MysqlIO.65"), + SQLError.SQL_STATE_GENERAL_ERROR, ex, getExceptionInterceptor()); + + throw sqlEx; } fileIn = null; @@ -2904,7 +4137,7 @@ * @throws CommunicationsException DOCUMENT ME! */ private Buffer checkErrorPacket(int command) throws SQLException { - int statusCode = 0; + //int statusCode = 0; Buffer resultPacket = null; this.serverStatus = 0; @@ -2914,15 +4147,23 @@ // exception chain and let someone higher up decide // what to do (barf, reconnect, etc). resultPacket = reuseAndReadPacket(this.reusablePacket); - statusCode = resultPacket.readByte(); } catch (SQLException sqlEx) { // Don't wrap SQL Exceptions throw sqlEx; } catch (Exception fallThru) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, fallThru); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, fallThru, getExceptionInterceptor()); } + checkErrorPacket(resultPacket); + + return resultPacket; + } + + private void checkErrorPacket(Buffer resultPacket) throws SQLException { + + int statusCode = resultPacket.readByte(); + // Error handling if (statusCode == (byte) 0xff) { String serverErrorMessage; @@ -2933,10 +4174,10 @@ String xOpen = null; - serverErrorMessage = - resultPacket.readString(this.connection.getErrorMessageEncoding()); + serverErrorMessage = + resultPacket.readString(this.connection.getErrorMessageEncoding(), getExceptionInterceptor()); - if (serverErrorMessage.startsWith("#")) { //$NON-NLS-1$ + if (serverErrorMessage.charAt(0) == '#') { //$NON-NLS-1$ // we have an SQLState if (serverErrorMessage.length() > 6) { @@ -2976,42 +4217,40 @@ errorBuf.append("\""); //$NON-NLS-1$ } } - - appendInnodbStatusInformation(xOpen, errorBuf); - + + appendDeadlockStatusInformation(xOpen, errorBuf); + if (xOpen != null && xOpen.startsWith("22")) { - throw new MysqlDataTruncation(errorBuf.toString(), 0, true, false, 0, 0); - } else { - throw SQLError.createSQLException(errorBuf.toString(), xOpen, errno); + 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()); + this.connection.getErrorMessageEncoding(), getExceptionInterceptor()); clearInputStream(); if (serverErrorMessage.indexOf(Messages.getString("MysqlIO.70")) != -1) { //$NON-NLS-1$ throw SQLError.createSQLException(SQLError.get( SQLError.SQL_STATE_COLUMN_NOT_FOUND) + ", " //$NON-NLS-1$ +serverErrorMessage, SQLError.SQL_STATE_COLUMN_NOT_FOUND, - -1); + -1, false, getExceptionInterceptor(), this.connection); } StringBuffer errorBuf = new StringBuffer(Messages.getString( "MysqlIO.72")); //$NON-NLS-1$ errorBuf.append(serverErrorMessage); errorBuf.append("\""); //$NON-NLS-1$ - + throw SQLError.createSQLException(SQLError.get( SQLError.SQL_STATE_GENERAL_ERROR) + ", " //$NON-NLS-1$ - +errorBuf.toString(), SQLError.SQL_STATE_GENERAL_ERROR, -1); + +errorBuf.toString(), SQLError.SQL_STATE_GENERAL_ERROR, -1, false, getExceptionInterceptor(), this.connection); } - - return resultPacket; } - private void appendInnodbStatusInformation(String xOpen, + private void appendDeadlockStatusInformation(String xOpen, StringBuffer errorBuf) throws SQLException { if (this.connection.getIncludeInnodbStatusInDeadlockExceptions() && xOpen != null @@ -3022,17 +4261,20 @@ try { rs = sqlQueryDirect(null, "SHOW ENGINE INNODB STATUS", this.connection.getEncoding(), null, -1, - this.connection, ResultSet.TYPE_FORWARD_ONLY, + ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, false, this.connection - .getCatalog(), true); + .getCatalog(), null); + if (rs.next()) { errorBuf.append("\n\n"); - errorBuf.append(rs.getString(1)); + errorBuf.append(rs.getString("Status")); } else { + errorBuf.append("\n\n"); errorBuf.append(Messages .getString("MysqlIO.NoInnoDBStatusFound")); } } catch (Exception ex) { + errorBuf.append("\n\n"); errorBuf.append(Messages .getString("MysqlIO.InnoDBStatusFailed")); errorBuf.append("\n\n"); @@ -3043,126 +4285,164 @@ } } } + + if (this.connection.getIncludeThreadDumpInDeadlockExceptions()) { + errorBuf.append("\n\n*** Java threads running at time of deadlock ***\n\n"); + + ThreadMXBean threadMBean = ManagementFactory.getThreadMXBean(); + long[] threadIds = threadMBean.getAllThreadIds(); + + ThreadInfo[] threads = threadMBean.getThreadInfo(threadIds, + Integer.MAX_VALUE); + List activeThreads = new ArrayList(); + + for (ThreadInfo info : threads) { + if (info != null) { + activeThreads.add(info); + } + } + + for (ThreadInfo threadInfo : activeThreads) { + // "Thread-60" daemon prio=1 tid=0x093569c0 nid=0x1b99 in + // Object.wait() + + errorBuf.append('"'); + errorBuf.append(threadInfo.getThreadName()); + errorBuf.append("\" tid="); + errorBuf.append(threadInfo.getThreadId()); + errorBuf.append(" "); + errorBuf.append(threadInfo.getThreadState()); + + if (threadInfo.getLockName() != null) { + errorBuf.append(" on lock=" + threadInfo.getLockName()); + } + if (threadInfo.isSuspended()) { + errorBuf.append(" (suspended)"); + } + if (threadInfo.isInNative()) { + errorBuf.append(" (running in native)"); + } + + StackTraceElement[] stackTrace = threadInfo.getStackTrace(); + + if (stackTrace.length > 0) { + errorBuf.append(" in "); + errorBuf.append(stackTrace[0].getClassName()); + errorBuf.append("."); + errorBuf.append(stackTrace[0].getMethodName()); + errorBuf.append("()"); + } + + errorBuf.append("\n"); + + if (threadInfo.getLockOwnerName() != null) { + errorBuf.append("\t owned by " + threadInfo.getLockOwnerName() + + " Id=" + threadInfo.getLockOwnerId()); + errorBuf.append("\n"); + } + + for (int j = 0; j < stackTrace.length; j++) { + StackTraceElement ste = stackTrace[j]; + errorBuf.append("\tat " + ste.toString()); + errorBuf.append("\n"); + } + } + } } /** - * Sends a large packet to the server as a series of smaller packets - * - * @param packet - * DOCUMENT ME! - * - * @throws SQLException - * DOCUMENT ME! - * @throws CommunicationsException - * DOCUMENT ME! - */ - private final void sendSplitPackets(Buffer packet) + * Sends a large packet to the server as a series of smaller packets + * + * @param packet DOCUMENT ME! + * + * @throws SQLException DOCUMENT ME! + * @throws CommunicationsException DOCUMENT ME! + */ + private final void sendSplitPackets(Buffer packet, int packetLen) throws SQLException { try { - // - // Big packets are handled by splitting them in packets of MAX_THREE_BYTES - // length. The last packet is always a packet that is < MAX_THREE_BYTES. - // (The last packet may even have a length of 0) - // - // - // NB: Guarded by execSQL. If the driver changes architecture, this - // will need to be synchronized in some other way - // - Buffer headerPacket = (this.splitBufRef == null) ? null - : (Buffer) (this.splitBufRef.get()); + Buffer packetToSend = (this.splitBufRef == null) ? null : this.splitBufRef.get(); + Buffer toCompress = (!this.useCompression || this.compressBufRef == null) ? null : this.compressBufRef.get(); // // Store this packet in a soft reference...It can be re-used if not GC'd (so clients // that use it frequently won't have to re-alloc the 16M buffer), but we don't // penalize infrequent users of large packets by keeping 16M allocated all of the time // - if (headerPacket == null) { - headerPacket = new Buffer((this.maxThreeBytes + - HEADER_LENGTH)); - this.splitBufRef = new SoftReference(headerPacket); + if (packetToSend == null) { + packetToSend = new Buffer((this.maxThreeBytes + HEADER_LENGTH)); + this.splitBufRef = new SoftReference(packetToSend); } + if (this.useCompression) { + int cbuflen = packetLen + ((packetLen / this.maxThreeBytes) + 1) * HEADER_LENGTH; + if (toCompress == null) { + toCompress = new Buffer(cbuflen); + } else if (toCompress.getBufLength() < cbuflen) { + toCompress.setPosition(toCompress.getBufLength()); + toCompress.ensureCapacity(cbuflen - toCompress.getBufLength()); + } + } - int len = packet.getPosition(); + int len = packetLen - HEADER_LENGTH; // payload length left int splitSize = this.maxThreeBytes; int originalPacketPos = HEADER_LENGTH; byte[] origPacketBytes = packet.getByteBuffer(); - byte[] headerPacketBytes = headerPacket.getByteBuffer(); - while (len >= this.maxThreeBytes) { + int toCompressPosition = 0; + + // split to MySQL packets + while (len >= 0) { this.packetSequence++; - headerPacket.setPosition(0); - headerPacket.writeLongInt(splitSize); - - headerPacket.writeByte(this.packetSequence); - System.arraycopy(origPacketBytes, originalPacketPos, - headerPacketBytes, 4, splitSize); - - int packetLen = splitSize + HEADER_LENGTH; - - // - // Swap a compressed packet in, if we're using - // compression... - // - if (!this.useCompression) { - this.mysqlOutput.write(headerPacketBytes, 0, - splitSize + HEADER_LENGTH); - this.mysqlOutput.flush(); + if (len < splitSize) { + splitSize = len; + } + + packetToSend.setPosition(0); + packetToSend.writeLongInt(splitSize); + packetToSend.writeByte(this.packetSequence); + if (len > 0) { + System.arraycopy(origPacketBytes, originalPacketPos, packetToSend.getByteBuffer(), HEADER_LENGTH, splitSize); + } + + if (this.useCompression) { + System.arraycopy(packetToSend.getByteBuffer(), 0, toCompress.getByteBuffer(), toCompressPosition, HEADER_LENGTH + splitSize); + toCompressPosition += HEADER_LENGTH + splitSize; } else { - Buffer packetToSend; - - headerPacket.setPosition(0); - packetToSend = compressPacket(headerPacket, HEADER_LENGTH, - splitSize, HEADER_LENGTH); - packetLen = packetToSend.getPosition(); - - this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, - packetLen); + this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, HEADER_LENGTH + splitSize); this.mysqlOutput.flush(); } originalPacketPos += splitSize; - len -= splitSize; + len -= this.maxThreeBytes; + } - // - // Write last packet - // - headerPacket.clear(); - headerPacket.setPosition(0); - headerPacket.writeLongInt(len - HEADER_LENGTH); - this.packetSequence++; - headerPacket.writeByte(this.packetSequence); + // split to compressed packets + if (this.useCompression) { + len = toCompressPosition; + toCompressPosition = 0; + splitSize = this.maxThreeBytes- COMP_HEADER_LENGTH; + while (len >= 0) { + this.compressedPacketSequence++; - if (len != 0) { - System.arraycopy(origPacketBytes, originalPacketPos, - headerPacketBytes, 4, len - HEADER_LENGTH); - } + if (len < splitSize) { + splitSize = len; + } - int packetLen = len - HEADER_LENGTH; + Buffer compressedPacketToSend = compressPacket(toCompress, toCompressPosition, splitSize); + packetLen = compressedPacketToSend.getPosition(); + this.mysqlOutput.write(compressedPacketToSend.getByteBuffer(), 0, packetLen); + this.mysqlOutput.flush(); - // - // Swap a compressed packet in, if we're using - // compression... - // - if (!this.useCompression) { - this.mysqlOutput.write(headerPacket.getByteBuffer(), 0, len); - this.mysqlOutput.flush(); - } else { - Buffer packetToSend; - headerPacket.setPosition(0); - packetToSend = compressPacket(headerPacket, HEADER_LENGTH, - packetLen, HEADER_LENGTH); - packetLen = packetToSend.getPosition(); - - this.mysqlOutput.write(packetToSend.getByteBuffer(), 0, - packetLen); - this.mysqlOutput.flush(); + toCompressPosition += splitSize; + len -= (this.maxThreeBytes-COMP_HEADER_LENGTH); + } } } catch (IOException ioEx) { - throw new CommunicationsException(this.connection, - this.lastPacketSentTimeMs, ioEx); + throw SQLError.createCommunicationsException(this.connection, + this.lastPacketSentTimeMs, this.lastPacketReceivedTimeMs, ioEx, getExceptionInterceptor()); } } @@ -3176,12 +4456,12 @@ boolean hadWarnings() { return this.hadWarnings; } - + void scanForAndThrowDataTruncation() throws SQLException { if ((this.streamingData == null) && versionMeetsMinimum(4, 1, 0) && this.connection.getJdbcCompliantTruncation() && this.warningCount > 0) { - SQLError.convertShowWarningsToSQLWarnings(this.connection, - this.warningCount, true); + SQLError.convertShowWarningsToSQLWarnings(this.connection, + this.warningCount, true); } } @@ -3229,18 +4509,18 @@ } // User/Password data - packet.writeString(user, "Cp1252", this.connection); + packet.writeString(user, CODE_PAGE_1252, this.connection); if (password.length() != 0) { /* Prepare false scramble */ - packet.writeString(FALSE_SCRAMBLE, "Cp1252", this.connection); + packet.writeString(FALSE_SCRAMBLE, CODE_PAGE_1252, this.connection); } else { /* For empty password*/ - packet.writeString("", "Cp1252", this.connection); //$NON-NLS-1$ + packet.writeString("", CODE_PAGE_1252, this.connection); //$NON-NLS-1$ } if (this.useConnectWithDb) { - packet.writeString(database, "Cp1252", this.connection); + packet.writeString(database, CODE_PAGE_1252, this.connection); } send(packet, packet.getPosition()); @@ -3279,11 +4559,11 @@ byte[] mysqlScrambleBuff = new byte[20]; /* Decypt and store scramble 4 = hash for stage2 */ - Security.passwordCrypt(packetDataAfterSalt, + Security.xorString(packetDataAfterSalt, mysqlScrambleBuff, passwordHash, 20); /* Encode scramble with password. Recycle buffer */ - Security.passwordCrypt(mysqlScrambleBuff, buff, buff, 20); + Security.xorString(mysqlScrambleBuff, buff, buff, 20); Buffer packet2 = new Buffer(25); packet2.writeBytesNoNull(buff); @@ -3294,7 +4574,7 @@ } catch (NoSuchAlgorithmException nse) { throw SQLError.createSQLException(Messages.getString("MysqlIO.91") //$NON-NLS-1$ +Messages.getString("MysqlIO.92"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } else { try { @@ -3310,22 +4590,22 @@ byte[] mysqlScrambleBuff = new byte[20]; /* Decypt and store scramble 4 = hash for stage2 */ - Security.passwordCrypt(netReadPos4, mysqlScrambleBuff, + Security.xorString(netReadPos4, mysqlScrambleBuff, passwordHash, 20); /* Finally scramble decoded scramble with password */ - String scrambledPassword = Util.scramble(new String( + String scrambledPassword = Util.scramble(StringUtils.toString( mysqlScrambleBuff), password); Buffer packet2 = new Buffer(packLength); - packet2.writeString(scrambledPassword, "Cp1252", this.connection); + packet2.writeString(scrambledPassword, CODE_PAGE_1252, this.connection); this.packetSequence++; send(packet2, 24); } catch (NoSuchAlgorithmException nse) { throw SQLError.createSQLException(Messages.getString("MysqlIO.93") //$NON-NLS-1$ +Messages.getString("MysqlIO.94"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } } @@ -3375,10 +4655,10 @@ packet.writeLong(this.clientParam); packet.writeLong(this.maxThreeBytes); - // charset, JDBC will connect as 'latin1', + // charset, JDBC will connect as 'utf8', // and use 'SET NAMES' to change to the desired // charset after the connection is established. - packet.writeByte((byte) 8); + packet.writeByte((byte) UTF8_CHARSET_INDEX); // Set of bytes reserved for future use. packet.writeBytesNoNull(new byte[23]); @@ -3393,26 +4673,51 @@ } // User/Password data - packet.writeString(user); + packet.writeString(user, "utf-8", this.connection); if (password.length() != 0) { packet.writeByte((byte) 0x14); try { - packet.writeBytesNoNull(Security.scramble411(password, this.seed)); + packet.writeBytesNoNull(Security.scramble411(password, this.seed, + this.connection.getPasswordCharacterEncoding())); } catch (NoSuchAlgorithmException nse) { throw SQLError.createSQLException(Messages.getString("MysqlIO.95") //$NON-NLS-1$ +Messages.getString("MysqlIO.96"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); - } + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + } catch (UnsupportedEncodingException e) { + throw SQLError.createSQLException(Messages.getString("MysqlIO.95") //$NON-NLS-1$ + +Messages.getString("MysqlIO.96"), //$NON-NLS-1$ + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + } } else { /* For empty password*/ packet.writeByte((byte) 0); } if (this.useConnectWithDb) { - packet.writeString(database); + packet.writeString(database, "utf-8", this.connection); + } else { + /* For empty database*/ + packet.writeByte((byte) 0); } + + if ((this.serverCapabilities & CLIENT_PROTOCOL_41) != 0) { + // charset (2 bytes low-endian) + String mysqlEncodingName = this.connection.getServerCharacterEncoding(); + if ("ucs2".equalsIgnoreCase(mysqlEncodingName) || + "utf16".equalsIgnoreCase(mysqlEncodingName) || + "utf16le".equalsIgnoreCase(mysqlEncodingName) || + "uft32".equalsIgnoreCase(mysqlEncodingName)) { + packet.writeByte((byte) UTF8_CHARSET_INDEX); + packet.writeByte((byte) 0); + } + } + + // connection attributes + if ((this.serverCapabilities & CLIENT_CONNECT_ATTRS) != 0) { + sendConnectionAttributes(packet, "utf-8", this.connection); + } send(packet, packet.getPosition()); @@ -3448,110 +4753,103 @@ * * @throws SQLException DOCUMENT ME! */ - private final Object[] unpackBinaryResultSetRow(Field[] fields, + private final ResultSetRow unpackBinaryResultSetRow(Field[] fields, Buffer binaryData, int resultSetConcurrency) throws SQLException { int numFields = fields.length; - Object[] unpackedRowData = new Object[numFields]; + byte[][] unpackedRowData = new byte[numFields][]; // // Unpack the null bitmask, first // - /* Reserve place for null-marker bytes */ int nullCount = (numFields + 9) / 8; - - byte[] nullBitMask = new byte[nullCount]; - - for (int i = 0; i < nullCount; i++) { - nullBitMask[i] = binaryData.readByte(); - } - - int nullMaskPos = 0; + int nullMaskPos = binaryData.getPosition(); + binaryData.setPosition(nullMaskPos + nullCount); int bit = 4; // first two bits are reserved for future use - + // // TODO: Benchmark if moving check for updatable result // sets out of loop is worthwhile? // - + for (int i = 0; i < numFields; i++) { - if ((nullBitMask[nullMaskPos] & bit) != 0) { + if ((binaryData.readByte(nullMaskPos) & bit) != 0) { unpackedRowData[i] = null; } else { - if (resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) { - extractNativeEncodedColumn(binaryData, fields, i, + if (resultSetConcurrency != ResultSetInternalMethods.CONCUR_UPDATABLE) { + extractNativeEncodedColumn(binaryData, fields, i, unpackedRowData); } else { - unpackNativeEncodedColumn(binaryData, fields, i, + unpackNativeEncodedColumn(binaryData, fields, i, unpackedRowData); - } + } } - + if (((bit <<= 1) & 255) == 0) { bit = 1; /* To next byte */ nullMaskPos++; } } - return unpackedRowData; + return new ByteArrayRow(unpackedRowData, getExceptionInterceptor()); } - - private final void extractNativeEncodedColumn(Buffer binaryData, - Field[] fields, int columnIndex, Object[] unpackedRowData) throws SQLException { + + private final void extractNativeEncodedColumn(Buffer binaryData, + Field[] fields, int columnIndex, byte[][] unpackedRowData) throws SQLException { Field curField = fields[columnIndex]; - + switch (curField.getMysqlType()) { case MysqlDefs.FIELD_TYPE_NULL: break; // for dummy binds - + case MysqlDefs.FIELD_TYPE_TINY: unpackedRowData[columnIndex] = new byte[] {binaryData.readByte()}; break; - + case MysqlDefs.FIELD_TYPE_SHORT: case MysqlDefs.FIELD_TYPE_YEAR: - + unpackedRowData[columnIndex] = binaryData.getBytes(2); break; case MysqlDefs.FIELD_TYPE_LONG: case MysqlDefs.FIELD_TYPE_INT24: - + unpackedRowData[columnIndex] = binaryData.getBytes(4); break; case MysqlDefs.FIELD_TYPE_LONGLONG: unpackedRowData[columnIndex] = binaryData.getBytes(8); break; case MysqlDefs.FIELD_TYPE_FLOAT: - + unpackedRowData[columnIndex] = binaryData.getBytes(4); - break; + break; case MysqlDefs.FIELD_TYPE_DOUBLE: - + unpackedRowData[columnIndex] = binaryData.getBytes(8); break; case MysqlDefs.FIELD_TYPE_TIME: - + int length = (int) binaryData.readFieldLength(); - + unpackedRowData[columnIndex] = binaryData.getBytes(length); break; case MysqlDefs.FIELD_TYPE_DATE: - + length = (int) binaryData.readFieldLength(); - + unpackedRowData[columnIndex] = binaryData.getBytes(length); break; case MysqlDefs.FIELD_TYPE_DATETIME: case MysqlDefs.FIELD_TYPE_TIMESTAMP: length = (int) binaryData.readFieldLength(); - + unpackedRowData[columnIndex] = binaryData.getBytes(length); break; case MysqlDefs.FIELD_TYPE_TINY_BLOB: @@ -3565,346 +4863,346 @@ case MysqlDefs.FIELD_TYPE_NEW_DECIMAL: case MysqlDefs.FIELD_TYPE_GEOMETRY: unpackedRowData[columnIndex] = binaryData.readLenByteArray(0); - + break; case MysqlDefs.FIELD_TYPE_BIT: unpackedRowData[columnIndex] = binaryData.readLenByteArray(0); - + break; default: throw SQLError.createSQLException(Messages.getString("MysqlIO.97") //$NON-NLS-1$ +curField.getMysqlType() + Messages.getString("MysqlIO.98") + columnIndex + Messages.getString("MysqlIO.99") //$NON-NLS-1$ //$NON-NLS-2$ + fields.length + Messages.getString("MysqlIO.100"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } - private final void unpackNativeEncodedColumn(Buffer binaryData, - Field[] fields, int columnIndex, Object[] unpackedRowData) + private final void unpackNativeEncodedColumn(Buffer binaryData, + Field[] fields, int columnIndex, byte[][] unpackedRowData) throws SQLException { Field curField = fields[columnIndex]; - + switch (curField.getMysqlType()) { case MysqlDefs.FIELD_TYPE_NULL: break; // for dummy binds - + case MysqlDefs.FIELD_TYPE_TINY: - + byte tinyVal = binaryData.readByte(); - - if (!curField.isUnsigned()) { - unpackedRowData[columnIndex] = String.valueOf(tinyVal) - .getBytes(); + + if (!curField.isUnsigned()) { + unpackedRowData[columnIndex] = StringUtils.getBytes( + String.valueOf(tinyVal)); } else { short unsignedTinyVal = (short) (tinyVal & 0xff); - - unpackedRowData[columnIndex] = String.valueOf(unsignedTinyVal) - .getBytes(); + + unpackedRowData[columnIndex] = StringUtils.getBytes( + String.valueOf(unsignedTinyVal)); } - + break; - + case MysqlDefs.FIELD_TYPE_SHORT: case MysqlDefs.FIELD_TYPE_YEAR: - + short shortVal = (short) binaryData.readInt(); - + if (!curField.isUnsigned()) { - unpackedRowData[columnIndex] = String.valueOf(shortVal) - .getBytes(); + unpackedRowData[columnIndex] = StringUtils.getBytes( + String.valueOf(shortVal)); } else { int unsignedShortVal = shortVal & 0xffff; - unpackedRowData[columnIndex] = String.valueOf(unsignedShortVal) - .getBytes(); + unpackedRowData[columnIndex] = StringUtils.getBytes( + String.valueOf(unsignedShortVal)); } - + break; - + case MysqlDefs.FIELD_TYPE_LONG: case MysqlDefs.FIELD_TYPE_INT24: - + int intVal = (int) binaryData.readLong(); - + if (!curField.isUnsigned()) { - unpackedRowData[columnIndex] = String.valueOf(intVal) - .getBytes(); + unpackedRowData[columnIndex] = StringUtils.getBytes( + String.valueOf(intVal)); } else { long longVal = intVal & 0xffffffffL; - unpackedRowData[columnIndex] = String.valueOf(longVal) - .getBytes(); + unpackedRowData[columnIndex] = StringUtils.getBytes( + String.valueOf(longVal)); } - + break; - + case MysqlDefs.FIELD_TYPE_LONGLONG: - + long longVal = binaryData.readLongLong(); - + if (!curField.isUnsigned()) { - unpackedRowData[columnIndex] = String.valueOf(longVal) - .getBytes(); + unpackedRowData[columnIndex] = StringUtils.getBytes( + String.valueOf(longVal)); } else { - BigInteger asBigInteger = ResultSet.convertLongToUlong(longVal); + BigInteger asBigInteger = ResultSetImpl.convertLongToUlong(longVal); - unpackedRowData[columnIndex] = asBigInteger.toString() - .getBytes(); + unpackedRowData[columnIndex] = StringUtils.getBytes( + asBigInteger.toString()); } - + break; - + case MysqlDefs.FIELD_TYPE_FLOAT: - + float floatVal = Float.intBitsToFloat(binaryData.readIntAsLong()); - - unpackedRowData[columnIndex] = String.valueOf(floatVal).getBytes(); + unpackedRowData[columnIndex] = StringUtils.getBytes( + String.valueOf(floatVal)); + break; - + case MysqlDefs.FIELD_TYPE_DOUBLE: - + double doubleVal = Double.longBitsToDouble(binaryData.readLongLong()); - unpackedRowData[columnIndex] = String.valueOf(doubleVal).getBytes(); + unpackedRowData[columnIndex] = StringUtils.getBytes( + String.valueOf(doubleVal)); break; - + case MysqlDefs.FIELD_TYPE_TIME: - + int length = (int) binaryData.readFieldLength(); - + int hour = 0; int minute = 0; int seconds = 0; - + if (length != 0) { binaryData.readByte(); // skip tm->neg binaryData.readLong(); // skip daysPart hour = binaryData.readByte(); minute = binaryData.readByte(); seconds = binaryData.readByte(); - + if (length > 8) { binaryData.readLong(); // ignore 'secondsPart' } } - - + + byte[] timeAsBytes = new byte[8]; - + timeAsBytes[0] = (byte) Character.forDigit(hour / 10, 10); timeAsBytes[1] = (byte) Character.forDigit(hour % 10, 10); - + timeAsBytes[2] = (byte) ':'; - + timeAsBytes[3] = (byte) Character.forDigit(minute / 10, 10); timeAsBytes[4] = (byte) Character.forDigit(minute % 10, 10); - + timeAsBytes[5] = (byte) ':'; - + timeAsBytes[6] = (byte) Character.forDigit(seconds / 10, 10); timeAsBytes[7] = (byte) Character.forDigit(seconds % 10, 10); - + unpackedRowData[columnIndex] = timeAsBytes; - - + + break; - + case MysqlDefs.FIELD_TYPE_DATE: length = (int) binaryData.readFieldLength(); - + int year = 0; int month = 0; int day = 0; - + hour = 0; minute = 0; seconds = 0; - + if (length != 0) { year = binaryData.readInt(); month = binaryData.readByte(); day = binaryData.readByte(); } - + if ((year == 0) && (month == 0) && (day == 0)) { - if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals( + if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals( this.connection.getZeroDateTimeBehavior())) { unpackedRowData[columnIndex] = null; - + break; - } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals( + } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals( this.connection.getZeroDateTimeBehavior())) { throw SQLError.createSQLException("Value '0000-00-00' can not be represented as java.sql.Date", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } - + year = 1; month = 1; day = 1; } - - + + byte[] dateAsBytes = new byte[10]; - + dateAsBytes[0] = (byte) Character.forDigit(year / 1000, 10); - + int after1000 = year % 1000; - + dateAsBytes[1] = (byte) Character.forDigit(after1000 / 100, 10); - + int after100 = after1000 % 100; - + dateAsBytes[2] = (byte) Character.forDigit(after100 / 10, 10); dateAsBytes[3] = (byte) Character.forDigit(after100 % 10, 10); - + dateAsBytes[4] = (byte) '-'; - + dateAsBytes[5] = (byte) Character.forDigit(month / 10, 10); dateAsBytes[6] = (byte) Character.forDigit(month % 10, 10); - + dateAsBytes[7] = (byte) '-'; - + dateAsBytes[8] = (byte) Character.forDigit(day / 10, 10); dateAsBytes[9] = (byte) Character.forDigit(day % 10, 10); - + unpackedRowData[columnIndex] = dateAsBytes; - - + + break; - + case MysqlDefs.FIELD_TYPE_DATETIME: case MysqlDefs.FIELD_TYPE_TIMESTAMP: length = (int) binaryData.readFieldLength(); - + year = 0; month = 0; day = 0; - + hour = 0; minute = 0; seconds = 0; - + int nanos = 0; - + if (length != 0) { year = binaryData.readInt(); month = binaryData.readByte(); day = binaryData.readByte(); - + if (length > 4) { hour = binaryData.readByte(); minute = binaryData.readByte(); seconds = binaryData.readByte(); } - + //if (length > 7) { // nanos = (int)binaryData.readLong(); //} } - + if ((year == 0) && (month == 0) && (day == 0)) { - if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals( + if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals( this.connection.getZeroDateTimeBehavior())) { unpackedRowData[columnIndex] = null; - + break; - } else if (ConnectionProperties.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals( + } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals( this.connection.getZeroDateTimeBehavior())) { throw SQLError.createSQLException("Value '0000-00-00' can not be represented as java.sql.Timestamp", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } - + year = 1; month = 1; day = 1; } - - + + int stringLength = 19; - - byte[] nanosAsBytes = Integer.toString(nanos).getBytes(); - + + byte[] nanosAsBytes = StringUtils.getBytes(Integer.toString(nanos)); + stringLength += (1 + nanosAsBytes.length); // '.' + # of digits - + byte[] datetimeAsBytes = new byte[stringLength]; - + datetimeAsBytes[0] = (byte) Character.forDigit(year / 1000, 10); - + after1000 = year % 1000; - + datetimeAsBytes[1] = (byte) Character.forDigit(after1000 / 100, 10); - + after100 = after1000 % 100; - + datetimeAsBytes[2] = (byte) Character.forDigit(after100 / 10, 10); datetimeAsBytes[3] = (byte) Character.forDigit(after100 % 10, 10); - + datetimeAsBytes[4] = (byte) '-'; - + datetimeAsBytes[5] = (byte) Character.forDigit(month / 10, 10); datetimeAsBytes[6] = (byte) Character.forDigit(month % 10, 10); - + datetimeAsBytes[7] = (byte) '-'; - + datetimeAsBytes[8] = (byte) Character.forDigit(day / 10, 10); datetimeAsBytes[9] = (byte) Character.forDigit(day % 10, 10); - + datetimeAsBytes[10] = (byte) ' '; - + datetimeAsBytes[11] = (byte) Character.forDigit(hour / 10, 10); datetimeAsBytes[12] = (byte) Character.forDigit(hour % 10, 10); - + datetimeAsBytes[13] = (byte) ':'; - + datetimeAsBytes[14] = (byte) Character.forDigit(minute / 10, 10); datetimeAsBytes[15] = (byte) Character.forDigit(minute % 10, 10); - + datetimeAsBytes[16] = (byte) ':'; - + datetimeAsBytes[17] = (byte) Character.forDigit(seconds / 10, 10); datetimeAsBytes[18] = (byte) Character.forDigit(seconds % 10, 10); - + datetimeAsBytes[19] = (byte) '.'; + + final int nanosOffset = 20; + + System.arraycopy(nanosAsBytes, 0, datetimeAsBytes, nanosOffset, nanosAsBytes.length); - int nanosOffset = 20; - - for (int j = 0; j < nanosAsBytes.length; j++) { - datetimeAsBytes[nanosOffset + j] = nanosAsBytes[j]; - } - unpackedRowData[columnIndex] = datetimeAsBytes; - - + + break; - + case MysqlDefs.FIELD_TYPE_TINY_BLOB: case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB: case MysqlDefs.FIELD_TYPE_LONG_BLOB: @@ -3916,32 +5214,20 @@ case MysqlDefs.FIELD_TYPE_NEW_DECIMAL: case MysqlDefs.FIELD_TYPE_BIT: unpackedRowData[columnIndex] = binaryData.readLenByteArray(0); - + break; - + default: throw SQLError.createSQLException(Messages.getString("MysqlIO.97") //$NON-NLS-1$ +curField.getMysqlType() + Messages.getString("MysqlIO.98") + columnIndex + Messages.getString("MysqlIO.99") //$NON-NLS-1$ //$NON-NLS-2$ + fields.length + Messages.getString("MysqlIO.100"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } } - + /** - * Optimization to only use one calendar per-session, or calculate it - * for each call, depending on user configuration - */ - private Calendar getCalendarInstanceForSessionOrNew() { - if (this.connection.getDynamicCalendars()) { - return Calendar.getInstance(); - } else { - return this.sessionCalendar; - } - } - - /** * Negotiates the SSL communications channel used when connecting * to a MySQL server that understands SSL. * @@ -3954,17 +5240,14 @@ */ private void negotiateSSLConnection(String user, String password, String database, int packLength) - throws SQLException, CommunicationsException { + throws SQLException { if (!ExportControlled.enabled()) { throw new ConnectionFeatureNotAvailableException(this.connection, this.lastPacketSentTimeMs, null); } - boolean doSecureAuth = false; - if ((this.serverCapabilities & CLIENT_SECURE_CONNECTION) != 0) { this.clientParam |= CLIENT_SECURE_CONNECTION; - doSecureAuth = true; } this.clientParam |= CLIENT_SSL; @@ -3973,78 +5256,55 @@ if (this.use41Extensions) { packet.writeLong(this.clientParam); + packet.writeLong(this.maxThreeBytes); + int charsetIndex = 0; + if (this.connection.getEncoding() != null) { + charsetIndex = CharsetMapping.getCharsetIndexForMysqlEncodingName(CharsetMapping.getMysqlEncodingForJavaEncoding(this.connection.getEncoding(), this.connection)); + } + packet.writeByte(charsetIndex == 0 ? (byte) UTF8_CHARSET_INDEX : (byte) charsetIndex); + packet.writeBytesNoNull(new byte[23]); // Set of bytes reserved for future use. } else { packet.writeInt((int) this.clientParam); } send(packet, packet.getPosition()); ExportControlled.transformSocketToSSLSocket(this); - - packet.clear(); - - if (doSecureAuth) { - if (versionMeetsMinimum(4, 1, 1)) { - secureAuth411(null, packLength, user, password, database, true); - } else { - secureAuth411(null, packLength, user, password, database, true); - } - } else { - if (this.use41Extensions) { - packet.writeLong(this.clientParam); - packet.writeLong(this.maxThreeBytes); - } else { - packet.writeInt((int) this.clientParam); - packet.writeLongInt(this.maxThreeBytes); - } - - // User/Password data - packet.writeString(user); - - if (this.protocolVersion > 9) { - packet.writeString(Util.newCrypt(password, this.seed)); - } else { - packet.writeString(Util.oldCrypt(password, this.seed)); - } - - if (((this.serverCapabilities & CLIENT_CONNECT_WITH_DB) != 0) && - (database != null) && (database.length() > 0)) { - packet.writeString(database); - } - - send(packet, packet.getPosition()); - } } + public boolean isSSLEstablished() { + return ExportControlled.enabled() && ExportControlled.isSSLEstablished(this); + } + protected int getServerStatus() { return this.serverStatus; } - protected List fetchRowsViaCursor(List fetchedRows, long statementId, - Field[] columnTypes, int fetchSize) throws SQLException { - + protected List fetchRowsViaCursor(List fetchedRows, long statementId, + Field[] columnTypes, int fetchSize, boolean useBufferRowExplicit) throws SQLException { + if (fetchedRows == null) { - fetchedRows = new ArrayList(fetchSize); + fetchedRows = new ArrayList(fetchSize); } else { fetchedRows.clear(); } - + this.sharedSendPacket.clear(); - + this.sharedSendPacket.writeByte((byte) MysqlDefs.COM_FETCH); this.sharedSendPacket.writeLong(statementId); this.sharedSendPacket.writeLong(fetchSize); - + sendCommand(MysqlDefs.COM_FETCH, null, this.sharedSendPacket, true, - null); - - Object[] row = null; - + null, 0); + + ResultSetRow row = null; + while ((row = nextRow(columnTypes, columnTypes.length, true, - ResultSet.CONCUR_READ_ONLY)) != null) { + ResultSet.CONCUR_READ_ONLY, false, useBufferRowExplicit, false, null)) != null) { fetchedRows.add(row); } - + return fetchedRows; } @@ -4063,4 +5323,45 @@ protected String getQueryTimingUnits() { return this.queryTimingUnits; } + + protected int getCommandCount() { + return this.commandCount; + } + + private void checkTransactionState(int oldStatus) throws SQLException { + boolean previouslyInTrans = ((oldStatus & SERVER_STATUS_IN_TRANS) != 0); + boolean currentlyInTrans = ((this.serverStatus & SERVER_STATUS_IN_TRANS) != 0); + + if (previouslyInTrans && !currentlyInTrans) { + this.connection.transactionCompleted(); + } else if (!previouslyInTrans && currentlyInTrans) { + this.connection.transactionBegun(); + } + } + + protected void setStatementInterceptors(List statementInterceptors) { + this.statementInterceptors = statementInterceptors.isEmpty() ? null : statementInterceptors; + } + + protected ExceptionInterceptor getExceptionInterceptor() { + return this.exceptionInterceptor; + } + + protected void setSocketTimeout(int milliseconds) throws SQLException { + try { + mysqlConnection.setSoTimeout(milliseconds); + } catch (SocketException e) { + SQLException sqlEx = SQLError.createSQLException("Invalid socket timeout value or state", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + sqlEx.initCause(e); + + throw sqlEx; + } + } + + protected void releaseResources() { + if (this.deflater != null) { + this.deflater.end(); + this.deflater = null; + } + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlParameterMetadata.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlParameterMetadata.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlParameterMetadata.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlParameterMetadata.java 30 Jul 2014 08:37:25 -0000 1.1.2.1 @@ -1,25 +1,25 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc; @@ -29,134 +29,186 @@ public class MysqlParameterMetadata implements ParameterMetaData { boolean returnSimpleMetadata = false; + ResultSetMetaData metadata = null; + int parameterCount = 0; + + private ExceptionInterceptor exceptionInterceptor; - - MysqlParameterMetadata(Field[] fieldInfo, int parameterCount) { - this.metadata = new ResultSetMetaData(fieldInfo, false); - + MysqlParameterMetadata(Field[] fieldInfo, int parameterCount, ExceptionInterceptor exceptionInterceptor) { + this.metadata = new ResultSetMetaData(fieldInfo, false, true, exceptionInterceptor); + this.parameterCount = parameterCount; + this.exceptionInterceptor = exceptionInterceptor; } - + /** - * Used for "fake" basic metadata for client-side prepared statements - * when we don't know the parameter types. + * Used for "fake" basic metadata for client-side prepared statements when + * we don't know the parameter types. * * @param parameterCount */ MysqlParameterMetadata(int count) { this.parameterCount = count; this.returnSimpleMetadata = true; } - + public int getParameterCount() throws SQLException { return this.parameterCount; } public int isNullable(int arg0) throws SQLException { checkAvailable(); - + return this.metadata.isNullable(arg0); } private void checkAvailable() throws SQLException { if (this.metadata == null || this.metadata.fields == null) { throw SQLError.createSQLException( - "Parameter metadata not available for the given statement", - SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); + "Parameter metadata not available for the given statement", + SQLError.SQL_STATE_DRIVER_NOT_CAPABLE, this.exceptionInterceptor); } } public boolean isSigned(int arg0) throws SQLException { if (this.returnSimpleMetadata) { checkBounds(arg0); - + return false; } - + checkAvailable(); - + return (this.metadata.isSigned(arg0)); } public int getPrecision(int arg0) throws SQLException { if (this.returnSimpleMetadata) { checkBounds(arg0); - + return 0; } - + checkAvailable(); - + return (this.metadata.getPrecision(arg0)); } public int getScale(int arg0) throws SQLException { if (this.returnSimpleMetadata) { checkBounds(arg0); - + return 0; } - + checkAvailable(); - + return (this.metadata.getScale(arg0)); } public int getParameterType(int arg0) throws SQLException { if (this.returnSimpleMetadata) { checkBounds(arg0); - + return Types.VARCHAR; } - + checkAvailable(); - + return (this.metadata.getColumnType(arg0)); } public String getParameterTypeName(int arg0) throws SQLException { if (this.returnSimpleMetadata) { checkBounds(arg0); - + return "VARCHAR"; } - + checkAvailable(); - + return (this.metadata.getColumnTypeName(arg0)); } public String getParameterClassName(int arg0) throws SQLException { if (this.returnSimpleMetadata) { checkBounds(arg0); - + return "java.lang.String"; } - + checkAvailable(); - + return (this.metadata.getColumnClassName(arg0)); } public int getParameterMode(int arg0) throws SQLException { return parameterModeIn; } - + private void checkBounds(int paramNumber) throws SQLException { if (paramNumber < 1) { - throw SQLError.createSQLException("Parameter index of '" + paramNumber + - "' is invalid.", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError.createSQLException("Parameter index of '" + + paramNumber + "' is invalid.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } - + 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); - + throw SQLError.createSQLException("Parameter index of '" + + paramNumber + + "' is greater than number of parameters, which is '" + + this.parameterCount + "'.", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } } + + /** + * Returns true if this either implements the interface argument or is directly or indirectly a wrapper + * for an object that does. Returns false otherwise. If this implements the interface then return true, + * else if this is a wrapper then return the result of recursively calling isWrapperFor on the wrapped + * object. If this does not implement the interface and is not a wrapper, return false. + * This method should be implemented as a low-cost operation compared to unwrap so that + * callers can use this method to avoid expensive unwrap calls that may fail. If this method + * returns true then calling unwrap with the same argument should succeed. + * + * @param interfaces a Class defining an interface. + * @return true if this implements the interface or directly or indirectly wraps an object that does. + * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper + * for an object with the given interface. + * @since 1.6 + */ + public boolean isWrapperFor(Class iface) throws SQLException { + + // This works for classes that aren't actually wrapping + // anything + return iface.isInstance(this); + } + + /** + * Returns an object that implements the given interface to allow access to non-standard methods, + * or standard methods not exposed by the proxy. + * The result may be either the object found to implement the interface or a proxy for that object. + * If the receiver implements the interface then that is the object. If the receiver is a wrapper + * and the wrapped object implements the interface then that is the object. Otherwise the object is + * the result of calling unwrap recursively on the wrapped object. If the receiver is not a + * wrapper and does not implement the interface, then an SQLException is thrown. + * + * @param iface A Class defining an interface that the result must implement. + * @return an object that implements the interface. May be a proxy for the actual implementing object. + * @throws java.sql.SQLException If no object found that implements the interface + * @since 1.6 + */ + public Object unwrap(Class iface) throws java.sql.SQLException { + try { + // This works for classes that aren't actually wrapping + // anything + return Util.cast(iface, this); + } catch (ClassCastException cce) { + throw SQLError.createSQLException("Unable to unwrap to " + iface.toString(), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlSavepoint.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlSavepoint.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlSavepoint.java 17 Aug 2012 14:57:08 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlSavepoint.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.rmi.server.UID; @@ -42,7 +41,8 @@ int uidLength = uidStr.length(); - StringBuffer safeString = new StringBuffer(uidLength); + StringBuffer safeString = new StringBuffer(uidLength+1); + safeString.append('_'); for (int i = 0; i < uidLength; i++) { char c = uidStr.charAt(i); @@ -58,6 +58,8 @@ } private String savepointName; + + private ExceptionInterceptor exceptionInterceptor; /** * Creates an unnamed savepoint. @@ -67,8 +69,8 @@ * @throws SQLException * if an error occurs */ - MysqlSavepoint() throws SQLException { - this(getUniqueId()); + MysqlSavepoint(ExceptionInterceptor exceptionInterceptor) throws SQLException { + this(getUniqueId(), exceptionInterceptor); } /** @@ -80,21 +82,23 @@ * @throws SQLException * if name == null or is empty. */ - MysqlSavepoint(String name) throws SQLException { + MysqlSavepoint(String name, ExceptionInterceptor exceptionInterceptor) throws SQLException { if (name == null || name.length() == 0) { throw SQLError.createSQLException("Savepoint name can not be NULL or empty", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } this.savepointName = name; + + this.exceptionInterceptor = exceptionInterceptor; } /** * @see java.sql.Savepoint#getSavepointId() */ public int getSavepointId() throws SQLException { throw SQLError.createSQLException("Only named savepoints are supported.", - SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); + SQLError.SQL_STATE_DRIVER_NOT_CAPABLE, exceptionInterceptor); } /** Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/NamedPipeSocketFactory.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/NamedPipeSocketFactory.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/NamedPipeSocketFactory.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/NamedPipeSocketFactory.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,45 +1,43 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; - import java.net.Socket; import java.net.SocketException; - +import java.sql.SQLException; import java.util.Properties; /** * A socket factory for named pipes (on Windows) * * @author Mark Matthews */ -public class NamedPipeSocketFactory implements SocketFactory { +public class NamedPipeSocketFactory implements SocketFactory, SocketMetadata { /** * A socket that encapsulates named pipes on Windows */ @@ -171,7 +169,7 @@ } } - private static final String NAMED_PIPE_PROP_NAME = "namedPipePath"; //$NON-NLS-1$ + public static final String NAMED_PIPE_PROP_NAME = "namedPipePath"; //$NON-NLS-1$ private Socket namedPipeSocket; @@ -216,4 +214,9 @@ return this.namedPipeSocket; } + + public boolean isLocallyConnected(ConnectionImpl conn) throws SQLException { + // Until I learn otherwise (or learn how to detect it), I assume that we are + return true; + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/NdbLoadBalanceExceptionChecker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/NetworkResources.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/NoSubInterceptorWrapper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringDriver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringDriver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringDriver.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringDriver.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,43 +1,43 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.lang.ref.PhantomReference; +import java.lang.ref.ReferenceQueue; import java.net.URLDecoder; -import java.sql.Connection; import java.sql.DriverPropertyInfo; import java.sql.SQLException; - import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Properties; import java.util.StringTokenizer; - +import java.util.concurrent.ConcurrentHashMap; /** * The Java SQL framework allows for multiple database drivers. Each driver * should supply a class that implements the Driver interface @@ -68,14 +68,54 @@ * @see java.sql.Driver */ public class NonRegisteringDriver implements java.sql.Driver { + private static final String ALLOWED_QUOTES = "\"'"; + private static final String REPLICATION_URL_PREFIX = "jdbc:mysql:replication://"; private static final String URL_PREFIX = "jdbc:mysql://"; private static final String MXJ_URL_PREFIX = "jdbc:mysql:mxj://"; - private static final String LOADBALANCE_URL_PREFIX = "jdbc:mysql:loadbalance://"; + public static final String LOADBALANCE_URL_PREFIX = "jdbc:mysql:loadbalance://"; + protected static final ConcurrentHashMap connectionPhantomRefs = new ConcurrentHashMap(); + + protected static final ReferenceQueue refQueue = new ReferenceQueue(); + + public static final String OS = getOSName(); + public static final String PLATFORM = getPlatform(); + public static final String LICENSE = "@MYSQL_CJ_LICENSE_TYPE@"; + public static final String RUNTIME_VENDOR = System.getProperty("java.vendor"); + public static final String RUNTIME_VERSION = System.getProperty("java.version"); + public static final String VERSION = "@MYSQL_CJ_VERSION@"; + public static final String NAME = "@MYSQL_CJ_DISPLAY_PROD_NAME@"; + + /* + * Standardizes OS name information to align with other drivers/clients + * for MySQL connection attributes + * + * @return the transformed, standardized OS name + */ + public static String getOSName() { + return System.getProperty("os.name"); + } + + /* + * Standardizes platform information to align with other drivers/clients + * for MySQL connection attributes + * + * @return the transformed, standardized platform details + */ + public static String getPlatform() { + return System.getProperty("os.arch"); + } + + + static { + AbandonedConnectionCleanupThread referenceThread = new AbandonedConnectionCleanupThread(); + referenceThread.setDaemon(true); + referenceThread.start(); + } /** * Key used to retreive the database value from the properties instance * passed to the driver. @@ -94,6 +134,8 @@ */ public static final String HOST_PROPERTY_KEY = "HOST"; + public static final String NUM_HOSTS_PROPERTY_KEY = "NUM_HOSTS"; + /** * Key used to retreive the password value from the properties instance * passed to the driver. @@ -122,6 +164,10 @@ */ public static final String USER_PROPERTY_KEY = "user"; + public static final String PROTOCOL_PROPERTY_KEY = "PROTOCOL"; + + public static final String PATH_PROPERTY_KEY = "PATH"; + /** * Gets the drivers major version number * @@ -156,10 +202,19 @@ */ protected static String[] parseHostPortPair(String hostPortPair) throws SQLException { - int portIndex = hostPortPair.indexOf(":"); //$NON-NLS-1$ + String[] splitValues = new String[2]; + if (StringUtils.startsWithIgnoreCaseAndWs(hostPortPair, "address")) { + splitValues[HOST_NAME_INDEX] = hostPortPair.trim(); + splitValues[PORT_NUMBER_INDEX] = null; + + return splitValues; + } + + int portIndex = hostPortPair.indexOf(":"); //$NON-NLS-1$ + String hostname = null; if (portIndex != -1) { @@ -173,7 +228,7 @@ } else { throw SQLError.createSQLException(Messages .getString("NonRegisteringDriver.37"), //$NON-NLS-1$ - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); + SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); } } else { splitValues[HOST_NAME_INDEX] = hostPortPair; @@ -281,24 +336,38 @@ return null; } + if (!"1".equals(props.getProperty(NUM_HOSTS_PROPERTY_KEY))) { + return connectFailover(url, info); + } + try { - Connection newConn = new com.mysql.jdbc.Connection(host(props), - port(props), props, database(props), url); - + Connection newConn = com.mysql.jdbc.ConnectionImpl.getInstance( + host(props), port(props), props, database(props), url); + return newConn; } catch (SQLException sqlEx) { // Don't wrap SQLExceptions, throw // them un-changed. throw sqlEx; } catch (Exception ex) { - throw SQLError.createSQLException(Messages + SQLException sqlEx = SQLError.createSQLException(Messages .getString("NonRegisteringDriver.17") //$NON-NLS-1$ + ex.toString() + Messages.getString("NonRegisteringDriver.18"), //$NON-NLS-1$ - SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE); + SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, null); + + sqlEx.initCause(ex); + + throw sqlEx; } } + protected static void trackConnection(Connection newConn) { + + ConnectionPhantomReference phantomRef = new ConnectionPhantomReference((ConnectionImpl) newConn, refQueue); + connectionPhantomRefs.put(phantomRef, phantomRef); + } + private java.sql.Connection connectLoadBalanced(String url, Properties info) throws SQLException { Properties parsedProps = parseURL(url, info); @@ -307,28 +376,63 @@ return null; } - String hostValues = parsedProps.getProperty(HOST_PROPERTY_KEY); + // People tend to drop this in, it doesn't make sense + parsedProps.remove("roundRobinLoadBalance"); + + int numHosts = Integer.parseInt(parsedProps.getProperty(NUM_HOSTS_PROPERTY_KEY)); - List hostList = null; + List hostList = new ArrayList(); - if (hostValues != null) { - hostList = StringUtils.split(hostValues, ",", true); + for (int i = 0; i < numHosts; i++) { + int index = i + 1; + + hostList.add(parsedProps.getProperty(HOST_PROPERTY_KEY + "." + index) + ":" + + parsedProps.getProperty(PORT_PROPERTY_KEY + "." + index)); } - if (hostList == null) { - hostList = new ArrayList(); - hostList.add("localhost:3306"); - } - LoadBalancingConnectionProxy proxyBal = new LoadBalancingConnectionProxy( hostList, parsedProps); return (java.sql.Connection) java.lang.reflect.Proxy.newProxyInstance(this .getClass().getClassLoader(), - new Class[] { java.sql.Connection.class }, proxyBal); + new Class[] { com.mysql.jdbc.LoadBalancedConnection.class }, proxyBal); } + + private java.sql.Connection connectFailover(String url, Properties info) + throws SQLException { + Properties parsedProps = parseURL(url, info); - private java.sql.Connection connectReplicationConnection(String url, Properties info) + if (parsedProps == null) { + return null; + } + + // People tend to drop this in, it doesn't make sense + parsedProps.remove("roundRobinLoadBalance"); + parsedProps.setProperty("autoReconnect", "false"); + + int numHosts = Integer.parseInt(parsedProps + .getProperty(NUM_HOSTS_PROPERTY_KEY)); + + List hostList = new ArrayList(); + + for (int i = 0; i < numHosts; i++) { + int index = i + 1; + + hostList.add(parsedProps.getProperty(HOST_PROPERTY_KEY + "." + + index) + + ":" + + parsedProps.getProperty(PORT_PROPERTY_KEY + "." + index)); + } + + FailoverConnectionProxy connProxy = new FailoverConnectionProxy( + hostList, parsedProps); + + return (java.sql.Connection) java.lang.reflect.Proxy.newProxyInstance( + this.getClass().getClassLoader(), + new Class[] { com.mysql.jdbc.Connection.class }, connProxy); + } + + protected java.sql.Connection connectReplicationConnection(String url, Properties info) throws SQLException { Properties parsedProps = parseURL(url, info); @@ -343,61 +447,71 @@ // debugging slavesProps.setProperty("com.mysql.jdbc.ReplicationConnection.isSlave", "true"); + + int numHosts = Integer.parseInt(parsedProps.getProperty(NUM_HOSTS_PROPERTY_KEY)); - String hostValues = parsedProps.getProperty(HOST_PROPERTY_KEY); - - if (hostValues != null) { - StringTokenizer st = new StringTokenizer(hostValues, ","); - - StringBuffer masterHost = new StringBuffer(); - StringBuffer slaveHosts = new StringBuffer(); - - if (st.hasMoreTokens()) { - String[] hostPortPair = parseHostPortPair(st.nextToken()); - - if (hostPortPair[HOST_NAME_INDEX] != null) { - masterHost.append(hostPortPair[HOST_NAME_INDEX]); + if (numHosts < 2) { + throw SQLError + .createSQLException( + "Must specify at least one slave host to connect to for master/slave replication load-balancing functionality", + SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); + } + List slaveHostList = new ArrayList(); + List masterHostList = new ArrayList(); + + + String firstHost = masterProps.getProperty(HOST_PROPERTY_KEY + ".1") + ":" + + masterProps.getProperty(PORT_PROPERTY_KEY + ".1"); + + boolean usesExplicitServerType = NonRegisteringDriver.isHostPropertiesList(firstHost); + + for (int i = 0; i < numHosts; i++) { + int index = i + 1; + + masterProps.remove(HOST_PROPERTY_KEY + "." + index); + masterProps.remove(PORT_PROPERTY_KEY + "." + index); + slavesProps.remove(HOST_PROPERTY_KEY + "." + index); + slavesProps.remove(PORT_PROPERTY_KEY + "." + index); + + String host = parsedProps.getProperty(HOST_PROPERTY_KEY + "." + index); + String port = parsedProps.getProperty(PORT_PROPERTY_KEY + "." + index); + if(usesExplicitServerType) { + if(isHostMaster(host)) { + masterHostList.add(host); + } else { + slaveHostList.add(host); } - - if (hostPortPair[PORT_NUMBER_INDEX] != null) { - masterHost.append(":"); - masterHost.append(hostPortPair[PORT_NUMBER_INDEX]); - } - } - - boolean firstSlaveHost = true; - - while (st.hasMoreTokens()) { - String[] hostPortPair = parseHostPortPair(st.nextToken()); - - if (!firstSlaveHost) { - slaveHosts.append(","); + } else { + if(i == 0) { + masterHostList.add(host + ":" + port); } else { - firstSlaveHost = false; + slaveHostList.add(host + ":" + port); } - - if (hostPortPair[HOST_NAME_INDEX] != null) { - slaveHosts.append(hostPortPair[HOST_NAME_INDEX]); - } - - if (hostPortPair[PORT_NUMBER_INDEX] != null) { - slaveHosts.append(":"); - slaveHosts.append(hostPortPair[PORT_NUMBER_INDEX]); - } } + } - if (slaveHosts.length() == 0) { - throw SQLError - .createSQLException( - "Must specify at least one slave host to connect to for master/slave replication load-balancing functionality", - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); - } + slavesProps.remove(NUM_HOSTS_PROPERTY_KEY); + masterProps.remove(NUM_HOSTS_PROPERTY_KEY); + masterProps.remove(HOST_PROPERTY_KEY); + masterProps.remove(PORT_PROPERTY_KEY); + slavesProps.remove(HOST_PROPERTY_KEY); + slavesProps.remove(PORT_PROPERTY_KEY); + - masterProps.setProperty(HOST_PROPERTY_KEY, masterHost.toString()); - slavesProps.setProperty(HOST_PROPERTY_KEY, slaveHosts.toString()); + return new ReplicationConnection(masterProps, slavesProps, masterHostList, slaveHostList); + } + + + + private boolean isHostMaster(String host) { + if (NonRegisteringDriver.isHostPropertiesList(host)) { + Properties hostSpecificProps = NonRegisteringDriver.expandHostKeyValues(host); + if(hostSpecificProps.containsKey("type") && + "master".equalsIgnoreCase(hostSpecificProps.get("type").toString())) { + return true; + } } - - return new ReplicationConnection(masterProps, slavesProps); + return false; } /** @@ -421,10 +535,6 @@ return getMajorVersionInternal(); } - // - // return the value of any property this driver knows about - // - /** * Get the drivers minor version number * @@ -497,7 +607,7 @@ passwordProp.description = Messages .getString("NonRegisteringDriver.16"); //$NON-NLS-1$ - DriverPropertyInfo[] dpi = ConnectionProperties + DriverPropertyInfo[] dpi = ConnectionPropertiesImpl .exposeAsDriverPropertyInfo(info, 5); dpi[0] = hostProp; @@ -509,6 +619,10 @@ return dpi; } + // + // return the value of any property this driver knows about + // + /** * Returns the hostname property * @@ -560,6 +674,7 @@ int beginningOfSlashes = url.indexOf("//"); if (StringUtils.startsWithIgnoreCase(url, MXJ_URL_PREFIX)) { + urlProps .setProperty("socketFactory", "com.mysql.management.driverlaunched.ServerLauncherSocketFactory"); @@ -614,7 +729,7 @@ String hostStuff = null; - int slashIndex = url.indexOf("/"); //$NON-NLS-1$ + int slashIndex = StringUtils.indexOfIgnoreCaseRespectMarker(0, url, "/", ALLOWED_QUOTES, ALLOWED_QUOTES, true); //$NON-NLS-1$ if (slashIndex != -1) { hostStuff = url.substring(0, slashIndex); @@ -627,10 +742,39 @@ hostStuff = url; } - if ((hostStuff != null) && (hostStuff.length() > 0)) { - urlProps.put(HOST_PROPERTY_KEY, hostStuff); //$NON-NLS-1$ + int numHosts = 0; + + if ((hostStuff != null) && (hostStuff.trim().length() > 0)) { + List hosts = StringUtils.split(hostStuff, ",", ALLOWED_QUOTES, ALLOWED_QUOTES, false); + + + for (String hostAndPort : hosts) { + numHosts++; + + String[] hostPortPair = parseHostPortPair(hostAndPort); + + if (hostPortPair[HOST_NAME_INDEX] != null && hostPortPair[HOST_NAME_INDEX].trim().length() > 0) { + urlProps.setProperty(HOST_PROPERTY_KEY + "." + numHosts, hostPortPair[HOST_NAME_INDEX]); + } else { + urlProps.setProperty(HOST_PROPERTY_KEY + "." + numHosts, "localhost"); + } + + if (hostPortPair[PORT_NUMBER_INDEX] != null) { + urlProps.setProperty(PORT_PROPERTY_KEY + "." + numHosts, hostPortPair[PORT_NUMBER_INDEX]); + } else { + urlProps.setProperty(PORT_PROPERTY_KEY + "." + numHosts, "3306"); + } + } + } else { + numHosts = 1; + urlProps.setProperty(HOST_PROPERTY_KEY + ".1", "localhost"); + urlProps.setProperty(PORT_PROPERTY_KEY + ".1", "3306"); } + urlProps.setProperty(NUM_HOSTS_PROPERTY_KEY, String.valueOf(numHosts)); + urlProps.setProperty(HOST_PROPERTY_KEY, urlProps.getProperty(HOST_PROPERTY_KEY + ".1")); + urlProps.setProperty(PORT_PROPERTY_KEY, urlProps.getProperty(PORT_PROPERTY_KEY + ".1")); + String propertiesTransformClassName = urlProps .getProperty(PROPERTIES_TRANSFORM_KEY); @@ -646,24 +790,24 @@ + propertiesTransformClassName + "' due to underlying exception: " + e.toString(), - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); + 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); + 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); + SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); } } - + if (Util.isColdFusion() && urlProps.getProperty("autoConfigureForColdFusion", "true").equalsIgnoreCase("true")) { String configs = urlProps.getProperty(USE_CONFIG_PROPERTY_KEY); @@ -694,14 +838,14 @@ } if (configNames != null) { - List splitNames = StringUtils.split(configNames, ",", true); + List splitNames = StringUtils.split(configNames, ",", true); Properties configProps = new Properties(); - Iterator namesIter = splitNames.iterator(); + Iterator namesIter = splitNames.iterator(); while (namesIter.hasNext()) { - String configName = (String) namesIter.next(); + String configName = namesIter.next(); try { InputStream configAsStream = getClass() @@ -713,20 +857,23 @@ .createSQLException( "Can't find configuration template named '" + configName + "'", - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); + SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); } configProps.load(configAsStream); } catch (IOException ioEx) { - throw SQLError.createSQLException( + SQLException sqlEx = SQLError.createSQLException( "Unable to load configuration template '" + configName + "' due to underlying IOException: " + ioEx, - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); + SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null); + sqlEx.initCause(ioEx); + + throw sqlEx; } } - Iterator propsIter = urlProps.keySet().iterator(); + Iterator propsIter = urlProps.keySet().iterator(); while (propsIter.hasNext()) { String key = propsIter.next().toString(); @@ -740,12 +887,14 @@ // Properties passed in should override ones in URL if (defaults != null) { - Iterator propsIter = defaults.keySet().iterator(); + Iterator propsIter = defaults.keySet().iterator(); while (propsIter.hasNext()) { String key = propsIter.next().toString(); - String property = defaults.getProperty(key); - urlProps.setProperty(key, property); + if (!key.equals(NUM_HOSTS_PROPERTY_KEY)) { + String property = defaults.getProperty(key); + urlProps.setProperty(key, property); + } } } @@ -777,4 +926,79 @@ public String property(String name, Properties props) { return props.getProperty(name); } + + + /** + * Expands hosts of the form address=(protocol=tcp)(host=localhost)(port=3306) + * into a java.util.Properties. Special characters (in this case () and =) must be quoted. + * Any values that are string-quoted ("" or '') are also stripped of quotes. + */ + public static Properties expandHostKeyValues(String host) { + Properties hostProps = new Properties(); + + if (isHostPropertiesList(host)) { + host = host.substring("address=".length() + 1); + List hostPropsList = StringUtils.split(host, ")", "'\"", "'\"", true); + + for (String propDef : hostPropsList) { + if (propDef.startsWith("(")) { + propDef = propDef.substring(1); + } + + List kvp = StringUtils.split(propDef, "=", "'\"", "'\"", true); + + String key = kvp.get(0); + String value = kvp.size() > 1 ? kvp.get(1) : null; + + if (value != null && ((value.startsWith("\"") && value.endsWith("\"")) || (value.startsWith("'") && value.endsWith("'")))) { + value = value.substring(1, value.length() - 1); + } + + if (value != null) { + if (HOST_PROPERTY_KEY.equalsIgnoreCase(key) || + DBNAME_PROPERTY_KEY.equalsIgnoreCase(key) || + PORT_PROPERTY_KEY.equalsIgnoreCase(key) || + PROTOCOL_PROPERTY_KEY.equalsIgnoreCase(key) || + PATH_PROPERTY_KEY.equalsIgnoreCase(key)) { + key = key.toUpperCase(Locale.ENGLISH); + } else if (USER_PROPERTY_KEY.equalsIgnoreCase(key) || + PASSWORD_PROPERTY_KEY.equalsIgnoreCase(key)) { + key = key.toLowerCase(Locale.ENGLISH); + } + + hostProps.setProperty(key, value); + } + } + } + + return hostProps; + } + + public static boolean isHostPropertiesList(String host) { + return host != null && StringUtils.startsWithIgnoreCase(host, "address="); + } + + static class ConnectionPhantomReference extends PhantomReference { + private NetworkResources io; + + ConnectionPhantomReference(ConnectionImpl connectionImpl, ReferenceQueue q) { + super(connectionImpl, q); + + try { + io = connectionImpl.getIO().getNetworkResources(); + } catch (SQLException e) { + // if we somehow got here and there's really no i/o, we deal with it later + } + } + + void cleanup() { + if (io != null) { + try { + io.forceClose(); + } finally { + io = null; + } + } + } + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringReplicationDriver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringReplicationDriver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringReplicationDriver.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/NonRegisteringReplicationDriver.java 30 Jul 2014 08:37:25 -0000 1.1.2.1 @@ -1,24 +1,23 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. - + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */ @@ -27,7 +26,6 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; -import java.util.StringTokenizer; /** * Driver that opens two connections, one two a replication master, and another @@ -48,71 +46,6 @@ * @see java.sql.Driver#connect(java.lang.String, java.util.Properties) */ public Connection connect(String url, Properties info) throws SQLException { - Properties parsedProps = parseURL(url, info); - - if (parsedProps == null) { - return null; - } - - Properties masterProps = (Properties)parsedProps.clone(); - Properties slavesProps = (Properties)parsedProps.clone(); - - // Marker used for further testing later on, also when - // debugging - slavesProps.setProperty("com.mysql.jdbc.ReplicationConnection.isSlave", "true"); - - String hostValues = parsedProps.getProperty(HOST_PROPERTY_KEY); - - if (hostValues != null) { - StringTokenizer st = new StringTokenizer(hostValues, ","); - - StringBuffer masterHost = new StringBuffer(); - StringBuffer slaveHosts = new StringBuffer(); - - if (st.hasMoreTokens()) { - String[] hostPortPair = parseHostPortPair(st.nextToken()); - - if (hostPortPair[HOST_NAME_INDEX] != null) { - masterHost.append(hostPortPair[HOST_NAME_INDEX]); - } - - if (hostPortPair[PORT_NUMBER_INDEX] != null) { - masterHost.append(":"); - masterHost.append(hostPortPair[PORT_NUMBER_INDEX]); - } - } - - boolean firstSlaveHost = true; - - while (st.hasMoreTokens()) { - String[] hostPortPair = parseHostPortPair(st.nextToken()); - - if (!firstSlaveHost) { - slaveHosts.append(","); - } else { - firstSlaveHost = false; - } - - if (hostPortPair[HOST_NAME_INDEX] != null) { - slaveHosts.append(hostPortPair[HOST_NAME_INDEX]); - } - - if (hostPortPair[PORT_NUMBER_INDEX] != null) { - slaveHosts.append(":"); - slaveHosts.append(hostPortPair[PORT_NUMBER_INDEX]); - } - } - - if (slaveHosts.length() == 0) { - throw SQLError.createSQLException( - "Must specify at least one slave host to connect to for master/slave replication load-balancing functionality", - SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); - } - - masterProps.setProperty(HOST_PROPERTY_KEY, masterHost.toString()); - slavesProps.setProperty(HOST_PROPERTY_KEY, slaveHosts.toString()); - } - - return new ReplicationConnection(masterProps, slavesProps); + return connectReplicationConnection(url, info); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/NotImplemented.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/NotImplemented.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/NotImplemented.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/NotImplemented.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; /** @@ -30,6 +29,9 @@ * @author Mark Matthews */ public class NotImplemented extends java.sql.SQLException { + + static final long serialVersionUID = 7768433826547599990L; + // ~ Constructors // ----------------------------------------------------------- Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/NotUpdatable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/NotUpdatable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/NotUpdatable.java 17 Aug 2012 14:57:08 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/NotUpdatable.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.SQLException; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/OperationNotSupportedException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/OperationNotSupportedException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/OperationNotSupportedException.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/OperationNotSupportedException.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,14 +1,34 @@ /* - * Created on Sep 23, 2004 - * - * TODO To change the template for this generated file go to - * Window - Preferences - Java - Code Style - Code Templates + Copyright (c) 2004, 2014, 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 FLOSS 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; class OperationNotSupportedException extends SQLException { + + static final long serialVersionUID = 474918612056813430L; + OperationNotSupportedException() { super( Messages.getString("RowDataDynamic.10"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/OutputStreamWatcher.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/OutputStreamWatcher.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/OutputStreamWatcher.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/OutputStreamWatcher.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; /** Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/PacketTooBigException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/PacketTooBigException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/PacketTooBigException.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/PacketTooBigException.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.SQLException; @@ -32,6 +31,9 @@ * @author Mark Matthews */ public class PacketTooBigException extends SQLException { + + static final long serialVersionUID = 7248633977685452174L; + // ~ Constructors // ----------------------------------------------------------- Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ParameterBindings.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/PerConnectionLRUFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/PerVmServerConfigCacheFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/PingTarget.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/PingTarget.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/PingTarget.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/PingTarget.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,25 +1,26 @@ /* - Copyright (C) 2007 MySQL AB + Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + */ - + package com.mysql.jdbc; import java.sql.SQLException; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/PreparedStatement.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/PreparedStatement.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/PreparedStatement.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/PreparedStatement.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.ByteArrayInputStream; @@ -32,11 +31,18 @@ import java.io.Reader; import java.io.StringReader; import java.io.UnsupportedEncodingException; +import java.lang.reflect.Constructor; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; import java.sql.Array; import java.sql.Clob; +import java.sql.DatabaseMetaData; +import java.sql.Date; import java.sql.ParameterMetaData; import java.sql.Ref; import java.sql.SQLException; @@ -47,13 +53,17 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; import java.util.TimeZone; -import com.mysql.jdbc.Statement.CancelTask; +import com.mysql.jdbc.exceptions.MySQLStatementCancelledException; import com.mysql.jdbc.exceptions.MySQLTimeoutException; import com.mysql.jdbc.profiler.ProfilerEvent; + /** * A SQL Statement is pre-compiled and stored in a PreparedStatement object. * This object can then be used to efficiently execute this statement multiple @@ -78,18 +88,53 @@ * @see java.sql.ResultSet * @see java.sql.PreparedStatement */ -public class PreparedStatement extends com.mysql.jdbc.Statement implements +public class PreparedStatement extends com.mysql.jdbc.StatementImpl implements java.sql.PreparedStatement { - class BatchParams { - boolean[] isNull = null; + private static final Constructor JDBC_4_PSTMT_2_ARG_CTOR; + private static final Constructor JDBC_4_PSTMT_3_ARG_CTOR; + private static final Constructor JDBC_4_PSTMT_4_ARG_CTOR; + + static { + if (Util.isJdbc4()) { + try { + JDBC_4_PSTMT_2_ARG_CTOR = Class.forName( + "com.mysql.jdbc.JDBC4PreparedStatement") + .getConstructor( + new Class[] { MySQLConnection.class, String.class }); + JDBC_4_PSTMT_3_ARG_CTOR = Class.forName( + "com.mysql.jdbc.JDBC4PreparedStatement") + .getConstructor( + new Class[] { MySQLConnection.class, String.class, + String.class }); + JDBC_4_PSTMT_4_ARG_CTOR = Class.forName( + "com.mysql.jdbc.JDBC4PreparedStatement") + .getConstructor( + new Class[] { MySQLConnection.class, String.class, + String.class, ParseInfo.class }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_PSTMT_2_ARG_CTOR = null; + JDBC_4_PSTMT_3_ARG_CTOR = null; + JDBC_4_PSTMT_4_ARG_CTOR = null; + } + } + + public class BatchParams { + public boolean[] isNull = null; - boolean[] isStream = null; + public boolean[] isStream = null; - InputStream[] parameterStreams = null; + public InputStream[] parameterStreams = null; - byte[][] parameterStrings = null; + public byte[][] parameterStrings = null; - int[] streamLengths = null; + public int[] streamLengths = null; BatchParams(byte[][] strings, InputStream[] streams, boolean[] isStreamFlags, int[] lengths, boolean[] isNullFlags) { @@ -128,228 +173,518 @@ class ParseInfo { char firstStmtChar = 0; - boolean foundLimitClause = false; - boolean foundLoadData = false; long lastUsed = 0; int statementLength = 0; - + int statementStartPos = 0; + boolean canRewriteAsMultiValueInsert = false; + byte[][] staticSql = null; + boolean isOnDuplicateKeyUpdate = false; + + int locationOfOnDuplicateKeyUpdate = -1; + + String valuesClause; + + boolean parametersInDuplicateKeyClause = false; + /** * Represents the "parsed" state of a client-side * prepared statement, with the statement broken up into * it's static and dynamic (where parameters are bound) * parts. */ - public ParseInfo(String sql, Connection conn, + ParseInfo(String sql, MySQLConnection conn, java.sql.DatabaseMetaData dbmd, String encoding, SingleByteCharsetConverter converter) throws SQLException { - if (sql == null) { - throw SQLError.createSQLException(Messages - .getString("PreparedStatement.61"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } + this(sql, conn, dbmd, encoding, converter, true); + } + + public ParseInfo(String sql, MySQLConnection conn, + java.sql.DatabaseMetaData dbmd, String encoding, + SingleByteCharsetConverter converter, boolean buildRewriteInfo) throws SQLException { + try { + if (sql == null) { + throw SQLError.createSQLException(Messages + .getString("PreparedStatement.61"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } - this.lastUsed = System.currentTimeMillis(); + this.locationOfOnDuplicateKeyUpdate = getOnDuplicateKeyLocation(sql); + this.isOnDuplicateKeyUpdate = this.locationOfOnDuplicateKeyUpdate != -1; + + this.lastUsed = System.currentTimeMillis(); - String quotedIdentifierString = dbmd.getIdentifierQuoteString(); + String quotedIdentifierString = dbmd.getIdentifierQuoteString(); - char quotedIdentifierChar = 0; + char quotedIdentifierChar = 0; - if ((quotedIdentifierString != null) - && !quotedIdentifierString.equals(" ") //$NON-NLS-1$ - && (quotedIdentifierString.length() > 0)) { - quotedIdentifierChar = quotedIdentifierString.charAt(0); - } + if ((quotedIdentifierString != null) + && !quotedIdentifierString.equals(" ") //$NON-NLS-1$ + && (quotedIdentifierString.length() > 0)) { + quotedIdentifierChar = quotedIdentifierString.charAt(0); + } - this.statementLength = sql.length(); + this.statementLength = sql.length(); - ArrayList endpointList = new ArrayList(); - boolean inQuotes = false; - char quoteChar = 0; - boolean inQuotedId = false; - int lastParmEnd = 0; - int i; + ArrayList endpointList = new ArrayList(); + boolean inQuotes = false; + char quoteChar = 0; + boolean inQuotedId = false; + int lastParmEnd = 0; + int i; - int stopLookingForLimitClause = this.statementLength - 5; + boolean noBackslashEscapes = connection.isNoBackslashEscapesSet(); - this.foundLimitClause = false; - - boolean noBackslashEscapes = connection.isNoBackslashEscapesSet(); - - // we're not trying to be real pedantic here, but we'd like to - // skip comments at the beginning of statements, as frameworks - // such as Hibernate use them to aid in debugging - - statementStartPos = findStartOfStatement(sql); - - for (i = statementStartPos; i < this.statementLength; ++i) { - char c = sql.charAt(i); + // we're not trying to be real pedantic here, but we'd like to + // skip comments at the beginning of statements, as frameworks + // such as Hibernate use them to aid in debugging - if ((this.firstStmtChar == 0) && !Character.isWhitespace(c)) { - // Determine what kind of statement we're doing (_S_elect, - // _I_nsert, etc.) - this.firstStmtChar = Character.toUpperCase(c); - } + statementStartPos = findStartOfStatement(sql); - if (!noBackslashEscapes && - c == '\\' && i < (this.statementLength - 1)) { - i++; - continue; // next character is escaped - } - - // are we in a quoted identifier? - // (only valid when the id is not inside a 'string') - if (!inQuotes && (quotedIdentifierChar != 0) - && (c == quotedIdentifierChar)) { - inQuotedId = !inQuotedId; - } else if (!inQuotedId) { - // only respect quotes when not in a quoted identifier - - if (inQuotes) { - if (((c == '\'') || (c == '"')) && c == quoteChar) { - if (i < (this.statementLength - 1) && sql.charAt(i + 1) == quoteChar) { - i++; - continue; // inline quote escape + for (i = statementStartPos; i < this.statementLength; ++i) { + char c = sql.charAt(i); + + if ((this.firstStmtChar == 0) && Character.isLetter(c)) { + // Determine what kind of statement we're doing (_S_elect, + // _I_nsert, etc.) + this.firstStmtChar = Character.toUpperCase(c); + } + + if (!noBackslashEscapes && + c == '\\' && i < (this.statementLength - 1)) { + i++; + continue; // next character is escaped + } + + // are we in a quoted identifier? + // (only valid when the id is not inside a 'string') + if (!inQuotes && (quotedIdentifierChar != 0) + && (c == quotedIdentifierChar)) { + inQuotedId = !inQuotedId; + } else if (!inQuotedId) { + // only respect quotes when not in a quoted identifier + + if (inQuotes) { + if (((c == '\'') || (c == '"')) && c == quoteChar) { + if (i < (this.statementLength - 1) && sql.charAt(i + 1) == quoteChar) { + i++; + continue; // inline quote escape + } + + inQuotes = !inQuotes; + quoteChar = 0; + } else if (((c == '\'') || (c == '"')) && c == quoteChar) { + inQuotes = !inQuotes; + quoteChar = 0; } - - inQuotes = !inQuotes; - quoteChar = 0; - } else if (((c == '\'') || (c == '"')) && c == quoteChar) { - inQuotes = !inQuotes; - quoteChar = 0; - } - } else { - if (c == '#' + } else { + if (c == '#' || (c == '-' && (i + 1) < this.statementLength && sql .charAt(i + 1) == '-')) { - // run out to end of statement, or newline, - // whichever comes first - int endOfStmt = this.statementLength - 1; + // run out to end of statement, or newline, + // whichever comes first + int endOfStmt = this.statementLength - 1; - for (; i < endOfStmt; i++) { - c = sql.charAt(i); + for (; i < endOfStmt; i++) { + c = sql.charAt(i); - if (c == '\r' || c == '\n') { - break; + if (c == '\r' || c == '\n') { + break; + } } - } - continue; - } else if (c == '/' && (i + 1) < this.statementLength) { - // Comment? - char cNext = sql.charAt(i + 1); - - if (cNext == '*') { - i+= 2; - - for (int j = i; j < this.statementLength; j++) { - i++; - cNext = sql.charAt(j); - - if (cNext == '*' && (j + 1) < this.statementLength) { - if (sql.charAt(j + 1) == '/') { - i++; - - if (i < this.statementLength) { - c = sql.charAt(i); + continue; + } else if (c == '/' && (i + 1) < this.statementLength) { + // Comment? + char cNext = sql.charAt(i + 1); + + if (cNext == '*') { + i+= 2; + + for (int j = i; j < this.statementLength; j++) { + i++; + cNext = sql.charAt(j); + + if (cNext == '*' && (j + 1) < this.statementLength) { + if (sql.charAt(j + 1) == '/') { + i++; + + if (i < this.statementLength) { + c = sql.charAt(i); + } + + break; // comment done } - - break; // comment done } } } + } else if ((c == '\'') || (c == '"')) { + inQuotes = true; + quoteChar = c; } - } else if ((c == '\'') || (c == '"')) { - inQuotes = true; - quoteChar = c; } } + + if ((c == '?') && !inQuotes && !inQuotedId) { + endpointList.add(new int[] { lastParmEnd, i }); + lastParmEnd = i + 1; + + if (isOnDuplicateKeyUpdate && i > locationOfOnDuplicateKeyUpdate) { + parametersInDuplicateKeyClause = true; + } + } } - if ((c == '?') && !inQuotes && !inQuotedId) { - endpointList.add(new int[] { lastParmEnd, i }); - lastParmEnd = i + 1; + if (this.firstStmtChar == 'L') { + if (StringUtils.startsWithIgnoreCaseAndWs(sql, "LOAD DATA")) { //$NON-NLS-1$ + this.foundLoadData = true; + } else { + this.foundLoadData = false; + } + } else { + this.foundLoadData = false; } - if (!inQuotes && (i < stopLookingForLimitClause)) { - if ((c == 'L') || (c == 'l')) { - char posI1 = sql.charAt(i + 1); + endpointList.add(new int[] { lastParmEnd, this.statementLength }); + this.staticSql = new byte[endpointList.size()][]; - if ((posI1 == 'I') || (posI1 == 'i')) { - char posM = sql.charAt(i + 2); + for (i = 0; i < this.staticSql.length; i++) { + int[] ep = endpointList.get(i); + int end = ep[1]; + int begin = ep[0]; + int len = end - begin; - if ((posM == 'M') || (posM == 'm')) { - char posI2 = sql.charAt(i + 3); + if (this.foundLoadData) { + this.staticSql[i] = StringUtils.getBytes(sql, begin, len); + } else if (encoding == null) { + byte[] buf = new byte[len]; - if ((posI2 == 'I') || (posI2 == 'i')) { - char posT = sql.charAt(i + 4); + for (int j = 0; j < len; j++) { + buf[j] = (byte) sql.charAt(begin + j); + } - if ((posT == 'T') || (posT == 't')) { - foundLimitClause = true; - } - } - } + this.staticSql[i] = buf; + } else { + if (converter != null) { + this.staticSql[i] = StringUtils.getBytes(sql, + converter, encoding, connection + .getServerCharacterEncoding(), begin, + len, connection.parserKnowsUnicode(), getExceptionInterceptor()); + } else { + this.staticSql[i] = StringUtils.getBytes(sql, encoding, + connection.getServerCharacterEncoding(), begin, len, + connection.parserKnowsUnicode(), conn, getExceptionInterceptor()); } } } + } catch (StringIndexOutOfBoundsException oobEx) { + SQLException sqlEx = new SQLException("Parse error for " + sql); + sqlEx.initCause(oobEx); + + throw sqlEx; } + + + if (buildRewriteInfo) { + this.canRewriteAsMultiValueInsert = PreparedStatement + .canRewrite(sql, this.isOnDuplicateKeyUpdate, + this.locationOfOnDuplicateKeyUpdate, + this.statementStartPos) && !this.parametersInDuplicateKeyClause; - if (this.firstStmtChar == 'L') { - if (StringUtils.startsWithIgnoreCaseAndWs(sql, "LOAD DATA")) { //$NON-NLS-1$ - this.foundLoadData = true; - } else { - this.foundLoadData = false; + if (this.canRewriteAsMultiValueInsert + && conn.getRewriteBatchedStatements()) { + buildRewriteBatchedParams(sql, conn, dbmd, encoding, + converter); } + } + } + + private ParseInfo batchHead; + + private ParseInfo batchValues; + + private ParseInfo batchODKUClause; + + private void buildRewriteBatchedParams(String sql, MySQLConnection conn, + DatabaseMetaData metadata, String encoding, + SingleByteCharsetConverter converter) throws SQLException { + this.valuesClause = extractValuesClause(sql); + String odkuClause = isOnDuplicateKeyUpdate ? sql + .substring(locationOfOnDuplicateKeyUpdate) : null; + + String headSql = null; + + if (isOnDuplicateKeyUpdate) { + headSql = sql.substring(0, locationOfOnDuplicateKeyUpdate); } else { - this.foundLoadData = false; + headSql = sql; } - endpointList.add(new int[] { lastParmEnd, this.statementLength }); - this.staticSql = new byte[endpointList.size()][]; - char[] asCharArray = sql.toCharArray(); + this.batchHead = new ParseInfo(headSql, conn, metadata, encoding, + converter, false); + this.batchValues = new ParseInfo("," + this.valuesClause, conn, + metadata, encoding, converter, false); + this.batchODKUClause = null; - for (i = 0; i < this.staticSql.length; i++) { - int[] ep = (int[]) endpointList.get(i); - int end = ep[1]; - int begin = ep[0]; - int len = end - begin; + if (odkuClause != null && odkuClause.length() > 0) { + this.batchODKUClause = new ParseInfo("," + this.valuesClause + + " " + odkuClause, conn, metadata, encoding, + converter, false); + } + } - if (this.foundLoadData) { - String temp = new String(asCharArray, begin, len); - this.staticSql[i] = temp.getBytes(); - } else if (encoding == null) { - byte[] buf = new byte[len]; + private String extractValuesClause(String sql) throws SQLException { + String quoteCharStr = connection.getMetaData() + .getIdentifierQuoteString(); - for (int j = 0; j < len; j++) { - buf[j] = (byte) sql.charAt(begin + j); - } + int indexOfValues = -1; + int valuesSearchStart = statementStartPos; - this.staticSql[i] = buf; + while (indexOfValues == -1) { + if (quoteCharStr.length() > 0) { + indexOfValues = StringUtils.indexOfIgnoreCaseRespectQuotes( + valuesSearchStart, + originalSql, "VALUES", quoteCharStr.charAt(0), false); } else { - if (converter != null) { - this.staticSql[i] = StringUtils.getBytes(sql, - converter, encoding, connection - .getServerCharacterEncoding(), begin, - len, connection.parserKnowsUnicode()); + indexOfValues = StringUtils.indexOfIgnoreCase(valuesSearchStart, + originalSql, + "VALUES"); + } + + if (indexOfValues > 0) { + /* check if the char immediately preceding VALUES may be part of the table name */ + char c = originalSql.charAt(indexOfValues - 1); + if(!(Character.isWhitespace(c) || c == ')' || c == '`')){ + valuesSearchStart = indexOfValues + 6; + indexOfValues = -1; } else { - String temp = new String(asCharArray, begin, len); + /* check if the char immediately following VALUES may be whitespace or open parenthesis */ + c = originalSql.charAt(indexOfValues + 6); + if(!(Character.isWhitespace(c) || c == '(')){ + valuesSearchStart = indexOfValues + 6; + indexOfValues = -1; + } + } + } else { + break; + } + } - this.staticSql[i] = StringUtils.getBytes(temp, - encoding, connection - .getServerCharacterEncoding(), - connection.parserKnowsUnicode(), conn); + if (indexOfValues == -1) { + return null; + } + + int indexOfFirstParen = sql.indexOf('(', indexOfValues + 6); + + if (indexOfFirstParen == -1) { + return null; + } + + int endOfValuesClause = sql.lastIndexOf(')'); + + if (endOfValuesClause == -1) { + return null; + } + + if (isOnDuplicateKeyUpdate) { + endOfValuesClause = this.locationOfOnDuplicateKeyUpdate - 1; + } + + return sql.substring(indexOfFirstParen, endOfValuesClause + 1); + } + + /** + * Returns a ParseInfo for a multi-value INSERT for a batch of size numBatch (without parsing!). + */ + synchronized ParseInfo getParseInfoForBatch(int numBatch) { + AppendingBatchVisitor apv = new AppendingBatchVisitor(); + buildInfoForBatch(numBatch, apv); + + ParseInfo batchParseInfo = new ParseInfo(apv.getStaticSqlStrings(), + this.firstStmtChar, this.foundLoadData, this.isOnDuplicateKeyUpdate, + this.locationOfOnDuplicateKeyUpdate, this.statementLength, + this.statementStartPos); + + return batchParseInfo; + } + + /** + * Returns a preparable SQL string for the number of batched parameters, used by server-side prepared statements + * when re-writing batch INSERTs. + */ + + String getSqlForBatch(int numBatch) throws UnsupportedEncodingException { + ParseInfo batchInfo = getParseInfoForBatch(numBatch); + + return getSqlForBatch(batchInfo); + } + + /** + * Used for filling in the SQL for getPreparedSql() - for debugging + */ + String getSqlForBatch(ParseInfo batchInfo) throws UnsupportedEncodingException { + int size = 0; + final byte[][] sqlStrings = batchInfo.staticSql; + final int sqlStringsLength = sqlStrings.length; + + for (int i = 0; i < sqlStringsLength; i++) { + size += sqlStrings[i].length; + size++; // for the '?' + } + + StringBuffer buf = new StringBuffer(size); + + for (int i = 0; i < sqlStringsLength - 1; i++) { + buf.append(StringUtils.toString(sqlStrings[i], charEncoding)); + buf.append("?"); + } + + buf.append(StringUtils.toString(sqlStrings[sqlStringsLength - 1])); + + return buf.toString(); + } + + /** + * Builds a ParseInfo for the given batch size, without parsing. We use + * a visitor pattern here, because the if {}s make computing a size for the + * resultant byte[][] make this too complex, and we don't necessarily want to + * use a List for this, because the size can be dynamic, and thus we'll not be + * able to guess a good initial size for an array-based list, and it's not + * efficient to convert a LinkedList to an array. + */ + private void buildInfoForBatch(int numBatch, BatchVisitor visitor) { + final byte[][] headStaticSql = this.batchHead.staticSql; + final int headStaticSqlLength = headStaticSql.length; + + if (headStaticSqlLength > 1) { + for (int i = 0; i < headStaticSqlLength - 1; i++) { + visitor.append(headStaticSql[i]).increment(); + } + } + + // merge end of head, with beginning of a value clause + byte[] endOfHead = headStaticSql[headStaticSqlLength - 1]; + final byte[][] valuesStaticSql = this.batchValues.staticSql; + byte[] beginOfValues = valuesStaticSql[0]; + + visitor.merge(endOfHead, beginOfValues).increment(); + + int numValueRepeats = numBatch - 1; // first one is in the "head" + + if (this.batchODKUClause != null) { + numValueRepeats--; // Last one is in the ODKU clause + } + + final int valuesStaticSqlLength = valuesStaticSql.length; + byte[] endOfValues = valuesStaticSql[valuesStaticSqlLength - 1]; + + for (int i = 0; i < numValueRepeats; i++) { + for (int j = 1; j < valuesStaticSqlLength - 1; j++) { + visitor.append(valuesStaticSql[j]).increment(); + } + visitor.merge(endOfValues, beginOfValues).increment(); + } + + if (this.batchODKUClause != null) { + final byte[][] batchOdkuStaticSql = this.batchODKUClause.staticSql; + byte[] beginOfOdku = batchOdkuStaticSql[0]; + visitor.decrement().merge(endOfValues, beginOfOdku).increment(); + + final int batchOdkuStaticSqlLength = batchOdkuStaticSql.length; + + if (numBatch > 1) { + for (int i = 1; i < batchOdkuStaticSqlLength; i++) { + visitor.append(batchOdkuStaticSql[i]) + .increment(); } + } else { + visitor.decrement().append(batchOdkuStaticSql[(batchOdkuStaticSqlLength - 1)]); } + } else { + // Everything after the values clause, but not ODKU, which today is nothing + // but a syntax error, but we should still not mangle the SQL! + visitor.decrement().append(this.staticSql[this.staticSql.length - 1]); } } + + private ParseInfo(byte[][] staticSql, char firstStmtChar, + boolean foundLoadData, boolean isOnDuplicateKeyUpdate, + int locationOfOnDuplicateKeyUpdate, int statementLength, + int statementStartPos) { + this.firstStmtChar = firstStmtChar; + this.foundLoadData = foundLoadData; + this.isOnDuplicateKeyUpdate = isOnDuplicateKeyUpdate; + this.locationOfOnDuplicateKeyUpdate = locationOfOnDuplicateKeyUpdate; + this.statementLength = statementLength; + this.statementStartPos = statementStartPos; + this.staticSql = staticSql; + } } + interface BatchVisitor { + abstract BatchVisitor increment(); + + abstract BatchVisitor decrement(); + + abstract BatchVisitor append(byte[] values); + + abstract BatchVisitor merge(byte[] begin, byte[] end); + } + + class AppendingBatchVisitor implements BatchVisitor { + LinkedList statementComponents = new LinkedList(); + + public BatchVisitor append(byte[] values) { + statementComponents.addLast(values); + + return this; + } + + public BatchVisitor increment() { + // no-op + return this; + } + + public BatchVisitor decrement() { + statementComponents.removeLast(); + + return this; + } + + public BatchVisitor merge(byte[] front, byte[] back) { + int mergedLength = front.length + back.length; + byte[] merged = new byte[mergedLength]; + System.arraycopy(front, 0, merged, 0, front.length); + System.arraycopy(back, 0, merged, front.length, back.length); + statementComponents.addLast(merged); + return this; + } + + public byte[][] getStaticSqlStrings() { + byte[][] asBytes = new byte[this.statementComponents.size()][]; + this.statementComponents.toArray(asBytes); + + return asBytes; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + Iterator iter = this.statementComponents.iterator(); + while (iter.hasNext()) { + buf.append(StringUtils.toString(iter.next())); + } + + return buf.toString(); + } + + } + private final static byte[] HEX_DIGITS = new byte[] { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'A', @@ -371,7 +706,7 @@ * @throws IOException * DOCUMENT ME! */ - private static int readFully(Reader reader, char[] buf, int length) + protected static int readFully(Reader reader, char[] buf, int length) throws IOException { int numCharsRead = 0; @@ -404,13 +739,10 @@ */ protected char firstCharOfStmt = 0; - /** Does the SQL for this statement contain a 'limit' clause? */ - protected boolean hasLimitClause = false; - /** Is this query a LOAD DATA query? */ protected boolean isLoadDataQuery = false; - private boolean[] isNull = null; + protected boolean[] isNull = null; private boolean[] isStream = null; @@ -428,13 +760,19 @@ private byte[][] parameterValues = null; - private ParseInfo parseInfo; + /** + * Only used by statement interceptors at the moment to + * provide introspection of bound values + */ + protected int[] parameterTypes = null; + + protected ParseInfo parseInfo; private java.sql.ResultSetMetaData pstmtResultMetaData; private byte[][] staticSqlStrings = null; - private byte[] streamConvertBuf = new byte[4096]; + private byte[] streamConvertBuf = null; private int[] streamLengths = null; @@ -445,26 +783,75 @@ */ protected boolean useTrueBoolean = false; - private boolean usingAnsiMode; + protected boolean usingAnsiMode; - private String batchedValuesClause; + protected String batchedValuesClause; - /** Where does the statement text actually start? */ + private boolean doPingInstead; + private SimpleDateFormat ddf; + private SimpleDateFormat tdf; - private int statementAfterCommentsPos; + private boolean compensateForOnDuplicateKeyUpdate = false; + + /** Charset encoder used to escape if needed, such as Yen sign in SJIS */ + private CharsetEncoder charsetEncoder; + + /** Command index of currently executing batch command. */ + protected int batchCommandIndex = -1; + + protected boolean serverSupportsFracSecs; + + /** + * Creates a prepared statement instance -- We need to provide factory-style + * methods so we can support both JDBC3 (and older) and JDBC4 runtimes, + * otherwise the class verifier complains when it tries to load JDBC4-only + * interface classes that are present in JDBC4 method signatures. + */ + protected static PreparedStatement getInstance(MySQLConnection conn, + String catalog) throws SQLException { + if (!Util.isJdbc4()) { + return new PreparedStatement(conn, catalog); + } + + return (PreparedStatement) Util.handleNewInstance( + JDBC_4_PSTMT_2_ARG_CTOR, new Object[] { conn, catalog }, conn.getExceptionInterceptor()); + } + /** - * have we checked whether we can rewrite this statement as a multi-value - * insert? + * Creates a prepared statement instance -- We need to provide factory-style + * methods so we can support both JDBC3 (and older) and JDBC4 runtimes, + * otherwise the class verifier complains when it tries to load JDBC4-only + * interface classes that are present in JDBC4 method signatures. */ - private boolean hasCheckedForRewrite = false; + protected static PreparedStatement getInstance(MySQLConnection conn, String sql, + String catalog) throws SQLException { + if (!Util.isJdbc4()) { + return new PreparedStatement(conn, sql, catalog); + } - /** Can we actually rewrite this statement as a multi-value insert? */ + return (PreparedStatement) Util.handleNewInstance( + JDBC_4_PSTMT_3_ARG_CTOR, new Object[] { conn, sql, catalog }, conn.getExceptionInterceptor()); + } - private boolean canRewrite = false; + /** + * Creates a prepared statement instance -- We need to provide factory-style + * methods so we can support both JDBC3 (and older) and JDBC4 runtimes, + * otherwise the class verifier complains when it tries to load JDBC4-only + * interface classes that are present in JDBC4 method signatures. + */ - private boolean doPingInstead; + protected static PreparedStatement getInstance(MySQLConnection conn, String sql, + String catalog, ParseInfo cachedParseInfo) throws SQLException { + if (!Util.isJdbc4()) { + return new PreparedStatement(conn, sql, catalog, cachedParseInfo); + } + + return (PreparedStatement) Util.handleNewInstance( + JDBC_4_PSTMT_4_ARG_CTOR, new Object[] { conn, sql, catalog, + cachedParseInfo }, conn.getExceptionInterceptor()); + } /** * Constructor used by server-side prepared statements @@ -477,11 +864,19 @@ * @throws SQLException * if an error occurs */ - protected PreparedStatement(Connection conn, String catalog) + public PreparedStatement(MySQLConnection conn, String catalog) throws SQLException { super(conn, catalog); + + detectFractionalSecondsSupport(); + this.compensateForOnDuplicateKeyUpdate = this.connection.getCompensateOnDuplicateKeyUpdateCounts(); } + protected void detectFractionalSecondsSupport() throws SQLException { + this.serverSupportsFracSecs = this.connection != null && + this.connection.versionMeetsMinimum(5, 6, 4); + } + /** * Constructor for the PreparedStatement class. * @@ -495,15 +890,16 @@ * @throws SQLException * if a database error occurs. */ - public PreparedStatement(Connection conn, String sql, String catalog) + public PreparedStatement(MySQLConnection conn, String sql, String catalog) throws SQLException { super(conn, catalog); if (sql == null) { throw SQLError.createSQLException(Messages.getString("PreparedStatement.0"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } + detectFractionalSecondsSupport(); this.originalSql = sql; if (this.originalSql.startsWith(PING_MARKER)) { @@ -520,6 +916,11 @@ this.charEncoding, this.charConverter); initializeFromParseInfo(); + + this.compensateForOnDuplicateKeyUpdate = this.connection.getCompensateOnDuplicateKeyUpdateCounts(); + + if (conn.getRequiresEscapingEncoder()) + charsetEncoder = Charset.forName(conn.getEncoding()).newEncoder(); } /** @@ -537,15 +938,16 @@ * @throws SQLException * DOCUMENT ME! */ - public PreparedStatement(Connection conn, String sql, String catalog, + public PreparedStatement(MySQLConnection conn, String sql, String catalog, ParseInfo cachedParseInfo) throws SQLException { super(conn, catalog); if (sql == null) { throw SQLError.createSQLException(Messages.getString("PreparedStatement.1"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } + detectFractionalSecondsSupport(); this.originalSql = sql; this.dbmd = this.connection.getMetaData(); @@ -557,6 +959,11 @@ this.usingAnsiMode = !this.connection.useAnsiQuotedIdentifiers(); initializeFromParseInfo(); + + this.compensateForOnDuplicateKeyUpdate = this.connection.getCompensateOnDuplicateKeyUpdateCounts(); + + if (conn.getRequiresEscapingEncoder()) + charsetEncoder = Charset.forName(conn.getEncoding()).newEncoder(); } /** @@ -565,103 +972,131 @@ * @exception SQLException * if a database-access error occurs. * - * @see Statement#addBatch + * @see StatementImpl#addBatch */ public void addBatch() throws SQLException { - if (this.batchedArgs == null) { - this.batchedArgs = new ArrayList(); + synchronized (checkClosed().getConnectionMutex()) { + if (this.batchedArgs == null) { + this.batchedArgs = new ArrayList(); + } + + for (int i = 0; i < this.parameterValues.length; i++) { + checkAllParametersSet(this.parameterValues[i], + this.parameterStreams[i], i); + } + + this.batchedArgs.add(new BatchParams(this.parameterValues, + this.parameterStreams, this.isStream, this.streamLengths, + this.isNull)); } - - this.batchedArgs.add(new BatchParams(this.parameterValues, - this.parameterStreams, this.isStream, this.streamLengths, - this.isNull)); } - public synchronized void addBatch(String sql) throws SQLException { - this.batchHasPlainStatements = true; - - super.addBatch(sql); + public void addBatch(String sql) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + this.batchHasPlainStatements = true; + + super.addBatch(sql); + } } - protected String asSql() throws SQLException { + public String asSql() throws SQLException { return asSql(false); } - protected String asSql(boolean quoteStreamsAndUnknowns) throws SQLException { - if (this.isClosed) { - return "statement has been closed, no further internal information available"; - } - - StringBuffer buf = new StringBuffer(); - - try { - for (int i = 0; i < this.parameterCount; ++i) { - if (this.charEncoding != null) { - buf.append(new String(this.staticSqlStrings[i], - this.charEncoding)); - } else { - buf.append(new String(this.staticSqlStrings[i])); - } - - if ((this.parameterValues[i] == null) && !this.isStream[i]) { - if (quoteStreamsAndUnknowns) { - buf.append("'"); + public String asSql(boolean quoteStreamsAndUnknowns) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + + StringBuffer buf = new StringBuffer(); + + try { + int realParameterCount = this.parameterCount + getParameterIndexOffset(); + Object batchArg = null; + if (batchCommandIndex != -1) + batchArg = batchedArgs.get(batchCommandIndex); + + for (int i = 0; i < realParameterCount; ++i) { + if (this.charEncoding != null) { + buf.append(StringUtils.toString(this.staticSqlStrings[i], + this.charEncoding)); + } else { + buf.append(StringUtils.toString(this.staticSqlStrings[i])); } - - buf.append("** NOT SPECIFIED **"); //$NON-NLS-1$ - - if (quoteStreamsAndUnknowns) { - buf.append("'"); + + byte val[] = null; + if (batchArg != null && batchArg instanceof String) { + buf.append((String)batchArg); + continue; } - } else if (this.isStream[i]) { - if (quoteStreamsAndUnknowns) { - buf.append("'"); - } - - buf.append("** STREAM DATA **"); //$NON-NLS-1$ - - if (quoteStreamsAndUnknowns) { - buf.append("'"); - } - } else { - if (this.charConverter != null) { - buf.append(this.charConverter - .toString(this.parameterValues[i])); + if (batchCommandIndex == -1) + val = parameterValues[i]; + else + val = ((BatchParams)batchArg).parameterStrings[i]; + + boolean isStreamParam = false; + if (batchCommandIndex == -1) + isStreamParam = isStream[i]; + else + isStreamParam = ((BatchParams)batchArg).isStream[i]; + + if ((val == null) && !isStreamParam) { + if (quoteStreamsAndUnknowns) { + buf.append("'"); + } + + buf.append("** NOT SPECIFIED **"); //$NON-NLS-1$ + + if (quoteStreamsAndUnknowns) { + buf.append("'"); + } + } else if (isStreamParam) { + if (quoteStreamsAndUnknowns) { + buf.append("'"); + } + + buf.append("** STREAM DATA **"); //$NON-NLS-1$ + + if (quoteStreamsAndUnknowns) { + buf.append("'"); + } } else { - if (this.charEncoding != null) { - buf.append(new String(this.parameterValues[i], - this.charEncoding)); + if (this.charConverter != null) { + buf.append(this.charConverter.toString(val)); } else { - buf.append(StringUtils - .toAsciiString(this.parameterValues[i])); + if (this.charEncoding != null) { + buf.append(new String(val, this.charEncoding)); + } else { + buf.append(StringUtils.toAsciiString(val)); + } } } } + + if (this.charEncoding != null) { + buf.append(StringUtils.toString( + this.staticSqlStrings[this.parameterCount + getParameterIndexOffset()], + this.charEncoding)); + } else { + buf + .append(StringUtils + .toAsciiString(this.staticSqlStrings[this.parameterCount + getParameterIndexOffset()])); + } + } catch (UnsupportedEncodingException uue) { + throw new RuntimeException(Messages + .getString("PreparedStatement.32") //$NON-NLS-1$ + + this.charEncoding + + Messages.getString("PreparedStatement.33")); //$NON-NLS-1$ } - - if (this.charEncoding != null) { - buf.append(new String( - this.staticSqlStrings[this.parameterCount], - this.charEncoding)); - } else { - buf - .append(StringUtils - .toAsciiString(this.staticSqlStrings[this.parameterCount])); - } - } catch (UnsupportedEncodingException uue) { - throw new RuntimeException(Messages - .getString("PreparedStatement.32") //$NON-NLS-1$ - + this.charEncoding - + Messages.getString("PreparedStatement.33")); //$NON-NLS-1$ + + return buf.toString(); } - - return buf.toString(); } - public synchronized void clearBatch() throws SQLException { - this.batchHasPlainStatements = false; - - super.clearBatch(); + public void clearBatch() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + this.batchHasPlainStatements = false; + + super.clearBatch(); + } } /** @@ -674,27 +1109,19 @@ * @exception SQLException * if a database access error occurs */ - public synchronized void clearParameters() throws SQLException { - checkClosed(); + public void clearParameters() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { - for (int i = 0; i < this.parameterValues.length; i++) { - this.parameterValues[i] = null; - this.parameterStreams[i] = null; - this.isStream[i] = false; - this.isNull[i] = false; + for (int i = 0; i < this.parameterValues.length; i++) { + this.parameterValues[i] = null; + this.parameterStreams[i] = null; + this.isStream[i] = false; + this.isNull[i] = false; + this.parameterTypes[i] = Types.NULL; + } } } - /** - * Closes this prepared statement and releases all resources. - * - * @throws SQLException - * if database error occurs. - */ - public synchronized void close() throws SQLException { - realClose(true, true); - } - private final void escapeblockFast(byte[] buf, Buffer packet, int size) throws SQLException { int lastwritten = 0; @@ -771,6 +1198,18 @@ bytesOut.write(buf, lastwritten, size - lastwritten); } } + + /** + * Check to see if the statement is safe for read-only slaves after failover. + * + * @return true if safe for read-only. + * @throws SQLException + */ + protected boolean checkReadOnlySafeStatement() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + return this.firstCharOfStmt == 'S' || !this.connection.isReadOnly(); + } + } /** * Some prepared statements return multiple results; the execute method @@ -784,109 +1223,88 @@ * if a database access error occurs */ public boolean execute() throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - Connection locallyScopedConn = this.connection; - - if (locallyScopedConn.isReadOnly() && (this.firstCharOfStmt != 'S')) { - throw SQLError.createSQLException(Messages.getString("PreparedStatement.20") //$NON-NLS-1$ - + Messages.getString("PreparedStatement.21"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - ResultSet rs = null; - - CachedResultSetMetaData cachedMetadata = null; - - synchronized (locallyScopedConn.getMutex()) { + MySQLConnection locallyScopedConn = this.connection; + + if(!checkReadOnlySafeStatement()) { + throw SQLError.createSQLException(Messages.getString("PreparedStatement.20") //$NON-NLS-1$ + + Messages.getString("PreparedStatement.21"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + + ResultSetInternalMethods rs = null; + + CachedResultSetMetaData cachedMetadata = null; + + lastQueryIsOnDupKeyUpdate = false; + + if (retrieveGeneratedKeys) { + lastQueryIsOnDupKeyUpdate = containsOnDuplicateKeyUpdateInSQL(); + } + + boolean doStreaming = createStreamingResultSet(); + clearWarnings(); - + + // Adjust net_write_timeout to a higher value if we're + // streaming result sets. More often than not, someone runs into + // an issue where they blow net_write_timeout when using this + // feature, and if they're willing to hold a result set open + // for 30 seconds or more, one more round-trip isn't going to hurt + // + // This is reset by RowDataDynamic.close(). + + if (doStreaming + && this.connection.getNetTimeoutForStreamingResults() > 0) { + executeSimpleNonQuery(locallyScopedConn, + "SET net_write_timeout=" + + this.connection + .getNetTimeoutForStreamingResults()); + } + this.batchedGeneratedKeys = null; - + Buffer sendPacket = fillSendPacket(); - + String oldCatalog = null; - + if (!locallyScopedConn.getCatalog().equals(this.currentCatalog)) { oldCatalog = locallyScopedConn.getCatalog(); locallyScopedConn.setCatalog(this.currentCatalog); } - + // // Check if we have cached metadata for this query... // if (locallyScopedConn.getCacheResultSetMetadata()) { cachedMetadata = locallyScopedConn.getCachedMetaData(this.originalSql); } - + Field[] metadataFromCache = null; if (cachedMetadata != null) { metadataFromCache = cachedMetadata.fields; } boolean oldInfoMsgState = false; - + if (this.retrieveGeneratedKeys) { oldInfoMsgState = locallyScopedConn.isReadInfoMsgEnabled(); locallyScopedConn.setReadInfoMsgEnabled(true); } - // If there isn't a limit clause in the SQL - // then limit the number of rows to return in - // an efficient manner. Only do this if - // setMaxRows() hasn't been used on any Statements - // generated from the current Connection (saves - // a query, and network traffic). // // Only apply max_rows to selects // - if (locallyScopedConn.useMaxRows()) { - int rowLimit = -1; + locallyScopedConn.setSessionMaxRows(this.firstCharOfStmt == 'S' ? this.maxRows : -1); - if (this.firstCharOfStmt == 'S') { - if (this.hasLimitClause) { - rowLimit = this.maxRows; - } else { - if (this.maxRows <= 0) { - locallyScopedConn.execSQL(this, - "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, //$NON-NLS-1$ - null, java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.currentCatalog, true); - } else { - locallyScopedConn - .execSQL( - this, - "SET OPTION SQL_SELECT_LIMIT=" + this.maxRows, -1, //$NON-NLS-1$ - null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, - false, this.currentCatalog, - true); - } - } - } else { - locallyScopedConn.execSQL(this, - "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, //$NON-NLS-1$ - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.currentCatalog, true); - } + rs = executeInternal(this.maxRows, sendPacket, doStreaming, (this.firstCharOfStmt == 'S'), + metadataFromCache, false); - // Finally, execute the query - rs = executeInternal(rowLimit, sendPacket, - createStreamingResultSet(), - (this.firstCharOfStmt == 'S'), true, metadataFromCache, false); - } else { - rs = executeInternal(-1, sendPacket, - createStreamingResultSet(), - (this.firstCharOfStmt == 'S'), true, metadataFromCache, false); - } - if (cachedMetadata != null) { locallyScopedConn.initializeResultsMetadataFromCache(this.originalSql, - cachedMetadata, this.results); + cachedMetadata, rs); } else { if (rs.reallyResult() && locallyScopedConn.getCacheResultSetMetadata()) { locallyScopedConn.initializeResultsMetadataFromCache(this.originalSql, @@ -898,19 +1316,19 @@ locallyScopedConn.setReadInfoMsgEnabled(oldInfoMsgState); rs.setFirstCharOfQuery(this.firstCharOfStmt); } - + if (oldCatalog != null) { locallyScopedConn.setCatalog(oldCatalog); } - - this.lastInsertId = rs.getUpdateID(); - + if (rs != null) { + this.lastInsertId = rs.getUpdateID(); + this.results = rs; } + + return ((rs != null) && rs.reallyResult()); } - - return ((rs != null) && rs.reallyResult()); } /** @@ -928,352 +1346,682 @@ * DOCUMENT ME! */ public int[] executeBatch() throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - if (this.connection.isReadOnly()) { - throw new SQLException(Messages.getString("PreparedStatement.25") //$NON-NLS-1$ - + Messages.getString("PreparedStatement.26"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } + if (this.connection.isReadOnly()) { + throw new SQLException(Messages.getString("PreparedStatement.25") //$NON-NLS-1$ + + Messages.getString("PreparedStatement.26"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + } - synchronized (this.connection.getMutex()) { - if (this.batchedArgs == null || this.batchedArgs.size() == 0) { + if (this.batchedArgs == null || this.batchedArgs.size() == 0) { return new int[0]; } - + + // we timeout the entire batch, not individual statements + int batchTimeout = this.timeoutInMillis; + this.timeoutInMillis = 0; + + resetCancelledState(); + try { + statementBegins(); + clearWarnings(); if (!this.batchHasPlainStatements && this.connection.getRewriteBatchedStatements()) { - - if (canRewriteAsMultivalueInsertStatement()) { - return executeBatchedInserts(); + + + if (canRewriteAsMultiValueInsertAtSqlLevel()) { + return executeBatchedInserts(batchTimeout); } + + if (this.connection.versionMeetsMinimum(4, 1, 0) + && !this.batchHasPlainStatements + && this.batchedArgs != null + && this.batchedArgs.size() > 3 /* cost of option setting rt-wise */) { + return executePreparedBatchAsMultiStatement(batchTimeout); + } } - return executeBatchSerially(); - } catch (NullPointerException npe) { - // We do this, otherwise we need to totally overhaul how executeBatch() reuses - // existing execute() functionality, and pass around a locally-scoped connection, - // or catch the very rare race condition and handle it here. - - checkClosed(); // if we're really closed, this will throw a SQLException - - throw npe; // otherwise someone (me!) goofed error + return executeBatchSerially(batchTimeout); } finally { + this.statementExecuting.set(false); + clearBatch(); } } } - public synchronized boolean canRewriteAsMultivalueInsertStatement() { - if (!this.hasCheckedForRewrite) { - // Needs to be INSERT, can't have INSERT ... SELECT or - // INSERT ... ON DUPLICATE KEY UPDATE - // - // We're not smart enough to re-write to - // - // INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) - // ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b); - // - // (yet) - - this.canRewrite = StringUtils.startsWithIgnoreCaseAndWs( - this.originalSql, "INSERT", this.statementAfterCommentsPos) - && StringUtils.indexOfIgnoreCaseRespectMarker(this.statementAfterCommentsPos, this.originalSql, "SELECT", "\"'`", "\"'`", false) == -1 - && StringUtils.indexOfIgnoreCaseRespectMarker(this.statementAfterCommentsPos, this.originalSql, "UPDATE", "\"'`", "\"'`", false) == -1; - - this.hasCheckedForRewrite = true; - } - - return this.canRewrite; + public boolean canRewriteAsMultiValueInsertAtSqlLevel() throws SQLException { + return this.parseInfo.canRewriteAsMultiValueInsert; } + + protected int getLocationOfOnDuplicateKeyUpdate() throws SQLException { + return this.parseInfo.locationOfOnDuplicateKeyUpdate; + } /** - * Rewrites the already prepared statement into a multi-value insert - * statement of 'statementsPerBatch' values and executes the entire batch + * Rewrites the already prepared statement into a multi-statement + * query of 'statementsPerBatch' values and executes the entire batch * using this new statement. * * @return update counts in the same fashion as executeBatch() * * @throws SQLException */ - protected int[] executeBatchedInserts() throws SQLException { - String valuesClause = extractValuesClause(); + + protected int[] executePreparedBatchAsMultiStatement(int batchTimeout) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + // This is kind of an abuse, but it gets the job done + if (this.batchedValuesClause == null) { + this.batchedValuesClause = this.originalSql + ";"; + } + + MySQLConnection locallyScopedConn = this.connection; + + boolean multiQueriesEnabled = locallyScopedConn.getAllowMultiQueries(); + CancelTask timeoutTask = null; + + try { + clearWarnings(); + + int numBatchedArgs = this.batchedArgs.size(); + + if (this.retrieveGeneratedKeys) { + this.batchedGeneratedKeys = new ArrayList(numBatchedArgs); + } - Connection locallyScopedConn = this.connection; - - if (valuesClause == null) { - return executeBatchSerially(); - } + int numValuesPerBatch = computeBatchSize(numBatchedArgs); - int numBatchedArgs = this.batchedArgs.size(); - - if (this.retrieveGeneratedKeys) { - this.batchedGeneratedKeys = new ArrayList(numBatchedArgs); - } + if (numBatchedArgs < numValuesPerBatch) { + numValuesPerBatch = numBatchedArgs; + } - int numValuesPerBatch = computeBatchSize(numBatchedArgs); + java.sql.PreparedStatement batchedStatement = null; - if (numBatchedArgs < numValuesPerBatch) { - numValuesPerBatch = numBatchedArgs; - } + int batchedParamIndex = 1; + int numberToExecuteAsMultiValue = 0; + int batchCounter = 0; + int updateCountCounter = 0; + int[] updateCounts = new int[numBatchedArgs]; + SQLException sqlEx = null; + + try { + if (!multiQueriesEnabled) { + locallyScopedConn.getIO().enableMultiQueries(); + } + + if (this.retrieveGeneratedKeys) { + batchedStatement = locallyScopedConn.prepareStatement( + generateMultiStatementForBatch(numValuesPerBatch), + RETURN_GENERATED_KEYS); + } else { + batchedStatement = locallyScopedConn + .prepareStatement(generateMultiStatementForBatch(numValuesPerBatch)); + } - java.sql.PreparedStatement batchedStatement = null; + if (locallyScopedConn.getEnableQueryTimeouts() && + batchTimeout != 0 + && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) { + timeoutTask = new CancelTask((StatementImpl)batchedStatement); + locallyScopedConn.getCancelTimer().schedule(timeoutTask, + batchTimeout); + } + + if (numBatchedArgs < numValuesPerBatch) { + numberToExecuteAsMultiValue = numBatchedArgs; + } else { + numberToExecuteAsMultiValue = numBatchedArgs / numValuesPerBatch; + } + + int numberArgsToExecute = numberToExecuteAsMultiValue * numValuesPerBatch; + + for (int i = 0; i < numberArgsToExecute; i++) { + if (i != 0 && i % numValuesPerBatch == 0) { + try { + batchedStatement.execute(); + } catch (SQLException ex) { + sqlEx = handleExceptionForBatch(batchCounter, numValuesPerBatch, + updateCounts, ex); + } + + updateCountCounter = processMultiCountsAndKeys( + (StatementImpl)batchedStatement, updateCountCounter, + updateCounts); + + batchedStatement.clearParameters(); + batchedParamIndex = 1; + } + + batchedParamIndex = setOneBatchedParameterSet(batchedStatement, + batchedParamIndex, this.batchedArgs + .get(batchCounter++)); + } + + try { + batchedStatement.execute(); + } catch (SQLException ex) { + sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, + updateCounts, ex); + } + + updateCountCounter = processMultiCountsAndKeys( + (StatementImpl)batchedStatement, updateCountCounter, + updateCounts); + + batchedStatement.clearParameters(); + + numValuesPerBatch = numBatchedArgs - batchCounter; + } finally { + if (batchedStatement != null) { + batchedStatement.close(); + batchedStatement = null; + } + } + + try { + if (numValuesPerBatch > 0) { + + if (this.retrieveGeneratedKeys) { + batchedStatement = locallyScopedConn.prepareStatement( + generateMultiStatementForBatch(numValuesPerBatch), + RETURN_GENERATED_KEYS); + } else { + batchedStatement = locallyScopedConn.prepareStatement( + generateMultiStatementForBatch(numValuesPerBatch)); + } + + if (timeoutTask != null) { + timeoutTask.toCancel = (StatementImpl)batchedStatement; + } + + batchedParamIndex = 1; + + while (batchCounter < numBatchedArgs) { + batchedParamIndex = setOneBatchedParameterSet(batchedStatement, + batchedParamIndex, this.batchedArgs + .get(batchCounter++)); + } + + try { + batchedStatement.execute(); + } catch (SQLException ex) { + sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, + updateCounts, ex); + } + + updateCountCounter = processMultiCountsAndKeys( + (StatementImpl)batchedStatement, updateCountCounter, + updateCounts); + + batchedStatement.clearParameters(); + } + + if (timeoutTask != null) { + if (timeoutTask.caughtWhileCancelling != null) { + throw timeoutTask.caughtWhileCancelling; + } - int batchedParamIndex = 1; - int updateCountRunningTotal = 0; - int numberToExecuteAsMultiValue = 0; - int batchCounter = 0; - - try { - if (this.retrieveGeneratedKeys) { - batchedStatement = locallyScopedConn.prepareStatement( - generateBatchedInsertSQL(valuesClause, numValuesPerBatch), - RETURN_GENERATED_KEYS); - } else { - batchedStatement = locallyScopedConn - .prepareStatement(generateBatchedInsertSQL(valuesClause, - numValuesPerBatch)); + timeoutTask.cancel(); + + locallyScopedConn.getCancelTimer().purge(); + + timeoutTask = null; + } + + if (sqlEx != null) { + SQLException batchUpdateException = new java.sql.BatchUpdateException(sqlEx + .getMessage(), sqlEx.getSQLState(), sqlEx + .getErrorCode(), updateCounts); + batchUpdateException.initCause(sqlEx); + throw batchUpdateException; + } + + return updateCounts; + } finally { + if (batchedStatement != null) { + batchedStatement.close(); + } + } + } finally { + if (timeoutTask != null) { + timeoutTask.cancel(); + locallyScopedConn.getCancelTimer().purge(); + } + + resetCancelledState(); + + if (!multiQueriesEnabled) { + locallyScopedConn.getIO().disableMultiQueries(); + } + + clearBatch(); } - - if (numBatchedArgs < numValuesPerBatch) { - numberToExecuteAsMultiValue = numBatchedArgs; - } else { - numberToExecuteAsMultiValue = numBatchedArgs / numValuesPerBatch; + } + } + + private String generateMultiStatementForBatch(int numBatches) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + StringBuffer newStatementSql = new StringBuffer((this.originalSql + .length() + 1) * numBatches); + + newStatementSql.append(this.originalSql); + + for (int i = 0; i < numBatches - 1; i++) { + newStatementSql.append(';'); + newStatementSql.append(this.originalSql); } - int numberArgsToExecute = numberToExecuteAsMultiValue * numValuesPerBatch; + return newStatementSql.toString(); + } + } - for (int i = 0; i < numberArgsToExecute; i++) { - if (i != 0 && i % numValuesPerBatch == 0) { - updateCountRunningTotal += batchedStatement.executeUpdate(); + /** + * Rewrites the already prepared statement into a multi-value insert + * statement of 'statementsPerBatch' values and executes the entire batch + * using this new statement. + * + * @return update counts in the same fashion as executeBatch() + * + * @throws SQLException + */ + protected int[] executeBatchedInserts(int batchTimeout) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + String valuesClause = getValuesClause(); - getBatchedGeneratedKeys(batchedStatement); - batchedStatement.clearParameters(); - batchedParamIndex = 1; + MySQLConnection locallyScopedConn = this.connection; - } + if (valuesClause == null) { + return executeBatchSerially(batchTimeout); + } - batchedParamIndex = setOneBatchedParameterSet(batchedStatement, - batchedParamIndex, this.batchedArgs - .get(batchCounter++)); + int numBatchedArgs = this.batchedArgs.size(); + + if (this.retrieveGeneratedKeys) { + this.batchedGeneratedKeys = new ArrayList(numBatchedArgs); } - updateCountRunningTotal += batchedStatement.executeUpdate(); - getBatchedGeneratedKeys(batchedStatement); + int numValuesPerBatch = computeBatchSize(numBatchedArgs); - numValuesPerBatch = numBatchedArgs - batchCounter; - } finally { - if (batchedStatement != null) { - batchedStatement.close(); + if (numBatchedArgs < numValuesPerBatch) { + numValuesPerBatch = numBatchedArgs; } - } - - try { - if (numValuesPerBatch > 0) { - if (this.retrieveGeneratedKeys) { - batchedStatement = locallyScopedConn.prepareStatement( - generateBatchedInsertSQL(valuesClause, numValuesPerBatch), - RETURN_GENERATED_KEYS); - } else { - batchedStatement = locallyScopedConn.prepareStatement( - generateBatchedInsertSQL(valuesClause, numValuesPerBatch)); - } - - batchedParamIndex = 1; + java.sql.PreparedStatement batchedStatement = null; - while (batchCounter < numBatchedArgs) { - batchedParamIndex = setOneBatchedParameterSet(batchedStatement, - batchedParamIndex, this.batchedArgs - .get(batchCounter++)); + int batchedParamIndex = 1; + int updateCountRunningTotal = 0; + int numberToExecuteAsMultiValue = 0; + int batchCounter = 0; + CancelTask timeoutTask = null; + SQLException sqlEx = null; + + int[] updateCounts = new int[numBatchedArgs]; + + try { + try { + batchedStatement = /* FIXME -if we ever care about folks proxying our MySQLConnection */ + prepareBatchedInsertSQL(locallyScopedConn, numValuesPerBatch); + + if (locallyScopedConn.getEnableQueryTimeouts() + && batchTimeout != 0 + && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) { + timeoutTask = new CancelTask( + (StatementImpl) batchedStatement); + locallyScopedConn.getCancelTimer().schedule(timeoutTask, + batchTimeout); + } + + if (numBatchedArgs < numValuesPerBatch) { + numberToExecuteAsMultiValue = numBatchedArgs; + } else { + numberToExecuteAsMultiValue = numBatchedArgs + / numValuesPerBatch; + } + + int numberArgsToExecute = numberToExecuteAsMultiValue + * numValuesPerBatch; + + for (int i = 0; i < numberArgsToExecute; i++) { + if (i != 0 && i % numValuesPerBatch == 0) { + try { + updateCountRunningTotal += batchedStatement + .executeUpdate(); + } catch (SQLException ex) { + sqlEx = handleExceptionForBatch(batchCounter - 1, + numValuesPerBatch, updateCounts, ex); + } + + getBatchedGeneratedKeys(batchedStatement); + batchedStatement.clearParameters(); + batchedParamIndex = 1; + + } + + batchedParamIndex = setOneBatchedParameterSet( + batchedStatement, batchedParamIndex, + this.batchedArgs.get(batchCounter++)); + } + + try { + updateCountRunningTotal += + batchedStatement.executeUpdate(); + } catch (SQLException ex) { + sqlEx = handleExceptionForBatch(batchCounter - 1, + numValuesPerBatch, updateCounts, ex); + } + + getBatchedGeneratedKeys(batchedStatement); + + numValuesPerBatch = numBatchedArgs - batchCounter; + } finally { + if (batchedStatement != null) { + batchedStatement.close(); + batchedStatement = null; + } } - updateCountRunningTotal += batchedStatement.executeUpdate(); - getBatchedGeneratedKeys(batchedStatement); - } + try { + if (numValuesPerBatch > 0) { + batchedStatement = + prepareBatchedInsertSQL(locallyScopedConn, + numValuesPerBatch); + + if (timeoutTask != null) { + timeoutTask.toCancel = (StatementImpl) batchedStatement; + } - int[] updateCounts = new int[this.batchedArgs.size()]; + batchedParamIndex = 1; - for (int i = 0; i < this.batchedArgs.size(); i++) { - updateCounts[i] = 1; - } + while (batchCounter < numBatchedArgs) { + batchedParamIndex = setOneBatchedParameterSet( + batchedStatement, batchedParamIndex, + this.batchedArgs.get(batchCounter++)); + } - return updateCounts; - } finally { - if (batchedStatement != null) { - batchedStatement.close(); + try { + updateCountRunningTotal += batchedStatement.executeUpdate(); + } catch (SQLException ex) { + sqlEx = handleExceptionForBatch(batchCounter - 1, + numValuesPerBatch, updateCounts, ex); + } + + getBatchedGeneratedKeys(batchedStatement); + } + + if (sqlEx != null) { + SQLException batchUpdateException = new java.sql.BatchUpdateException(sqlEx + .getMessage(), sqlEx.getSQLState(), sqlEx + .getErrorCode(), updateCounts); + batchUpdateException.initCause(sqlEx); + throw batchUpdateException; + } + + if (numBatchedArgs > 1) { + int updCount = updateCountRunningTotal > 0 ? Statement.SUCCESS_NO_INFO : 0; + for (int j = 0; j < numBatchedArgs; j++) { + updateCounts[j] = updCount; + } + } else { + updateCounts[0] = updateCountRunningTotal; + } + return updateCounts; + } finally { + if (batchedStatement != null) { + batchedStatement.close(); + } + } + } finally { + if (timeoutTask != null) { + timeoutTask.cancel(); + locallyScopedConn.getCancelTimer().purge(); + } + + resetCancelledState(); } } } + protected String getValuesClause() throws SQLException { + return this.parseInfo.valuesClause; + } + /** * Computes the optimum number of batched parameter lists to send * without overflowing max_allowed_packet. * * @param numBatchedArgs * @return + * @throws SQLException */ - protected int computeBatchSize(int numBatchedArgs) { - long[] combinedValues = computeMaxParameterSetSizeAndBatchSize(numBatchedArgs); - - long maxSizeOfParameterSet = combinedValues[0]; - long sizeOfEntireBatch = combinedValues[1]; - - int maxAllowedPacket = this.connection.getMaxAllowedPacket(); - - if (sizeOfEntireBatch < maxAllowedPacket - this.originalSql.length()) { - return numBatchedArgs; + protected int computeBatchSize(int numBatchedArgs) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + long[] combinedValues = computeMaxParameterSetSizeAndBatchSize(numBatchedArgs); + + long maxSizeOfParameterSet = combinedValues[0]; + long sizeOfEntireBatch = combinedValues[1]; + + int maxAllowedPacket = this.connection.getMaxAllowedPacket(); + + if (sizeOfEntireBatch < maxAllowedPacket - this.originalSql.length()) { + return numBatchedArgs; + } + + return (int)Math.max(1, (maxAllowedPacket - this.originalSql.length()) / maxSizeOfParameterSet); } - - return (int)Math.max(1, (maxAllowedPacket - this.originalSql.length()) / maxSizeOfParameterSet); } - + /** * Computes the maximum parameter set size, and entire batch size given * the number of arguments in the batch. + * @throws SQLException */ - protected long[] computeMaxParameterSetSizeAndBatchSize(int numBatchedArgs) { - long sizeOfEntireBatch = 0; - long maxSizeOfParameterSet = 0; - - for (int i = 0; i < numBatchedArgs; i++) { - BatchParams paramArg = (BatchParams) this.batchedArgs - .get(i); - - boolean[] isNullBatch = paramArg.isNull; - boolean[] isStreamBatch = paramArg.isStream; - - long sizeOfParameterSet = 0; + protected long[] computeMaxParameterSetSizeAndBatchSize(int numBatchedArgs) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + long sizeOfEntireBatch = 0; + long maxSizeOfParameterSet = 0; - for (int j = 0; j < isNullBatch.length; j++) { - if (!isNullBatch[j]) { - - if (isStreamBatch[j]) { - int streamLength = paramArg.streamLengths[j]; - - if (streamLength != -1) { - sizeOfParameterSet += streamLength * 2; // for safety in escaping + for (int i = 0; i < numBatchedArgs; i++) { + BatchParams paramArg = (BatchParams) this.batchedArgs + .get(i); + + boolean[] isNullBatch = paramArg.isNull; + boolean[] isStreamBatch = paramArg.isStream; + + long sizeOfParameterSet = 0; + + for (int j = 0; j < isNullBatch.length; j++) { + if (!isNullBatch[j]) { + + if (isStreamBatch[j]) { + int streamLength = paramArg.streamLengths[j]; + + if (streamLength != -1) { + sizeOfParameterSet += streamLength * 2; // for safety in escaping + } else { + int paramLength = paramArg.parameterStrings[j].length; + sizeOfParameterSet += paramLength; + } + } else { + sizeOfParameterSet += paramArg.parameterStrings[j].length; } } else { - sizeOfParameterSet += paramArg.parameterStrings[j].length; + sizeOfParameterSet += 4; // for NULL literal in SQL } + } + + // + // Account for static part of values clause + // This is a little naiive, because the ?s will be replaced + // but it gives us some padding, and is less housekeeping + // to ignore them. We're looking for a "fuzzy" value here + // anyway + // + + if (getValuesClause() != null) { + sizeOfParameterSet += getValuesClause().length() + 1; } else { - sizeOfParameterSet += 4; // for NULL literal in SQL + sizeOfParameterSet += this.originalSql.length() + 1; } - } + + sizeOfEntireBatch += sizeOfParameterSet; + + if (sizeOfParameterSet > maxSizeOfParameterSet) { + maxSizeOfParameterSet = sizeOfParameterSet; + } + } - // - // Account for static part of values clause - // This is a little naiive, because the ?s will be replaced - // but it gives us some padding, and is less housekeeping - // to ignore them. We're looking for a "fuzzy" value here - // anyway - // - - sizeOfParameterSet += this.batchedValuesClause.length() + 1; - sizeOfEntireBatch += sizeOfParameterSet; - - if (sizeOfParameterSet > maxSizeOfParameterSet) { - maxSizeOfParameterSet = sizeOfParameterSet; - } - } - - return new long[] {maxSizeOfParameterSet, sizeOfEntireBatch}; + return new long[] {maxSizeOfParameterSet, sizeOfEntireBatch}; + } } + /** * Executes the current batch of statements by executing them one-by-one. * * @return a list of update counts * @throws SQLException * if an error occurs */ - protected int[] executeBatchSerially() throws SQLException { + protected int[] executeBatchSerially(int batchTimeout) throws SQLException { - Connection locallyScopedConn = this.connection; - - if (locallyScopedConn == null) { - checkClosed(); - } - - int[] updateCounts = null; - - if (this.batchedArgs != null) { - int nbrCommands = this.batchedArgs.size(); - updateCounts = new int[nbrCommands]; - - for (int i = 0; i < nbrCommands; i++) { - updateCounts[i] = -3; + synchronized (checkClosed().getConnectionMutex()) { + MySQLConnection locallyScopedConn = this.connection; + + if (locallyScopedConn == null) { + checkClosed(); } - - SQLException sqlEx = null; - - int commandIndex = 0; - - if (this.retrieveGeneratedKeys) { - this.batchedGeneratedKeys = new ArrayList(nbrCommands); - } - - for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) { - Object arg = this.batchedArgs.get(commandIndex); - - if (arg instanceof String) { - updateCounts[commandIndex] = executeUpdate((String) arg); - } else { - BatchParams paramArg = (BatchParams) arg; - - try { - updateCounts[commandIndex] = executeUpdate( - paramArg.parameterStrings, - paramArg.parameterStreams, paramArg.isStream, - paramArg.streamLengths, paramArg.isNull, true); - - if (this.retrieveGeneratedKeys) { - java.sql.ResultSet rs = null; - + + int[] updateCounts = null; + + if (this.batchedArgs != null) { + int nbrCommands = this.batchedArgs.size(); + updateCounts = new int[nbrCommands]; + + for (int i = 0; i < nbrCommands; i++) { + updateCounts[i] = -3; + } + + SQLException sqlEx = null; + + CancelTask timeoutTask = null; + + try { + if (locallyScopedConn.getEnableQueryTimeouts() && + batchTimeout != 0 + && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) { + timeoutTask = new CancelTask(this); + locallyScopedConn.getCancelTimer().schedule(timeoutTask, + batchTimeout); + } + + if (this.retrieveGeneratedKeys) { + this.batchedGeneratedKeys = new ArrayList(nbrCommands); + } + + for (batchCommandIndex = 0; batchCommandIndex < nbrCommands; batchCommandIndex++) { + Object arg = this.batchedArgs.get(batchCommandIndex); + + if (arg instanceof String) { + updateCounts[batchCommandIndex] = executeUpdate((String) arg); + } else { + BatchParams paramArg = (BatchParams) arg; + try { - rs = getGeneratedKeysInternal(); - - while (rs.next()) { - this.batchedGeneratedKeys - .add(new byte[][] { rs.getBytes(1) }); + updateCounts[batchCommandIndex] = executeUpdate( + paramArg.parameterStrings, + paramArg.parameterStreams, paramArg.isStream, + paramArg.streamLengths, paramArg.isNull, true); + + if (this.retrieveGeneratedKeys) { + java.sql.ResultSet rs = null; + + try { + if (containsOnDuplicateKeyUpdateInSQL()) + rs = getGeneratedKeysInternal(1); + else + rs = getGeneratedKeysInternal(); + + while (rs.next()) { + this.batchedGeneratedKeys + .add(new ByteArrayRow(new byte[][] { rs.getBytes(1) }, getExceptionInterceptor())); + } + } finally { + if (rs != null) { + rs.close(); + } + } } - } finally { - if (rs != null) { - rs.close(); + } catch (SQLException ex) { + updateCounts[batchCommandIndex] = EXECUTE_FAILED; + + if (this.continueBatchOnError && + !(ex instanceof MySQLTimeoutException) && + !(ex instanceof MySQLStatementCancelledException) && + !hasDeadlockOrTimeoutRolledBackTx(ex)) { + sqlEx = ex; + } else { + int[] newUpdateCounts = new int[batchCommandIndex]; + System.arraycopy(updateCounts, 0, + newUpdateCounts, 0, batchCommandIndex); + + SQLException batchUpdateException = new java.sql.BatchUpdateException(ex + .getMessage(), ex.getSQLState(), ex + .getErrorCode(), newUpdateCounts); + batchUpdateException.initCause(ex); + throw batchUpdateException; } } } - } catch (SQLException ex) { - updateCounts[commandIndex] = EXECUTE_FAILED; - - if (this.continueBatchOnError) { - sqlEx = ex; - } else { - int[] newUpdateCounts = new int[commandIndex]; - System.arraycopy(updateCounts, 0, newUpdateCounts, - 0, commandIndex); - - throw new java.sql.BatchUpdateException(ex - .getMessage(), ex.getSQLState(), ex - .getErrorCode(), newUpdateCounts); - } } + + if (sqlEx != null) { + SQLException batchUpdateException = new java.sql.BatchUpdateException(sqlEx.getMessage(), + sqlEx.getSQLState(), sqlEx.getErrorCode(), updateCounts); + batchUpdateException.initCause(sqlEx); + throw batchUpdateException; + } + } catch (NullPointerException npe) { + try { + checkClosed(); + } catch (SQLException connectionClosedEx) { + updateCounts[batchCommandIndex] = EXECUTE_FAILED; + + int[] newUpdateCounts = new int[batchCommandIndex]; + + System.arraycopy(updateCounts, 0, + newUpdateCounts, 0, batchCommandIndex); + + throw new java.sql.BatchUpdateException(connectionClosedEx + .getMessage(), connectionClosedEx.getSQLState(), connectionClosedEx + .getErrorCode(), newUpdateCounts); + } + + throw npe; // we don't know why this happened, punt + } finally { + batchCommandIndex = -1; + + if (timeoutTask != null) { + timeoutTask.cancel(); + locallyScopedConn.getCancelTimer().purge(); + } + + resetCancelledState(); } } - - if (sqlEx != null) { - throw new java.sql.BatchUpdateException(sqlEx.getMessage(), - sqlEx.getSQLState(), sqlEx.getErrorCode(), updateCounts); - } + + return (updateCounts != null) ? updateCounts : new int[0]; } - - return (updateCounts != null) ? updateCounts : new int[0]; + } + public String getDateTime(String pattern){ + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + return sdf.format(new java.util.Date()); + } + /** * Actually execute the prepared statement. This is here so server-side * PreparedStatements can re-use most of the code from this class. @@ -1294,75 +2042,94 @@ * @throws SQLException * if an error occurs. */ - protected ResultSet executeInternal(int maxRowsToRetrieve, + protected ResultSetInternalMethods executeInternal(int maxRowsToRetrieve, Buffer sendPacket, boolean createStreamingResultSet, - boolean queryIsSelectOnly, boolean unpackFields, Field[] cachedFields, + boolean queryIsSelectOnly, Field[] metadataFromCache, boolean isBatch) throws SQLException { - try { - - - synchronized (this.cancelTimeoutMutex) { - this.wasCancelled = false; - } - - Connection locallyScopedConnection= this.connection; - - this.numberOfExecutions++; - - if (this.doPingInstead) { - doPingInstead(); - - return this.results; - } - - ResultSet rs; - - CancelTask timeoutTask = null; - + synchronized (checkClosed().getConnectionMutex()) { try { - if (locallyScopedConnection.getEnableQueryTimeouts() && - this.timeoutInMillis != 0 - && locallyScopedConnection.versionMeetsMinimum(5, 0, 0)) { - timeoutTask = new CancelTask(); - Connection.getCancelTimer().schedule(timeoutTask, - this.timeoutInMillis); + + resetCancelledState(); + + MySQLConnection locallyScopedConnection = this.connection; + + this.numberOfExecutions++; + + if (this.doPingInstead) { + doPingInstead(); + + return this.results; } - rs = locallyScopedConnection.execSQL(this, null, maxRowsToRetrieve, sendPacket, - this.resultSetType, this.resultSetConcurrency, - createStreamingResultSet, this.currentCatalog, - unpackFields, isBatch); + ResultSetInternalMethods rs; - if (timeoutTask != null) { - timeoutTask.cancel(); + CancelTask timeoutTask = null; + + try { + if (locallyScopedConnection.getEnableQueryTimeouts() && + this.timeoutInMillis != 0 + && locallyScopedConnection.versionMeetsMinimum(5, 0, 0)) { + timeoutTask = new CancelTask(this); + locallyScopedConnection.getCancelTimer().schedule(timeoutTask, + this.timeoutInMillis); + } + + if (!isBatch) { + statementBegins(); + } - if (timeoutTask.caughtWhileCancelling != null) { - throw timeoutTask.caughtWhileCancelling; + rs = locallyScopedConnection.execSQL(this, null, maxRowsToRetrieve, sendPacket, + this.resultSetType, this.resultSetConcurrency, + createStreamingResultSet, this.currentCatalog, + metadataFromCache, isBatch); + + if (timeoutTask != null) { + timeoutTask.cancel(); + + locallyScopedConnection.getCancelTimer().purge(); + + if (timeoutTask.caughtWhileCancelling != null) { + throw timeoutTask.caughtWhileCancelling; + } + + timeoutTask = null; } + + synchronized (this.cancelTimeoutMutex) { + if (this.wasCancelled) { + SQLException cause = null; + + if (this.wasCancelledByTimeout) { + cause = new MySQLTimeoutException(); + } else { + cause = new MySQLStatementCancelledException(); + } + + resetCancelledState(); + + throw cause; + } + } + } finally { + if (!isBatch) { + this.statementExecuting.set(false); + } - timeoutTask = null; - } - - synchronized (this.cancelTimeoutMutex) { - if (this.wasCancelled) { - this.wasCancelled = false; - throw new MySQLTimeoutException(); + if (timeoutTask != null) { + timeoutTask.cancel(); + locallyScopedConnection.getCancelTimer().purge(); } } - } finally { - if (timeoutTask != null) { - timeoutTask.cancel(); - } + + 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. + + throw npe; } - - 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. - - throw npe; } } @@ -1376,33 +2143,50 @@ * if a database access error occurs */ public java.sql.ResultSet executeQuery() throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - Connection locallyScopedConn = this.connection; - - checkForDml(this.originalSql, this.firstCharOfStmt); + MySQLConnection locallyScopedConn = this.connection; + + checkForDml(this.originalSql, this.firstCharOfStmt); + + CachedResultSetMetaData cachedMetadata = null; + - CachedResultSetMetaData cachedMetadata = null; - - // We need to execute this all together - // So synchronize on the Connection's mutex (because - // even queries going through there synchronize - // on the same mutex. - synchronized (locallyScopedConn.getMutex()) { clearWarnings(); + boolean doStreaming = createStreamingResultSet(); + this.batchedGeneratedKeys = null; - Buffer sendPacket = fillSendPacket(); - - if (this.results != null) { - if (!this.connection.getHoldResultsOpenOverStatementClose()) { - if (!this.holdResultsOpenOverClose) { - this.results.realClose(false); + // Adjust net_write_timeout to a higher value if we're + // streaming result sets. More often than not, someone runs into + // an issue where they blow net_write_timeout when using this + // feature, and if they're willing to hold a result set open + // for 30 seconds or more, one more round-trip isn't going to hurt + // + // This is reset by RowDataDynamic.close(). + + if (doStreaming + && this.connection.getNetTimeoutForStreamingResults() > 0) { + + java.sql.Statement stmt = null; + + try { + stmt = this.connection.createStatement(); + + ((com.mysql.jdbc.StatementImpl)stmt).executeSimpleNonQuery(this.connection, "SET net_write_timeout=" + + this.connection.getNetTimeoutForStreamingResults()); + } finally { + if (stmt != null) { + stmt.close(); } } } + + Buffer sendPacket = fillSendPacket(); + implicitlyCloseAllOpenResults(); + String oldCatalog = null; if (!locallyScopedConn.getCatalog().equals(this.currentCatalog)) { @@ -1422,52 +2206,10 @@ if (cachedMetadata != null) { metadataFromCache = cachedMetadata.fields; } - - if (locallyScopedConn.useMaxRows()) { - // If there isn't a limit clause in the SQL - // then limit the number of rows to return in - // an efficient manner. Only do this if - // setMaxRows() hasn't been used on any Statements - // generated from the current Connection (saves - // a query, and network traffic). - if (this.hasLimitClause) { - this.results = executeInternal(this.maxRows, sendPacket, - createStreamingResultSet(), true, - (cachedMetadata == null), metadataFromCache, false); - } else { - if (this.maxRows <= 0) { - locallyScopedConn - .execSQL( - this, - "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, //$NON-NLS-1$ - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, - false, this.currentCatalog, true); - } else { - locallyScopedConn - .execSQL( - this, - "SET OPTION SQL_SELECT_LIMIT=" + this.maxRows, -1, null, //$NON-NLS-1$ - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, - false, this.currentCatalog, true); - } - - - this.results = executeInternal(-1, sendPacket, - createStreamingResultSet(), true, - (cachedMetadata == null), metadataFromCache, false); + locallyScopedConn.setSessionMaxRows(this.maxRows); - if (oldCatalog != null) { - this.connection.setCatalog(oldCatalog); - } - } - } else { - this.results = executeInternal(-1, sendPacket, - createStreamingResultSet(), true, - (cachedMetadata == null), metadataFromCache, false); - } + this.results = executeInternal(this.maxRows, sendPacket, doStreaming, true, metadataFromCache, false); if (oldCatalog != null) { locallyScopedConn.setCatalog(oldCatalog); @@ -1482,13 +2224,13 @@ null /* will be created */, this.results); } } - } - this.lastInsertId = this.results.getUpdateID(); - - return this.results; + this.lastInsertId = this.results.getUpdateID(); + + return this.results; + } } - + /** * Execute a SQL INSERT, UPDATE or DELETE statement. In addition, SQL * statements that return nothing such as SQL DDL statements can be @@ -1511,13 +2253,15 @@ */ protected int executeUpdate( boolean clearBatchedGeneratedKeysAndWarnings, boolean isBatch) throws SQLException { - if (clearBatchedGeneratedKeysAndWarnings) { - clearWarnings(); - this.batchedGeneratedKeys = null; + synchronized (checkClosed().getConnectionMutex()) { + if (clearBatchedGeneratedKeysAndWarnings) { + clearWarnings(); + this.batchedGeneratedKeys = null; + } + + return executeUpdate(this.parameterValues, this.parameterStreams, + this.isStream, this.streamLengths, this.isNull, isBatch); } - - return executeUpdate(this.parameterValues, this.parameterStreams, - this.isStream, this.streamLengths, this.isNull, isBatch); } /** @@ -1544,34 +2288,26 @@ int[] batchedStreamLengths, boolean[] batchedIsNull, boolean isReallyBatch) throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - Connection locallyScopedConn = this.connection; - - if (locallyScopedConn.isReadOnly()) { - throw SQLError.createSQLException(Messages.getString("PreparedStatement.34") //$NON-NLS-1$ - + Messages.getString("PreparedStatement.35"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - if ((this.firstCharOfStmt == 'S') - && isSelectQuery()) { //$NON-NLS-1$ - throw SQLError.createSQLException(Messages.getString("PreparedStatement.37"), //$NON-NLS-1$ - "01S03"); //$NON-NLS-1$ - } - - if (this.results != null) { - if (!locallyScopedConn.getHoldResultsOpenOverStatementClose()) { - this.results.realClose(false); + MySQLConnection locallyScopedConn = this.connection; + + if (locallyScopedConn.isReadOnly()) { + throw SQLError.createSQLException(Messages.getString("PreparedStatement.34") //$NON-NLS-1$ + + Messages.getString("PreparedStatement.35"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } - } + + if ((this.firstCharOfStmt == 'S') + && isSelectQuery()) { //$NON-NLS-1$ + throw SQLError.createSQLException(Messages.getString("PreparedStatement.37"), //$NON-NLS-1$ + "01S03", getExceptionInterceptor()); //$NON-NLS-1$ + } + + implicitlyCloseAllOpenResults(); - ResultSet rs = null; + ResultSetInternalMethods rs = null; - // The checking and changing of catalogs - // must happen in sequence, so synchronize - // on the same mutex that _conn is using - synchronized (locallyScopedConn.getMutex()) { Buffer sendPacket = fillSendPacket(batchedParameterStrings, batchedParameterStreams, batchedIsStream, batchedStreamLengths); @@ -1586,13 +2322,7 @@ // // Only apply max_rows to selects // - if (locallyScopedConn.useMaxRows()) { - locallyScopedConn.execSQL(this, - "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, //$NON-NLS-1$ - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.currentCatalog, true); - } + locallyScopedConn.setSessionMaxRows(-1); boolean oldInfoMsgState = false; @@ -1601,7 +2331,7 @@ locallyScopedConn.setReadInfoMsgEnabled(true); } - rs = executeInternal(-1, sendPacket, false, false, true, null, + rs = executeInternal(-1, sendPacket, false, false, null, isReallyBatch); if (this.retrieveGeneratedKeys) { @@ -1612,66 +2342,36 @@ if (oldCatalog != null) { locallyScopedConn.setCatalog(oldCatalog); } - } - this.results = rs; - - this.updateCount = rs.getUpdateCount(); - - int truncatedUpdateCount = 0; - - if (this.updateCount > Integer.MAX_VALUE) { - truncatedUpdateCount = Integer.MAX_VALUE; - } else { - truncatedUpdateCount = (int) this.updateCount; - } - - this.lastInsertId = rs.getUpdateID(); - - return truncatedUpdateCount; - } - - private String extractValuesClause() throws SQLException { - if (this.batchedValuesClause == null) { - String quoteCharStr = this.connection.getMetaData() - .getIdentifierQuoteString(); + this.results = rs; - int indexOfValues = -1; - - if (quoteCharStr.length() > 0) { - indexOfValues = StringUtils.indexOfIgnoreCaseRespectQuotes( - this.statementAfterCommentsPos, - this.originalSql, "VALUES ", quoteCharStr.charAt(0), false); - } else { - indexOfValues = StringUtils.indexOfIgnoreCase(this.statementAfterCommentsPos, - this.originalSql, - "VALUES "); + this.updateCount = rs.getUpdateCount(); + + if (containsOnDuplicateKeyUpdateInSQL() && + this.compensateForOnDuplicateKeyUpdate) { + if (this.updateCount == 2 || this.updateCount == 0) { + this.updateCount = 1; + } } - if (indexOfValues == -1) { - return null; - } + int truncatedUpdateCount = 0; - int indexOfFirstParen = this.originalSql - .indexOf('(', indexOfValues + 7); - - if (indexOfFirstParen == -1) { - return null; + if (this.updateCount > Integer.MAX_VALUE) { + truncatedUpdateCount = Integer.MAX_VALUE; + } else { + truncatedUpdateCount = (int) this.updateCount; } - int indexOfLastParen = this.originalSql.lastIndexOf(')'); + this.lastInsertId = rs.getUpdateID(); - if (indexOfLastParen == -1) { - return null; - } - - this.batchedValuesClause = this.originalSql.substring(indexOfFirstParen, - indexOfLastParen + 1); + return truncatedUpdateCount; } - - return this.batchedValuesClause; } + protected boolean containsOnDuplicateKeyUpdateInSQL() { + return this.parseInfo.isOnDuplicateKeyUpdate; + } + /** * Creates the packet that contains the query to be sent to the server. * @@ -1682,8 +2382,10 @@ * if an error occurs. */ protected Buffer fillSendPacket() throws SQLException { - return fillSendPacket(this.parameterValues, this.parameterStreams, - this.isStream, this.streamLengths); + synchronized (checkClosed().getConnectionMutex()) { + return fillSendPacket(this.parameterValues, this.parameterStreams, + this.isStream, this.streamLengths); + } } /** @@ -1706,70 +2408,126 @@ protected Buffer fillSendPacket(byte[][] batchedParameterStrings, InputStream[] batchedParameterStreams, boolean[] batchedIsStream, int[] batchedStreamLengths) throws SQLException { - Buffer sendPacket = this.connection.getIO().getSharedSendPacket(); - - sendPacket.clear(); - - sendPacket.writeByte((byte) MysqlDefs.QUERY); - - boolean useStreamLengths = this.connection - .getUseStreamLengthsInPrepStmts(); - - // - // Try and get this allocation as close as possible - // for BLOBs - // - int ensurePacketSize = 0; - - for (int i = 0; i < batchedParameterStrings.length; i++) { - if (batchedIsStream[i] && useStreamLengths) { - ensurePacketSize += batchedStreamLengths[i]; + synchronized (checkClosed().getConnectionMutex()) { + Buffer sendPacket = this.connection.getIO().getSharedSendPacket(); + + sendPacket.clear(); + + sendPacket.writeByte((byte) MysqlDefs.QUERY); + + boolean useStreamLengths = this.connection + .getUseStreamLengthsInPrepStmts(); + + // + // Try and get this allocation as close as possible + // for BLOBs + // + int ensurePacketSize = 0; + + String statementComment = this.connection.getStatementComment(); + + byte[] commentAsBytes = null; + + if (statementComment != null) { + if (this.charConverter != null) { + commentAsBytes = this.charConverter.toBytes(statementComment); + } else { + commentAsBytes = StringUtils.getBytes(statementComment, this.charConverter, + this.charEncoding, this.connection + .getServerCharacterEncoding(), this.connection + .parserKnowsUnicode(), getExceptionInterceptor()); + } + + ensurePacketSize += commentAsBytes.length; + ensurePacketSize += 6; // for /*[space] [space]*/ } - } - - if (ensurePacketSize != 0) { - sendPacket.ensureCapacity(ensurePacketSize); - } - - for (int i = 0; i < batchedParameterStrings.length; i++) { - if ((batchedParameterStrings[i] == null) - && (batchedParameterStreams[i] == null)) { - throw SQLError.createSQLException(Messages - .getString("PreparedStatement.40") //$NON-NLS-1$ - + (i + 1), SQLError.SQL_STATE_WRONG_NO_OF_PARAMETERS); + + for (int i = 0; i < batchedParameterStrings.length; i++) { + if (batchedIsStream[i] && useStreamLengths) { + ensurePacketSize += batchedStreamLengths[i]; + } } - - sendPacket.writeBytesNoNull(this.staticSqlStrings[i]); - - if (batchedIsStream[i]) { - streamToBytes(sendPacket, batchedParameterStreams[i], true, - batchedStreamLengths[i], useStreamLengths); - } else { - sendPacket.writeBytesNoNull(batchedParameterStrings[i]); + + if (ensurePacketSize != 0) { + sendPacket.ensureCapacity(ensurePacketSize); } + + if (commentAsBytes != null) { + sendPacket.writeBytesNoNull(Constants.SLASH_STAR_SPACE_AS_BYTES); + sendPacket.writeBytesNoNull(commentAsBytes); + sendPacket.writeBytesNoNull(Constants.SPACE_STAR_SLASH_SPACE_AS_BYTES); + } + + for (int i = 0; i < batchedParameterStrings.length; i++) { + checkAllParametersSet(batchedParameterStrings[i], + batchedParameterStreams[i], i); + + sendPacket.writeBytesNoNull(this.staticSqlStrings[i]); + + if (batchedIsStream[i]) { + streamToBytes(sendPacket, batchedParameterStreams[i], true, + batchedStreamLengths[i], useStreamLengths); + } else { + sendPacket.writeBytesNoNull(batchedParameterStrings[i]); + } + } + + sendPacket + .writeBytesNoNull(this.staticSqlStrings[batchedParameterStrings.length]); + + return sendPacket; } + } - sendPacket - .writeBytesNoNull(this.staticSqlStrings[batchedParameterStrings.length]); + private void checkAllParametersSet(byte[] parameterString, + InputStream parameterStream, int columnIndex) throws SQLException { + if ((parameterString == null) + && parameterStream == null) { - return sendPacket; + throw SQLError.createSQLException(Messages + .getString("PreparedStatement.40") //$NON-NLS-1$ + + (columnIndex + 1), SQLError.SQL_STATE_WRONG_NO_OF_PARAMETERS, getExceptionInterceptor()); + } } - private String generateBatchedInsertSQL(String valuesClause, int numBatches) { - StringBuffer newStatementSql = new StringBuffer(this.originalSql - .length() - + (numBatches * (valuesClause.length() + 1))); - - newStatementSql.append(this.originalSql); - - for (int i = 0; i < numBatches - 1; i++) { - newStatementSql.append(','); - newStatementSql.append(valuesClause); + /** + * Returns a prepared statement for the number of batched parameters, used when re-writing batch INSERTs. + */ + protected PreparedStatement prepareBatchedInsertSQL(MySQLConnection localConn, int numBatches) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + PreparedStatement pstmt = new PreparedStatement(localConn, "Rewritten batch of: " + this.originalSql, this.currentCatalog, this.parseInfo.getParseInfoForBatch(numBatches)); + pstmt.setRetrieveGeneratedKeys(this.retrieveGeneratedKeys); + pstmt.rewrittenBatchSize = numBatches; + + return pstmt; } + } - return newStatementSql.toString(); + protected void setRetrieveGeneratedKeys(boolean flag) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + this.retrieveGeneratedKeys = flag; + } } + protected int rewrittenBatchSize = 0; + + public int getRewrittenBatchSize() { + return this.rewrittenBatchSize; + } + + public String getNonRewrittenSql() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + int indexOfBatch = this.originalSql.indexOf(" of: "); + + if (indexOfBatch != -1) { + return this.originalSql.substring(indexOfBatch + 5); + } + + return this.originalSql; + } + } + + /** * DOCUMENT ME! * @@ -1783,28 +2541,75 @@ */ public byte[] getBytesRepresentation(int parameterIndex) throws SQLException { - if (this.isStream[parameterIndex]) { - return streamToBytes(this.parameterStreams[parameterIndex], false, - this.streamLengths[parameterIndex], this.connection - .getUseStreamLengthsInPrepStmts()); + synchronized (checkClosed().getConnectionMutex()) { + if (this.isStream[parameterIndex]) { + return streamToBytes(this.parameterStreams[parameterIndex], false, + this.streamLengths[parameterIndex], this.connection + .getUseStreamLengthsInPrepStmts()); + } + + byte[] parameterVal = this.parameterValues[parameterIndex]; + + if (parameterVal == null) { + return null; + } + + if ((parameterVal[0] == '\'') + && (parameterVal[parameterVal.length - 1] == '\'')) { + byte[] valNoQuotes = new byte[parameterVal.length - 2]; + System.arraycopy(parameterVal, 1, valNoQuotes, 0, + parameterVal.length - 2); + + return valNoQuotes; + } + + return parameterVal; } - - byte[] parameterVal = this.parameterValues[parameterIndex]; - - if (parameterVal == null) { - return null; + } + + /** + * Get bytes representation for a parameter in a statement batch. + * @param parameterIndex + * @param commandIndex + * @return + * @throws SQLException + */ + protected byte[] getBytesRepresentationForBatch(int parameterIndex, int commandIndex) + throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + Object batchedArg = batchedArgs.get(commandIndex); + if (batchedArg instanceof String) { + try { + return (StringUtils.getBytes((String)batchedArg, charEncoding)); + + } catch (UnsupportedEncodingException uue) { + throw new RuntimeException(Messages + .getString("PreparedStatement.32") //$NON-NLS-1$ + + this.charEncoding + + Messages.getString("PreparedStatement.33")); //$NON-NLS-1$ + } + } + + BatchParams params = (BatchParams)batchedArg; + if (params.isStream[parameterIndex]) + return streamToBytes(params.parameterStreams[parameterIndex], false, + params.streamLengths[parameterIndex], + connection.getUseStreamLengthsInPrepStmts()); + byte parameterVal[] = params.parameterStrings[parameterIndex]; + if (parameterVal == null) + return null; + + if ((parameterVal[0] == '\'') + && (parameterVal[parameterVal.length - 1] == '\'')) { + byte[] valNoQuotes = new byte[parameterVal.length - 2]; + System.arraycopy(parameterVal, 1, valNoQuotes, 0, + parameterVal.length - 2); + + return valNoQuotes; + } + + return parameterVal; } - - if ((parameterVal[0] == '\'') - && (parameterVal[parameterVal.length - 1] == '\'')) { - byte[] valNoQuotes = new byte[parameterVal.length - 2]; - System.arraycopy(parameterVal, 1, valNoQuotes, 0, - parameterVal.length - 2); - - return valNoQuotes; - } - - return parameterVal; } // --------------------------JDBC 2.0----------------------------- @@ -1865,20 +2670,20 @@ char c; char separator; StringReader reader = new StringReader(dt + " "); //$NON-NLS-1$ - ArrayList vec = new ArrayList(); - ArrayList vecRemovelist = new ArrayList(); + ArrayList vec = new ArrayList(); + ArrayList vecRemovelist = new ArrayList(); Object[] nv = new Object[3]; Object[] v; - nv[0] = new Character('y'); + nv[0] = Character.valueOf('y'); nv[1] = new StringBuffer(); - nv[2] = new Integer(0); + nv[2] = Integer.valueOf(0); vec.add(nv); if (toTime) { nv = new Object[3]; - nv[0] = new Character('h'); + nv[0] = Character.valueOf('h'); nv[1] = new StringBuffer(); - nv[2] = new Integer(0); + nv[2] = Integer.valueOf(0); vec.add(nv); } @@ -1887,7 +2692,7 @@ maxvecs = vec.size(); for (count = 0; count < maxvecs; count++) { - v = (Object[]) vec.get(count); + v = vec.get(count); n = ((Integer) v[2]).intValue(); c = getSuccessor(((Character) v[0]).charValue(), n); @@ -1898,7 +2703,7 @@ ((StringBuffer) v[1]).append(separator); if ((c == 'X') || (c == 'Y')) { - v[2] = new Integer(4); + v[2] = Integer.valueOf(4); } } } else { @@ -1907,34 +2712,34 @@ nv = new Object[3]; nv[1] = (new StringBuffer(((StringBuffer) v[1]) .toString())).append('M'); - nv[0] = new Character('M'); - nv[2] = new Integer(1); + nv[0] = Character.valueOf('M'); + nv[2] = Integer.valueOf(1); vec.add(nv); } else if (c == 'Y') { c = 'M'; nv = new Object[3]; nv[1] = (new StringBuffer(((StringBuffer) v[1]) .toString())).append('d'); - nv[0] = new Character('d'); - nv[2] = new Integer(1); + nv[0] = Character.valueOf('d'); + nv[2] = Integer.valueOf(1); vec.add(nv); } ((StringBuffer) v[1]).append(c); if (c == ((Character) v[0]).charValue()) { - v[2] = new Integer(n + 1); + v[2] = Integer.valueOf(n + 1); } else { - v[0] = new Character(c); - v[2] = new Integer(1); + v[0] = Character.valueOf(c); + v[2] = Integer.valueOf(1); } } } int size = vecRemovelist.size(); for (int i = 0; i < size; i++) { - v = (Object[]) vecRemovelist.get(i); + v = vecRemovelist.get(i); vec.remove(v); } @@ -1944,7 +2749,7 @@ int size = vec.size(); for (int i = 0; i < size; i++) { - v = (Object[]) vec.get(i); + v = vec.get(i); c = ((Character) v[0]).charValue(); n = ((Integer) v[2]).intValue(); @@ -1966,7 +2771,7 @@ } vecRemovelist.clear(); - v = (Object[]) vec.get(0); // might throw exception + v = vec.get(0); // might throw exception StringBuffer format = (StringBuffer) v[1]; format.setLength(format.length() - 1); @@ -1986,103 +2791,109 @@ public java.sql.ResultSetMetaData getMetaData() throws SQLException { - // - // We could just tack on a LIMIT 0 here no matter what the - // statement, and check if a result set was returned or not, - // but I'm not comfortable with that, myself, so we take - // the "safer" road, and only allow metadata for _actual_ - // SELECTS (but not SHOWs). - // - // CALL's are trapped further up and you end up with a - // CallableStatement anyway. - // - - if (!isSelectQuery()) { - return null; - } - - PreparedStatement mdStmt = null; - java.sql.ResultSet mdRs = null; - - if (this.pstmtResultMetaData == null) { - try { - mdStmt = new PreparedStatement(this.connection, - this.originalSql, this.currentCatalog, this.parseInfo); - - mdStmt.setMaxRows(0); - - int paramCount = this.parameterValues.length; - - for (int i = 1; i <= paramCount; i++) { - mdStmt.setString(i, ""); //$NON-NLS-1$ - } - - boolean hadResults = mdStmt.execute(); - - if (hadResults) { - mdRs = mdStmt.getResultSet(); - - this.pstmtResultMetaData = mdRs.getMetaData(); - } else { - this.pstmtResultMetaData = new ResultSetMetaData( - new Field[0], - this.connection.getUseOldAliasMetadataBehavior()); - } - } finally { - SQLException sqlExRethrow = null; - - if (mdRs != null) { - try { - mdRs.close(); - } catch (SQLException sqlEx) { - sqlExRethrow = sqlEx; + synchronized (checkClosed().getConnectionMutex()) { + // + // We could just tack on a LIMIT 0 here no matter what the + // statement, and check if a result set was returned or not, + // but I'm not comfortable with that, myself, so we take + // the "safer" road, and only allow metadata for _actual_ + // SELECTS (but not SHOWs). + // + // CALL's are trapped further up and you end up with a + // CallableStatement anyway. + // + + if (!isSelectQuery()) { + return null; + } + + PreparedStatement mdStmt = null; + java.sql.ResultSet mdRs = null; + + if (this.pstmtResultMetaData == null) { + try { + mdStmt = new PreparedStatement(this.connection, + this.originalSql, this.currentCatalog, this.parseInfo); + + mdStmt.setMaxRows(1); + + int paramCount = this.parameterValues.length; + + for (int i = 1; i <= paramCount; i++) { + mdStmt.setString(i, ""); //$NON-NLS-1$ } - - mdRs = null; - } - - if (mdStmt != null) { - try { - mdStmt.close(); - } catch (SQLException sqlEx) { - sqlExRethrow = sqlEx; + + boolean hadResults = mdStmt.execute(); + + if (hadResults) { + mdRs = mdStmt.getResultSet(); + + this.pstmtResultMetaData = mdRs.getMetaData(); + } else { + this.pstmtResultMetaData = new ResultSetMetaData(new Field[0], + connection.getUseOldAliasMetadataBehavior(), connection.getYearIsDateType(), + getExceptionInterceptor()); } - - mdStmt = null; + } finally { + SQLException sqlExRethrow = null; + + if (mdRs != null) { + try { + mdRs.close(); + } catch (SQLException sqlEx) { + sqlExRethrow = sqlEx; + } + + mdRs = null; + } + + if (mdStmt != null) { + try { + mdStmt.close(); + } catch (SQLException sqlEx) { + sqlExRethrow = sqlEx; + } + + mdStmt = null; + } + + if (sqlExRethrow != null) { + throw sqlExRethrow; + } } - - if (sqlExRethrow != null) { - throw sqlExRethrow; - } } + + return this.pstmtResultMetaData; } - - return this.pstmtResultMetaData; } - protected boolean isSelectQuery() { - return StringUtils.startsWithIgnoreCaseAndWs( - StringUtils.stripComments(this.originalSql, - "'\"", "'\"", true, false, true, true), - "SELECT"); + protected boolean isSelectQuery() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + return StringUtils.startsWithIgnoreCaseAndWs( + StringUtils.stripComments(this.originalSql, + "'\"", "'\"", true, false, true, true), + "SELECT"); + } } /** * @see PreparedStatement#getParameterMetaData() */ public ParameterMetaData getParameterMetaData() throws SQLException { - if (this.parameterMetaData == null) { - if (this.connection.getGenerateSimpleParameterMetadata()) { - this.parameterMetaData = new MysqlParameterMetadata(this.parameterCount); - } else { - this.parameterMetaData = new MysqlParameterMetadata( - null, this.parameterCount); + synchronized (checkClosed().getConnectionMutex()) { + if (this.parameterMetaData == null) { + if (this.connection.getGenerateSimpleParameterMetadata()) { + this.parameterMetaData = new MysqlParameterMetadata(this.parameterCount); + } else { + this.parameterMetaData = new MysqlParameterMetadata( + null, this.parameterCount, getExceptionInterceptor()); + } } + + return this.parameterMetaData; } - - return this.parameterMetaData; - } +} ParseInfo getParseInfo() { return this.parseInfo; @@ -2126,38 +2937,43 @@ } private void initializeFromParseInfo() throws SQLException { - this.staticSqlStrings = this.parseInfo.staticSql; - this.hasLimitClause = this.parseInfo.foundLimitClause; - this.isLoadDataQuery = this.parseInfo.foundLoadData; - this.firstCharOfStmt = this.parseInfo.firstStmtChar; - - this.parameterCount = this.staticSqlStrings.length - 1; - - this.parameterValues = new byte[this.parameterCount][]; - this.parameterStreams = new InputStream[this.parameterCount]; - this.isStream = new boolean[this.parameterCount]; - this.streamLengths = new int[this.parameterCount]; - this.isNull = new boolean[this.parameterCount]; - - clearParameters(); - - for (int j = 0; j < this.parameterCount; j++) { - this.isStream[j] = false; - } + synchronized (checkClosed().getConnectionMutex()) { + this.staticSqlStrings = this.parseInfo.staticSql; + this.isLoadDataQuery = this.parseInfo.foundLoadData; + this.firstCharOfStmt = this.parseInfo.firstStmtChar; + + this.parameterCount = this.staticSqlStrings.length - 1; + + this.parameterValues = new byte[this.parameterCount][]; + this.parameterStreams = new InputStream[this.parameterCount]; + this.isStream = new boolean[this.parameterCount]; + this.streamLengths = new int[this.parameterCount]; + this.isNull = new boolean[this.parameterCount]; + this.parameterTypes = new int[this.parameterCount]; - this.statementAfterCommentsPos = this.parseInfo.statementStartPos; + clearParameters(); + + for (int j = 0; j < this.parameterCount; j++) { + this.isStream[j] = false; + } + } } - boolean isNull(int paramIndex) { - return this.isNull[paramIndex]; + boolean isNull(int paramIndex) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + return this.isNull[paramIndex]; + } } private final int readblock(InputStream i, byte[] b) throws SQLException { try { return i.read(b); - } catch (Throwable E) { - throw SQLError.createSQLException(Messages.getString("PreparedStatement.56") //$NON-NLS-1$ - + E.getClass().getName(), SQLError.SQL_STATE_GENERAL_ERROR); + } catch (Throwable ex) { + SQLException sqlEx = SQLError.createSQLException(Messages.getString("PreparedStatement.56") //$NON-NLS-1$ + + ex.getClass().getName(), SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + sqlEx.initCause(ex); + + throw sqlEx; } } @@ -2171,9 +2987,12 @@ } return i.read(b, 0, lengthToRead); - } catch (Throwable E) { - throw SQLError.createSQLException(Messages.getString("PreparedStatement.55") //$NON-NLS-1$ - + E.getClass().getName(), SQLError.SQL_STATE_GENERAL_ERROR); + } catch (Throwable ex) { + SQLException sqlEx = SQLError.createSQLException(Messages.getString("PreparedStatement.56") //$NON-NLS-1$ + + ex.getClass().getName(), SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + sqlEx.initCause(ex); + + throw sqlEx; } } @@ -2188,30 +3007,42 @@ */ protected void realClose(boolean calledExplicitly, boolean closeOpenResults) throws SQLException { - if (this.useUsageAdvisor) { - if (this.numberOfExecutions <= 1) { - String message = Messages.getString("PreparedStatement.43"); //$NON-NLS-1$ + MySQLConnection locallyScopedConn = this.connection; - this.eventSink.consumeEvent(new ProfilerEvent( - ProfilerEvent.TYPE_WARN, "", this.currentCatalog, //$NON-NLS-1$ - this.connectionId, this.getId(), -1, System - .currentTimeMillis(), 0, Constants.MILLIS_I18N, - null, - this.pointOfOrigin, message)); + if (locallyScopedConn == null) return; // already closed + + synchronized (locallyScopedConn.getConnectionMutex()) { + + // additional check in case Statement was closed + // while current thread was waiting for lock + if (this.isClosed) return; + + if (this.useUsageAdvisor) { + if (this.numberOfExecutions <= 1) { + String message = Messages.getString("PreparedStatement.43"); //$NON-NLS-1$ + + this.eventSink.consumeEvent(new ProfilerEvent( + ProfilerEvent.TYPE_WARN, "", this.currentCatalog, //$NON-NLS-1$ + this.connectionId, this.getId(), -1, System + .currentTimeMillis(), 0, Constants.MILLIS_I18N, + null, + this.pointOfOrigin, message)); + } } + + super.realClose(calledExplicitly, closeOpenResults); + + this.dbmd = null; + this.originalSql = null; + this.staticSqlStrings = null; + this.parameterValues = null; + this.parameterStreams = null; + this.isStream = null; + this.streamLengths = null; + this.isNull = null; + this.streamConvertBuf = null; + this.parameterTypes = null; } - - super.realClose(calledExplicitly, closeOpenResults); - - this.dbmd = null; - this.originalSql = null; - this.staticSqlStrings = null; - this.parameterValues = null; - this.parameterStreams = null; - this.isStream = null; - this.streamLengths = null; - this.isNull = null; - this.streamConvertBuf = null; } /** @@ -2228,7 +3059,7 @@ * DOCUMENT ME! */ public void setArray(int i, Array x) throws SQLException { - throw new NotImplemented(); + throw SQLError.notImplemented(); } /** @@ -2281,6 +3112,8 @@ } else { setInternal(parameterIndex, StringUtils .fixDecimalExponent(StringUtils.consistentToString(x))); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.DECIMAL; } } @@ -2306,31 +3139,39 @@ */ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { - if (x == null) { - setNull(parameterIndex, java.sql.Types.BINARY); - } else { - int parameterIndexOffset = getParameterIndexOffset(); - - if ((parameterIndex < 1) - || (parameterIndex > this.staticSqlStrings.length)) { - throw SQLError.createSQLException( - Messages.getString("PreparedStatement.2") //$NON-NLS-1$ - + parameterIndex - + Messages.getString("PreparedStatement.3") + this.staticSqlStrings.length + Messages.getString("PreparedStatement.4"), //$NON-NLS-1$ //$NON-NLS-2$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } 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); + synchronized (checkClosed().getConnectionMutex()) { + if (x == null) { + setNull(parameterIndex, java.sql.Types.BINARY); + } else { + int parameterIndexOffset = getParameterIndexOffset(); + + if ((parameterIndex < 1) + || (parameterIndex > this.staticSqlStrings.length)) { + throw SQLError.createSQLException( + Messages.getString("PreparedStatement.2") //$NON-NLS-1$ + + parameterIndex + + Messages.getString("PreparedStatement.3") + this.staticSqlStrings.length + Messages.getString("PreparedStatement.4"), //$NON-NLS-1$ //$NON-NLS-2$ + 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()); + } + + + this.parameterStreams[parameterIndex - 1 + parameterIndexOffset] = x; + this.isStream[parameterIndex - 1 + parameterIndexOffset] = true; + this.streamLengths[parameterIndex - 1 + parameterIndexOffset] = length; + this.isNull[parameterIndex - 1 + parameterIndexOffset] = false; + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.BLOB; } - - - this.parameterStreams[parameterIndex - 1 + parameterIndexOffset] = x; - this.isStream[parameterIndex - 1 + parameterIndexOffset] = true; - this.streamLengths[parameterIndex - 1 + parameterIndexOffset] = length; - this.isNull[parameterIndex - 1 + parameterIndexOffset] = false; } } + public void setBlob(int parameterIndex, InputStream inputStream, long length) + throws SQLException { + setBinaryStream(parameterIndex, inputStream, (int)length); + } + /** * JDBC 2.0 Set a BLOB parameter. * @@ -2354,6 +3195,8 @@ bytesOut.write('\''); setInternal(i, bytesOut.toByteArray()); + + this.parameterTypes[i - 1 + getParameterIndexOffset()] = Types.BLOB; } } @@ -2374,6 +3217,8 @@ setInternal(parameterIndex, x ? "1" : "0"); //$NON-NLS-1$ //$NON-NLS-2$ } else { setInternal(parameterIndex, x ? "'t'" : "'f'"); //$NON-NLS-1$ //$NON-NLS-2$ + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.BOOLEAN; } } @@ -2391,6 +3236,8 @@ */ public void setByte(int parameterIndex, byte x) throws SQLException { setInternal(parameterIndex, String.valueOf(x)); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.TINYINT; } /** @@ -2408,124 +3255,138 @@ */ public void setBytes(int parameterIndex, byte[] x) throws SQLException { setBytes(parameterIndex, x, true, true); + + if (x != null) { + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.BINARY; + } } protected void setBytes(int parameterIndex, byte[] x, boolean checkForIntroducer, boolean escapeForMBChars) throws SQLException { - if (x == null) { - setNull(parameterIndex, java.sql.Types.BINARY); - } else { - String connectionEncoding = this.connection.getEncoding(); - - if (this.connection.isNoBackslashEscapesSet() - || (escapeForMBChars - && this.connection.getUseUnicode() - && connectionEncoding != null - && CharsetMapping.isMultibyteCharset(connectionEncoding))) { - - // Send as hex - - ByteArrayOutputStream bOut = new ByteArrayOutputStream( - (x.length * 2) + 3); - bOut.write('x'); + synchronized (checkClosed().getConnectionMutex()) { + if (x == null) { + setNull(parameterIndex, java.sql.Types.BINARY); + } else { + String connectionEncoding = this.connection.getEncoding(); + + try { + if (this.connection.isNoBackslashEscapesSet() + || (escapeForMBChars + && this.connection.getUseUnicode() + && connectionEncoding != null + && CharsetMapping.isMultibyteCharset(connectionEncoding))) { + + // Send as hex + + ByteArrayOutputStream bOut = new ByteArrayOutputStream( + (x.length * 2) + 3); + bOut.write('x'); + bOut.write('\''); + + for (int i = 0; i < x.length; i++) { + int lowBits = (x[i] & 0xff) / 16; + int highBits = (x[i] & 0xff) % 16; + + bOut.write(HEX_DIGITS[lowBits]); + bOut.write(HEX_DIGITS[highBits]); + } + + bOut.write('\''); + + setInternal(parameterIndex, bOut.toByteArray()); + + return; + } + } 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; + } + + // escape them + int numBytes = x.length; + + int pad = 2; + + boolean needsIntroducer = checkForIntroducer + && this.connection.versionMeetsMinimum(4, 1, 0); + + if (needsIntroducer) { + pad += 7; + } + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(numBytes + + pad); + + if (needsIntroducer) { + bOut.write('_'); + bOut.write('b'); + bOut.write('i'); + bOut.write('n'); + bOut.write('a'); + bOut.write('r'); + bOut.write('y'); + } bOut.write('\''); - - for (int i = 0; i < x.length; i++) { - int lowBits = (x[i] & 0xff) / 16; - int highBits = (x[i] & 0xff) % 16; - - bOut.write(HEX_DIGITS[lowBits]); - bOut.write(HEX_DIGITS[highBits]); + + for (int i = 0; i < numBytes; ++i) { + byte b = x[i]; + + switch (b) { + case 0: /* Must be escaped for 'mysql' */ + bOut.write('\\'); + bOut.write('0'); + + break; + + case '\n': /* Must be escaped for logs */ + bOut.write('\\'); + bOut.write('n'); + + break; + + case '\r': + bOut.write('\\'); + bOut.write('r'); + + break; + + case '\\': + bOut.write('\\'); + bOut.write('\\'); + + break; + + case '\'': + bOut.write('\\'); + bOut.write('\''); + + break; + + case '"': /* Better safe than sorry */ + bOut.write('\\'); + bOut.write('"'); + + break; + + case '\032': /* This gives problems on Win32 */ + bOut.write('\\'); + bOut.write('Z'); + + break; + + default: + bOut.write(b); + } } - + bOut.write('\''); - + setInternal(parameterIndex, bOut.toByteArray()); - - return; } - - // escape them - int numBytes = x.length; - - int pad = 2; - - boolean needsIntroducer = checkForIntroducer - && this.connection.versionMeetsMinimum(4, 1, 0); - - if (needsIntroducer) { - pad += 7; - } - - ByteArrayOutputStream bOut = new ByteArrayOutputStream(numBytes - + pad); - - if (needsIntroducer) { - bOut.write('_'); - bOut.write('b'); - bOut.write('i'); - bOut.write('n'); - bOut.write('a'); - bOut.write('r'); - bOut.write('y'); - } - bOut.write('\''); - - for (int i = 0; i < numBytes; ++i) { - byte b = x[i]; - - switch (b) { - case 0: /* Must be escaped for 'mysql' */ - bOut.write('\\'); - bOut.write('0'); - - break; - - case '\n': /* Must be escaped for logs */ - bOut.write('\\'); - bOut.write('n'); - - break; - - case '\r': - bOut.write('\\'); - bOut.write('r'); - - break; - - case '\\': - bOut.write('\\'); - bOut.write('\\'); - - break; - - case '\'': - bOut.write('\\'); - bOut.write('\''); - - break; - - case '"': /* Better safe than sorry */ - bOut.write('\\'); - bOut.write('"'); - - break; - - case '\032': /* This gives problems on Win32 */ - bOut.write('\\'); - bOut.write('Z'); - - break; - - default: - bOut.write(b); - } - } - - bOut.write('\''); - - setInternal(parameterIndex, bOut.toByteArray()); } } @@ -2581,63 +3442,67 @@ */ public void setCharacterStream(int parameterIndex, java.io.Reader reader, int length) throws SQLException { - try { - if (reader == null) { - setNull(parameterIndex, Types.LONGVARCHAR); - } else { - char[] c = null; - int len = 0; - - boolean useLength = this.connection - .getUseStreamLengthsInPrepStmts(); - - String forcedEncoding = this.connection.getClobCharacterEncoding(); - - if (useLength && (length != -1)) { - c = new char[length]; - - int numCharsRead = readFully(reader, c, length); // blocks - // until - // all - // read - - if (forcedEncoding == null) { - setString(parameterIndex, new String(c, 0, numCharsRead)); - } else { - try { - setBytes(parameterIndex, new String(c, - 0, - numCharsRead).getBytes(forcedEncoding)); - } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException("Unsupported character encoding " + - forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - } + synchronized (checkClosed().getConnectionMutex()) { + try { + if (reader == null) { + setNull(parameterIndex, Types.LONGVARCHAR); } else { - c = new char[4096]; - - StringBuffer buf = new StringBuffer(); - - while ((len = reader.read(c)) != -1) { - buf.append(c, 0, len); - } - - if (forcedEncoding == null) { - setString(parameterIndex, buf.toString()); + char[] c = null; + int len = 0; + + boolean useLength = this.connection + .getUseStreamLengthsInPrepStmts(); + + String forcedEncoding = this.connection.getClobCharacterEncoding(); + + if (useLength && (length != -1)) { + c = new char[length]; + + int numCharsRead = readFully(reader, c, length); // blocks + // until + // all + // read + + if (forcedEncoding == null) { + setString(parameterIndex, new String(c, 0, numCharsRead)); + } else { + try { + setBytes(parameterIndex, StringUtils.getBytes(new String(c, + 0, + numCharsRead), forcedEncoding)); + } catch (UnsupportedEncodingException uee) { + throw SQLError.createSQLException("Unsupported character encoding " + + forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + } } else { - try { - setBytes(parameterIndex, - buf.toString().getBytes(forcedEncoding)); - } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException("Unsupported character encoding " + - forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + c = new char[4096]; + + StringBuffer buf = new StringBuffer(); + + while ((len = reader.read(c)) != -1) { + buf.append(c, 0, len); } + + if (forcedEncoding == null) { + setString(parameterIndex, buf.toString()); + } else { + try { + setBytes(parameterIndex, + StringUtils.getBytes(buf.toString(), forcedEncoding)); + } catch (UnsupportedEncodingException uee) { + throw SQLError.createSQLException("Unsupported character encoding " + + forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + } } + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.CLOB; } + } catch (java.io.IOException ioEx) { + throw SQLError.createSQLException(ioEx.toString(), + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } - } catch (java.io.IOException ioEx) { - throw SQLError.createSQLException(ioEx.toString(), - SQLError.SQL_STATE_GENERAL_ERROR); } } @@ -2653,23 +3518,26 @@ * if a database error occurs */ public void setClob(int i, Clob x) throws SQLException { - if (x == null) { - setNull(i, Types.CLOB); - - return; - } - - String forcedEncoding = this.connection.getClobCharacterEncoding(); - - if (forcedEncoding == null) { - setString(i, x.getSubString(1L, (int) x.length())); - } else { - try { - setBytes(i, x.getSubString(1L, - (int)x.length()).getBytes(forcedEncoding)); - } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException("Unsupported character encoding " + - forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + synchronized (checkClosed().getConnectionMutex()) { + if (x == null) { + setNull(i, Types.CLOB); + } else { + + String forcedEncoding = this.connection.getClobCharacterEncoding(); + + if (forcedEncoding == null) { + setString(i, x.getSubString(1L, (int) x.length())); + } else { + try { + setBytes(i, StringUtils.getBytes(x.getSubString(1L, + (int)x.length()), forcedEncoding)); + } catch (UnsupportedEncodingException uee) { + throw SQLError.createSQLException("Unsupported character encoding " + + forcedEncoding, SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + } + + this.parameterTypes[i - 1 + getParameterIndexOffset()] = Types.CLOB; } } } @@ -2688,15 +3556,7 @@ */ public void setDate(int parameterIndex, java.sql.Date x) throws java.sql.SQLException { - if (x == null) { - setNull(parameterIndex, java.sql.Types.DATE); - } else { - // FIXME: Have instance version of this, problem as it's - // not thread-safe :( - SimpleDateFormat dateFormatter = new SimpleDateFormat( - "''yyyy-MM-dd''", Locale.US); //$NON-NLS-1$ - setInternal(parameterIndex, dateFormatter.format(x)); - } + setDate(parameterIndex, x, null); } /** @@ -2715,7 +3575,23 @@ */ public void setDate(int parameterIndex, java.sql.Date x, Calendar cal) throws SQLException { - setDate(parameterIndex, x); + if (x == null) { + setNull(parameterIndex, java.sql.Types.DATE); + } else { + checkClosed(); + + if (!this.useLegacyDatetimeCode) { + newSetDateInternal(parameterIndex, x, cal); + } else { + // FIXME: Have instance version of this, problem as it's + // not thread-safe :( + SimpleDateFormat dateFormatter = new SimpleDateFormat( + "''yyyy-MM-dd''", Locale.US); //$NON-NLS-1$ + setInternal(parameterIndex, dateFormatter.format(x)); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.DATE; + } + } } /** @@ -2731,18 +3607,21 @@ * if a database access error occurs */ public void setDouble(int parameterIndex, double x) throws SQLException { - - if (!this.connection.getAllowNanAndInf() - && (x == Double.POSITIVE_INFINITY - || x == Double.NEGATIVE_INFINITY || Double.isNaN(x))) { - throw SQLError.createSQLException("'" + x - + "' is not a valid numeric or approximate numeric value", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - + synchronized (checkClosed().getConnectionMutex()) { + if (!this.connection.getAllowNanAndInf() + && (x == Double.POSITIVE_INFINITY + || x == Double.NEGATIVE_INFINITY || Double.isNaN(x))) { + throw SQLError.createSQLException("'" + x + + "' is not a valid numeric or approximate numeric value", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + + } + + setInternal(parameterIndex, StringUtils.fixDecimalExponent(String + .valueOf(x))); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.DOUBLE; } - - setInternal(parameterIndex, StringUtils.fixDecimalExponent(String - .valueOf(x))); } /** @@ -2760,6 +3639,8 @@ public void setFloat(int parameterIndex, float x) throws SQLException { setInternal(parameterIndex, StringUtils.fixDecimalExponent(String .valueOf(x))); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.FLOAT; } /** @@ -2776,55 +3657,63 @@ */ public void setInt(int parameterIndex, int x) throws SQLException { setInternal(parameterIndex, String.valueOf(x)); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.INTEGER; } - private final void setInternal(int paramIndex, byte[] val) + protected final void setInternal(int paramIndex, byte[] val) throws SQLException { - if (this.isClosed) { - throw SQLError.createSQLException(Messages.getString("PreparedStatement.48"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + synchronized (checkClosed().getConnectionMutex()) { + + int parameterIndexOffset = getParameterIndexOffset(); + + checkBounds(paramIndex, parameterIndexOffset); + + this.isStream[paramIndex - 1 + parameterIndexOffset] = false; + this.isNull[paramIndex - 1 + parameterIndexOffset] = false; + this.parameterStreams[paramIndex - 1 + parameterIndexOffset] = null; + this.parameterValues[paramIndex - 1 + parameterIndexOffset] = val; } - - int parameterIndexOffset = getParameterIndexOffset(); - - if ((paramIndex < 1)) { - throw SQLError.createSQLException( - Messages.getString("PreparedStatement.49") //$NON-NLS-1$ - + paramIndex - + Messages.getString("PreparedStatement.50"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } else if (paramIndex > this.parameterCount) { - throw SQLError.createSQLException( - Messages.getString("PreparedStatement.51") //$NON-NLS-1$ - + paramIndex - + Messages.getString("PreparedStatement.52") + (this.parameterValues.length) + Messages.getString("PreparedStatement.53"), //$NON-NLS-1$ //$NON-NLS-2$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } 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); - } + } - this.isStream[paramIndex - 1 + parameterIndexOffset] = false; - this.isNull[paramIndex - 1 + parameterIndexOffset] = false; - this.parameterStreams[paramIndex - 1 + parameterIndexOffset] = null; - this.parameterValues[paramIndex - 1 + parameterIndexOffset] = val; + protected void checkBounds(int paramIndex, int parameterIndexOffset) + throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if ((paramIndex < 1)) { + throw SQLError.createSQLException( + Messages.getString("PreparedStatement.49") //$NON-NLS-1$ + + paramIndex + + Messages.getString("PreparedStatement.50"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); //$NON-NLS-1$ + } else if (paramIndex > this.parameterCount) { + throw SQLError.createSQLException( + Messages.getString("PreparedStatement.51") //$NON-NLS-1$ + + paramIndex + + Messages.getString("PreparedStatement.52") + (this.parameterValues.length) + Messages.getString("PreparedStatement.53"), //$NON-NLS-1$ //$NON-NLS-2$ + 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()); + } + } } - private final void setInternal(int paramIndex, String val) + protected final void setInternal(int paramIndex, String val) throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - byte[] parameterAsBytes = null; - - if (this.charConverter != null) { - parameterAsBytes = this.charConverter.toBytes(val); - } else { - parameterAsBytes = StringUtils.getBytes(val, this.charConverter, - this.charEncoding, this.connection - .getServerCharacterEncoding(), this.connection - .parserKnowsUnicode()); + byte[] parameterAsBytes = null; + + if (this.charConverter != null) { + parameterAsBytes = this.charConverter.toBytes(val); + } else { + parameterAsBytes = StringUtils.getBytes(val, this.charConverter, + this.charEncoding, this.connection + .getServerCharacterEncoding(), this.connection + .parserKnowsUnicode(), getExceptionInterceptor()); + } + + setInternal(paramIndex, parameterAsBytes); } - - setInternal(paramIndex, parameterAsBytes); } /** @@ -2841,6 +3730,8 @@ */ public void setLong(int parameterIndex, long x) throws SQLException { setInternal(parameterIndex, String.valueOf(x)); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.BIGINT; } /** @@ -2860,8 +3751,12 @@ * if a database access error occurs */ public void setNull(int parameterIndex, int sqlType) throws SQLException { - setInternal(parameterIndex, "null"); //$NON-NLS-1$ - this.isNull[parameterIndex - 1] = true; + synchronized (checkClosed().getConnectionMutex()) { + setInternal(parameterIndex, "null"); //$NON-NLS-1$ + this.isNull[parameterIndex - 1 + getParameterIndexOffset()] = true; + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.NULL; + } } /** @@ -2884,24 +3779,31 @@ public void setNull(int parameterIndex, int sqlType, String arg) throws SQLException { setNull(parameterIndex, sqlType); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.NULL; } private void setNumericObject(int parameterIndex, Object parameterObj, int targetSqlType, int scale) throws SQLException { Number parameterAsNum; if (parameterObj instanceof Boolean) { parameterAsNum = ((Boolean) parameterObj) - .booleanValue() ? new Integer(1) : new Integer( + .booleanValue() ? Integer.valueOf(1) : Integer.valueOf( 0); } else if (parameterObj instanceof String) { switch (targetSqlType) { case Types.BIT: - boolean parameterAsBoolean = "true" - .equalsIgnoreCase((String) parameterObj); + if ("1".equals(parameterObj) + || "0".equals(parameterObj)) { + parameterAsNum = Integer.valueOf((String) parameterObj); + } else { + boolean parameterAsBoolean = "true" + .equalsIgnoreCase((String) parameterObj); - parameterAsNum = parameterAsBoolean ? new Integer(1) - : new Integer(0); - + parameterAsNum = parameterAsBoolean ? Integer.valueOf(1) + : Integer.valueOf(0); + } + break; case Types.TINYINT: @@ -2986,7 +3888,7 @@ + scale + "' for DECIMAL argument '" + parameterAsNum + "'", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } @@ -3007,63 +3909,54 @@ } } - /** - * DOCUMENT ME! - * - * @param parameterIndex - * DOCUMENT ME! - * @param parameterObj - * DOCUMENT ME! - * - * @throws SQLException - * DOCUMENT ME! - */ public void setObject(int parameterIndex, Object parameterObj) throws SQLException { - if (parameterObj == null) { - setNull(parameterIndex, java.sql.Types.OTHER); - } else { - if (parameterObj instanceof Byte) { - setInt(parameterIndex, ((Byte) parameterObj).intValue()); - } else if (parameterObj instanceof String) { - setString(parameterIndex, (String) parameterObj); - } else if (parameterObj instanceof BigDecimal) { - setBigDecimal(parameterIndex, (BigDecimal) parameterObj); - } else if (parameterObj instanceof Short) { - setShort(parameterIndex, ((Short) parameterObj).shortValue()); - } else if (parameterObj instanceof Integer) { - setInt(parameterIndex, ((Integer) parameterObj).intValue()); - } else if (parameterObj instanceof Long) { - setLong(parameterIndex, ((Long) parameterObj).longValue()); - } else if (parameterObj instanceof Float) { - setFloat(parameterIndex, ((Float) parameterObj).floatValue()); - } else if (parameterObj instanceof Double) { - setDouble(parameterIndex, ((Double) parameterObj).doubleValue()); - } else if (parameterObj instanceof byte[]) { - setBytes(parameterIndex, (byte[]) parameterObj); - } else if (parameterObj instanceof java.sql.Date) { - setDate(parameterIndex, (java.sql.Date) parameterObj); - } else if (parameterObj instanceof Time) { - setTime(parameterIndex, (Time) parameterObj); - } else if (parameterObj instanceof Timestamp) { - setTimestamp(parameterIndex, (Timestamp) parameterObj); - } else if (parameterObj instanceof Boolean) { - setBoolean(parameterIndex, ((Boolean) parameterObj) - .booleanValue()); - } else if (parameterObj instanceof InputStream) { - setBinaryStream(parameterIndex, (InputStream) parameterObj, -1); - } else if (parameterObj instanceof java.sql.Blob) { - setBlob(parameterIndex, (java.sql.Blob) parameterObj); - } else if (parameterObj instanceof java.sql.Clob) { - setClob(parameterIndex, (java.sql.Clob) parameterObj); - } else if (this.connection.getTreatUtilDateAsTimestamp() && - parameterObj instanceof java.util.Date) { - setTimestamp(parameterIndex, new Timestamp( - ((java.util.Date) parameterObj).getTime())); - } else if (parameterObj instanceof BigInteger) { - setString(parameterIndex, parameterObj.toString()); + synchronized (checkClosed().getConnectionMutex()) { + if (parameterObj == null) { + setNull(parameterIndex, java.sql.Types.OTHER); } else { - setSerializableObject(parameterIndex, parameterObj); + if (parameterObj instanceof Byte) { + setInt(parameterIndex, ((Byte) parameterObj).intValue()); + } else if (parameterObj instanceof String) { + setString(parameterIndex, (String) parameterObj); + } else if (parameterObj instanceof BigDecimal) { + setBigDecimal(parameterIndex, (BigDecimal) parameterObj); + } else if (parameterObj instanceof Short) { + setShort(parameterIndex, ((Short) parameterObj).shortValue()); + } else if (parameterObj instanceof Integer) { + setInt(parameterIndex, ((Integer) parameterObj).intValue()); + } else if (parameterObj instanceof Long) { + setLong(parameterIndex, ((Long) parameterObj).longValue()); + } else if (parameterObj instanceof Float) { + setFloat(parameterIndex, ((Float) parameterObj).floatValue()); + } else if (parameterObj instanceof Double) { + setDouble(parameterIndex, ((Double) parameterObj).doubleValue()); + } else if (parameterObj instanceof byte[]) { + setBytes(parameterIndex, (byte[]) parameterObj); + } else if (parameterObj instanceof java.sql.Date) { + setDate(parameterIndex, (java.sql.Date) parameterObj); + } else if (parameterObj instanceof Time) { + setTime(parameterIndex, (Time) parameterObj); + } else if (parameterObj instanceof Timestamp) { + setTimestamp(parameterIndex, (Timestamp) parameterObj); + } else if (parameterObj instanceof Boolean) { + setBoolean(parameterIndex, ((Boolean) parameterObj) + .booleanValue()); + } else if (parameterObj instanceof InputStream) { + setBinaryStream(parameterIndex, (InputStream) parameterObj, -1); + } else if (parameterObj instanceof java.sql.Blob) { + setBlob(parameterIndex, (java.sql.Blob) parameterObj); + } else if (parameterObj instanceof java.sql.Clob) { + setClob(parameterIndex, (java.sql.Clob) parameterObj); + } else if (this.connection.getTreatUtilDateAsTimestamp() && + parameterObj instanceof java.util.Date) { + setTimestamp(parameterIndex, new Timestamp( + ((java.util.Date) parameterObj).getTime())); + } else if (parameterObj instanceof BigInteger) { + setString(parameterIndex, parameterObj.toString()); + } else { + setSerializableObject(parameterIndex, parameterObj); + } } } } @@ -3123,191 +4016,197 @@ */ public void setObject(int parameterIndex, Object parameterObj, int targetSqlType, int scale) throws SQLException { - if (parameterObj == null) { - setNull(parameterIndex, java.sql.Types.OTHER); - } else { - try { - switch (targetSqlType) { - case Types.BOOLEAN: - /* - From Table-B5 in the JDBC-3.0 Spec - - T S I B R F D D N B B C V L - I M N I E L O E U I O H A O - N A T G A O U C M T O A R N - Y L E I L A B I E L R C G - I L G N T L M R E H V - N I E T E A I A A A - T N R L C N R R - T C - H - A - R - ----------------------------------- - Boolean x x x x x x x x x x x x x x - */ + synchronized (checkClosed().getConnectionMutex()) { + if (parameterObj == null) { + setNull(parameterIndex, java.sql.Types.OTHER); + } else { + try { + switch (targetSqlType) { + case Types.BOOLEAN: + /* + From Table-B5 in the JDBC-3.0 Spec - if (parameterObj instanceof Boolean) { - setBoolean(parameterIndex, ((Boolean)parameterObj).booleanValue()); + T S I B R F D D N B B C V L + I M N I E L O E U I O H A O + N A T G A O U C M T O A R N + Y L E I L A B I E L R C G + I L G N T L M R E H V + N I E T E A I A A A + T N R L C N R R + T C + H + A + R + ----------------------------------- + Boolean x x x x x x x x x x x x x x + */ - break; - } else if (parameterObj instanceof String) { - setBoolean(parameterIndex, "true".equalsIgnoreCase((String)parameterObj) || - !"0".equalsIgnoreCase((String)parameterObj)); + if (parameterObj instanceof Boolean) { + setBoolean(parameterIndex, ((Boolean)parameterObj).booleanValue()); + + break; + } else if (parameterObj instanceof String) { + setBoolean(parameterIndex, "true".equalsIgnoreCase((String)parameterObj) || + !"0".equalsIgnoreCase((String)parameterObj)); + + break; + } else if (parameterObj instanceof Number) { + int intValue = ((Number)parameterObj).intValue(); + + setBoolean(parameterIndex, intValue != 0); + + break; + } else { + throw SQLError.createSQLException("No conversion from " + parameterObj.getClass().getName() + + " to Types.BOOLEAN possible.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } - break; - } else if (parameterObj instanceof Number) { - int intValue = ((Number)parameterObj).intValue(); - setBoolean(parameterIndex, intValue != 0); - + case Types.BIT: + case Types.TINYINT: + case Types.SMALLINT: + case Types.INTEGER: + case Types.BIGINT: + case Types.REAL: + case Types.FLOAT: + case Types.DOUBLE: + case Types.DECIMAL: + case Types.NUMERIC: + + setNumericObject(parameterIndex, parameterObj, targetSqlType, scale); + break; - } else { - throw SQLError.createSQLException("No conversion from " + parameterObj.getClass().getName() + - " to Types.BOOLEAN possible.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - - case Types.BIT: - case Types.TINYINT: - case Types.SMALLINT: - case Types.INTEGER: - case Types.BIGINT: - case Types.REAL: - case Types.FLOAT: - case Types.DOUBLE: - case Types.DECIMAL: - case Types.NUMERIC: - - setNumericObject(parameterIndex, parameterObj, targetSqlType, scale); - - break; - - case Types.CHAR: - case Types.VARCHAR: - case Types.LONGVARCHAR: - if (parameterObj instanceof BigDecimal) { - setString( - parameterIndex, - (StringUtils - .fixDecimalExponent(StringUtils - .consistentToString((BigDecimal) parameterObj)))); - } else { - setString(parameterIndex, parameterObj.toString()); - } - - break; - - case Types.CLOB: - - if (parameterObj instanceof java.sql.Clob) { - setClob(parameterIndex, (java.sql.Clob) parameterObj); - } else { - setString(parameterIndex, parameterObj.toString()); - } - - break; - - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - case Types.BLOB: - - if (parameterObj instanceof byte[]) { - setBytes(parameterIndex, (byte[]) parameterObj); - } else if (parameterObj instanceof java.sql.Blob) { - setBlob(parameterIndex, (java.sql.Blob) parameterObj); - } else { - setBytes(parameterIndex, StringUtils.getBytes( - parameterObj.toString(), this.charConverter, - this.charEncoding, this.connection - .getServerCharacterEncoding(), - this.connection.parserKnowsUnicode())); - } - - break; - - case Types.DATE: - case Types.TIMESTAMP: - - java.util.Date parameterAsDate; - - if (parameterObj instanceof String) { - ParsePosition pp = new ParsePosition(0); - java.text.DateFormat sdf = new java.text.SimpleDateFormat( - getDateTimePattern((String) parameterObj, false), Locale.US); - parameterAsDate = sdf.parse((String) parameterObj, pp); - } else { - parameterAsDate = (java.util.Date) parameterObj; - } - - switch (targetSqlType) { - case Types.DATE: - - if (parameterAsDate instanceof java.sql.Date) { - setDate(parameterIndex, - (java.sql.Date) parameterAsDate); + + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + if (parameterObj instanceof BigDecimal) { + setString( + parameterIndex, + (StringUtils + .fixDecimalExponent(StringUtils + .consistentToString((BigDecimal) parameterObj)))); } else { - setDate(parameterIndex, new java.sql.Date( - parameterAsDate.getTime())); + setString(parameterIndex, parameterObj.toString()); } - + break; - + + case Types.CLOB: + + if (parameterObj instanceof java.sql.Clob) { + setClob(parameterIndex, (java.sql.Clob) parameterObj); + } else { + setString(parameterIndex, parameterObj.toString()); + } + + break; + + case Types.BINARY: + case Types.VARBINARY: + case Types.LONGVARBINARY: + case Types.BLOB: + + if (parameterObj instanceof byte[]) { + setBytes(parameterIndex, (byte[]) parameterObj); + } else if (parameterObj instanceof java.sql.Blob) { + setBlob(parameterIndex, (java.sql.Blob) parameterObj); + } else { + setBytes(parameterIndex, StringUtils.getBytes( + parameterObj.toString(), this.charConverter, + this.charEncoding, this.connection + .getServerCharacterEncoding(), + this.connection.parserKnowsUnicode(), getExceptionInterceptor())); + } + + break; + + case Types.DATE: case Types.TIMESTAMP: - - if (parameterAsDate instanceof java.sql.Timestamp) { - setTimestamp(parameterIndex, - (java.sql.Timestamp) parameterAsDate); + + java.util.Date parameterAsDate; + + if (parameterObj instanceof String) { + ParsePosition pp = new ParsePosition(0); + java.text.DateFormat sdf = new java.text.SimpleDateFormat( + getDateTimePattern((String) parameterObj, false), Locale.US); + parameterAsDate = sdf.parse((String) parameterObj, pp); } else { - setTimestamp(parameterIndex, - new java.sql.Timestamp(parameterAsDate - .getTime())); + parameterAsDate = (java.util.Date) parameterObj; } - + + switch (targetSqlType) { + case Types.DATE: + + if (parameterAsDate instanceof java.sql.Date) { + setDate(parameterIndex, + (java.sql.Date) parameterAsDate); + } else { + setDate(parameterIndex, new java.sql.Date( + parameterAsDate.getTime())); + } + + break; + + case Types.TIMESTAMP: + + if (parameterAsDate instanceof java.sql.Timestamp) { + setTimestamp(parameterIndex, + (java.sql.Timestamp) parameterAsDate); + } else { + setTimestamp(parameterIndex, + new java.sql.Timestamp(parameterAsDate + .getTime())); + } + + break; + } + break; + + case Types.TIME: + + if (parameterObj instanceof String) { + java.text.DateFormat sdf = new java.text.SimpleDateFormat( + getDateTimePattern((String) parameterObj, true), Locale.US); + setTime(parameterIndex, new java.sql.Time(sdf.parse( + (String) parameterObj).getTime())); + } else if (parameterObj instanceof Timestamp) { + Timestamp xT = (Timestamp) parameterObj; + setTime(parameterIndex, new java.sql.Time(xT.getTime())); + } else { + setTime(parameterIndex, (java.sql.Time) parameterObj); + } + + break; + + case Types.OTHER: + setSerializableObject(parameterIndex, parameterObj); + + break; + + default: + throw SQLError.createSQLException(Messages + .getString("PreparedStatement.16"), //$NON-NLS-1$ + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } - - break; - - case Types.TIME: - - if (parameterObj instanceof String) { - java.text.DateFormat sdf = new java.text.SimpleDateFormat( - getDateTimePattern((String) parameterObj, true), Locale.US); - setTime(parameterIndex, new java.sql.Time(sdf.parse( - (String) parameterObj).getTime())); - } else if (parameterObj instanceof Timestamp) { - Timestamp xT = (Timestamp) parameterObj; - setTime(parameterIndex, new java.sql.Time(xT.getTime())); - } else { - setTime(parameterIndex, (java.sql.Time) parameterObj); + } catch (Exception ex) { + if (ex instanceof SQLException) { + throw (SQLException) ex; } - - break; - - case Types.OTHER: - setSerializableObject(parameterIndex, parameterObj); - - break; - - default: - throw SQLError.createSQLException(Messages - .getString("PreparedStatement.16"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); + + SQLException sqlEx = SQLError.createSQLException( + Messages.getString("PreparedStatement.17") //$NON-NLS-1$ + + parameterObj.getClass().toString() + + Messages.getString("PreparedStatement.18") //$NON-NLS-1$ + + ex.getClass().getName() + + Messages.getString("PreparedStatement.19") + ex.getMessage(), //$NON-NLS-1$ + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + + sqlEx.initCause(ex); + + throw sqlEx; } - } catch (Exception ex) { - if (ex instanceof SQLException) { - throw (SQLException) ex; - } - - throw SQLError.createSQLException( - Messages.getString("PreparedStatement.17") //$NON-NLS-1$ - + parameterObj.getClass().toString() - + Messages.getString("PreparedStatement.18") //$NON-NLS-1$ - + ex.getClass().getName() - + Messages.getString("PreparedStatement.19") + ex.getMessage(), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); } } } @@ -3338,7 +4237,7 @@ return batchedParamIndex; } - + /** * JDBC 2.0 Set a REF(<structured-type>) parameter. * @@ -3353,39 +4252,11 @@ * DOCUMENT ME! */ public void setRef(int i, Ref x) throws SQLException { - throw new NotImplemented(); + throw SQLError.notImplemented(); } - /** - * Sets the concurrency for result sets generated by this statement - * - * @param concurrencyFlag - * DOCUMENT ME! - */ - void setResultSetConcurrency(int concurrencyFlag) { - this.resultSetConcurrency = concurrencyFlag; - } /** - * Sets the result set type for result sets generated by this statement - * - * @param typeFlag - * DOCUMENT ME! - */ - void setResultSetType(int typeFlag) { - this.resultSetType = typeFlag; - } - - /** - * DOCUMENT ME! - * - * @param retrieveGeneratedKeys - */ - protected void setRetrieveGeneratedKeys(boolean retrieveGeneratedKeys) { - this.retrieveGeneratedKeys = retrieveGeneratedKeys; - } - - /** * Sets the value for the placeholder as a serialized Java object (used by * various forms of setObject() * @@ -3411,10 +4282,14 @@ byte[] buf = bytesOut.toByteArray(); ByteArrayInputStream bytesIn = new ByteArrayInputStream(buf); setBinaryStream(parameterIndex, bytesIn, buf.length); + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.BINARY; } catch (Exception ex) { - throw SQLError.createSQLException(Messages.getString("PreparedStatement.54") //$NON-NLS-1$ + SQLException sqlEx = SQLError.createSQLException(Messages.getString("PreparedStatement.54") //$NON-NLS-1$ + ex.getClass().getName(), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + sqlEx.initCause(ex); + + throw sqlEx; } } @@ -3432,6 +4307,8 @@ */ public void setShort(int parameterIndex, short x) throws SQLException { setInternal(parameterIndex, String.valueOf(x)); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.SMALLINT; } /** @@ -3448,184 +4325,222 @@ * if a database access error occurs */ public void setString(int parameterIndex, String x) throws SQLException { - // if the passed string is null, then set this column to null - if (x == null) { - setNull(parameterIndex, Types.CHAR); - } else { - checkClosed(); - - int stringLength = x.length(); - - if (this.connection.isNoBackslashEscapesSet()) { - // Scan for any nasty chars - - boolean needsHexEscape = false; - - for (int i = 0; i < stringLength; ++i) { - char c = x.charAt(i); - - switch (c) { - case 0: /* Must be escaped for 'mysql' */ - - needsHexEscape = true; - break; - - case '\n': /* Must be escaped for logs */ - needsHexEscape = true; - - break; - - case '\r': - needsHexEscape = true; - break; - - case '\\': - needsHexEscape = true; - - break; - - case '\'': - needsHexEscape = true; - - break; - - case '"': /* Better safe than sorry */ - needsHexEscape = true; - - break; - - case '\032': /* This gives problems on Win32 */ - needsHexEscape = true; - break; + synchronized (checkClosed().getConnectionMutex()) { + // if the passed string is null, then set this column to null + if (x == null) { + setNull(parameterIndex, Types.CHAR); + } else { + checkClosed(); + + int stringLength = x.length(); + + if (this.connection.isNoBackslashEscapesSet()) { + // Scan for any nasty chars + + boolean needsHexEscape = isEscapeNeededForString(x, + stringLength); + + if (!needsHexEscape) { + byte[] parameterAsBytes = null; + + StringBuffer quotedString = new StringBuffer(x.length() + 2); + quotedString.append('\''); + quotedString.append(x); + quotedString.append('\''); + + if (!this.isLoadDataQuery) { + parameterAsBytes = StringUtils.getBytes(quotedString.toString(), + this.charConverter, this.charEncoding, + this.connection.getServerCharacterEncoding(), + this.connection.parserKnowsUnicode(), getExceptionInterceptor()); + } else { + // Send with platform character encoding + parameterAsBytes = StringUtils.getBytes(quotedString.toString()); + } + + setInternal(parameterIndex, parameterAsBytes); + } else { + byte[] parameterAsBytes = null; + + if (!this.isLoadDataQuery) { + parameterAsBytes = StringUtils.getBytes(x, + this.charConverter, this.charEncoding, + this.connection.getServerCharacterEncoding(), + this.connection.parserKnowsUnicode(), getExceptionInterceptor()); + } else { + // Send with platform character encoding + parameterAsBytes = StringUtils.getBytes(x); + } + + setBytes(parameterIndex, parameterAsBytes); } - - if (needsHexEscape) { - break; // no need to scan more - } + + return; } - + + String parameterAsString = x; + boolean needsQuoted = true; - - if (!needsHexEscape) { - byte[] parameterAsBytes = null; - - StringBuffer quotedString = new StringBuffer(x.length() + 2); - quotedString.append('\''); - quotedString.append(x); - quotedString.append('\''); + if (this.isLoadDataQuery || isEscapeNeededForString(x, stringLength)) { + needsQuoted = false; // saves an allocation later - if (!this.isLoadDataQuery) { - parameterAsBytes = StringUtils.getBytes(quotedString.toString(), - this.charConverter, this.charEncoding, - this.connection.getServerCharacterEncoding(), - this.connection.parserKnowsUnicode()); - } else { - // Send with platform character encoding - parameterAsBytes = quotedString.toString().getBytes(); - } + StringBuffer buf = new StringBuffer((int) (x.length() * 1.1)); - setInternal(parameterIndex, parameterAsBytes); - } else { - byte[] parameterAsBytes = null; - - if (!this.isLoadDataQuery) { - parameterAsBytes = StringUtils.getBytes(x, - this.charConverter, this.charEncoding, - this.connection.getServerCharacterEncoding(), - this.connection.parserKnowsUnicode()); + buf.append('\''); + + // + // Note: buf.append(char) is _faster_ than + // appending in blocks, because the block + // append requires a System.arraycopy().... + // go figure... + // + + for (int i = 0; i < stringLength; ++i) { + char c = x.charAt(i); + + switch (c) { + case 0: /* Must be escaped for 'mysql' */ + buf.append('\\'); + buf.append('0'); + + break; + + case '\n': /* Must be escaped for logs */ + buf.append('\\'); + buf.append('n'); + + break; + + case '\r': + buf.append('\\'); + buf.append('r'); + + break; + + case '\\': + buf.append('\\'); + buf.append('\\'); + + break; + + case '\'': + buf.append('\\'); + buf.append('\''); + + break; + + case '"': /* Better safe than sorry */ + if (this.usingAnsiMode) { + buf.append('\\'); + } + + buf.append('"'); + + break; + + case '\032': /* This gives problems on Win32 */ + buf.append('\\'); + buf.append('Z'); + + break; + + case '\u00a5': + case '\u20a9': + // escape characters interpreted as backslash by mysql + if(charsetEncoder != null) { + CharBuffer cbuf = CharBuffer.allocate(1); + ByteBuffer bbuf = ByteBuffer.allocate(1); + cbuf.put(c); + cbuf.position(0); + charsetEncoder.encode(cbuf, bbuf, true); + if(bbuf.get(0) == '\\') { + buf.append('\\'); + } + } + // fall through + + default: + buf.append(c); + } + } + + buf.append('\''); + + parameterAsString = buf.toString(); + } + + byte[] parameterAsBytes = null; + + if (!this.isLoadDataQuery) { + if (needsQuoted) { + parameterAsBytes = StringUtils.getBytesWrapped(parameterAsString, + '\'', '\'', this.charConverter, this.charEncoding, this.connection + .getServerCharacterEncoding(), this.connection + .parserKnowsUnicode(), getExceptionInterceptor()); } else { - // Send with platform character encoding - parameterAsBytes = x.getBytes(); + parameterAsBytes = StringUtils.getBytes(parameterAsString, + this.charConverter, this.charEncoding, this.connection + .getServerCharacterEncoding(), this.connection + .parserKnowsUnicode(), getExceptionInterceptor()); } - - setBytes(parameterIndex, parameterAsBytes); + } else { + // Send with platform character encoding + parameterAsBytes = StringUtils.getBytes(parameterAsString); } - - return; + + setInternal(parameterIndex, parameterAsBytes); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.VARCHAR; } + } + } - StringBuffer buf = new StringBuffer((int) (x.length() * 1.1)); - buf.append('\''); + private boolean isEscapeNeededForString(String x, int stringLength) { + boolean needsHexEscape = false; - // - // Note: buf.append(char) is _faster_ than - // appending in blocks, because the block - // append requires a System.arraycopy().... - // go figure... - // + for (int i = 0; i < stringLength; ++i) { + char c = x.charAt(i); - for (int i = 0; i < stringLength; ++i) { - char c = x.charAt(i); + switch (c) { + case 0: /* Must be escaped for 'mysql' */ - switch (c) { - case 0: /* Must be escaped for 'mysql' */ - buf.append('\\'); - buf.append('0'); + needsHexEscape = true; + break; - break; + case '\n': /* Must be escaped for logs */ + needsHexEscape = true; - case '\n': /* Must be escaped for logs */ - buf.append('\\'); - buf.append('n'); + break; - break; + case '\r': + needsHexEscape = true; + break; - case '\r': - buf.append('\\'); - buf.append('r'); + case '\\': + needsHexEscape = true; - break; + break; - case '\\': - buf.append('\\'); - buf.append('\\'); + case '\'': + needsHexEscape = true; - break; + break; - case '\'': - buf.append('\\'); - buf.append('\''); + case '"': /* Better safe than sorry */ + needsHexEscape = true; - break; + break; - case '"': /* Better safe than sorry */ - if (this.usingAnsiMode) { - buf.append('\\'); - } - - buf.append('"'); - - break; - - case '\032': /* This gives problems on Win32 */ - buf.append('\\'); - buf.append('Z'); - - break; - - default: - buf.append(c); - } + case '\032': /* This gives problems on Win32 */ + needsHexEscape = true; + break; } - buf.append('\''); - - String parameterAsString = buf.toString(); - - byte[] parameterAsBytes = null; - - if (!this.isLoadDataQuery) { - parameterAsBytes = StringUtils.getBytes(parameterAsString, - this.charConverter, this.charEncoding, this.connection - .getServerCharacterEncoding(), this.connection - .parserKnowsUnicode()); - } else { - // Send with platform character encoding - parameterAsBytes = parameterAsString.getBytes(); + if (needsHexEscape) { + break; // no need to scan more } - - setInternal(parameterIndex, parameterAsBytes); } + return needsHexEscape; } /** @@ -3661,7 +4576,7 @@ */ public void setTime(int parameterIndex, Time x) throws java.sql.SQLException { - setTimeInternal(parameterIndex, x, null, this.connection.getDefaultTimeZone(), false); + setTimeInternal(parameterIndex, x, null, Util.getDefaultTimeZone(), false); } /** @@ -3682,22 +4597,30 @@ private void setTimeInternal(int parameterIndex, Time x, Calendar targetCalendar, TimeZone tz, boolean rollForward) throws java.sql.SQLException { - if (x == null) { - setNull(parameterIndex, java.sql.Types.TIME); - } else { - checkClosed(); - - Calendar sessionCalendar = getCalendarInstanceForSessionOrNew(); - - synchronized (sessionCalendar) { - x = TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - x, tz, this.connection - .getServerTimezoneTZ(), rollForward); + synchronized (checkClosed().getConnectionMutex()) { + if (x == null) { + setNull(parameterIndex, java.sql.Types.TIME); + } else { + checkClosed(); + + if (!this.useLegacyDatetimeCode) { + newSetTimeInternal(parameterIndex, x, targetCalendar); + } else { + Calendar sessionCalendar = getCalendarInstanceForSessionOrNew(); + + synchronized (sessionCalendar) { + x = TimeUtil.changeTimezone(this.connection, + sessionCalendar, + targetCalendar, + x, tz, this.connection + .getServerTimezoneTZ(), rollForward); + } + + setInternal(parameterIndex, "'" + x.toString() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.TIME; } - - setInternal(parameterIndex, "'" + x.toString() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ } } @@ -3734,7 +4657,7 @@ */ public void setTimestamp(int parameterIndex, Timestamp x) throws java.sql.SQLException { - setTimestampInternal(parameterIndex, x, null, this.connection.getDefaultTimeZone(), false); + setTimestampInternal(parameterIndex, x, null, Util.getDefaultTimeZone(), false); } /** @@ -3754,113 +4677,211 @@ private void setTimestampInternal(int parameterIndex, Timestamp x, Calendar targetCalendar, TimeZone tz, boolean rollForward) throws SQLException { - if (x == null) { - setNull(parameterIndex, java.sql.Types.TIMESTAMP); - } else { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { + if (x == null) { + setNull(parameterIndex, java.sql.Types.TIMESTAMP); + } else { + checkClosed(); + + if (!this.useLegacyDatetimeCode) { + newSetTimestampInternal(parameterIndex, x, targetCalendar); + } else { + Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ? + this.connection.getUtcCalendar() : + getCalendarInstanceForSessionOrNew(); + + synchronized (sessionCalendar) { + x = TimeUtil.changeTimezone(this.connection, + sessionCalendar, + targetCalendar, + x, tz, this.connection + .getServerTimezoneTZ(), rollForward); + } + + if (this.connection.getUseSSPSCompatibleTimezoneShift()) { + doSSPSCompatibleTimezoneShift(parameterIndex, x, sessionCalendar); + } else { + synchronized (this) { + if (this.tsdf == null) { + this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US); //$NON-NLS-1$ + } + + StringBuffer buf = new StringBuffer(); + buf.append(this.tsdf.format(x)); + + if (this.serverSupportsFracSecs) { + int nanos = x.getNanos(); + + if (nanos != 0) { + buf.append('.'); + buf.append(TimeUtil.formatNanos(nanos, this.serverSupportsFracSecs, true)); + } + } + + buf.append('\''); + + setInternal(parameterIndex, buf.toString()); // SimpleDateFormat is not + // thread-safe + } + } + } + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.TIMESTAMP; + } + } + } + + private void newSetTimestampInternal(int parameterIndex, + Timestamp x, Calendar targetCalendar) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (this.tsdf == null) { + this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US); //$NON-NLS-1$ + } String timestampString = null; - Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ? - this.connection.getUtcCalendar() : - getCalendarInstanceForSessionOrNew(); - - synchronized (sessionCalendar) { - x = TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - x, tz, this.connection - .getServerTimezoneTZ(), rollForward); + if (targetCalendar != null) { + targetCalendar.setTime(x); + this.tsdf.setTimeZone(targetCalendar.getTimeZone()); + + timestampString = this.tsdf.format(x); + } else { + this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ()); + timestampString = this.tsdf.format(x); } - + + StringBuffer buf = new StringBuffer(); + buf.append(timestampString); + buf.append('.'); + buf.append(TimeUtil.formatNanos(x.getNanos(), this.serverSupportsFracSecs, true)); + buf.append('\''); - if (this.connection.getUseSSPSCompatibleTimezoneShift()) { - doSSPSCompatibleTimezoneShift(parameterIndex, x, sessionCalendar); - } else { + setInternal(parameterIndex, buf.toString()); + } + } + + private void newSetTimeInternal(int parameterIndex, + Time x, Calendar targetCalendar) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (this.tdf == null) { + this.tdf = new SimpleDateFormat("''HH:mm:ss''", Locale.US); //$NON-NLS-1$ - if (this.tsdf == null) { - this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss''", Locale.US); //$NON-NLS-1$ - } + } + + String timeString = null; + + if (targetCalendar != null) { + targetCalendar.setTime(x); + this.tdf.setTimeZone(targetCalendar.getTimeZone()); - timestampString = this.tsdf.format(x); - - setInternal(parameterIndex, timestampString); // SimpleDateFormat is not - // thread-safe + timeString = this.tdf.format(x); + } else { + this.tdf.setTimeZone(this.connection.getServerTimezoneTZ()); + timeString = this.tdf.format(x); } + + setInternal(parameterIndex, timeString); } } + + private void newSetDateInternal(int parameterIndex, + Date x, Calendar targetCalendar) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (this.ddf == null) { + this.ddf = new SimpleDateFormat("''yyyy-MM-dd''", Locale.US); //$NON-NLS-1$ + } + + String timeString = null; + + if (targetCalendar != null) { + targetCalendar.setTime(x); + this.ddf.setTimeZone(targetCalendar.getTimeZone()); + + timeString = this.ddf.format(x); + } else { + this.ddf.setTimeZone(this.connection.getServerTimezoneTZ()); + timeString = this.ddf.format(x); + } + + setInternal(parameterIndex, timeString); + } + } private void doSSPSCompatibleTimezoneShift(int parameterIndex, Timestamp x, Calendar sessionCalendar) throws SQLException { - Calendar sessionCalendar2 = (this.connection - .getUseJDBCCompliantTimezoneShift()) ? this.connection - .getUtcCalendar() - : getCalendarInstanceForSessionOrNew(); - - synchronized (sessionCalendar2) { - java.util.Date oldTime = sessionCalendar2.getTime(); - - try { - sessionCalendar2.setTime(x); - - int year = sessionCalendar2.get(Calendar.YEAR); - int month = sessionCalendar2.get(Calendar.MONTH) + 1; - int date = sessionCalendar2.get(Calendar.DAY_OF_MONTH); - - int hour = sessionCalendar2.get(Calendar.HOUR_OF_DAY); - int minute = sessionCalendar2.get(Calendar.MINUTE); - int seconds = sessionCalendar2.get(Calendar.SECOND); - - StringBuffer tsBuf = new StringBuffer(); - - tsBuf.append('\''); - tsBuf.append(year); - - tsBuf.append("-"); - - if (month < 10) { - tsBuf.append('0'); + synchronized (checkClosed().getConnectionMutex()) { + Calendar sessionCalendar2 = (this.connection + .getUseJDBCCompliantTimezoneShift()) ? this.connection + .getUtcCalendar() + : getCalendarInstanceForSessionOrNew(); + + synchronized (sessionCalendar2) { + java.util.Date oldTime = sessionCalendar2.getTime(); + + try { + sessionCalendar2.setTime(x); + + int year = sessionCalendar2.get(Calendar.YEAR); + int month = sessionCalendar2.get(Calendar.MONTH) + 1; + int date = sessionCalendar2.get(Calendar.DAY_OF_MONTH); + + int hour = sessionCalendar2.get(Calendar.HOUR_OF_DAY); + int minute = sessionCalendar2.get(Calendar.MINUTE); + int seconds = sessionCalendar2.get(Calendar.SECOND); + + StringBuffer tsBuf = new StringBuffer(); + + tsBuf.append('\''); + tsBuf.append(year); + + tsBuf.append("-"); + + if (month < 10) { + tsBuf.append('0'); + } + + tsBuf.append(month); + + tsBuf.append('-'); + + if (date < 10) { + tsBuf.append('0'); + } + + tsBuf.append(date); + + tsBuf.append(' '); + + if (hour < 10) { + tsBuf.append('0'); + } + + tsBuf.append(hour); + + tsBuf.append(':'); + + if (minute < 10) { + tsBuf.append('0'); + } + + tsBuf.append(minute); + + tsBuf.append(':'); + + if (seconds < 10) { + tsBuf.append('0'); + } + + tsBuf.append(seconds); + + tsBuf.append('.'); + tsBuf.append(TimeUtil.formatNanos(x.getNanos(), this.serverSupportsFracSecs, true)); + tsBuf.append('\''); + + setInternal(parameterIndex, tsBuf.toString()); + + } finally { + sessionCalendar.setTime(oldTime); } - - tsBuf.append(month); - - tsBuf.append('-'); - - if (date < 10) { - tsBuf.append('0'); - } - - tsBuf.append(date); - - tsBuf.append(' '); - - if (hour < 10) { - tsBuf.append('0'); - } - - tsBuf.append(hour); - - tsBuf.append(':'); - - if (minute < 10) { - tsBuf.append('0'); - } - - tsBuf.append(minute); - - tsBuf.append(':'); - - if (seconds < 10) { - tsBuf.append('0'); - } - - tsBuf.append(seconds); - - tsBuf.append('\''); - - setInternal(parameterIndex, tsBuf.toString()); - - } finally { - sessionCalendar.setTime(oldTime); } } } @@ -3895,6 +4916,8 @@ setNull(parameterIndex, java.sql.Types.VARCHAR); } else { setBinaryStream(parameterIndex, x, length); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.CLOB; } } @@ -3904,6 +4927,8 @@ public void setURL(int parameterIndex, URL arg) throws SQLException { if (arg != null) { setString(parameterIndex, arg.toString()); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.DATALINK; } else { setNull(parameterIndex, Types.CHAR); } @@ -3912,148 +4937,165 @@ private final void streamToBytes(Buffer packet, InputStream in, boolean escape, int streamLength, boolean useLength) throws SQLException { - try { - String connectionEncoding = this.connection.getEncoding(); - - boolean hexEscape = false; - - if (this.connection.isNoBackslashEscapesSet() - || (this.connection.getUseUnicode() - && connectionEncoding != null - && CharsetMapping.isMultibyteCharset(connectionEncoding) - && !this.connection.parserKnowsUnicode())) { - hexEscape = true; - } - - if (streamLength == -1) { - useLength = false; - } - - int bc = -1; - - if (useLength) { - bc = readblock(in, streamConvertBuf, streamLength); - } else { - bc = readblock(in, streamConvertBuf); - } - - int lengthLeftToRead = streamLength - bc; - - if (hexEscape) { - packet.writeStringNoNull("x"); - } else if (this.connection.getIO().versionMeetsMinimum(4, 1, 0)) { - packet.writeStringNoNull("_binary"); - } - - if (escape) { - packet.writeByte((byte) '\''); - } - - while (bc > 0) { - if (hexEscape) { - hexEscapeBlock(streamConvertBuf, packet, bc); - } else if (escape) { - escapeblockFast(streamConvertBuf, packet, bc); - } else { - packet.writeBytesNoNull(streamConvertBuf, 0, bc); + synchronized (checkClosed().getConnectionMutex()) { + try { + if (streamConvertBuf == null) { + streamConvertBuf = new byte[4096]; } - - if (useLength) { - bc = readblock(in, streamConvertBuf, lengthLeftToRead); - - if (bc > 0) { - lengthLeftToRead -= bc; + + String connectionEncoding = this.connection.getEncoding(); + + boolean hexEscape = false; + + try { + if (this.connection.isNoBackslashEscapesSet() + || (this.connection.getUseUnicode() + && connectionEncoding != null + && CharsetMapping.isMultibyteCharset(connectionEncoding) + && !this.connection.parserKnowsUnicode())) { + hexEscape = true; } + } catch (RuntimeException ex) { + SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + sqlEx.initCause(ex); + throw sqlEx; + } + + if (streamLength == -1) { + useLength = false; + } + + int bc = -1; + + if (useLength) { + bc = readblock(in, streamConvertBuf, streamLength); } else { bc = readblock(in, streamConvertBuf); } - } - - if (escape) { - packet.writeByte((byte) '\''); - } - } finally { - if (this.connection.getAutoClosePStmtStreams()) { - try { - in.close(); - } catch (IOException ioEx) { - ; + + int lengthLeftToRead = streamLength - bc; + + if (hexEscape) { + packet.writeStringNoNull("x"); + } else if (this.connection.getIO().versionMeetsMinimum(4, 1, 0)) { + packet.writeStringNoNull("_binary"); } - - in = null; + + if (escape) { + packet.writeByte((byte) '\''); + } + + while (bc > 0) { + if (hexEscape) { + hexEscapeBlock(streamConvertBuf, packet, bc); + } else if (escape) { + escapeblockFast(streamConvertBuf, packet, bc); + } else { + packet.writeBytesNoNull(streamConvertBuf, 0, bc); + } + + if (useLength) { + bc = readblock(in, streamConvertBuf, lengthLeftToRead); + + if (bc > 0) { + lengthLeftToRead -= bc; + } + } else { + bc = readblock(in, streamConvertBuf); + } + } + + if (escape) { + packet.writeByte((byte) '\''); + } + } finally { + if (this.connection.getAutoClosePStmtStreams()) { + try { + in.close(); + } catch (IOException ioEx) { + ; + } + + in = null; + } } } } private final byte[] streamToBytes(InputStream in, boolean escape, int streamLength, boolean useLength) throws SQLException { - try { - if (streamLength == -1) { - useLength = false; - } - - ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); - - int bc = -1; - - if (useLength) { - bc = readblock(in, this.streamConvertBuf, streamLength); - } else { - bc = readblock(in, this.streamConvertBuf); - } - - int lengthLeftToRead = streamLength - bc; - - if (escape) { - if (this.connection.versionMeetsMinimum(4, 1, 0)) { - bytesOut.write('_'); - bytesOut.write('b'); - bytesOut.write('i'); - bytesOut.write('n'); - bytesOut.write('a'); - bytesOut.write('r'); - bytesOut.write('y'); + synchronized (checkClosed().getConnectionMutex()) { + try { + if (streamConvertBuf == null) { + streamConvertBuf = new byte[4096]; } - - bytesOut.write('\''); - } - - while (bc > 0) { - if (escape) { - escapeblockFast(this.streamConvertBuf, bytesOut, bc); - } else { - bytesOut.write(this.streamConvertBuf, 0, bc); + if (streamLength == -1) { + useLength = false; } - + + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + + int bc = -1; + if (useLength) { - bc = readblock(in, this.streamConvertBuf, lengthLeftToRead); - - if (bc > 0) { - lengthLeftToRead -= bc; - } + bc = readblock(in, this.streamConvertBuf, streamLength); } else { bc = readblock(in, this.streamConvertBuf); } - } - - if (escape) { - bytesOut.write('\''); - } - - return bytesOut.toByteArray(); - } finally { - if (this.connection.getAutoClosePStmtStreams()) { - try { - in.close(); - } catch (IOException ioEx) { - ; + + int lengthLeftToRead = streamLength - bc; + + if (escape) { + if (this.connection.versionMeetsMinimum(4, 1, 0)) { + bytesOut.write('_'); + bytesOut.write('b'); + bytesOut.write('i'); + bytesOut.write('n'); + bytesOut.write('a'); + bytesOut.write('r'); + bytesOut.write('y'); + } + + bytesOut.write('\''); } - - in = null; + + while (bc > 0) { + if (escape) { + escapeblockFast(this.streamConvertBuf, bytesOut, bc); + } else { + bytesOut.write(this.streamConvertBuf, 0, bc); + } + + if (useLength) { + bc = readblock(in, this.streamConvertBuf, lengthLeftToRead); + + if (bc > 0) { + lengthLeftToRead -= bc; + } + } else { + bc = readblock(in, this.streamConvertBuf); + } + } + + if (escape) { + bytesOut.write('\''); + } + + return bytesOut.toByteArray(); + } finally { + if (this.connection.getAutoClosePStmtStreams()) { + try { + in.close(); + } catch (IOException ioEx) { + ; + } + + in = null; + } } } } - + /** * Returns this PreparedStatement represented as a string. * @@ -4072,7 +5114,8 @@ return buf.toString(); } - + + /** * For calling stored functions, this will be -1 as we don't really count * the first '?' parameter marker, it's only syntax, but JDBC counts it @@ -4083,4 +5126,510 @@ protected int getParameterIndexOffset() { return 0; } + + public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { + setAsciiStream(parameterIndex, x, -1); + } + + public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { + setAsciiStream(parameterIndex, x, (int)length); + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.CLOB; + } + + public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { + setBinaryStream(parameterIndex, x, -1); + } + + public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { + setBinaryStream(parameterIndex, x, (int)length); + } + + public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + setBinaryStream(parameterIndex, inputStream); + } + + public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + setCharacterStream(parameterIndex, reader, -1); + } + + public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { + setCharacterStream(parameterIndex, reader, (int)length); + + } + + public void setClob(int parameterIndex, Reader reader) throws SQLException { + setCharacterStream(parameterIndex, reader); + + } + + public void setClob(int parameterIndex, Reader reader, long length) + throws SQLException { + setCharacterStream(parameterIndex, reader, length); + } + + public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + setNCharacterStream(parameterIndex, value, -1); + } + + /** + * Set a parameter to a Java String value. The driver converts this to a SQL + * VARCHAR or LONGVARCHAR value with introducer _utf8 (depending on the + * arguments size relative to the driver's limits on VARCHARs) when it sends + * it to the database. If charset is set as utf8, this method just call setString. + * + * @param parameterIndex + * the first parameter is 1... + * @param x + * the parameter value + * + * @exception SQLException + * if a database access error occurs + */ + public void setNString(int parameterIndex, String x) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (this.charEncoding.equalsIgnoreCase("UTF-8") + || this.charEncoding.equalsIgnoreCase("utf8")) { + setString(parameterIndex, x); + return; + } + + // if the passed string is null, then set this column to null + if (x == null) { + setNull(parameterIndex, java.sql.Types.CHAR); + } else { + int stringLength = x.length(); + // Ignore sql_mode=NO_BACKSLASH_ESCAPES in current implementation. + + // Add introducer _utf8 for NATIONAL CHARACTER + StringBuffer buf = new StringBuffer((int) (x.length() * 1.1 + 4)); + buf.append("_utf8"); + buf.append('\''); + + // + // Note: buf.append(char) is _faster_ than + // appending in blocks, because the block + // append requires a System.arraycopy().... + // go figure... + // + + for (int i = 0; i < stringLength; ++i) { + char c = x.charAt(i); + + switch (c) { + case 0: /* Must be escaped for 'mysql' */ + buf.append('\\'); + buf.append('0'); + + break; + + case '\n': /* Must be escaped for logs */ + buf.append('\\'); + buf.append('n'); + + break; + + case '\r': + buf.append('\\'); + buf.append('r'); + + break; + + case '\\': + buf.append('\\'); + buf.append('\\'); + + break; + + case '\'': + buf.append('\\'); + buf.append('\''); + + break; + + case '"': /* Better safe than sorry */ + if (this.usingAnsiMode) { + buf.append('\\'); + } + + buf.append('"'); + + break; + + case '\032': /* This gives problems on Win32 */ + buf.append('\\'); + buf.append('Z'); + + break; + + default: + buf.append(c); + } + } + + buf.append('\''); + + String parameterAsString = buf.toString(); + + byte[] parameterAsBytes = null; + + if (!this.isLoadDataQuery) { + parameterAsBytes = StringUtils.getBytes(parameterAsString, + this.connection.getCharsetConverter("UTF-8"), "UTF-8", + this.connection.getServerCharacterEncoding(), + this.connection.parserKnowsUnicode(), getExceptionInterceptor()); + } else { + // Send with platform character encoding + parameterAsBytes = StringUtils.getBytes(parameterAsString); + } + + setInternal(parameterIndex, parameterAsBytes); + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = -9; /* Types.NVARCHAR */ + } + } + } + + /** + * JDBC 2.0 When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a java.io.Reader. JDBC + * will read the data from the stream as needed, until it reaches + * end-of-file. The JDBC driver will do any necessary conversion from + * UNICODE to the database char format. + * + *

+ * Note: This stream object can either be a standard Java stream + * object or your own subclass that implements the standard interface. + *

+ * + * @param parameterIndex + * the first parameter is 1, the second is 2, ... + * @param reader + * the java reader which contains the UNICODE data + * @param length + * the number of characters in the stream + * + * @exception SQLException + * if a database-access error occurs. + */ + public void setNCharacterStream(int parameterIndex, Reader reader, + long length) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + try { + if (reader == null) { + setNull(parameterIndex, java.sql.Types.LONGVARCHAR); + + } else { + char[] c = null; + int len = 0; + + boolean useLength = this.connection + .getUseStreamLengthsInPrepStmts(); + + // Ignore "clobCharacterEncoding" because utf8 should be used this time. + + if (useLength && (length != -1)) { + c = new char[(int) length]; // can't take more than Integer.MAX_VALUE + + int numCharsRead = readFully(reader, c, (int) length); // blocks + // until + // all + // read + setNString(parameterIndex, new String(c, 0, numCharsRead)); + + } else { + c = new char[4096]; + + StringBuffer buf = new StringBuffer(); + + while ((len = reader.read(c)) != -1) { + buf.append(c, 0, len); + } + + setNString(parameterIndex, buf.toString()); + } + + this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = 2011; /* Types.NCLOB */ + } + } catch (java.io.IOException ioEx) { + throw SQLError.createSQLException(ioEx.toString(), + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + } + } + } + + public void setNClob(int parameterIndex, Reader reader) throws SQLException { + setNCharacterStream(parameterIndex, reader); + } + + /** + * JDBC 4.0 Set a NCLOB parameter. + * + * @param parameterIndex + * the first parameter is 1, the second is 2, ... + * @param reader + * the java reader which contains the UNICODE data + * @param length + * the number of characters in the stream + * + * @throws SQLException + * if a database error occurs + */ + public void setNClob(int parameterIndex, Reader reader, long length) + throws SQLException { + if (reader == null) { + setNull(parameterIndex, java.sql.Types.LONGVARCHAR); + } else { + setNCharacterStream(parameterIndex, reader, length); + } + } + + public ParameterBindings getParameterBindings() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + return new EmulatedPreparedStatementBindings(); + } + } + + class EmulatedPreparedStatementBindings implements ParameterBindings { + + private ResultSetImpl bindingsAsRs; + private boolean[] parameterIsNull; + + EmulatedPreparedStatementBindings() throws SQLException { + List rows = new ArrayList(); + parameterIsNull = new boolean[parameterCount]; + System + .arraycopy(isNull, 0, this.parameterIsNull, 0, + parameterCount); + byte[][] rowData = new byte[parameterCount][]; + Field[] typeMetadata = new Field[parameterCount]; + + for (int i = 0; i < parameterCount; i++) { + if (batchCommandIndex == -1) + rowData[i] = getBytesRepresentation(i); + else + rowData[i] = getBytesRepresentationForBatch(i, batchCommandIndex); + + int charsetIndex = 0; + + if (parameterTypes[i] == Types.BINARY + || parameterTypes[i] == Types.BLOB) { + charsetIndex = 63; + } else { + try { + String mysqlEncodingName = CharsetMapping + .getMysqlEncodingForJavaEncoding(connection + .getEncoding(), connection); + charsetIndex = CharsetMapping + .getCharsetIndexForMysqlEncodingName(mysqlEncodingName); + } 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; + } + } + + Field parameterMetadata = new Field(null, "parameter_" + + (i + 1), charsetIndex, parameterTypes[i], + rowData[i].length); + parameterMetadata.setConnection(connection); + typeMetadata[i] = parameterMetadata; + } + + rows.add(new ByteArrayRow(rowData, getExceptionInterceptor())); + + this.bindingsAsRs = new ResultSetImpl(connection.getCatalog(), + typeMetadata, new RowDataStatic(rows), connection, null); + this.bindingsAsRs.next(); + } + + public Array getArray(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getArray(parameterIndex); + } + + public InputStream getAsciiStream(int parameterIndex) + throws SQLException { + return this.bindingsAsRs.getAsciiStream(parameterIndex); + } + + public BigDecimal getBigDecimal(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getBigDecimal(parameterIndex); + } + + public InputStream getBinaryStream(int parameterIndex) + throws SQLException { + return this.bindingsAsRs.getBinaryStream(parameterIndex); + } + + public java.sql.Blob getBlob(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getBlob(parameterIndex); + } + + public boolean getBoolean(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getBoolean(parameterIndex); + } + + public byte getByte(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getByte(parameterIndex); + } + + public byte[] getBytes(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getBytes(parameterIndex); + } + + public Reader getCharacterStream(int parameterIndex) + throws SQLException { + return this.bindingsAsRs.getCharacterStream(parameterIndex); + } + + public java.sql.Clob getClob(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getClob(parameterIndex); + } + + public Date getDate(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getDate(parameterIndex); + } + + public double getDouble(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getDouble(parameterIndex); + } + + public float getFloat(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getFloat(parameterIndex); + } + + public int getInt(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getInt(parameterIndex); + } + + public long getLong(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getLong(parameterIndex); + } + + public Reader getNCharacterStream(int parameterIndex) + throws SQLException { + return this.bindingsAsRs.getCharacterStream(parameterIndex); + } + + public Reader getNClob(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getCharacterStream(parameterIndex); + } + + public Object getObject(int parameterIndex) throws SQLException { + checkBounds(parameterIndex, 0); + + if (parameterIsNull[parameterIndex - 1]) { + return null; + } + + // we can't rely on the default mapping for JDBC's + // ResultSet.getObject() for numerics, they're not one-to-one with + // PreparedStatement.setObject + + switch (parameterTypes[parameterIndex - 1]) { + case Types.TINYINT: + return Byte.valueOf(getByte(parameterIndex)); + case Types.SMALLINT: + return Short.valueOf(getShort(parameterIndex)); + case Types.INTEGER: + return Integer.valueOf(getInt(parameterIndex)); + case Types.BIGINT: + return Long.valueOf(getLong(parameterIndex)); + case Types.FLOAT: + return Float.valueOf(getFloat(parameterIndex)); + case Types.DOUBLE: + return Double.valueOf(getDouble(parameterIndex)); + default: + return this.bindingsAsRs.getObject(parameterIndex); + } + } + + public Ref getRef(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getRef(parameterIndex); + } + + public short getShort(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getShort(parameterIndex); + } + + public String getString(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getString(parameterIndex); + } + + public Time getTime(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getTime(parameterIndex); + } + + public Timestamp getTimestamp(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getTimestamp(parameterIndex); + } + + public URL getURL(int parameterIndex) throws SQLException { + return this.bindingsAsRs.getURL(parameterIndex); + } + + public boolean isNull(int parameterIndex) throws SQLException { + checkBounds(parameterIndex, 0); + + return this.parameterIsNull[parameterIndex -1]; + } + } + + public String getPreparedSql() { + try { + synchronized (checkClosed().getConnectionMutex()) { + if (this.rewrittenBatchSize == 0) { + return this.originalSql; + } + + try { + return this.parseInfo.getSqlForBatch(this.parseInfo); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + } catch (SQLException e) { + throw new RuntimeException(e); // FIXME: evolve public interface + } + } + + public int getUpdateCount() throws SQLException { + int count = super.getUpdateCount(); + + if (containsOnDuplicateKeyUpdateInSQL() && + this.compensateForOnDuplicateKeyUpdate) { + if (count == 2 || count == 0) { + count = 1; + } + } + + return count; + } + + protected static boolean canRewrite(String sql, boolean isOnDuplicateKeyUpdate, int locationOfOnDuplicateKeyUpdate, int statementStartPos) { + // Needs to be INSERT, can't have INSERT ... SELECT or + // INSERT ... ON DUPLICATE KEY UPDATE with an id=LAST_INSERT_ID(...) + + boolean rewritableOdku = true; + + if (isOnDuplicateKeyUpdate) { + int updateClausePos = StringUtils.indexOfIgnoreCase( + locationOfOnDuplicateKeyUpdate, sql, " UPDATE "); + + if (updateClausePos != -1) { + rewritableOdku = StringUtils + .indexOfIgnoreCaseRespectMarker(updateClausePos, + sql, "LAST_INSERT_ID", "\"'`", "\"'`", + false) == -1; + } + } + + return StringUtils + .startsWithIgnoreCaseAndWs(sql, "INSERT", + statementStartPos) + && StringUtils.indexOfIgnoreCaseRespectMarker( + statementStartPos, sql, "SELECT", "\"'`", + "\"'`", false) == -1 && rewritableOdku; + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ProfilerEventHandlerFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/RandomBalanceStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ReflectiveStatementInterceptorAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnection.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnection.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,24 +1,26 @@ /* - Copyright (C) 2004 MySQL AB + Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + */ + package com.mysql.jdbc; import java.sql.CallableStatement; @@ -28,9 +30,15 @@ import java.sql.SQLWarning; import java.sql.Savepoint; import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.TimeZone; +import java.util.concurrent.Executor; +import com.mysql.jdbc.log.Log; + /** * Connection that opens two connections, one two a replication master, and * another to one or more slaves, and decides to use master when the connection @@ -39,43 +47,177 @@ * @version $Id: ReplicationConnection.java,v 1.1.2.1 2005/05/13 18:58:38 * mmatthews Exp $ */ -public class ReplicationConnection implements java.sql.Connection, PingTarget { - private Connection currentConnection; +public class ReplicationConnection implements Connection, PingTarget { + protected Connection currentConnection; - private Connection masterConnection; + protected LoadBalancedConnection masterConnection; - private Connection slavesConnection; + protected LoadBalancedConnection slavesConnection; + + private Properties slaveProperties; + + private Properties masterProperties; + + private NonRegisteringDriver driver; + private long connectionGroupID = -1; + + private ReplicationConnectionGroup connectionGroup; + + private List slaveHosts; + + private List masterHosts; + + private boolean allowMasterDownConnections = false; + + private boolean enableJMX = false; + + private boolean readOnly = false; + + protected ReplicationConnection() {} + public ReplicationConnection(Properties masterProperties, - Properties slaveProperties) throws SQLException { - Driver driver = new Driver(); + Properties slaveProperties, List masterHostList, List slaveHostList) throws SQLException { + String enableJMXAsString = masterProperties.getProperty("replicationEnableJMX", + "false"); + try{ + enableJMX = Boolean.parseBoolean(enableJMXAsString); + } catch (Exception e){ + throw SQLError.createSQLException(Messages.getString( + "ReplicationConnection.badValueForReplicationEnableJMX", + new Object[] { enableJMXAsString }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + } + + String allowMasterDownConnectionsAsString = masterProperties.getProperty("allowMasterDownConnections", + "false"); + try{ + this.allowMasterDownConnections = Boolean.parseBoolean(allowMasterDownConnectionsAsString); + } catch (Exception e){ + throw SQLError.createSQLException(Messages.getString( + "ReplicationConnection.badValueForAllowMasterDownConnections", + new Object[] { enableJMXAsString }), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + } - StringBuffer masterUrl = new StringBuffer("jdbc:mysql://"); - StringBuffer slaveUrl = new StringBuffer("jdbc:mysql://"); + + String group = masterProperties.getProperty("replicationConnectionGroup", + null); + + if(group != null){ + this.connectionGroup = ReplicationConnectionGroupManager.getConnectionGroupInstance(group); + if(enableJMX){ + ReplicationConnectionGroupManager.registerJmx(); + } + this.connectionGroupID = this.connectionGroup.registerReplicationConnection(this, masterHostList, slaveHostList); + + this.slaveHosts = new ArrayList(this.connectionGroup.getSlaveHosts()); + this.masterHosts = new ArrayList(this.connectionGroup.getMasterHosts()); + } else { + this.slaveHosts = new ArrayList(slaveHostList); + this.masterHosts = new ArrayList(masterHostList); + } - String masterHost = masterProperties - .getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY); - - if (masterHost != null) { - masterUrl.append(masterHost); + this.driver = new NonRegisteringDriver(); + this.slaveProperties = slaveProperties; + this.masterProperties = masterProperties; + + boolean createdMaster = this.initializeMasterConnection(); + this.initializeSlaveConnection(); + if(!createdMaster) { + this.readOnly = true; + this.currentConnection = this.slavesConnection; + return; } - - String slaveHost = slaveProperties - .getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY); - - if (slaveHost != null) { - slaveUrl.append(slaveHost); - } + this.currentConnection = this.masterConnection; + } + + private boolean initializeMasterConnection() throws SQLException { + return this.initializeMasterConnection(this.allowMasterDownConnections); + } + + public long getConnectionGroupId() { + return this.connectionGroupID; + } + + private boolean initializeMasterConnection(boolean allowMasterDown) throws SQLException { + // get this value before we change the masterConnection reference: + boolean isMaster = this.isMasterConnection(); + + StringBuffer masterUrl = new StringBuffer(NonRegisteringDriver.LOADBALANCE_URL_PREFIX); + + + boolean firstHost = true; + for(String host : this.masterHosts) { + if(!firstHost) { + masterUrl.append(','); + } + masterUrl.append(host); + firstHost = false; + } + String masterDb = masterProperties .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY); + masterUrl.append("/"); if (masterDb != null) { masterUrl.append(masterDb); } + LoadBalancedConnection newMasterConn = null; + try { + newMasterConn = (com.mysql.jdbc.LoadBalancedConnection) driver.connect( + masterUrl.toString(), masterProperties); + } catch (SQLException ex) { + if(allowMasterDown){ + this.currentConnection = this.slavesConnection; + this.masterConnection = null; + this.readOnly = true; + return false; + } + throw ex; + } + + + if(isMaster && this.currentConnection != null) { + this.swapConnections(newMasterConn, currentConnection); + } + + if(this.masterConnection != null) { + try { + this.masterConnection.close(); + this.masterConnection = null; + } catch (SQLException e) {} + } + + + this.masterConnection = newMasterConn; + return true; + + + } + + + private void initializeSlaveConnection() throws SQLException { + if (this.slaveHosts.size() == 0) { + return; + } + + StringBuffer slaveUrl = new StringBuffer(NonRegisteringDriver.LOADBALANCE_URL_PREFIX); + + boolean firstHost = true; + for(String host : this.slaveHosts) { + if(!firstHost) { + slaveUrl.append(','); + } + slaveUrl.append(host); + firstHost = false; + } + + String slaveDb = slaveProperties .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY); @@ -85,21 +227,28 @@ slaveUrl.append(slaveDb); } - this.masterConnection = (com.mysql.jdbc.Connection) driver.connect( - masterUrl.toString(), masterProperties); - this.slavesConnection = (com.mysql.jdbc.Connection) driver.connect( + + this.slavesConnection = (com.mysql.jdbc.LoadBalancedConnection) driver.connect( slaveUrl.toString(), slaveProperties); - - this.currentConnection = this.masterConnection; + this.slavesConnection.setReadOnly(true); + + // 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 (this.currentConnection != null && + this.currentConnection == this.masterConnection && + this.readOnly) { + switchToSlavesConnection(); + } } /* * (non-Javadoc) * * @see java.sql.Connection#clearWarnings() */ - public synchronized void clearWarnings() throws SQLException { - this.currentConnection.clearWarnings(); + public void clearWarnings() throws SQLException { + getCurrentConnection().clearWarnings(); } /* @@ -108,26 +257,145 @@ * @see java.sql.Connection#close() */ public synchronized void close() throws SQLException { - this.masterConnection.close(); - this.slavesConnection.close(); + if(this.masterConnection != null) { + this.masterConnection.close(); + } + if(this.slavesConnection != null) { + this.slavesConnection.close(); + } + + if (this.connectionGroup != null) { + this.connectionGroup.handleCloseConnection(this); + } + } /* * (non-Javadoc) * * @see java.sql.Connection#commit() */ - public synchronized void commit() throws SQLException { - this.currentConnection.commit(); + public void commit() throws SQLException { + getCurrentConnection().commit(); } + + public boolean isHostMaster(String host) { + if(host == null) { + return false; + } + for(String test : this.masterHosts) { + if(test.equalsIgnoreCase(host)) { + return true; + } + } + return false; + } + + public boolean isHostSlave(String host) { + if(host == null) { + return false; + } + for(String test : this.slaveHosts) { + if(test.equalsIgnoreCase(host)) { + return true; + } + } + return false; + + + } + + + + public synchronized void removeSlave(String host) throws SQLException { + removeSlave(host, true); + } + + public synchronized void removeSlave(String host, boolean closeGently) throws SQLException { + + this.slaveHosts.remove(host); + if(this.slavesConnection == null) { + return; + } + + if(closeGently) { + slavesConnection.removeHostWhenNotInUse(host); + } else { + slavesConnection.removeHost(host); + } + + // close the connection if it's the last slave + if (this.slaveHosts.size() == 0) { + switchToMasterConnection(); + this.slavesConnection.close(); + this.slavesConnection = null; + setReadOnly(this.readOnly); // maintain + } + } + + public synchronized void addSlaveHost(String host) throws SQLException { + if(this.isHostSlave(host)){ + // throw new SQLException("Cannot add existing host!"); + return; + } + this.slaveHosts.add(host); + if (this.slavesConnection == null) { + initializeSlaveConnection(); + } else { + this.slavesConnection.addHost(host); + } + } + + public synchronized void promoteSlaveToMaster(String host) throws SQLException { + if(!this.isHostSlave(host)) { +// turned this off as one might walk up the replication tree and set master +// to the current's master's master. +// throw SQLError.createSQLException("Cannot promote host " + host + " to master, as it must first be configured as a slave.", null); + + } + + this.masterHosts.add(host); + this.removeSlave(host); + if(this.masterConnection != null) { + this.masterConnection.addHost(host); + } + + } + + public synchronized void removeMasterHost(String host) throws SQLException { + this.removeMasterHost(host, true); + } + + public synchronized void removeMasterHost(String host, boolean waitUntilNotInUse) throws SQLException { + this.removeMasterHost(host, waitUntilNotInUse, false); + } + + public synchronized void removeMasterHost(String host, boolean waitUntilNotInUse, boolean isNowSlave) throws SQLException { + if(isNowSlave) { + this.slaveHosts.add(host); + } + this.masterHosts.remove(host); + + if(this.masterConnection == null) { + return; + } + + if(waitUntilNotInUse){ + this.masterConnection.removeHostWhenNotInUse(host); + } else { + this.masterConnection.removeHost(host); + } + + } + /* * (non-Javadoc) * * @see java.sql.Connection#createStatement() */ public Statement createStatement() throws SQLException { - Statement stmt = this.currentConnection.createStatement(); + Statement stmt = getCurrentConnection().createStatement(); ((com.mysql.jdbc.Statement) stmt).setPingTarget(this); return stmt; @@ -138,9 +406,9 @@ * * @see java.sql.Connection#createStatement(int, int) */ - public synchronized Statement createStatement(int resultSetType, + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { - Statement stmt = this.currentConnection.createStatement(resultSetType, + Statement stmt = getCurrentConnection().createStatement(resultSetType, resultSetConcurrency); ((com.mysql.jdbc.Statement) stmt).setPingTarget(this); @@ -153,10 +421,10 @@ * * @see java.sql.Connection#createStatement(int, int, int) */ - public synchronized Statement createStatement(int resultSetType, + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - Statement stmt = this.currentConnection.createStatement(resultSetType, + Statement stmt = getCurrentConnection().createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); ((com.mysql.jdbc.Statement) stmt).setPingTarget(this); @@ -169,17 +437,17 @@ * * @see java.sql.Connection#getAutoCommit() */ - public synchronized boolean getAutoCommit() throws SQLException { - return this.currentConnection.getAutoCommit(); + public boolean getAutoCommit() throws SQLException { + return getCurrentConnection().getAutoCommit(); } /* * (non-Javadoc) * * @see java.sql.Connection#getCatalog() */ - public synchronized String getCatalog() throws SQLException { - return this.currentConnection.getCatalog(); + public String getCatalog() throws SQLException { + return getCurrentConnection().getCatalog(); } public synchronized Connection getCurrentConnection() { @@ -191,8 +459,8 @@ * * @see java.sql.Connection#getHoldability() */ - public synchronized int getHoldability() throws SQLException { - return this.currentConnection.getHoldability(); + public int getHoldability() throws SQLException { + return getCurrentConnection().getHoldability(); } public synchronized Connection getMasterConnection() { @@ -204,8 +472,8 @@ * * @see java.sql.Connection#getMetaData() */ - public synchronized DatabaseMetaData getMetaData() throws SQLException { - return this.currentConnection.getMetaData(); + public DatabaseMetaData getMetaData() throws SQLException { + return getCurrentConnection().getMetaData(); } public synchronized Connection getSlavesConnection() { @@ -217,35 +485,35 @@ * * @see java.sql.Connection#getTransactionIsolation() */ - public synchronized int getTransactionIsolation() throws SQLException { - return this.currentConnection.getTransactionIsolation(); + public int getTransactionIsolation() throws SQLException { + return getCurrentConnection().getTransactionIsolation(); } /* * (non-Javadoc) * * @see java.sql.Connection#getTypeMap() */ - public synchronized Map getTypeMap() throws SQLException { - return this.currentConnection.getTypeMap(); + public Map> getTypeMap() throws SQLException { + return getCurrentConnection().getTypeMap(); } /* * (non-Javadoc) * * @see java.sql.Connection#getWarnings() */ - public synchronized SQLWarning getWarnings() throws SQLException { - return this.currentConnection.getWarnings(); + public SQLWarning getWarnings() throws SQLException { + return getCurrentConnection().getWarnings(); } /* * (non-Javadoc) * * @see java.sql.Connection#isClosed() */ - public synchronized boolean isClosed() throws SQLException { - return this.currentConnection.isClosed(); + public boolean isClosed() throws SQLException { + return getCurrentConnection().isClosed(); } /* @@ -254,16 +522,16 @@ * @see java.sql.Connection#isReadOnly() */ public synchronized boolean isReadOnly() throws SQLException { - return this.currentConnection == this.slavesConnection; + return this.readOnly; } /* * (non-Javadoc) * * @see java.sql.Connection#nativeSQL(java.lang.String) */ - public synchronized String nativeSQL(String sql) throws SQLException { - return this.currentConnection.nativeSQL(sql); + public String nativeSQL(String sql) throws SQLException { + return getCurrentConnection().nativeSQL(sql); } /* @@ -272,17 +540,17 @@ * @see java.sql.Connection#prepareCall(java.lang.String) */ public CallableStatement prepareCall(String sql) throws SQLException { - return this.currentConnection.prepareCall(sql); + return getCurrentConnection().prepareCall(sql); } /* * (non-Javadoc) * * @see java.sql.Connection#prepareCall(java.lang.String, int, int) */ - public synchronized CallableStatement prepareCall(String sql, + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - return this.currentConnection.prepareCall(sql, resultSetType, + return getCurrentConnection().prepareCall(sql, resultSetType, resultSetConcurrency); } @@ -291,10 +559,10 @@ * * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int) */ - public synchronized CallableStatement prepareCall(String sql, + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - return this.currentConnection.prepareCall(sql, resultSetType, + return getCurrentConnection().prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); } @@ -304,8 +572,8 @@ * @see java.sql.Connection#prepareStatement(java.lang.String) */ public PreparedStatement prepareStatement(String sql) throws SQLException { - PreparedStatement pstmt = this.currentConnection.prepareStatement(sql); - + PreparedStatement pstmt = getCurrentConnection().prepareStatement(sql); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); return pstmt; @@ -316,9 +584,9 @@ * * @see java.sql.Connection#prepareStatement(java.lang.String, int) */ - public synchronized PreparedStatement prepareStatement(String sql, + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { - PreparedStatement pstmt = this.currentConnection.prepareStatement(sql, autoGeneratedKeys); + PreparedStatement pstmt = getCurrentConnection().prepareStatement(sql, autoGeneratedKeys); ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); @@ -330,9 +598,9 @@ * * @see java.sql.Connection#prepareStatement(java.lang.String, int, int) */ - public synchronized PreparedStatement prepareStatement(String sql, + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - PreparedStatement pstmt = this.currentConnection.prepareStatement(sql, resultSetType, + PreparedStatement pstmt = getCurrentConnection().prepareStatement(sql, resultSetType, resultSetConcurrency); ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); @@ -346,10 +614,10 @@ * @see java.sql.Connection#prepareStatement(java.lang.String, int, int, * int) */ - public synchronized PreparedStatement prepareStatement(String sql, + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - PreparedStatement pstmt = this.currentConnection.prepareStatement(sql, resultSetType, + PreparedStatement pstmt = getCurrentConnection().prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); @@ -362,9 +630,9 @@ * * @see java.sql.Connection#prepareStatement(java.lang.String, int[]) */ - public synchronized PreparedStatement prepareStatement(String sql, + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { - PreparedStatement pstmt = this.currentConnection.prepareStatement(sql, columnIndexes); + PreparedStatement pstmt = getCurrentConnection().prepareStatement(sql, columnIndexes); ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); @@ -377,9 +645,9 @@ * @see java.sql.Connection#prepareStatement(java.lang.String, * java.lang.String[]) */ - public synchronized PreparedStatement prepareStatement(String sql, + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { - PreparedStatement pstmt = this.currentConnection.prepareStatement(sql, columnNames); + PreparedStatement pstmt = getCurrentConnection().prepareStatement(sql, columnNames); ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); @@ -391,56 +659,56 @@ * * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint) */ - public synchronized void releaseSavepoint(Savepoint savepoint) + public void releaseSavepoint(Savepoint savepoint) throws SQLException { - this.currentConnection.releaseSavepoint(savepoint); + getCurrentConnection().releaseSavepoint(savepoint); } /* * (non-Javadoc) * * @see java.sql.Connection#rollback() */ - public synchronized void rollback() throws SQLException { - this.currentConnection.rollback(); + public void rollback() throws SQLException { + getCurrentConnection().rollback(); } /* * (non-Javadoc) * * @see java.sql.Connection#rollback(java.sql.Savepoint) */ - public synchronized void rollback(Savepoint savepoint) throws SQLException { - this.currentConnection.rollback(savepoint); + public void rollback(Savepoint savepoint) throws SQLException { + getCurrentConnection().rollback(savepoint); } /* * (non-Javadoc) * * @see java.sql.Connection#setAutoCommit(boolean) */ - public synchronized void setAutoCommit(boolean autoCommit) + public void setAutoCommit(boolean autoCommit) throws SQLException { - this.currentConnection.setAutoCommit(autoCommit); + getCurrentConnection().setAutoCommit(autoCommit); } /* * (non-Javadoc) * * @see java.sql.Connection#setCatalog(java.lang.String) */ - public synchronized void setCatalog(String catalog) throws SQLException { - this.currentConnection.setCatalog(catalog); + public void setCatalog(String catalog) throws SQLException { + getCurrentConnection().setCatalog(catalog); } /* * (non-Javadoc) * * @see java.sql.Connection#setHoldability(int) */ - public synchronized void setHoldability(int holdability) + public void setHoldability(int holdability) throws SQLException { - this.currentConnection.setHoldability(holdability); + getCurrentConnection().setHoldability(holdability); } /* @@ -458,53 +726,60 @@ switchToMasterConnection(); } } + this.readOnly = readOnly; + // allow master connection to be set to/from read-only if + // there are no slaves + if (this.currentConnection == this.masterConnection) { + this.currentConnection.setReadOnly(this.readOnly); + } } /* * (non-Javadoc) * * @see java.sql.Connection#setSavepoint() */ - public synchronized Savepoint setSavepoint() throws SQLException { - return this.currentConnection.setSavepoint(); + public Savepoint setSavepoint() throws SQLException { + return getCurrentConnection().setSavepoint(); } /* * (non-Javadoc) * * @see java.sql.Connection#setSavepoint(java.lang.String) */ - public synchronized Savepoint setSavepoint(String name) throws SQLException { - return this.currentConnection.setSavepoint(name); + public Savepoint setSavepoint(String name) throws SQLException { + return getCurrentConnection().setSavepoint(name); } /* * (non-Javadoc) * * @see java.sql.Connection#setTransactionIsolation(int) */ - public synchronized void setTransactionIsolation(int level) + public void setTransactionIsolation(int level) throws SQLException { - this.currentConnection.setTransactionIsolation(level); + getCurrentConnection().setTransactionIsolation(level); } // For testing - /* - * (non-Javadoc) - * - * @see java.sql.Connection#setTypeMap(java.util.Map) - */ - public synchronized void setTypeMap(Map arg0) throws SQLException { - this.currentConnection.setTypeMap(arg0); - } - private synchronized void switchToMasterConnection() throws SQLException { + if(this.masterConnection == null || this.masterConnection.isClosed()){ + this.initializeMasterConnection(); + } swapConnections(this.masterConnection, this.slavesConnection); + this.masterConnection.setReadOnly(false); } private synchronized void switchToSlavesConnection() throws SQLException { - swapConnections(this.slavesConnection, this.masterConnection); + if(this.slavesConnection == null || this.slavesConnection.isClosed()) { + this.initializeSlaveConnection(); + } + if (this.slavesConnection != null) { + swapConnections(this.slavesConnection, this.masterConnection); + this.slavesConnection.setReadOnly(true); + } } /** @@ -519,6 +794,7 @@ */ private synchronized void swapConnections(Connection switchToConnection, Connection switchFromConnection) throws SQLException { + String switchFromCatalog = switchFromConnection.getCatalog(); String switchToCatalog = switchToConnection.getCatalog(); @@ -545,16 +821,2203 @@ .setTransactionIsolation(switchFromIsolation); } + switchToConnection.setSessionMaxRows(switchFromConnection.getSessionMaxRows()); + this.currentConnection = switchToConnection; } public synchronized void doPing() throws SQLException { + boolean isMasterConn = this.isMasterConnection(); if (this.masterConnection != null) { - this.masterConnection.ping(); + try { + this.masterConnection.ping(); + } catch (SQLException e) { + if (isMasterConn) { + // flip to slave connections: + this.currentConnection = this.slavesConnection; + this.masterConnection = null; + + throw e; + } + } + } else { + this.initializeMasterConnection(); } if (this.slavesConnection != null) { + try { + this.slavesConnection.ping(); + } catch (SQLException e) { + if (!isMasterConn) { + // flip to master connection: + this.currentConnection = this.masterConnection; + this.slavesConnection = null; + + throw e; + } + } + } else { + this.initializeSlaveConnection(); + } + } + + public synchronized void changeUser(String userName, String newPassword) + throws SQLException { + this.masterConnection.changeUser(userName, newPassword); + this.slavesConnection.changeUser(userName, newPassword); + } + + public synchronized void clearHasTriedMaster() { + this.masterConnection.clearHasTriedMaster(); + this.slavesConnection.clearHasTriedMaster(); + + } + + public PreparedStatement clientPrepareStatement(String sql) + throws SQLException { + PreparedStatement pstmt = getCurrentConnection().clientPrepareStatement(sql); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public PreparedStatement clientPrepareStatement(String sql, + int autoGenKeyIndex) throws SQLException { + PreparedStatement pstmt = getCurrentConnection().clientPrepareStatement(sql, autoGenKeyIndex); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public PreparedStatement clientPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency) throws SQLException { + PreparedStatement pstmt = getCurrentConnection().clientPrepareStatement(sql, resultSetType, resultSetConcurrency); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public PreparedStatement clientPrepareStatement(String sql, + int[] autoGenKeyIndexes) throws SQLException { + PreparedStatement pstmt = getCurrentConnection().clientPrepareStatement(sql, autoGenKeyIndexes); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public PreparedStatement clientPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException { + PreparedStatement pstmt = getCurrentConnection().clientPrepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public PreparedStatement clientPrepareStatement(String sql, + String[] autoGenKeyColNames) throws SQLException { + PreparedStatement pstmt = getCurrentConnection().clientPrepareStatement(sql, autoGenKeyColNames); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public int getActiveStatementCount() { + return getCurrentConnection().getActiveStatementCount(); + } + + public long getIdleFor() { + return getCurrentConnection().getIdleFor(); + } + + public Log getLog() throws SQLException { + return getCurrentConnection().getLog(); + } + + public String getServerCharacterEncoding() { + return getCurrentConnection().getServerCharacterEncoding(); + } + + public TimeZone getServerTimezoneTZ() { + return getCurrentConnection().getServerTimezoneTZ(); + } + + public String getStatementComment() { + return getCurrentConnection().getStatementComment(); + } + + public boolean hasTriedMaster() { + return getCurrentConnection().hasTriedMaster(); + } + + public void initializeExtension(Extension ex) throws SQLException { + getCurrentConnection().initializeExtension(ex); + } + + public boolean isAbonormallyLongQuery(long millisOrNanos) { + return getCurrentConnection().isAbonormallyLongQuery(millisOrNanos); + } + + public boolean isInGlobalTx() { + return getCurrentConnection().isInGlobalTx(); + } + + public boolean isMasterConnection() { + if(this.currentConnection == null) { + return true; + } + return this.currentConnection == this.masterConnection; + } + + public boolean isNoBackslashEscapesSet() { + return getCurrentConnection().isNoBackslashEscapesSet(); + } + + public boolean lowerCaseTableNames() { + return getCurrentConnection().lowerCaseTableNames(); + } + + public boolean parserKnowsUnicode() { + return getCurrentConnection().parserKnowsUnicode(); + } + + public synchronized void ping() throws SQLException { + try { + this.masterConnection.ping(); + } catch (SQLException e) { + if (this.isMasterConnection()) { + throw e; + } + } + try { this.slavesConnection.ping(); + } catch (SQLException e) { + if (!this.isMasterConnection()) { + throw e; + } } } -} \ No newline at end of file + + public void reportQueryTime(long millisOrNanos) { + getCurrentConnection().reportQueryTime(millisOrNanos); + } + + public void resetServerState() throws SQLException { + getCurrentConnection().resetServerState(); + } + + public PreparedStatement serverPrepareStatement(String sql) + throws SQLException { + PreparedStatement pstmt = getCurrentConnection().serverPrepareStatement(sql); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public PreparedStatement serverPrepareStatement(String sql, + int autoGenKeyIndex) throws SQLException { + PreparedStatement pstmt = getCurrentConnection().serverPrepareStatement(sql, autoGenKeyIndex); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public PreparedStatement serverPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency) throws SQLException { + PreparedStatement pstmt = getCurrentConnection().serverPrepareStatement(sql, resultSetType, resultSetConcurrency); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public PreparedStatement serverPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException { + PreparedStatement pstmt = getCurrentConnection().serverPrepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public PreparedStatement serverPrepareStatement(String sql, + int[] autoGenKeyIndexes) throws SQLException { + PreparedStatement pstmt = getCurrentConnection().serverPrepareStatement(sql, autoGenKeyIndexes); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public PreparedStatement serverPrepareStatement(String sql, + String[] autoGenKeyColNames) throws SQLException { + PreparedStatement pstmt = getCurrentConnection().serverPrepareStatement(sql, autoGenKeyColNames); + ((com.mysql.jdbc.Statement) pstmt).setPingTarget(this); + + return pstmt; + } + + public void setFailedOver(boolean flag) { + getCurrentConnection().setFailedOver(flag); + } + + public void setPreferSlaveDuringFailover(boolean flag) { + getCurrentConnection().setPreferSlaveDuringFailover(flag); + } + + public synchronized void setStatementComment(String comment) { + this.masterConnection.setStatementComment(comment); + this.slavesConnection.setStatementComment(comment); + } + + public void shutdownServer() throws SQLException { + getCurrentConnection().shutdownServer(); + } + + public boolean supportsIsolationLevel() { + return getCurrentConnection().supportsIsolationLevel(); + } + + public boolean supportsQuotedIdentifiers() { + return getCurrentConnection().supportsQuotedIdentifiers(); + } + + public boolean supportsTransactions() { + return getCurrentConnection().supportsTransactions(); + } + + public boolean versionMeetsMinimum(int major, int minor, int subminor) + throws SQLException { + return getCurrentConnection().versionMeetsMinimum(major, minor, subminor); + } + + public String exposeAsXml() throws SQLException { + return getCurrentConnection().exposeAsXml(); + } + + public boolean getAllowLoadLocalInfile() { + return getCurrentConnection().getAllowLoadLocalInfile(); + } + + public boolean getAllowMultiQueries() { + return getCurrentConnection().getAllowMultiQueries(); + } + + public boolean getAllowNanAndInf() { + return getCurrentConnection().getAllowNanAndInf(); + } + + public boolean getAllowUrlInLocalInfile() { + return getCurrentConnection().getAllowUrlInLocalInfile(); + } + + public boolean getAlwaysSendSetIsolation() { + return getCurrentConnection().getAlwaysSendSetIsolation(); + } + + public boolean getAutoClosePStmtStreams() { + return getCurrentConnection().getAutoClosePStmtStreams(); + } + + public boolean getAutoDeserialize() { + return getCurrentConnection().getAutoDeserialize(); + } + + public boolean getAutoGenerateTestcaseScript() { + return getCurrentConnection().getAutoGenerateTestcaseScript(); + } + + public boolean getAutoReconnectForPools() { + return getCurrentConnection().getAutoReconnectForPools(); + } + + public boolean getAutoSlowLog() { + return getCurrentConnection().getAutoSlowLog(); + } + + public int getBlobSendChunkSize() { + return getCurrentConnection().getBlobSendChunkSize(); + } + + public boolean getBlobsAreStrings() { + return getCurrentConnection().getBlobsAreStrings(); + } + + public boolean getCacheCallableStatements() { + return getCurrentConnection().getCacheCallableStatements(); + } + + public boolean getCacheCallableStmts() { + return getCurrentConnection().getCacheCallableStmts(); + } + + public boolean getCachePrepStmts() { + return getCurrentConnection().getCachePrepStmts(); + } + + public boolean getCachePreparedStatements() { + return getCurrentConnection().getCachePreparedStatements(); + } + + public boolean getCacheResultSetMetadata() { + return getCurrentConnection().getCacheResultSetMetadata(); + } + + public boolean getCacheServerConfiguration() { + return getCurrentConnection().getCacheServerConfiguration(); + } + + public int getCallableStatementCacheSize() { + return getCurrentConnection().getCallableStatementCacheSize(); + } + + public int getCallableStmtCacheSize() { + return getCurrentConnection().getCallableStmtCacheSize(); + } + + public boolean getCapitalizeTypeNames() { + return getCurrentConnection().getCapitalizeTypeNames(); + } + + public String getCharacterSetResults() { + return getCurrentConnection().getCharacterSetResults(); + } + + public String getClientCertificateKeyStorePassword() { + return getCurrentConnection().getClientCertificateKeyStorePassword(); + } + + public String getClientCertificateKeyStoreType() { + return getCurrentConnection().getClientCertificateKeyStoreType(); + } + + public String getClientCertificateKeyStoreUrl() { + return getCurrentConnection().getClientCertificateKeyStoreUrl(); + } + + public String getClientInfoProvider() { + return getCurrentConnection().getClientInfoProvider(); + } + + public String getClobCharacterEncoding() { + return getCurrentConnection().getClobCharacterEncoding(); + } + + public boolean getClobberStreamingResults() { + return getCurrentConnection().getClobberStreamingResults(); + } + + public int getConnectTimeout() { + return getCurrentConnection().getConnectTimeout(); + } + + public String getConnectionCollation() { + return getCurrentConnection().getConnectionCollation(); + } + + public String getConnectionLifecycleInterceptors() { + return getCurrentConnection().getConnectionLifecycleInterceptors(); + } + + public boolean getContinueBatchOnError() { + return getCurrentConnection().getContinueBatchOnError(); + } + + public boolean getCreateDatabaseIfNotExist() { + return getCurrentConnection().getCreateDatabaseIfNotExist(); + } + + public int getDefaultFetchSize() { + return getCurrentConnection().getDefaultFetchSize(); + } + + public boolean getDontTrackOpenResources() { + return getCurrentConnection().getDontTrackOpenResources(); + } + + public boolean getDumpMetadataOnColumnNotFound() { + return getCurrentConnection().getDumpMetadataOnColumnNotFound(); + } + + public boolean getDumpQueriesOnException() { + return getCurrentConnection().getDumpQueriesOnException(); + } + + public boolean getDynamicCalendars() { + return getCurrentConnection().getDynamicCalendars(); + } + + public boolean getElideSetAutoCommits() { + return getCurrentConnection().getElideSetAutoCommits(); + } + + public boolean getEmptyStringsConvertToZero() { + return getCurrentConnection().getEmptyStringsConvertToZero(); + } + + public boolean getEmulateLocators() { + return getCurrentConnection().getEmulateLocators(); + } + + public boolean getEmulateUnsupportedPstmts() { + return getCurrentConnection().getEmulateUnsupportedPstmts(); + } + + public boolean getEnablePacketDebug() { + return getCurrentConnection().getEnablePacketDebug(); + } + + public boolean getEnableQueryTimeouts() { + return getCurrentConnection().getEnableQueryTimeouts(); + } + + public String getEncoding() { + return getCurrentConnection().getEncoding(); + } + + public boolean getExplainSlowQueries() { + return getCurrentConnection().getExplainSlowQueries(); + } + + public boolean getFailOverReadOnly() { + return getCurrentConnection().getFailOverReadOnly(); + } + + public boolean getFunctionsNeverReturnBlobs() { + return getCurrentConnection().getFunctionsNeverReturnBlobs(); + } + + public boolean getGatherPerfMetrics() { + return getCurrentConnection().getGatherPerfMetrics(); + } + + public boolean getGatherPerformanceMetrics() { + return getCurrentConnection().getGatherPerformanceMetrics(); + } + + public boolean getGenerateSimpleParameterMetadata() { + return getCurrentConnection().getGenerateSimpleParameterMetadata(); + } + + public boolean getHoldResultsOpenOverStatementClose() { + return getCurrentConnection().getHoldResultsOpenOverStatementClose(); + } + + public boolean getIgnoreNonTxTables() { + return getCurrentConnection().getIgnoreNonTxTables(); + } + + public boolean getIncludeInnodbStatusInDeadlockExceptions() { + return getCurrentConnection().getIncludeInnodbStatusInDeadlockExceptions(); + } + + public int getInitialTimeout() { + return getCurrentConnection().getInitialTimeout(); + } + + public boolean getInteractiveClient() { + return getCurrentConnection().getInteractiveClient(); + } + + public boolean getIsInteractiveClient() { + return getCurrentConnection().getIsInteractiveClient(); + } + + public boolean getJdbcCompliantTruncation() { + return getCurrentConnection().getJdbcCompliantTruncation(); + } + + public boolean getJdbcCompliantTruncationForReads() { + return getCurrentConnection().getJdbcCompliantTruncationForReads(); + } + + public String getLargeRowSizeThreshold() { + return getCurrentConnection().getLargeRowSizeThreshold(); + } + + public String getLoadBalanceStrategy() { + return getCurrentConnection().getLoadBalanceStrategy(); + } + + public String getLocalSocketAddress() { + return getCurrentConnection().getLocalSocketAddress(); + } + + public int getLocatorFetchBufferSize() { + return getCurrentConnection().getLocatorFetchBufferSize(); + } + + public boolean getLogSlowQueries() { + return getCurrentConnection().getLogSlowQueries(); + } + + public boolean getLogXaCommands() { + return getCurrentConnection().getLogXaCommands(); + } + + public String getLogger() { + return getCurrentConnection().getLogger(); + } + + public String getLoggerClassName() { + return getCurrentConnection().getLoggerClassName(); + } + + public boolean getMaintainTimeStats() { + return getCurrentConnection().getMaintainTimeStats(); + } + + public int getMaxQuerySizeToLog() { + return getCurrentConnection().getMaxQuerySizeToLog(); + } + + public int getMaxReconnects() { + return getCurrentConnection().getMaxReconnects(); + } + + public int getMaxRows() { + return getCurrentConnection().getMaxRows(); + } + + public int getMetadataCacheSize() { + return getCurrentConnection().getMetadataCacheSize(); + } + + public int getNetTimeoutForStreamingResults() { + return getCurrentConnection().getNetTimeoutForStreamingResults(); + } + + public boolean getNoAccessToProcedureBodies() { + return getCurrentConnection().getNoAccessToProcedureBodies(); + } + + public boolean getNoDatetimeStringSync() { + return getCurrentConnection().getNoDatetimeStringSync(); + } + + public boolean getNoTimezoneConversionForTimeType() { + return getCurrentConnection().getNoTimezoneConversionForTimeType(); + } + + public boolean getNullCatalogMeansCurrent() { + return getCurrentConnection().getNullCatalogMeansCurrent(); + } + + public boolean getNullNamePatternMatchesAll() { + return getCurrentConnection().getNullNamePatternMatchesAll(); + } + + public boolean getOverrideSupportsIntegrityEnhancementFacility() { + return getCurrentConnection().getOverrideSupportsIntegrityEnhancementFacility(); + } + + public int getPacketDebugBufferSize() { + return getCurrentConnection().getPacketDebugBufferSize(); + } + + public boolean getPadCharsWithSpace() { + return getCurrentConnection().getPadCharsWithSpace(); + } + + public boolean getParanoid() { + return getCurrentConnection().getParanoid(); + } + + public boolean getPedantic() { + return getCurrentConnection().getPedantic(); + } + + public boolean getPinGlobalTxToPhysicalConnection() { + return getCurrentConnection().getPinGlobalTxToPhysicalConnection(); + } + + public boolean getPopulateInsertRowWithDefaultValues() { + return getCurrentConnection().getPopulateInsertRowWithDefaultValues(); + } + + public int getPrepStmtCacheSize() { + return getCurrentConnection().getPrepStmtCacheSize(); + } + + public int getPrepStmtCacheSqlLimit() { + return getCurrentConnection().getPrepStmtCacheSqlLimit(); + } + + public int getPreparedStatementCacheSize() { + return getCurrentConnection().getPreparedStatementCacheSize(); + } + + public int getPreparedStatementCacheSqlLimit() { + return getCurrentConnection().getPreparedStatementCacheSqlLimit(); + } + + public boolean getProcessEscapeCodesForPrepStmts() { + return getCurrentConnection().getProcessEscapeCodesForPrepStmts(); + } + + public boolean getProfileSQL() { + return getCurrentConnection().getProfileSQL(); + } + + public boolean getProfileSql() { + return getCurrentConnection().getProfileSql(); + } + + public String getProfilerEventHandler() { + return getCurrentConnection().getProfilerEventHandler(); + } + + public String getPropertiesTransform() { + return getCurrentConnection().getPropertiesTransform(); + } + + public int getQueriesBeforeRetryMaster() { + return getCurrentConnection().getQueriesBeforeRetryMaster(); + } + + public boolean getReconnectAtTxEnd() { + return getCurrentConnection().getReconnectAtTxEnd(); + } + + public boolean getRelaxAutoCommit() { + return getCurrentConnection().getRelaxAutoCommit(); + } + + public int getReportMetricsIntervalMillis() { + return getCurrentConnection().getReportMetricsIntervalMillis(); + } + + public boolean getRequireSSL() { + return getCurrentConnection().getRequireSSL(); + } + + public String getResourceId() { + return getCurrentConnection().getResourceId(); + } + + public int getResultSetSizeThreshold() { + return getCurrentConnection().getResultSetSizeThreshold(); + } + + public boolean getRewriteBatchedStatements() { + return getCurrentConnection().getRewriteBatchedStatements(); + } + + public boolean getRollbackOnPooledClose() { + return getCurrentConnection().getRollbackOnPooledClose(); + } + + public boolean getRoundRobinLoadBalance() { + return getCurrentConnection().getRoundRobinLoadBalance(); + } + + public boolean getRunningCTS13() { + return getCurrentConnection().getRunningCTS13(); + } + + public int getSecondsBeforeRetryMaster() { + return getCurrentConnection().getSecondsBeforeRetryMaster(); + } + + public int getSelfDestructOnPingMaxOperations() { + return getCurrentConnection().getSelfDestructOnPingMaxOperations(); + } + + public int getSelfDestructOnPingSecondsLifetime() { + return getCurrentConnection().getSelfDestructOnPingSecondsLifetime(); + } + + public String getServerTimezone() { + return getCurrentConnection().getServerTimezone(); + } + + public String getSessionVariables() { + return getCurrentConnection().getSessionVariables(); + } + + public int getSlowQueryThresholdMillis() { + return getCurrentConnection().getSlowQueryThresholdMillis(); + } + + public long getSlowQueryThresholdNanos() { + return getCurrentConnection().getSlowQueryThresholdNanos(); + } + + public String getSocketFactory() { + return getCurrentConnection().getSocketFactory(); + } + + public String getSocketFactoryClassName() { + return getCurrentConnection().getSocketFactoryClassName(); + } + + public int getSocketTimeout() { + return getCurrentConnection().getSocketTimeout(); + } + + public String getStatementInterceptors() { + return getCurrentConnection().getStatementInterceptors(); + } + + public boolean getStrictFloatingPoint() { + return getCurrentConnection().getStrictFloatingPoint(); + } + + public boolean getStrictUpdates() { + return getCurrentConnection().getStrictUpdates(); + } + + public boolean getTcpKeepAlive() { + return getCurrentConnection().getTcpKeepAlive(); + } + + public boolean getTcpNoDelay() { + return getCurrentConnection().getTcpNoDelay(); + } + + public int getTcpRcvBuf() { + return getCurrentConnection().getTcpRcvBuf(); + } + + public int getTcpSndBuf() { + return getCurrentConnection().getTcpSndBuf(); + } + + public int getTcpTrafficClass() { + return getCurrentConnection().getTcpTrafficClass(); + } + + public boolean getTinyInt1isBit() { + return getCurrentConnection().getTinyInt1isBit(); + } + + public boolean getTraceProtocol() { + return getCurrentConnection().getTraceProtocol(); + } + + public boolean getTransformedBitIsBoolean() { + return getCurrentConnection().getTransformedBitIsBoolean(); + } + + public boolean getTreatUtilDateAsTimestamp() { + return getCurrentConnection().getTreatUtilDateAsTimestamp(); + } + + public String getTrustCertificateKeyStorePassword() { + return getCurrentConnection().getTrustCertificateKeyStorePassword(); + } + + public String getTrustCertificateKeyStoreType() { + return getCurrentConnection().getTrustCertificateKeyStoreType(); + } + + public String getTrustCertificateKeyStoreUrl() { + return getCurrentConnection().getTrustCertificateKeyStoreUrl(); + } + + public boolean getUltraDevHack() { + return getCurrentConnection().getUltraDevHack(); + } + + public boolean getUseBlobToStoreUTF8OutsideBMP() { + return getCurrentConnection().getUseBlobToStoreUTF8OutsideBMP(); + } + + public boolean getUseCompression() { + return getCurrentConnection().getUseCompression(); + } + + public String getUseConfigs() { + return getCurrentConnection().getUseConfigs(); + } + + public boolean getUseCursorFetch() { + return getCurrentConnection().getUseCursorFetch(); + } + + public boolean getUseDirectRowUnpack() { + return getCurrentConnection().getUseDirectRowUnpack(); + } + + public boolean getUseDynamicCharsetInfo() { + return getCurrentConnection().getUseDynamicCharsetInfo(); + } + + public boolean getUseFastDateParsing() { + return getCurrentConnection().getUseFastDateParsing(); + } + + public boolean getUseFastIntParsing() { + return getCurrentConnection().getUseFastIntParsing(); + } + + public boolean getUseGmtMillisForDatetimes() { + return getCurrentConnection().getUseGmtMillisForDatetimes(); + } + + public boolean getUseHostsInPrivileges() { + return getCurrentConnection().getUseHostsInPrivileges(); + } + + public boolean getUseInformationSchema() { + return getCurrentConnection().getUseInformationSchema(); + } + + public boolean getUseJDBCCompliantTimezoneShift() { + return getCurrentConnection().getUseJDBCCompliantTimezoneShift(); + } + + public boolean getUseJvmCharsetConverters() { + return getCurrentConnection().getUseJvmCharsetConverters(); + } + + public boolean getUseLegacyDatetimeCode() { + return getCurrentConnection().getUseLegacyDatetimeCode(); + } + + public boolean getUseLocalSessionState() { + return getCurrentConnection().getUseLocalSessionState(); + } + + public boolean getUseNanosForElapsedTime() { + return getCurrentConnection().getUseNanosForElapsedTime(); + } + + public boolean getUseOldAliasMetadataBehavior() { + return getCurrentConnection().getUseOldAliasMetadataBehavior(); + } + + public boolean getUseOldUTF8Behavior() { + return getCurrentConnection().getUseOldUTF8Behavior(); + } + + public boolean getUseOnlyServerErrorMessages() { + return getCurrentConnection().getUseOnlyServerErrorMessages(); + } + + public boolean getUseReadAheadInput() { + return getCurrentConnection().getUseReadAheadInput(); + } + + public boolean getUseSSL() { + return getCurrentConnection().getUseSSL(); + } + + public boolean getUseSSPSCompatibleTimezoneShift() { + return getCurrentConnection().getUseSSPSCompatibleTimezoneShift(); + } + + public boolean getUseServerPrepStmts() { + return getCurrentConnection().getUseServerPrepStmts(); + } + + public boolean getUseServerPreparedStmts() { + return getCurrentConnection().getUseServerPreparedStmts(); + } + + public boolean getUseSqlStateCodes() { + return getCurrentConnection().getUseSqlStateCodes(); + } + + public boolean getUseStreamLengthsInPrepStmts() { + return getCurrentConnection().getUseStreamLengthsInPrepStmts(); + } + + public boolean getUseTimezone() { + return getCurrentConnection().getUseTimezone(); + } + + public boolean getUseUltraDevWorkAround() { + return getCurrentConnection().getUseUltraDevWorkAround(); + } + + public boolean getUseUnbufferedInput() { + return getCurrentConnection().getUseUnbufferedInput(); + } + + public boolean getUseUnicode() { + return getCurrentConnection().getUseUnicode(); + } + + public boolean getUseUsageAdvisor() { + return getCurrentConnection().getUseUsageAdvisor(); + } + + public String getUtf8OutsideBmpExcludedColumnNamePattern() { + return getCurrentConnection().getUtf8OutsideBmpExcludedColumnNamePattern(); + } + + public String getUtf8OutsideBmpIncludedColumnNamePattern() { + return getCurrentConnection().getUtf8OutsideBmpIncludedColumnNamePattern(); + } + + public boolean getVerifyServerCertificate() { + return getCurrentConnection().getVerifyServerCertificate(); + } + + public boolean getYearIsDateType() { + return getCurrentConnection().getYearIsDateType(); + } + + public String getZeroDateTimeBehavior() { + return getCurrentConnection().getZeroDateTimeBehavior(); + } + + public void setAllowLoadLocalInfile(boolean property) { + // not runtime configurable + + } + + public void setAllowMultiQueries(boolean property) { + // not runtime configurable + + } + + public void setAllowNanAndInf(boolean flag) { + // not runtime configurable + + } + + public void setAllowUrlInLocalInfile(boolean flag) { + // not runtime configurable + + } + + public void setAlwaysSendSetIsolation(boolean flag) { + // not runtime configurable + + } + + public void setAutoClosePStmtStreams(boolean flag) { + // not runtime configurable + + } + + public void setAutoDeserialize(boolean flag) { + // not runtime configurable + + } + + public void setAutoGenerateTestcaseScript(boolean flag) { + // not runtime configurable + + } + + public void setAutoReconnect(boolean flag) { + // not runtime configurable + + } + + public void setAutoReconnectForConnectionPools(boolean property) { + // not runtime configurable + + } + + public void setAutoReconnectForPools(boolean flag) { + // not runtime configurable + + } + + public void setAutoSlowLog(boolean flag) { + // not runtime configurable + + } + + public void setBlobSendChunkSize(String value) throws SQLException { + // not runtime configurable + + } + + public void setBlobsAreStrings(boolean flag) { + // not runtime configurable + + } + + public void setCacheCallableStatements(boolean flag) { + // not runtime configurable + + } + + public void setCacheCallableStmts(boolean flag) { + // not runtime configurable + + } + + public void setCachePrepStmts(boolean flag) { + // not runtime configurable + + } + + public void setCachePreparedStatements(boolean flag) { + // not runtime configurable + + } + + public void setCacheResultSetMetadata(boolean property) { + // not runtime configurable + + } + + public void setCacheServerConfiguration(boolean flag) { + // not runtime configurable + + } + + public void setCallableStatementCacheSize(int size) { + // not runtime configurable + + } + + public void setCallableStmtCacheSize(int cacheSize) { + // not runtime configurable + + } + + public void setCapitalizeDBMDTypes(boolean property) { + // not runtime configurable + + } + + public void setCapitalizeTypeNames(boolean flag) { + // not runtime configurable + + } + + public void setCharacterEncoding(String encoding) { + // not runtime configurable + + } + + public void setCharacterSetResults(String characterSet) { + // not runtime configurable + + } + + public void setClientCertificateKeyStorePassword(String value) { + // not runtime configurable + + } + + public void setClientCertificateKeyStoreType(String value) { + // not runtime configurable + + } + + public void setClientCertificateKeyStoreUrl(String value) { + // not runtime configurable + + } + + public void setClientInfoProvider(String classname) { + // not runtime configurable + + } + + public void setClobCharacterEncoding(String encoding) { + // not runtime configurable + + } + + public void setClobberStreamingResults(boolean flag) { + // not runtime configurable + + } + + public void setConnectTimeout(int timeoutMs) { + // not runtime configurable + + } + + public void setConnectionCollation(String collation) { + // not runtime configurable + + } + + public void setConnectionLifecycleInterceptors(String interceptors) { + // not runtime configurable + + } + + public void setContinueBatchOnError(boolean property) { + // not runtime configurable + + } + + public void setCreateDatabaseIfNotExist(boolean flag) { + // not runtime configurable + + } + + public void setDefaultFetchSize(int n) { + // not runtime configurable + + } + + public void setDetectServerPreparedStmts(boolean property) { + // not runtime configurable + + } + + public void setDontTrackOpenResources(boolean flag) { + // not runtime configurable + + } + + public void setDumpMetadataOnColumnNotFound(boolean flag) { + // not runtime configurable + + } + + public void setDumpQueriesOnException(boolean flag) { + // not runtime configurable + + } + + public void setDynamicCalendars(boolean flag) { + // not runtime configurable + + } + + public void setElideSetAutoCommits(boolean flag) { + // not runtime configurable + + } + + public void setEmptyStringsConvertToZero(boolean flag) { + // not runtime configurable + + } + + public void setEmulateLocators(boolean property) { + // not runtime configurable + + } + + public void setEmulateUnsupportedPstmts(boolean flag) { + // not runtime configurable + + } + + public void setEnablePacketDebug(boolean flag) { + // not runtime configurable + + } + + public void setEnableQueryTimeouts(boolean flag) { + // not runtime configurable + + } + + public void setEncoding(String property) { + // not runtime configurable + + } + + public void setExplainSlowQueries(boolean flag) { + // not runtime configurable + + } + + public void setFailOverReadOnly(boolean flag) { + // not runtime configurable + + } + + public void setFunctionsNeverReturnBlobs(boolean flag) { + // not runtime configurable + + } + + public void setGatherPerfMetrics(boolean flag) { + // not runtime configurable + + } + + public void setGatherPerformanceMetrics(boolean flag) { + // not runtime configurable + + } + + public void setGenerateSimpleParameterMetadata(boolean flag) { + // not runtime configurable + + } + + public void setHoldResultsOpenOverStatementClose(boolean flag) { + // not runtime configurable + + } + + public void setIgnoreNonTxTables(boolean property) { + // not runtime configurable + + } + + public void setIncludeInnodbStatusInDeadlockExceptions(boolean flag) { + // not runtime configurable + + } + + public void setInitialTimeout(int property) { + // not runtime configurable + + } + + public void setInteractiveClient(boolean property) { + // not runtime configurable + + } + + public void setIsInteractiveClient(boolean property) { + // not runtime configurable + + } + + public void setJdbcCompliantTruncation(boolean flag) { + // not runtime configurable + + } + + public void setJdbcCompliantTruncationForReads( + boolean jdbcCompliantTruncationForReads) { + // not runtime configurable + + } + + public void setLargeRowSizeThreshold(String value) { + // not runtime configurable + + } + + public void setLoadBalanceStrategy(String strategy) { + // not runtime configurable + + } + + public void setLocalSocketAddress(String address) { + // not runtime configurable + + } + + public void setLocatorFetchBufferSize(String value) throws SQLException { + // not runtime configurable + + } + + public void setLogSlowQueries(boolean flag) { + // not runtime configurable + + } + + public void setLogXaCommands(boolean flag) { + // not runtime configurable + + } + + public void setLogger(String property) { + // not runtime configurable + + } + + public void setLoggerClassName(String className) { + // not runtime configurable + + } + + public void setMaintainTimeStats(boolean flag) { + // not runtime configurable + + } + + public void setMaxQuerySizeToLog(int sizeInBytes) { + // not runtime configurable + + } + + public void setMaxReconnects(int property) { + // not runtime configurable + + } + + public void setMaxRows(int property) { + // not runtime configurable + + } + + public void setMetadataCacheSize(int value) { + // not runtime configurable + + } + + public void setNetTimeoutForStreamingResults(int value) { + // not runtime configurable + + } + + public void setNoAccessToProcedureBodies(boolean flag) { + // not runtime configurable + + } + + public void setNoDatetimeStringSync(boolean flag) { + // not runtime configurable + + } + + public void setNoTimezoneConversionForTimeType(boolean flag) { + // not runtime configurable + + } + + public void setNullCatalogMeansCurrent(boolean value) { + // not runtime configurable + + } + + public void setNullNamePatternMatchesAll(boolean value) { + // not runtime configurable + + } + + public void setOverrideSupportsIntegrityEnhancementFacility(boolean flag) { + // not runtime configurable + + } + + public void setPacketDebugBufferSize(int size) { + // not runtime configurable + + } + + public void setPadCharsWithSpace(boolean flag) { + // not runtime configurable + + } + + public void setParanoid(boolean property) { + // not runtime configurable + + } + + public void setPedantic(boolean property) { + // not runtime configurable + + } + + public void setPinGlobalTxToPhysicalConnection(boolean flag) { + // not runtime configurable + + } + + public void setPopulateInsertRowWithDefaultValues(boolean flag) { + // not runtime configurable + + } + + public void setPrepStmtCacheSize(int cacheSize) { + // not runtime configurable + + } + + public void setPrepStmtCacheSqlLimit(int sqlLimit) { + // not runtime configurable + + } + + public void setPreparedStatementCacheSize(int cacheSize) { + // not runtime configurable + + } + + public void setPreparedStatementCacheSqlLimit(int cacheSqlLimit) { + // not runtime configurable + + } + + public void setProcessEscapeCodesForPrepStmts(boolean flag) { + // not runtime configurable + + } + + public void setProfileSQL(boolean flag) { + // not runtime configurable + + } + + public void setProfileSql(boolean property) { + // not runtime configurable + + } + + public void setProfilerEventHandler(String handler) { + // not runtime configurable + + } + + public void setPropertiesTransform(String value) { + // not runtime configurable + + } + + public void setQueriesBeforeRetryMaster(int property) { + // not runtime configurable + + } + + public void setReconnectAtTxEnd(boolean property) { + // not runtime configurable + + } + + public void setRelaxAutoCommit(boolean property) { + // not runtime configurable + + } + + public void setReportMetricsIntervalMillis(int millis) { + // not runtime configurable + + } + + public void setRequireSSL(boolean property) { + // not runtime configurable + + } + + public void setResourceId(String resourceId) { + // not runtime configurable + + } + + public void setResultSetSizeThreshold(int threshold) { + // not runtime configurable + + } + + public void setRetainStatementAfterResultSetClose(boolean flag) { + // not runtime configurable + + } + + public void setRewriteBatchedStatements(boolean flag) { + // not runtime configurable + + } + + public void setRollbackOnPooledClose(boolean flag) { + // not runtime configurable + + } + + public void setRoundRobinLoadBalance(boolean flag) { + // not runtime configurable + + } + + public void setRunningCTS13(boolean flag) { + // not runtime configurable + + } + + public void setSecondsBeforeRetryMaster(int property) { + // not runtime configurable + + } + + public void setSelfDestructOnPingMaxOperations(int maxOperations) { + // not runtime configurable + + } + + public void setSelfDestructOnPingSecondsLifetime(int seconds) { + // not runtime configurable + + } + + public void setServerTimezone(String property) { + // not runtime configurable + + } + + public void setSessionVariables(String variables) { + // not runtime configurable + + } + + public void setSlowQueryThresholdMillis(int millis) { + // not runtime configurable + + } + + public void setSlowQueryThresholdNanos(long nanos) { + // not runtime configurable + + } + + public void setSocketFactory(String name) { + // not runtime configurable + + } + + public void setSocketFactoryClassName(String property) { + // not runtime configurable + + } + + public void setSocketTimeout(int property) { + // not runtime configurable + + } + + public void setStatementInterceptors(String value) { + // not runtime configurable + + } + + public void setStrictFloatingPoint(boolean property) { + // not runtime configurable + + } + + public void setStrictUpdates(boolean property) { + // not runtime configurable + + } + + public void setTcpKeepAlive(boolean flag) { + // not runtime configurable + + } + + public void setTcpNoDelay(boolean flag) { + // not runtime configurable + + } + + public void setTcpRcvBuf(int bufSize) { + // not runtime configurable + + } + + public void setTcpSndBuf(int bufSize) { + // not runtime configurable + + } + + public void setTcpTrafficClass(int classFlags) { + // not runtime configurable + + } + + public void setTinyInt1isBit(boolean flag) { + // not runtime configurable + + } + + public void setTraceProtocol(boolean flag) { + // not runtime configurable + + } + + public void setTransformedBitIsBoolean(boolean flag) { + // not runtime configurable + + } + + public void setTreatUtilDateAsTimestamp(boolean flag) { + // not runtime configurable + + } + + public void setTrustCertificateKeyStorePassword(String value) { + // not runtime configurable + + } + + public void setTrustCertificateKeyStoreType(String value) { + // not runtime configurable + + } + + public void setTrustCertificateKeyStoreUrl(String value) { + // not runtime configurable + + } + + public void setUltraDevHack(boolean flag) { + // not runtime configurable + + } + + public void setUseBlobToStoreUTF8OutsideBMP(boolean flag) { + // not runtime configurable + + } + + public void setUseCompression(boolean property) { + // not runtime configurable + + } + + public void setUseConfigs(String configs) { + // not runtime configurable + + } + + public void setUseCursorFetch(boolean flag) { + // not runtime configurable + + } + + public void setUseDirectRowUnpack(boolean flag) { + // not runtime configurable + + } + + public void setUseDynamicCharsetInfo(boolean flag) { + // not runtime configurable + + } + + public void setUseFastDateParsing(boolean flag) { + // not runtime configurable + + } + + public void setUseFastIntParsing(boolean flag) { + // not runtime configurable + + } + + public void setUseGmtMillisForDatetimes(boolean flag) { + // not runtime configurable + + } + + public void setUseHostsInPrivileges(boolean property) { + // not runtime configurable + + } + + public void setUseInformationSchema(boolean flag) { + // not runtime configurable + + } + + public void setUseJDBCCompliantTimezoneShift(boolean flag) { + // not runtime configurable + + } + + public void setUseJvmCharsetConverters(boolean flag) { + // not runtime configurable + + } + + public void setUseLegacyDatetimeCode(boolean flag) { + // not runtime configurable + + } + + public void setUseLocalSessionState(boolean flag) { + // not runtime configurable + + } + + public void setUseNanosForElapsedTime(boolean flag) { + // not runtime configurable + + } + + public void setUseOldAliasMetadataBehavior(boolean flag) { + // not runtime configurable + + } + + public void setUseOldUTF8Behavior(boolean flag) { + // not runtime configurable + + } + + public void setUseOnlyServerErrorMessages(boolean flag) { + // not runtime configurable + + } + + public void setUseReadAheadInput(boolean flag) { + // not runtime configurable + + } + + public void setUseSSL(boolean property) { + // not runtime configurable + + } + + public void setUseSSPSCompatibleTimezoneShift(boolean flag) { + // not runtime configurable + + } + + public void setUseServerPrepStmts(boolean flag) { + // not runtime configurable + + } + + public void setUseServerPreparedStmts(boolean flag) { + // not runtime configurable + + } + + public void setUseSqlStateCodes(boolean flag) { + // not runtime configurable + + } + + public void setUseStreamLengthsInPrepStmts(boolean property) { + // not runtime configurable + + } + + public void setUseTimezone(boolean property) { + // not runtime configurable + + } + + public void setUseUltraDevWorkAround(boolean property) { + // not runtime configurable + + } + + public void setUseUnbufferedInput(boolean flag) { + // not runtime configurable + + } + + public void setUseUnicode(boolean flag) { + // not runtime configurable + + } + + public void setUseUsageAdvisor(boolean useUsageAdvisorFlag) { + // not runtime configurable + + } + + public void setUtf8OutsideBmpExcludedColumnNamePattern(String regexPattern) { + // not runtime configurable + + } + + public void setUtf8OutsideBmpIncludedColumnNamePattern(String regexPattern) { + // not runtime configurable + + } + + public void setVerifyServerCertificate(boolean flag) { + // not runtime configurable + + } + + public void setYearIsDateType(boolean flag) { + // not runtime configurable + + } + + public void setZeroDateTimeBehavior(String behavior) { + // not runtime configurable + + } + + public boolean useUnbufferedInput() { + return getCurrentConnection().useUnbufferedInput(); + } + + public boolean isSameResource(Connection c) { + return getCurrentConnection().isSameResource(c); + } + + public void setInGlobalTx(boolean flag) { + getCurrentConnection().setInGlobalTx(flag); + } + + public boolean getUseColumnNamesInFindColumn() { + return getCurrentConnection().getUseColumnNamesInFindColumn(); + } + + public void setUseColumnNamesInFindColumn(boolean flag) { + // not runtime configurable + } + + public boolean getUseLocalTransactionState() { + return getCurrentConnection().getUseLocalTransactionState(); + } + + public void setUseLocalTransactionState(boolean flag) { + // not runtime configurable + + } + + public boolean getCompensateOnDuplicateKeyUpdateCounts() { + return getCurrentConnection().getCompensateOnDuplicateKeyUpdateCounts(); + } + + public void setCompensateOnDuplicateKeyUpdateCounts(boolean flag) { + // not runtime configurable + + } + + public boolean getUseAffectedRows() { + return getCurrentConnection().getUseAffectedRows(); + } + + public void setUseAffectedRows(boolean flag) { + // not runtime configurable + + } + + public String getPasswordCharacterEncoding() { + return getCurrentConnection().getPasswordCharacterEncoding(); + } + + public void setPasswordCharacterEncoding(String characterSet) { + getCurrentConnection().setPasswordCharacterEncoding(characterSet); + } + + public int getAutoIncrementIncrement() { + return getCurrentConnection().getAutoIncrementIncrement(); + } + + public int getLoadBalanceBlacklistTimeout() { + return getCurrentConnection().getLoadBalanceBlacklistTimeout(); + } + + public void setLoadBalanceBlacklistTimeout(int loadBalanceBlacklistTimeout) throws SQLException { + getCurrentConnection().setLoadBalanceBlacklistTimeout(loadBalanceBlacklistTimeout); + } + + public int getLoadBalancePingTimeout() { + return getCurrentConnection().getLoadBalancePingTimeout(); + } + + public void setLoadBalancePingTimeout(int loadBalancePingTimeout) throws SQLException { + getCurrentConnection().setLoadBalancePingTimeout(loadBalancePingTimeout); + } + + public boolean getLoadBalanceValidateConnectionOnSwapServer() { + return getCurrentConnection().getLoadBalanceValidateConnectionOnSwapServer(); + } + + public void setLoadBalanceValidateConnectionOnSwapServer(boolean loadBalanceValidateConnectionOnSwapServer) { + getCurrentConnection().setLoadBalanceValidateConnectionOnSwapServer(loadBalanceValidateConnectionOnSwapServer); + } + + public int getRetriesAllDown() { + return getCurrentConnection().getRetriesAllDown(); + } + + public void setRetriesAllDown(int retriesAllDown) throws SQLException { + getCurrentConnection().setRetriesAllDown(retriesAllDown); + } + + public ExceptionInterceptor getExceptionInterceptor() { + return getCurrentConnection().getExceptionInterceptor(); + } + + public String getExceptionInterceptors() { + return getCurrentConnection().getExceptionInterceptors(); + } + + public void setExceptionInterceptors(String exceptionInterceptors) { + getCurrentConnection().setExceptionInterceptors(exceptionInterceptors); + } + + public boolean getQueryTimeoutKillsConnection() { + return getCurrentConnection().getQueryTimeoutKillsConnection(); + } + + public void setQueryTimeoutKillsConnection( + boolean queryTimeoutKillsConnection) { + getCurrentConnection().setQueryTimeoutKillsConnection(queryTimeoutKillsConnection); + } + + public boolean hasSameProperties(Connection c) { + return this.masterConnection.hasSameProperties(c) && + this.slavesConnection.hasSameProperties(c); + } + + public Properties getProperties() { + Properties props = new Properties(); + props.putAll(this.masterConnection.getProperties()); + props.putAll(this.slavesConnection.getProperties()); + + return props; + } + + public String getHost() { + return getCurrentConnection().getHost(); + } + + public void setProxy(MySQLConnection proxy) { + getCurrentConnection().setProxy(proxy); + } + + public boolean getRetainStatementAfterResultSetClose() { + return getCurrentConnection().getRetainStatementAfterResultSetClose(); + } + + public int getMaxAllowedPacket() { + return getCurrentConnection().getMaxAllowedPacket(); + } + + public String getLoadBalanceConnectionGroup() { + return getCurrentConnection().getLoadBalanceConnectionGroup(); + } + + public boolean getLoadBalanceEnableJMX() { + return getCurrentConnection().getLoadBalanceEnableJMX(); + } + + public String getLoadBalanceExceptionChecker() { + return currentConnection + .getLoadBalanceExceptionChecker(); + } + + public String getLoadBalanceSQLExceptionSubclassFailover() { + return currentConnection + .getLoadBalanceSQLExceptionSubclassFailover(); + } + + public String getLoadBalanceSQLStateFailover() { + return currentConnection + .getLoadBalanceSQLStateFailover(); + } + + public void setLoadBalanceConnectionGroup(String loadBalanceConnectionGroup) { + currentConnection + .setLoadBalanceConnectionGroup(loadBalanceConnectionGroup); + + } + + public void setLoadBalanceEnableJMX(boolean loadBalanceEnableJMX) { + currentConnection + .setLoadBalanceEnableJMX(loadBalanceEnableJMX); + + } + + public void setLoadBalanceExceptionChecker( + String loadBalanceExceptionChecker) { + currentConnection + .setLoadBalanceExceptionChecker(loadBalanceExceptionChecker); + + } + + public void setLoadBalanceSQLExceptionSubclassFailover( + String loadBalanceSQLExceptionSubclassFailover) { + currentConnection + .setLoadBalanceSQLExceptionSubclassFailover(loadBalanceSQLExceptionSubclassFailover); + + } + + public void setLoadBalanceSQLStateFailover( + String loadBalanceSQLStateFailover) { + currentConnection + .setLoadBalanceSQLStateFailover(loadBalanceSQLStateFailover); + + } + + public String getLoadBalanceAutoCommitStatementRegex() { + return getCurrentConnection().getLoadBalanceAutoCommitStatementRegex(); + } + + public int getLoadBalanceAutoCommitStatementThreshold() { + return getCurrentConnection().getLoadBalanceAutoCommitStatementThreshold(); + } + + public void setLoadBalanceAutoCommitStatementRegex( + String loadBalanceAutoCommitStatementRegex) { + getCurrentConnection().setLoadBalanceAutoCommitStatementRegex(loadBalanceAutoCommitStatementRegex); + + } + + public void setLoadBalanceAutoCommitStatementThreshold( + int loadBalanceAutoCommitStatementThreshold) throws SQLException { + getCurrentConnection().setLoadBalanceAutoCommitStatementThreshold(loadBalanceAutoCommitStatementThreshold); + + } + + public void setTypeMap(Map> map) throws SQLException { + // TODO Auto-generated method stub + + } + + public boolean getIncludeThreadDumpInDeadlockExceptions() { + return getCurrentConnection().getIncludeThreadDumpInDeadlockExceptions(); + } + + public void setIncludeThreadDumpInDeadlockExceptions(boolean flag) { + getCurrentConnection().setIncludeThreadDumpInDeadlockExceptions(flag); + + } + + public boolean getIncludeThreadNamesAsStatementComment() { + return getCurrentConnection().getIncludeThreadNamesAsStatementComment(); + } + + public void setIncludeThreadNamesAsStatementComment(boolean flag) { + getCurrentConnection().setIncludeThreadNamesAsStatementComment(flag); + } + + public boolean isServerLocal() throws SQLException { + return getCurrentConnection().isServerLocal(); + } + + public void setAuthenticationPlugins(String authenticationPlugins) { + getCurrentConnection().setAuthenticationPlugins(authenticationPlugins); + } + + public String getAuthenticationPlugins() { + return getCurrentConnection().getAuthenticationPlugins(); + } + + public void setDisabledAuthenticationPlugins( + String disabledAuthenticationPlugins) { + getCurrentConnection().setDisabledAuthenticationPlugins(disabledAuthenticationPlugins); + } + + public String getDisabledAuthenticationPlugins() { + return getCurrentConnection().getDisabledAuthenticationPlugins(); + } + + public void setDefaultAuthenticationPlugin( + String defaultAuthenticationPlugin) { + getCurrentConnection().setDefaultAuthenticationPlugin(defaultAuthenticationPlugin); + } + + public String getDefaultAuthenticationPlugin() { + return getCurrentConnection().getDefaultAuthenticationPlugin(); + } + + public void setParseInfoCacheFactory(String factoryClassname) { + getCurrentConnection().setParseInfoCacheFactory(factoryClassname); + } + + public String getParseInfoCacheFactory() { + return getCurrentConnection().getParseInfoCacheFactory(); + } + + public void setSchema(String schema) throws SQLException { + getCurrentConnection().setSchema(schema); + } + + public String getSchema() throws SQLException { + return getCurrentConnection().getSchema(); + } + + public void abort(Executor executor) throws SQLException { + getCurrentConnection().abort(executor); + if(this.connectionGroup != null) { + this.connectionGroup.handleCloseConnection(this); + } + } + + public void setNetworkTimeout(Executor executor, int milliseconds) + throws SQLException { + getCurrentConnection().setNetworkTimeout(executor, milliseconds); + } + + public int getNetworkTimeout() throws SQLException { + return getCurrentConnection().getNetworkTimeout(); + } + + public void setServerConfigCacheFactory(String factoryClassname) { + getCurrentConnection().setServerConfigCacheFactory(factoryClassname); + } + + public String getServerConfigCacheFactory() { + return getCurrentConnection().getServerConfigCacheFactory(); + } + + public void setDisconnectOnExpiredPasswords(boolean disconnectOnExpiredPasswords) { + getCurrentConnection().setDisconnectOnExpiredPasswords(disconnectOnExpiredPasswords); + } + + public boolean getDisconnectOnExpiredPasswords() { + return getCurrentConnection().getDisconnectOnExpiredPasswords(); + } + + public void setGetProceduresReturnsFunctions(boolean getProcedureReturnsFunctions) { + getCurrentConnection().setGetProceduresReturnsFunctions(getProcedureReturnsFunctions); + } + + public boolean getGetProceduresReturnsFunctions() { + return getCurrentConnection().getGetProceduresReturnsFunctions(); + } + + public void abortInternal() throws SQLException { + getCurrentConnection().abortInternal(); + if(this.connectionGroup != null) { + this.connectionGroup.handleCloseConnection(this); + } + } + + public void checkClosed() throws SQLException { + getCurrentConnection().checkClosed(); + } + + public Object getConnectionMutex() { + return getCurrentConnection().getConnectionMutex(); + } + + public boolean getAllowMasterDownConnections() { + return this.allowMasterDownConnections; + } + + public void setAllowMasterDownConnections(boolean connectIfMasterDown) { + this.allowMasterDownConnections = connectIfMasterDown; + } + + public boolean getReplicationEnableJMX() { + return this.enableJMX; + } + + public void setReplicationEnableJMX(boolean replicationEnableJMX) { + this.enableJMX = replicationEnableJMX; + + } + + + public String getConnectionAttributes() throws SQLException { + return getCurrentConnection().getConnectionAttributes(); + } + + public void setDetectCustomCollations(boolean detectCustomCollations) { + getCurrentConnection().setDetectCustomCollations(detectCustomCollations); + } + + public boolean getDetectCustomCollations() { + return getCurrentConnection().getDetectCustomCollations(); + } + + public int getSessionMaxRows() { + return getCurrentConnection().getSessionMaxRows(); + } + + public void setSessionMaxRows(int max) throws SQLException { + getCurrentConnection().setSessionMaxRows(max); + } + + public String getServerRSAPublicKeyFile() { + return getCurrentConnection().getServerRSAPublicKeyFile(); + } + + public void setServerRSAPublicKeyFile(String serverRSAPublicKeyFile) throws SQLException { + getCurrentConnection().setServerRSAPublicKeyFile(serverRSAPublicKeyFile); + } + + public boolean getAllowPublicKeyRetrieval() { + return getCurrentConnection().getAllowPublicKeyRetrieval(); + } + + public void setAllowPublicKeyRetrieval(boolean allowPublicKeyRetrieval) throws SQLException { + getCurrentConnection().setAllowPublicKeyRetrieval(allowPublicKeyRetrieval); + } +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionGroup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionGroupManager.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationDriver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationDriver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationDriver.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationDriver.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.SQLException; Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetInternalMethods.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetMetaData.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetMetaData.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetMetaData.java 17 Aug 2012 14:57:08 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetMetaData.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,32 +1,28 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; import java.sql.SQLException; import java.sql.Types; @@ -79,16 +75,21 @@ Field[] fields; boolean useOldAliasBehavior = false; + boolean treatYearAsDate = true; + + private ExceptionInterceptor exceptionInterceptor; /** - * Initialise for a result with a tuple set and a field descriptor set + * Initialize for a result with a tuple set and a field descriptor set * * @param fields * the array of field descriptors */ - public ResultSetMetaData(Field[] fields, boolean useOldAliasBehavior) { + public ResultSetMetaData(Field[] fields, boolean useOldAliasBehavior, boolean treatYearAsDate, ExceptionInterceptor exceptionInterceptor) { this.fields = fields; this.useOldAliasBehavior = useOldAliasBehavior; + this.treatYearAsDate = treatYearAsDate; + this.exceptionInterceptor = exceptionInterceptor; } /** @@ -129,8 +130,13 @@ String javaName = null; if (mysqlName != null) { - javaName = CharsetMapping.getJavaEncodingForMysqlEncoding( - mysqlName, null); + try { + javaName = CharsetMapping.MYSQL_TO_JAVA_CHARSET_MAP.get(mysqlName); + } catch (RuntimeException ex) { + SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + sqlEx.initCause(ex); + throw sqlEx; + } } return javaName; @@ -180,7 +186,7 @@ f.isUnsigned(), f.getMysqlType(), f.isBinary() || f.isBlob(), - f.isOpaqueBinary()); + f.isOpaqueBinary(), treatYearAsDate); } /** @@ -247,8 +253,8 @@ public String getColumnName(int column) throws SQLException { if (this.useOldAliasBehavior) { return getField(column).getName(); - } - + } + String name = getField(column).getNameNoAliases(); if (name != null && name.length() == 0) { @@ -376,7 +382,10 @@ case MysqlDefs.FIELD_TYPE_SET: return "SET"; //$NON-NLS-1$ - + + case MysqlDefs.FIELD_TYPE_GEOMETRY: + return "GEOMETRY"; //$NON-NLS-1$ + default: return "UNKNOWN"; //$NON-NLS-1$ } @@ -396,7 +405,7 @@ protected Field getField(int columnIndex) throws SQLException { if ((columnIndex < 1) || (columnIndex > this.fields.length)) { throw SQLError.createSQLException(Messages.getString("ResultSetMetaData.46"), //$NON-NLS-1$ - SQLError.SQL_STATE_INVALID_COLUMN_NUMBER); + SQLError.SQL_STATE_INVALID_COLUMN_NUMBER, this.exceptionInterceptor); } return this.fields[columnIndex - 1]; @@ -718,65 +727,63 @@ return toStringBuf.toString(); } - - static String getClassNameForJavaType(int javaType, - boolean isUnsigned, int mysqlTypeIfKnown, - boolean isBinaryOrBlob, - boolean isOpaqueBinary) { + + static String getClassNameForJavaType(int javaType, boolean isUnsigned, int mysqlTypeIfKnown, + boolean isBinaryOrBlob, boolean isOpaqueBinary, boolean treatYearAsDate) { switch (javaType) { case Types.BIT: case Types.BOOLEAN: - return "java.lang.Boolean"; //$NON-NLS-1$ + return "java.lang.Boolean"; case Types.TINYINT: if (isUnsigned) { - return "java.lang.Integer"; //$NON-NLS-1$ + return "java.lang.Integer"; } - return "java.lang.Integer"; //$NON-NLS-1$ + return "java.lang.Integer"; case Types.SMALLINT: if (isUnsigned) { - return "java.lang.Integer"; //$NON-NLS-1$ + return "java.lang.Integer"; } - return "java.lang.Integer"; //$NON-NLS-1$ + return "java.lang.Integer"; case Types.INTEGER: if (!isUnsigned || mysqlTypeIfKnown == MysqlDefs.FIELD_TYPE_INT24) { - return "java.lang.Integer"; //$NON-NLS-1$ + return "java.lang.Integer"; } - return "java.lang.Long"; //$NON-NLS-1$ + return "java.lang.Long"; case Types.BIGINT: if (!isUnsigned) { - return "java.lang.Long"; //$NON-NLS-1$ + return "java.lang.Long"; } - return "java.math.BigInteger"; //$NON-NLS-1$ + return "java.math.BigInteger"; case Types.DECIMAL: case Types.NUMERIC: - return "java.math.BigDecimal"; //$NON-NLS-1$ + return "java.math.BigDecimal"; case Types.REAL: - return "java.lang.Float"; //$NON-NLS-1$ + return "java.lang.Float"; case Types.FLOAT: case Types.DOUBLE: - return "java.lang.Double"; //$NON-NLS-1$ + return "java.lang.Double"; case Types.CHAR: case Types.VARCHAR: case Types.LONGVARCHAR: if (!isOpaqueBinary) { - return "java.lang.String"; //$NON-NLS-1$ + return "java.lang.String"; } return "[B"; @@ -794,16 +801,63 @@ } case Types.DATE: - return "java.sql.Date"; //$NON-NLS-1$ + return (treatYearAsDate || mysqlTypeIfKnown != MysqlDefs.FIELD_TYPE_YEAR) ? "java.sql.Date" + : "java.lang.Short"; case Types.TIME: - return "java.sql.Time"; //$NON-NLS-1$ + return "java.sql.Time"; case Types.TIMESTAMP: - return "java.sql.Timestamp"; //$NON-NLS-1$ + return "java.sql.Timestamp"; default: - return "java.lang.Object"; //$NON-NLS-1$ + return "java.lang.Object"; } } + + /** + * Returns true if this either implements the interface argument or is directly or indirectly a wrapper + * for an object that does. Returns false otherwise. If this implements the interface then return true, + * else if this is a wrapper then return the result of recursively calling isWrapperFor on the wrapped + * object. If this does not implement the interface and is not a wrapper, return false. + * This method should be implemented as a low-cost operation compared to unwrap so that + * callers can use this method to avoid expensive unwrap calls that may fail. If this method + * returns true then calling unwrap with the same argument should succeed. + * + * @param interfaces a Class defining an interface. + * @return true if this implements the interface or directly or indirectly wraps an object that does. + * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper + * for an object with the given interface. + * @since 1.6 + */ + public boolean isWrapperFor(Class iface) throws SQLException { + // This works for classes that aren't actually wrapping + // anything + return iface.isInstance(this); + } + + /** + * Returns an object that implements the given interface to allow access to non-standard methods, + * or standard methods not exposed by the proxy. + * The result may be either the object found to implement the interface or a proxy for that object. + * If the receiver implements the interface then that is the object. If the receiver is a wrapper + * and the wrapped object implements the interface then that is the object. Otherwise the object is + * the result of calling unwrap recursively on the wrapped object. If the receiver is not a + * wrapper and does not implement the interface, then an SQLException is thrown. + * + * @param iface A Class defining an interface that the result must implement. + * @return an object that implements the interface. May be a proxy for the actual implementing object. + * @throws java.sql.SQLException If no object found that implements the interface + * @since 1.6 + */ + public Object unwrap(Class iface) throws java.sql.SQLException { + try { + // This works for classes that aren't actually wrapping + // anything + return Util.cast(iface, this); + } catch (ClassCastException cce) { + throw SQLError.createSQLException("Unable to unwrap to " + iface.toString(), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); + } + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetRow.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowData.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/RowData.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowData.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowData.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2006 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.SQLException; @@ -34,18 +33,13 @@ * @author dgan */ public interface RowData { - // ~ Static fields/initializers - // --------------------------------------------- /** * What's returned for the size of a result set when its size can not be * determined. */ public static final int RESULT_SET_SIZE_UNKNOWN = -1; - // ~ Methods - // ---------------------------------------------------------------- - /** * Adds a row to this row data. * @@ -54,7 +48,7 @@ * @throws SQLException * if a database error occurs */ - void addRow(byte[][] row) throws SQLException; + void addRow(ResultSetRow row) throws SQLException; /** * Moves to after last. @@ -97,7 +91,7 @@ * @throws SQLException * if a database error occurs */ - Object[] getAt(int index) throws SQLException; + ResultSetRow getAt(int index) throws SQLException; /** * Returns the current position in the result set as a row number. @@ -111,7 +105,7 @@ /** * Returns the result set that 'owns' this RowData */ - ResultSet getOwner(); + ResultSetInternalMethods getOwner(); /** * Returns true if another row exsists. @@ -196,7 +190,7 @@ * @throws SQLException * if a database error occurs */ - Object[] next() throws SQLException; + ResultSetRow next() throws SQLException; /** * Removes the row at the given index. @@ -224,7 +218,7 @@ * @param rs * the result set that 'owns' this RowData */ - void setOwner(ResultSet rs); + void setOwner(ResultSetImpl rs); /** * Only works on non dynamic result sets. @@ -239,4 +233,13 @@ * Did this result set have no rows? */ boolean wasEmpty(); + + /** + * Sometimes the driver doesn't have metadata until after + * the statement has the result set in-hand (because it's cached), + * so it can call this to set it after the fact. + * + * @param metadata field-level metadata for the result set + */ + void setMetadata(Field[] metadata); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataCursor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataDynamic.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataDynamic.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataDynamic.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataDynamic.java 30 Jul 2014 08:37:25 -0000 1.1.2.1 @@ -1,33 +1,33 @@ /* - Copyright (C) 2002-2006 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.SQLException; -import com.mysql.jdbc.profiler.ProfileEventSink; +import com.mysql.jdbc.exceptions.MySQLQueryInterruptedException; import com.mysql.jdbc.profiler.ProfilerEvent; +import com.mysql.jdbc.profiler.ProfilerEventHandler; /** * Allows streaming of MySQL data. @@ -36,48 +36,44 @@ * @version $Id$ */ public class RowDataDynamic implements RowData { - // ~ Instance fields - // -------------------------------------------------------- - class OperationNotSupportedException extends SQLException { - OperationNotSupportedException() { - super( - Messages.getString("RowDataDynamic.10"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } - } - private int columnCount; - private Field[] fields; + private Field[] metadata; private int index = -1; private MysqlIO io; private boolean isAfterEnd = false; - private boolean isAtEnd = false; + private boolean noMoreRows = false; private boolean isBinaryEncoded = false; - private Object[] nextRow; + private ResultSetRow nextRow; - private ResultSet owner; + private ResultSetImpl owner; private boolean streamerClosed = false; private boolean wasEmpty = false; // we don't know until we attempt to traverse - // ~ Methods - // ---------------------------------------------------------------- + private boolean useBufferRowExplicit; + private boolean moreResultsExisted; + + private ExceptionInterceptor exceptionInterceptor; + + private boolean isInterrupted = false; + /** * Creates a new RowDataDynamic object. * * @param io * the connection to MySQL that this data is coming from - * @param fields - * the fields that describe this data + * @param metadata + * the metadata that describe this data * @param isBinaryEncoded * is this data in native format? * @param colCount @@ -90,8 +86,9 @@ this.io = io; this.columnCount = colCount; this.isBinaryEncoded = isBinaryEncoded; - this.fields = fields; - nextRecord(); + this.metadata = fields; + this.exceptionInterceptor = this.io.getExceptionInterceptor(); + this.useBufferRowExplicit = MysqlIO.useBufferRowExplicit(this.metadata); } /** @@ -102,7 +99,7 @@ * @throws SQLException * if a database error occurs */ - public void addRow(byte[][] row) throws SQLException { + public void addRow(ResultSetRow row) throws SQLException { notSupported(); } @@ -143,61 +140,99 @@ * if a database error occurs */ public void close() throws SQLException { + // Belt and suspenders here - if we don't + // have a reference to the connection + // it's more than likely dead/gone and we + // won't be able to consume rows anyway + Object mutex = this; + + MySQLConnection conn = null; + + if (this.owner != null) { + conn = this.owner.connection; + + if (conn != null) { + mutex = conn.getConnectionMutex(); + } + } + boolean hadMore = false; int howMuchMore = 0; - // drain the rest of the records. - while (this.hasNext()) { - this.next(); - hadMore = true; - howMuchMore++; + synchronized (mutex) { + // drain the rest of the records. + while (next() != null) { + hadMore = true; + howMuchMore++; - if (howMuchMore % 100 == 0) { - Thread.yield(); + if (howMuchMore % 100 == 0) { + Thread.yield(); + } } - } - if (this.owner != null) { - Connection conn = this.owner.connection; + if (conn != null) { + if (!conn.getClobberStreamingResults() && + conn.getNetTimeoutForStreamingResults() > 0) { + String oldValue = conn + .getServerVariable("net_write_timeout"); - if (conn != null && conn.getUseUsageAdvisor()) { - if (hadMore) { + if (oldValue == null || oldValue.length() == 0) { + oldValue = "60"; // the current default + } - ProfileEventSink eventSink = ProfileEventSink - .getInstance(conn); + this.io.clearInputStream(); + + java.sql.Statement stmt = null; + + try { + stmt = conn.createStatement(); + ((com.mysql.jdbc.StatementImpl)stmt).executeSimpleNonQuery(conn, "SET net_write_timeout=" + oldValue); + } finally { + if (stmt != null) { + stmt.close(); + } + } + } + + if (conn.getUseUsageAdvisor()) { + if (hadMore) { - eventSink - .consumeEvent(new ProfilerEvent( - ProfilerEvent.TYPE_WARN, - "", //$NON-NLS-1$ - this.owner.owningStatement == null ? "N/A" : this.owner.owningStatement.currentCatalog, //$NON-NLS-1$ - 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") //$NON-NLS-1$ - + howMuchMore - + Messages - .getString("RowDataDynamic.3") //$NON-NLS-1$ - + Messages - .getString("RowDataDynamic.4") //$NON-NLS-1$ - + Messages - .getString("RowDataDynamic.5") //$NON-NLS-1$ - + Messages - .getString("RowDataDynamic.6") //$NON-NLS-1$ - + this.owner.pointOfOrigin)); + ProfilerEventHandler eventSink = ProfilerEventHandlerFactory + .getInstance(conn); + + eventSink + .consumeEvent(new ProfilerEvent( + ProfilerEvent.TYPE_WARN, + "", //$NON-NLS-1$ + this.owner.owningStatement == null ? "N/A" : this.owner.owningStatement.currentCatalog, //$NON-NLS-1$ + 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") //$NON-NLS-1$ + + howMuchMore + + Messages + .getString("RowDataDynamic.3") //$NON-NLS-1$ + + Messages + .getString("RowDataDynamic.4") //$NON-NLS-1$ + + Messages + .getString("RowDataDynamic.5") //$NON-NLS-1$ + + Messages + .getString("RowDataDynamic.6") //$NON-NLS-1$ + + this.owner.pointOfOrigin)); + } } } } - this.fields = null; + this.metadata = null; this.owner = null; } @@ -210,7 +245,7 @@ * @throws SQLException * if a database error occurs */ - public Object[] getAt(int ind) throws SQLException { + public ResultSetRow getAt(int ind) throws SQLException { notSupported(); return null; @@ -232,7 +267,7 @@ /** * @see com.mysql.jdbc.RowData#getOwner() */ - public ResultSet getOwner() { + public ResultSetInternalMethods getOwner() { return this.owner; } @@ -346,43 +381,55 @@ * @throws SQLException * if a database error occurs */ - public Object[] next() throws SQLException { - if (this.index != Integer.MAX_VALUE) { - this.index++; - } + public ResultSetRow next() throws SQLException { + - Object[] ret = this.nextRow; nextRecord(); - return ret; + if (this.nextRow == null && !this.streamerClosed && !this.moreResultsExisted) { + this.io.closeStreamer(this); + this.streamerClosed = true; + } + + if (this.nextRow != null) { + if (this.index != Integer.MAX_VALUE) { + this.index++; + } + } + + return this.nextRow; } private void nextRecord() throws SQLException { try { - if (!this.isAtEnd) { - - this.nextRow = this.io.nextRow(this.fields, this.columnCount, + if (!this.noMoreRows) { + this.nextRow = isInterrupted ? null : + this.io.nextRow(this.metadata, this.columnCount, this.isBinaryEncoded, - java.sql.ResultSet.CONCUR_READ_ONLY); + java.sql.ResultSet.CONCUR_READ_ONLY, true, + this.useBufferRowExplicit, true, null); if (this.nextRow == null) { - this.isAtEnd = true; - + this.noMoreRows = true; + this.isAfterEnd = true; + this.moreResultsExisted = this.io.tackOnMoreStreamingResults(this.owner); + if (this.index == -1) { this.wasEmpty = true; } } } else { this.isAfterEnd = true; } - } catch (CommunicationsException comEx) { - // Give a better error message - comEx.setWasStreamingResults(); - - throw comEx; } catch (SQLException sqlEx) { + if (sqlEx instanceof StreamingNotifiable) { + ((StreamingNotifiable)sqlEx).setWasStreamingResults(); + } else if (sqlEx instanceof MySQLQueryInterruptedException) { + this.isInterrupted = true; + } + // don't wrap SQLExceptions throw sqlEx; } catch (Exception ex) { @@ -392,10 +439,13 @@ exceptionMessage += Messages.getString("RowDataDynamic.7"); //$NON-NLS-1$ exceptionMessage += Util.stackTraceToString(ex); - throw new java.sql.SQLException( + SQLException sqlEx = SQLError.createSQLException( Messages.getString("RowDataDynamic.8") //$NON-NLS-1$ + exceptionType - + Messages.getString("RowDataDynamic.9") + exceptionMessage, SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$ + + Messages.getString("RowDataDynamic.9") + exceptionMessage, SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); //$NON-NLS-1$ + sqlEx.initCause(ex); + + throw sqlEx; } } @@ -415,9 +465,6 @@ notSupported(); } - // ~ Inner Classes - // ---------------------------------------------------------- - /** * Moves the current position in the result set to the given row number. * @@ -431,9 +478,9 @@ } /** - * @see com.mysql.jdbc.RowData#setOwner(com.mysql.jdbc.ResultSet) + * @see com.mysql.jdbc.RowData#setOwner(com.mysql.jdbc.ResultSetInternalMethods) */ - public void setOwner(ResultSet rs) { + public void setOwner(ResultSetImpl rs) { this.owner = rs; } @@ -449,7 +496,8 @@ public boolean wasEmpty() { return this.wasEmpty; } - - + public void setMetadata(Field[] metadata) { + this.metadata = metadata; + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataStatic.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataStatic.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataStatic.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/RowDataStatic.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,30 +1,29 @@ /* - Copyright (C) 2002-2006 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; -import java.util.ArrayList; +import java.sql.SQLException; import java.util.List; /** @@ -34,19 +33,21 @@ * @version $Id$ */ public class RowDataStatic implements RowData { + private Field[] metadata; + private int index; - ResultSet owner; + ResultSetImpl owner; - private List rows; + private List rows; /** * Creates a new RowDataStatic object. * * @param rows * DOCUMENT ME! */ - public RowDataStatic(ArrayList rows) { + public RowDataStatic(List rows) { this.index = -1; this.rows = rows; } @@ -57,7 +58,7 @@ * @param row * DOCUMENT ME! */ - public void addRow(byte[][] row) { + public void addRow(ResultSetRow row) { this.rows.add(row); } @@ -96,12 +97,12 @@ * * @return DOCUMENT ME! */ - public Object[] getAt(int atIndex) { + public ResultSetRow getAt(int atIndex) throws SQLException { if ((atIndex < 0) || (atIndex >= this.rows.size())) { return null; } - return (Object[]) this.rows.get(atIndex); + return (this.rows.get(atIndex)).setMetadata(this.metadata); } /** @@ -116,7 +117,7 @@ /** * @see com.mysql.jdbc.RowData#getOwner() */ - public ResultSet getOwner() { + public ResultSetInternalMethods getOwner() { return this.owner; } @@ -208,11 +209,13 @@ * * @return DOCUMENT ME! */ - public Object[] next() { + public ResultSetRow next() throws SQLException { this.index++; if (this.index < this.rows.size()) { - return (Object[]) this.rows.get(this.index); + ResultSetRow row = this.rows.get(this.index); + + return row.setMetadata(this.metadata); } return null; @@ -239,9 +242,9 @@ } /** - * @see com.mysql.jdbc.RowData#setOwner(com.mysql.jdbc.ResultSet) + * @see com.mysql.jdbc.RowData#setOwner(com.mysql.jdbc.ResultSetInternalMethods) */ - public void setOwner(ResultSet rs) { + public void setOwner(ResultSetImpl rs) { this.owner = rs; } @@ -257,4 +260,8 @@ public boolean wasEmpty() { return (this.rows != null && this.rows.size() == 0); } + + public void setMetadata(Field[] metadata) { + this.metadata = metadata; + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/SQLError.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/SQLError.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/SQLError.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/SQLError.java 30 Jul 2014 08:37:25 -0000 1.1.2.1 @@ -1,139 +1,179 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.BindException; import java.sql.DataTruncation; import java.sql.SQLException; import java.sql.SQLWarning; - import java.util.HashMap; import java.util.Hashtable; -import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import com.mysql.jdbc.exceptions.MySQLDataException; import com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException; import com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException; +import com.mysql.jdbc.exceptions.MySQLQueryInterruptedException; import com.mysql.jdbc.exceptions.MySQLSyntaxErrorException; import com.mysql.jdbc.exceptions.MySQLTransactionRollbackException; +import com.mysql.jdbc.exceptions.MySQLTransientConnectionException; /** * SQLError is a utility class that maps MySQL error codes to X/Open error codes * as is required by the JDBC spec. * * @author Mark Matthews - * @version $Id$ */ public class SQLError { static final int ER_WARNING_NOT_COMPLETE_ROLLBACK = 1196; - private static Map mysqlToSql99State; + private static Map mysqlToSql99State; - private static Map mysqlToSqlState; + private static Map mysqlToSqlState; + + // 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_PRIVILEGE_NOT_REVOKED = "01006"; + public static final String SQL_STATE_NO_DATA = "02000"; + public static final String SQL_STATE_WRONG_NO_OF_PARAMETERS = "07001"; + public static final String SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE = "08001"; + public static final String SQL_STATE_CONNECTION_IN_USE = "08002"; + public static final String SQL_STATE_CONNECTION_NOT_OPEN = "08003"; + public static final String SQL_STATE_CONNECTION_REJECTED = "08004"; + public static final String SQL_STATE_CONNECTION_FAILURE = "08006"; + public static final String SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN = "08007"; + public static final String SQL_STATE_COMMUNICATION_LINK_FAILURE = "08S01"; + public static final String SQL_STATE_FEATURE_NOT_SUPPORTED = "0A000"; + public static final String SQL_STATE_CARDINALITY_VIOLATION = "21000"; + public static final String SQL_STATE_INSERT_VALUE_LIST_NO_MATCH_COL_LIST = "21S01"; + public static final String SQL_STATE_STRING_DATA_RIGHT_TRUNCATION = "22001"; + public static final String SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE = "22003"; + public static final String SQL_STATE_INVALID_DATETIME_FORMAT = "22007"; + public static final String SQL_STATE_DATETIME_FIELD_OVERFLOW = "22008"; + public static final String SQL_STATE_DIVISION_BY_ZERO = "22012"; + public static final String SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST = "22018"; + public static final String SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION = "23000"; + public static final String SQL_STATE_INVALID_CURSOR_STATE = "24000"; + public static final String SQL_STATE_INVALID_TRANSACTION_STATE = "25000"; + public static final String SQL_STATE_INVALID_AUTH_SPEC = "28000"; + public static final String SQL_STATE_INVALID_TRANSACTION_TERMINATION = "2D000"; + public static final String SQL_STATE_INVALID_CONDITION_NUMBER = "35000"; + public static final String SQL_STATE_INVALID_CATALOG_NAME = "3D000"; + public static final String SQL_STATE_ROLLBACK_SERIALIZATION_FAILURE = "40001"; + public static final String SQL_STATE_SYNTAX_ERROR = "42000"; + public static final String SQL_STATE_ER_TABLE_EXISTS_ERROR = "42S01"; + public static final String SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND = "42S02"; + public static final String SQL_STATE_ER_NO_SUCH_INDEX = "42S12"; + public static final String SQL_STATE_ER_DUP_FIELDNAME = "42S21"; + public static final String SQL_STATE_ER_BAD_FIELD_ERROR = "42S22"; + + // SQL-99 + public static final String SQL_STATE_INVALID_CONNECTION_ATTRIBUTE = "01S00"; + public static final String SQL_STATE_ERROR_IN_ROW = "01S01"; + public static final String SQL_STATE_NO_ROWS_UPDATED_OR_DELETED = "01S03"; + public static final String SQL_STATE_MORE_THAN_ONE_ROW_UPDATED_OR_DELETED = "01S04"; + public static final String SQL_STATE_RESIGNAL_WHEN_HANDLER_NOT_ACTIVE = "0K000"; + public static final String SQL_STATE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER = "0Z002"; + public static final String SQL_STATE_CASE_NOT_FOUND_FOR_CASE_STATEMENT = "20000"; + public static final String SQL_STATE_NULL_VALUE_NOT_ALLOWED = "22004"; + public static final String SQL_STATE_INVALID_LOGARITHM_ARGUMENT = "2201E"; + public static final String SQL_STATE_ACTIVE_SQL_TRANSACTION = "25001"; + public static final String SQL_STATE_READ_ONLY_SQL_TRANSACTION = "25006"; + public static final String SQL_STATE_SRE_PROHIBITED_SQL_STATEMENT_ATTEMPTED = "2F003"; + public static final String SQL_STATE_SRE_FUNCTION_EXECUTED_NO_RETURN_STATEMENT = "2F005"; + public static final String SQL_STATE_DEADLOCK = "41000"; // non-standard ? + public static final String SQL_STATE_ER_QUERY_INTERRUPTED = "70100"; // non-standard ? + public static final String SQL_STATE_BASE_TABLE_OR_VIEW_ALREADY_EXISTS = "S0001"; + public static final String SQL_STATE_BASE_TABLE_NOT_FOUND = "S0002"; + public static final String SQL_STATE_INDEX_ALREADY_EXISTS = "S0011"; + public static final String SQL_STATE_INDEX_NOT_FOUND = "S0012"; + public static final String SQL_STATE_COLUMN_ALREADY_EXISTS = "S0021"; + public static final String SQL_STATE_COLUMN_NOT_FOUND = "S0022"; + public static final String SQL_STATE_NO_DEFAULT_FOR_COLUMN = "S0023"; + public static final String SQL_STATE_GENERAL_ERROR = "S1000"; + public static final String SQL_STATE_MEMORY_ALLOCATION_FAILURE = "S1001"; + public static final String SQL_STATE_INVALID_COLUMN_NUMBER = "S1002"; + public static final String SQL_STATE_ILLEGAL_ARGUMENT = "S1009"; + public static final String SQL_STATE_DRIVER_NOT_CAPABLE = "S1C00"; + public static final String SQL_STATE_TIMEOUT_EXPIRED = "S1T00"; + public static final String SQL_STATE_CLI_SPECIFIC_CONDITION = "HY000"; + public static final String SQL_STATE_MEMORY_ALLOCATION_ERROR = "HY001"; + public static final String SQL_STATE_XA_RBROLLBACK = "XA100"; + public static final String SQL_STATE_XA_RBDEADLOCK = "XA102"; + public static final String SQL_STATE_XA_RBTIMEOUT = "XA106"; + public static final String SQL_STATE_XA_RMERR = "XAE03"; + public static final String SQL_STATE_XAER_NOTA = "XAE04"; + public static final String SQL_STATE_XAER_INVAL = "XAE05"; + public static final String SQL_STATE_XAER_RMFAIL = "XAE07"; + public static final String SQL_STATE_XAER_DUPID = "XAE08"; + public static final String SQL_STATE_XAER_OUTSIDE = "XAE09"; - public static final String SQL_STATE_BASE_TABLE_NOT_FOUND = "S0002"; //$NON-NLS-1$ + private static Map sqlStateMessages; - public static final String SQL_STATE_BASE_TABLE_OR_VIEW_ALREADY_EXISTS = "S0001"; //$NON-NLS-1$ + private static final long DEFAULT_WAIT_TIMEOUT_SECONDS = 28800; - public static final String SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND = "42S02"; //$NON-NLS-1$ + private static final int DUE_TO_TIMEOUT_FALSE = 0; - public static final String SQL_STATE_COLUMN_ALREADY_EXISTS = "S0021"; //$NON-NLS-1$ + private static final int DUE_TO_TIMEOUT_MAYBE = 2; - public static final String SQL_STATE_COLUMN_NOT_FOUND = "S0022"; //$NON-NLS-1$ - - public static final String SQL_STATE_COMMUNICATION_LINK_FAILURE = "08S01"; //$NON-NLS-1$ - - public static final String SQL_STATE_CONNECTION_FAIL_DURING_TX = "08007"; //$NON-NLS-1$ - - public static final String SQL_STATE_CONNECTION_IN_USE = "08002"; //$NON-NLS-1$ - - public static final String SQL_STATE_CONNECTION_NOT_OPEN = "08003"; //$NON-NLS-1$ - - public static final String SQL_STATE_CONNECTION_REJECTED = "08004"; //$NON-NLS-1$ - - public static final String SQL_STATE_DATE_TRUNCATED = "01004"; //$NON-NLS-1$ - - public static final String SQL_STATE_DATETIME_FIELD_OVERFLOW = "22008"; //$NON-NLS-1$ - - public static final String SQL_STATE_DEADLOCK = "41000"; //$NON-NLS-1$ - - public static final String SQL_STATE_DISCONNECT_ERROR = "01002"; //$NON-NLS-1$ - - public static final String SQL_STATE_DIVISION_BY_ZERO = "22012"; //$NON-NLS-1$ - - public static final String SQL_STATE_DRIVER_NOT_CAPABLE = "S1C00"; //$NON-NLS-1$ - - public static final String SQL_STATE_ERROR_IN_ROW = "01S01"; //$NON-NLS-1$ - - public static final String SQL_STATE_GENERAL_ERROR = "S1000"; //$NON-NLS-1$ - - public static final String SQL_STATE_ILLEGAL_ARGUMENT = "S1009"; //$NON-NLS-1$ - - public static final String SQL_STATE_INDEX_ALREADY_EXISTS = "S0011"; //$NON-NLS-1$ - - public static final String SQL_STATE_INDEX_NOT_FOUND = "S0012"; //$NON-NLS-1$ - - public static final String SQL_STATE_INSERT_VALUE_LIST_NO_MATCH_COL_LIST = "21S01"; //$NON-NLS-1$ - - public static final String SQL_STATE_INVALID_AUTH_SPEC = "28000"; //$NON-NLS-1$ - - public static final String SQL_STATE_INVALID_CHARACTER_VALUE_FOR_CAST = "22018"; // $NON_NLS-1$ - - public static final String SQL_STATE_INVALID_COLUMN_NUMBER = "S1002"; //$NON-NLS-1$ - - public static final String SQL_STATE_INVALID_CONNECTION_ATTRIBUTE = "01S00"; //$NON-NLS-1$ - - public static final String SQL_STATE_MEMORY_ALLOCATION_FAILURE = "S1001"; //$NON-NLS-1$ - - public static final String SQL_STATE_MORE_THAN_ONE_ROW_UPDATED_OR_DELETED = "01S04"; //$NON-NLS-1$ - - public static final String SQL_STATE_NO_DEFAULT_FOR_COLUMN = "S0023"; //$NON-NLS-1$ - - public static final String SQL_STATE_NO_ROWS_UPDATED_OR_DELETED = "01S03"; //$NON-NLS-1$ - - public static final String SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE = "22003"; //$NON-NLS-1$ - - public static final String SQL_STATE_PRIVILEGE_NOT_REVOKED = "01006"; //$NON-NLS-1$ - - public static final String SQL_STATE_SYNTAX_ERROR = "42000"; //$NON-NLS-1$ - - public static final String SQL_STATE_TIMEOUT_EXPIRED = "S1T00"; //$NON-NLS-1$ - - public static final String SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN = "08007"; // $NON_NLS-1$ - - public static final String SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE = "08001"; //$NON-NLS-1$ - - public static final String SQL_STATE_WRONG_NO_OF_PARAMETERS = "07001"; //$NON-NLS-1$ + private static final int DUE_TO_TIMEOUT_TRUE = 1; - public static final String SQL_STATE_INVALID_TRANSACTION_TERMINATION = "2D000"; //$NON_NLS-1$ - - private static Map sqlStateMessages; - + private static final Constructor JDBC_4_COMMUNICATIONS_EXCEPTION_CTOR; + + private static Method THROWABLE_INIT_CAUSE_METHOD; + static { - sqlStateMessages = new HashMap(); + 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 }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_COMMUNICATIONS_EXCEPTION_CTOR = null; + } + + try { + THROWABLE_INIT_CAUSE_METHOD = Throwable.class.getMethod("initCause", new Class[] {Throwable.class}); + } catch (Throwable t) { + // we're not on a VM that has it + THROWABLE_INIT_CAUSE_METHOD = null; + } + + sqlStateMessages = new HashMap(); sqlStateMessages.put(SQL_STATE_DISCONNECT_ERROR, Messages .getString("SQLError.35")); //$NON-NLS-1$ sqlStateMessages.put(SQL_STATE_DATE_TRUNCATED, Messages @@ -158,7 +198,7 @@ .getString("SQLError.45")); //$NON-NLS-1$ sqlStateMessages.put(SQL_STATE_CONNECTION_REJECTED, Messages .getString("SQLError.46")); //$NON-NLS-1$ - sqlStateMessages.put(SQL_STATE_CONNECTION_FAIL_DURING_TX, Messages + sqlStateMessages.put(SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN, Messages .getString("SQLError.47")); //$NON-NLS-1$ sqlStateMessages.put(SQL_STATE_COMMUNICATION_LINK_FAILURE, Messages .getString("SQLError.48")); //$NON-NLS-1$ @@ -205,438 +245,447 @@ sqlStateMessages.put(SQL_STATE_TIMEOUT_EXPIRED, Messages .getString("SQLError.69")); //$NON-NLS-1$ - mysqlToSqlState = new Hashtable(); + mysqlToSqlState = new Hashtable(); - // - // Communications Errors - // - // ER_CON_COUNT_ERROR 1040 - // ER_BAD_HOST_ERROR 1042 - // ER_HANDSHAKE_ERROR 1043 - // ER_UNKNOWN_COM_ERROR 1047 - // ER_IPSOCK_ERROR 1081 - // - mysqlToSqlState.put(new Integer(1040), SQL_STATE_CONNECTION_REJECTED); - mysqlToSqlState.put(new Integer(1042), SQL_STATE_CONNECTION_REJECTED); - mysqlToSqlState.put(new Integer(1043), SQL_STATE_CONNECTION_REJECTED); - mysqlToSqlState.put(new Integer(1047), - SQL_STATE_COMMUNICATION_LINK_FAILURE); - mysqlToSqlState.put(new Integer(1081), - SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SELECT_REDUCED, SQL_STATE_WARNING); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WARN_TOO_FEW_RECORDS, SQL_STATE_WARNING); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WARN_TOO_MANY_RECORDS, SQL_STATE_WARNING); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WARN_DATA_TRUNCATED, SQL_STATE_WARNING); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_UNINIT_VAR, SQL_STATE_WARNING); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SIGNAL_WARN, SQL_STATE_WARNING); + mysqlToSqlState.put(MysqlErrorNumbers.ER_CON_COUNT_ERROR, SQL_STATE_CONNECTION_REJECTED); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NOT_SUPPORTED_AUTH_MODE, SQL_STATE_CONNECTION_REJECTED); + mysqlToSqlState.put(MysqlErrorNumbers.ER_BAD_HOST_ERROR, SQL_STATE_CONNECTION_REJECTED); // legacy, should be SQL_STATE_COMMUNICATION_LINK_FAILURE + mysqlToSqlState.put(MysqlErrorNumbers.ER_HANDSHAKE_ERROR, SQL_STATE_CONNECTION_REJECTED); // legacy, should be SQL_STATE_COMMUNICATION_LINK_FAILURE + mysqlToSqlState.put(MysqlErrorNumbers.ER_HOST_IS_BLOCKED, SQL_STATE_CONNECTION_REJECTED); // overrides HY000, why? + mysqlToSqlState.put(MysqlErrorNumbers.ER_HOST_NOT_PRIVILEGED, SQL_STATE_CONNECTION_REJECTED); // overrides HY000, why? + mysqlToSqlState.put(MysqlErrorNumbers.ER_UNKNOWN_COM_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SERVER_SHUTDOWN, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_FORCING_CLOSE, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_IPSOCK_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_ABORTING_CONNECTION, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NET_PACKET_TOO_LARGE, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NET_READ_ERROR_FROM_PIPE, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NET_FCNTL_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NET_PACKETS_OUT_OF_ORDER, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NET_UNCOMPRESS_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NET_READ_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NET_READ_INTERRUPTED, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NET_ERROR_ON_WRITE, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NET_WRITE_INTERRUPTED, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NEW_ABORTING_CONNECTION, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_MASTER_NET_READ, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_MASTER_NET_WRITE, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_CONNECT_TO_MASTER, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_BADSELECT, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_BADSTATEMENT, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_SUBSELECT_NYI, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSqlState.put(MysqlErrorNumbers.ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_NO_RETSET, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSqlState.put(MysqlErrorNumbers.ER_ALTER_OPERATION_NOT_SUPPORTED, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSqlState.put(MysqlErrorNumbers.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DBACCESS_DENIED_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_BAD_DB_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_FIELD_WITH_GROUP, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_GROUP_FIELD, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_SUM_SELECT, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_LONG_IDENT, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_DUP_FIELDNAME, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_ER_DUP_FIELDNAME + mysqlToSqlState.put(MysqlErrorNumbers.ER_DUP_KEYNAME, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_DUP_ENTRY, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_FIELD_SPEC, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_PARSE_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_EMPTY_QUERY, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NONUNIQ_TABLE, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_INVALID_DEFAULT, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_MULTIPLE_PRI_KEY, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_MANY_KEYS, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_MANY_KEY_PARTS, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_LONG_KEY, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_KEY_COLUMN_DOES_NOT_EXITS, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_BLOB_USED_AS_KEY, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_BIG_FIELDLENGTH, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_AUTO_KEY, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_NO_SUCH_INDEX, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_ER_NO_SUCH_INDEX + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_FIELD_TERMINATORS, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_BLOBS_AND_NO_TERMINATED, SQL_STATE_ILLEGAL_ARGUMENT); // legacy, should be SQL_STATE_SYNTAX_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_CANT_REMOVE_ALL_FIELDS, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_CANT_DROP_FIELD_OR_KEY, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_BLOB_CANT_HAVE_DEFAULT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_DB_NAME, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_TABLE_NAME, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_BIG_SELECT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_UNKNOWN_PROCEDURE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_PARAMCOUNT_TO_PROCEDURE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_FIELD_SPECIFIED_TWICE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_UNSUPPORTED_EXTENSION, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TABLE_MUST_HAVE_COLUMNS, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_UNKNOWN_CHARACTER_SET, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_BIG_ROWSIZE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_OUTER_JOIN, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NULL_COLUMN_IN_INDEX, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_PASSWORD_ANONYMOUS_USER, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_PASSWORD_NOT_ALLOWED, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_PASSWORD_NO_MATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_REGEXP_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_MIX_OF_GROUP_FUNC_AND_FIELDS, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NONEXISTING_GRANT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TABLEACCESS_DENIED_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_COLUMNACCESS_DENIED_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_ILLEGAL_GRANT_FOR_TABLE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_GRANT_WRONG_HOST_OR_USER, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NONEXISTING_TABLE_GRANT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NOT_ALLOWED_COMMAND, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SYNTAX_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_LONG_STRING, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TABLE_CANT_HANDLE_BLOB, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_COLUMN_NAME, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_KEY_COLUMN, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_BLOB_KEY_WITHOUT_LENGTH, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_PRIMARY_CANT_HAVE_NULL, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_MANY_ROWS, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_REQUIRES_PRIMARY_KEY, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_KEY_DOES_NOT_EXITS, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_CHECK_NO_SUCH_TABLE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_CHECK_NOT_IMPLEMENTED, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_MANY_USER_CONNECTIONS, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NO_PERMISSION_TO_CREATE_USER, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_USER_LIMIT_REACHED, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SPECIFIC_ACCESS_DENIED_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NO_DEFAULT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_VALUE_FOR_VAR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_TYPE_FOR_VAR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_CANT_USE_OPTION_HERE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NOT_SUPPORTED_YET, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_FK_DEF, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DERIVED_MUST_HAVE_ALIAS, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TABLENAME_NOT_ALLOWED_HERE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SPATIAL_CANT_HAVE_NULL, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_COLLATION_CHARSET_MISMATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_NAME_FOR_INDEX, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_NAME_FOR_CATALOG, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_UNKNOWN_STORAGE_ENGINE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_ALREADY_EXISTS, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_DOES_NOT_EXIST, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_LILABEL_MISMATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_LABEL_REDEFINE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_LABEL_MISMATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_BADRETURN, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_UPDATE_LOG_DEPRECATED_IGNORED, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_UPDATE_LOG_DEPRECATED_TRANSLATED, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_WRONG_NO_OF_ARGS, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_COND_MISMATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_NORETURN, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_BAD_CURSOR_QUERY, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_BAD_CURSOR_SELECT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_CURSOR_MISMATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_UNDECLARED_VAR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_DUP_PARAM, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_DUP_VAR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_DUP_COND, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_DUP_CURS, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_VARCOND_AFTER_CURSHNDLR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_CURSOR_AFTER_HANDLER, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_PROCACCESS_DENIED_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NONEXISTING_PROC_GRANT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_BAD_SQLSTATE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_CANT_CREATE_USER_WITH_GRANT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_DUP_HANDLER, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_NOT_VAR_ARG, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_BIG_SCALE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_BIG_PRECISION, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_M_BIGGER_THAN_D, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_LONG_BODY, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TOO_BIG_DISPLAYWIDTH, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_BAD_VAR_SHADOW, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_WRONG_NAME, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_NO_AGGREGATE, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_MAX_PREPARED_STMT_COUNT_REACHED, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NON_GROUPING_FIELD_USED, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_PARAMETERS_TO_NATIVE_FCT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_PARAMETERS_TO_STORED_FCT, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_FUNC_INEXISTENT_NAME_COLLISION, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DUP_SIGNAL_SET, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SPATIAL_MUST_HAVE_GEOM_COL, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TRUNCATE_ILLEGAL_FK, SQL_STATE_SYNTAX_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, SQL_STATE_CARDINALITY_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_OPERAND_COLUMNS, SQL_STATE_CARDINALITY_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SUBQUERY_NO_1_ROW, SQL_STATE_CARDINALITY_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DUP_KEY, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_BAD_NULL_ERROR, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NON_UNIQ_ERROR, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DUP_UNIQUE, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NO_REFERENCED_ROW, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_ROW_IS_REFERENCED, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_ROW_IS_REFERENCED_2, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NO_REFERENCED_ROW_2, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_FOREIGN_DUPLICATE_KEY, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DUP_ENTRY_WITH_KEY_NAME, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DUP_UNKNOWN_IN_INDEX, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DATA_TOO_LONG, SQL_STATE_STRING_DATA_RIGHT_TRUNCATION); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WARN_DATA_OUT_OF_RANGE, SQL_STATE_WARNING); // legacy, should be SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE + mysqlToSqlState.put(MysqlErrorNumbers.ER_CANT_CREATE_GEOMETRY_OBJECT, SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DATA_OUT_OF_RANGE, SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TRUNCATED_WRONG_VALUE, SQL_STATE_INVALID_DATETIME_FORMAT); + mysqlToSqlState.put(MysqlErrorNumbers.ER_ILLEGAL_VALUE_FOR_TYPE, SQL_STATE_INVALID_DATETIME_FORMAT); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DATETIME_FUNCTION_OVERFLOW, SQL_STATE_DATETIME_FIELD_OVERFLOW); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DIVISION_BY_ZERO, SQL_STATE_DIVISION_BY_ZERO); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_CURSOR_ALREADY_OPEN, SQL_STATE_INVALID_CURSOR_STATE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_SP_CURSOR_NOT_OPEN, SQL_STATE_INVALID_CURSOR_STATE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_CANT_DO_THIS_DURING_AN_TRANSACTION, SQL_STATE_INVALID_TRANSACTION_STATE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_READ_ONLY_TRANSACTION, SQL_STATE_INVALID_TRANSACTION_STATE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_ACCESS_DENIED_ERROR, SQL_STATE_INVALID_AUTH_SPEC); + mysqlToSqlState.put(MysqlErrorNumbers.ER_ACCESS_DENIED_NO_PASSWORD_ERROR, SQL_STATE_INVALID_AUTH_SPEC); + mysqlToSqlState.put(MysqlErrorNumbers.ER_ACCESS_DENIED_CHANGE_USER_ERROR, SQL_STATE_INVALID_AUTH_SPEC); + mysqlToSqlState.put(MysqlErrorNumbers.ER_DA_INVALID_CONDITION_NUMBER, SQL_STATE_INVALID_CONDITION_NUMBER); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NO_DB_ERROR, SQL_STATE_INVALID_CATALOG_NAME); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_VALUE_COUNT, SQL_STATE_INSERT_VALUE_LIST_NO_MATCH_COL_LIST); + mysqlToSqlState.put(MysqlErrorNumbers.ER_WRONG_VALUE_COUNT_ON_ROW, SQL_STATE_INSERT_VALUE_LIST_NO_MATCH_COL_LIST); + mysqlToSqlState.put(MysqlErrorNumbers.ER_TABLE_EXISTS_ERROR, SQL_STATE_ER_TABLE_EXISTS_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_BAD_TABLE_ERROR, SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND); + mysqlToSqlState.put(MysqlErrorNumbers.ER_UNKNOWN_TABLE, SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND); + mysqlToSqlState.put(MysqlErrorNumbers.ER_NO_SUCH_TABLE, SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND); + mysqlToSqlState.put(MysqlErrorNumbers.ER_BAD_FIELD_ERROR, SQL_STATE_COLUMN_NOT_FOUND); // legacy, should be SQL_STATE_ER_BAD_FIELD_ERROR + mysqlToSqlState.put(MysqlErrorNumbers.ER_ILLEGAL_REFERENCE, SQL_STATE_ER_BAD_FIELD_ERROR); + mysqlToSqlState.put(MysqlErrorNumbers.ER_OUTOFMEMORY, SQL_STATE_MEMORY_ALLOCATION_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_OUT_OF_SORTMEMORY, SQL_STATE_MEMORY_ALLOCATION_FAILURE); + mysqlToSqlState.put(MysqlErrorNumbers.ER_LOCK_WAIT_TIMEOUT, SQL_STATE_DEADLOCK); // overrides HY000, why? + mysqlToSqlState.put(MysqlErrorNumbers.ER_LOCK_DEADLOCK, SQL_STATE_DEADLOCK); // legacy, should be SQL_STATE_ROLLBACK_SERIALIZATION_FAILURE - // ER_HOST_IS_BLOCKED 1129 - // ER_HOST_NOT_PRIVILEGED 1130 - mysqlToSqlState.put(new Integer(1129), SQL_STATE_CONNECTION_REJECTED); - mysqlToSqlState.put(new Integer(1130), SQL_STATE_CONNECTION_REJECTED); + mysqlToSql99State = new HashMap(); - // - // Authentication Errors - // - // ER_ACCESS_DENIED_ERROR 1045 - // - mysqlToSqlState.put(new Integer(1045), SQL_STATE_INVALID_AUTH_SPEC); - - // - // Resource errors - // - // ER_CANT_CREATE_FILE 1004 - // ER_CANT_CREATE_TABLE 1005 - // ER_CANT_LOCK 1015 - // ER_DISK_FULL 1021 - // ER_CON_COUNT_ERROR 1040 - // ER_OUT_OF_RESOURCES 1041 - // - // Out-of-memory errors - // - // ER_OUTOFMEMORY 1037 - // ER_OUT_OF_SORTMEMORY 1038 - // - mysqlToSqlState.put(new Integer(1037), - SQL_STATE_MEMORY_ALLOCATION_FAILURE); - mysqlToSqlState.put(new Integer(1038), - SQL_STATE_MEMORY_ALLOCATION_FAILURE); - - // - // Syntax Errors - // - // ER_PARSE_ERROR 1064 - // ER_EMPTY_QUERY 1065 - // - mysqlToSqlState.put(new Integer(1064), SQL_STATE_SYNTAX_ERROR); - mysqlToSqlState.put(new Integer(1065), SQL_STATE_SYNTAX_ERROR); - - // - // Invalid argument errors - // - // ER_WRONG_FIELD_WITH_GROUP 1055 - // ER_WRONG_GROUP_FIELD 1056 - // ER_WRONG_SUM_SELECT 1057 - // ER_TOO_LONG_IDENT 1059 - // ER_DUP_FIELDNAME 1060 - // ER_DUP_KEYNAME 1061 - // ER_DUP_ENTRY 1062 - // ER_WRONG_FIELD_SPEC 1063 - // ER_NONUNIQ_TABLE 1066 - // ER_INVALID_DEFAULT 1067 - // ER_MULTIPLE_PRI_KEY 1068 - // ER_TOO_MANY_KEYS 1069 - // ER_TOO_MANY_KEY_PARTS 1070 - // ER_TOO_LONG_KEY 1071 - // ER_KEY_COLUMN_DOES_NOT_EXIST 1072 - // ER_BLOB_USED_AS_KEY 1073 - // ER_TOO_BIG_FIELDLENGTH 1074 - // ER_WRONG_AUTO_KEY 1075 - // ER_NO_SUCH_INDEX 1082 - // ER_WRONG_FIELD_TERMINATORS 1083 - // ER_BLOBS_AND_NO_TERMINATED 1084 - // - mysqlToSqlState.put(new Integer(1055), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1056), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1057), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1059), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1060), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1061), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1062), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1063), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1066), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1067), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1068), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1069), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1070), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1071), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1072), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1073), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1074), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1075), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1082), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1083), SQL_STATE_ILLEGAL_ARGUMENT); - mysqlToSqlState.put(new Integer(1084), SQL_STATE_ILLEGAL_ARGUMENT); - - // - // ER_WRONG_VALUE_COUNT 1058 - // - mysqlToSqlState.put(new Integer(1058), - SQL_STATE_INSERT_VALUE_LIST_NO_MATCH_COL_LIST); - - // ER_CANT_CREATE_DB 1006 - // ER_DB_CREATE_EXISTS 1007 - // ER_DB_DROP_EXISTS 1008 - // ER_DB_DROP_DELETE 1009 - // ER_DB_DROP_RMDIR 1010 - // ER_CANT_DELETE_FILE 1011 - // ER_CANT_FIND_SYSTEM_REC 1012 - // ER_CANT_GET_STAT 1013 - // ER_CANT_GET_WD 1014 - // ER_UNEXPECTED_EOF 1039 - // ER_CANT_OPEN_FILE 1016 - // ER_FILE_NOT_FOUND 1017 - // ER_CANT_READ_DIR 1018 - // ER_CANT_SET_WD 1019 - // ER_CHECKREAD 1020 - // ER_DUP_KEY 1022 - // ER_ERROR_ON_CLOSE 1023 - // ER_ERROR_ON_READ 1024 - // ER_ERROR_ON_RENAME 1025 - // ER_ERROR_ON_WRITE 1026 - // ER_FILE_USED 1027 - // ER_FILSORT_ABORT 1028 - // ER_FORM_NOT_FOUND 1029 - // ER_GET_ERRNO 1030 - // ER_ILLEGAL_HA 1031 - // ER_KEY_NOT_FOUND 1032 - // ER_NOT_FORM_FILE 1033 - // ER_DBACCESS_DENIED_ERROR 1044 - // ER_NO_DB_ERROR 1046 - // ER_BAD_NULL_ERROR 1048 - // ER_BAD_DB_ERROR 1049 - // ER_TABLE_EXISTS_ERROR 1050 - // ER_BAD_TABLE_ERROR 1051 - mysqlToSqlState.put(new Integer(1051), - SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND); - - // ER_NON_UNIQ_ERROR 1052 - // ER_BAD_FIELD_ERROR 1054 - mysqlToSqlState.put(new Integer(1054), SQL_STATE_COLUMN_NOT_FOUND); - - // ER_TEXTFILE_NOT_READABLE 1085 - // ER_FILE_EXISTS_ERROR 1086 - // ER_LOAD_INFO 1087 - // ER_ALTER_INFO 1088 - // ER_WRONG_SUB_KEY 1089 - // ER_CANT_REMOVE_ALL_FIELDS 1090 - // ER_CANT_DROP_FIELD_OR_KEY 1091 - // ER_INSERT_INFO 1092 - // ER_INSERT_TABLE_USED 1093 - // ER_LOCK_DEADLOCK 1213 - mysqlToSqlState.put(new Integer(1205), SQL_STATE_DEADLOCK); - mysqlToSqlState.put(new Integer(1213), SQL_STATE_DEADLOCK); - - mysqlToSql99State = new HashMap(); - - mysqlToSql99State.put(new Integer(1205), SQL_STATE_DEADLOCK); - mysqlToSql99State.put(new Integer(1213), SQL_STATE_DEADLOCK); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_DUP_KEY), - "23000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_OUTOFMEMORY), - "HY001"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_OUT_OF_SORTMEMORY), "HY001"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_CON_COUNT_ERROR), "08004"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_BAD_HOST_ERROR), - "08S01"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_HANDSHAKE_ERROR), "08S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_DBACCESS_DENIED_ERROR), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_ACCESS_DENIED_ERROR), "28000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_TABLE_EXISTS_ERROR), "42S01"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_BAD_TABLE_ERROR), "42S02"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_NON_UNIQ_ERROR), - "23000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_SERVER_SHUTDOWN), "08S01"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_BAD_FIELD_ERROR), "42S22"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_FIELD_WITH_GROUP), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_GROUP_FIELD), "42000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_WRONG_SUM_SELECT), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_VALUE_COUNT), "21S01"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_TOO_LONG_IDENT), - "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_DUP_FIELDNAME), - "42S21"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_DUP_KEYNAME), - "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_DUP_ENTRY), - "23000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_WRONG_FIELD_SPEC), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_PARSE_ERROR), - "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_EMPTY_QUERY), - "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_NONUNIQ_TABLE), - "42000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_INVALID_DEFAULT), "42000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_MULTIPLE_PRI_KEY), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_TOO_MANY_KEYS), - "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_TOO_MANY_KEY_PARTS), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_TOO_LONG_KEY), - "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_KEY_COLUMN_DOES_NOT_EXITS), "42000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_BLOB_USED_AS_KEY), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_TOO_BIG_FIELDLENGTH), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_WRONG_AUTO_KEY), - "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_FORCING_CLOSE), - "08S01"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_IPSOCK_ERROR), - "08S01"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_NO_SUCH_INDEX), - "42S12"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_FIELD_TERMINATORS), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_BLOBS_AND_NO_TERMINATED), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_CANT_REMOVE_ALL_FIELDS), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_CANT_DROP_FIELD_OR_KEY), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_BLOB_CANT_HAVE_DEFAULT), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_WRONG_DB_NAME), - "42000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_WRONG_TABLE_NAME), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_TOO_BIG_SELECT), - "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_UNKNOWN_PROCEDURE), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_PARAMCOUNT_TO_PROCEDURE), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_UNKNOWN_TABLE), - "42S02"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_FIELD_SPECIFIED_TWICE), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_UNSUPPORTED_EXTENSION), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_TABLE_MUST_HAVE_COLUMNS), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_UNKNOWN_CHARACTER_SET), "42000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_TOO_BIG_ROWSIZE), "42000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_WRONG_OUTER_JOIN), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NULL_COLUMN_IN_INDEX), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_PASSWORD_ANONYMOUS_USER), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_PASSWORD_NOT_ALLOWED), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_PASSWORD_NO_MATCH), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_VALUE_COUNT_ON_ROW), "21S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_INVALID_USE_OF_NULL), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_REGEXP_ERROR), - "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_MIX_OF_GROUP_FUNC_AND_FIELDS), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NONEXISTING_GRANT), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_TABLEACCESS_DENIED_ERROR), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_COLUMNACCESS_DENIED_ERROR), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_ILLEGAL_GRANT_FOR_TABLE), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_GRANT_WRONG_HOST_OR_USER), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_NO_SUCH_TABLE), - "42S02"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NONEXISTING_TABLE_GRANT), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NOT_ALLOWED_COMMAND), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_SYNTAX_ERROR), - "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_ABORTING_CONNECTION), "08S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NET_PACKET_TOO_LARGE), "08S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NET_READ_ERROR_FROM_PIPE), "08S01"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_NET_FCNTL_ERROR), "08S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NET_PACKETS_OUT_OF_ORDER), "08S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NET_UNCOMPRESS_ERROR), "08S01"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_NET_READ_ERROR), - "08S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NET_READ_INTERRUPTED), "08S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NET_ERROR_ON_WRITE), "08S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NET_WRITE_INTERRUPTED), "08S01"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_TOO_LONG_STRING), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_TABLE_CANT_HANDLE_BLOB), "42000"); - mysqlToSql99State - .put(new Integer( - MysqlErrorNumbers.ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), - "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_COLUMN_NAME), "42000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_WRONG_KEY_COLUMN), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_DUP_UNIQUE), - "23000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_BLOB_KEY_WITHOUT_LENGTH), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_PRIMARY_CANT_HAVE_NULL), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_TOO_MANY_ROWS), - "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_REQUIRES_PRIMARY_KEY), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_CHECK_NO_SUCH_TABLE), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_CHECK_NOT_IMPLEMENTED), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_CANT_DO_THIS_DURING_AN_TRANSACTION), - "25000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NEW_ABORTING_CONNECTION), "08S01"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_MASTER_NET_READ), "08S01"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_MASTER_NET_WRITE), "08S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_TOO_MANY_USER_CONNECTIONS), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_READ_ONLY_TRANSACTION), "25000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NO_PERMISSION_TO_CREATE_USER), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_LOCK_DEADLOCK), - "40001"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NO_REFERENCED_ROW), "23000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_ROW_IS_REFERENCED), "23000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_CONNECT_TO_MASTER), "08S01"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), - "21000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_USER_LIMIT_REACHED), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_NO_DEFAULT), - "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_VALUE_FOR_VAR), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_TYPE_FOR_VAR), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_CANT_USE_OPTION_HERE), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NOT_SUPPORTED_YET), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_WRONG_FK_DEF), - "42000"); - mysqlToSql99State.put( - new Integer(MysqlErrorNumbers.ER_OPERAND_COLUMNS), "21000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_SUBQUERY_NO_1_ROW), "21000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_ILLEGAL_REFERENCE), "42S22"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_DERIVED_MUST_HAVE_ALIAS), "42000"); - mysqlToSql99State.put(new Integer(MysqlErrorNumbers.ER_SELECT_REDUCED), - "01000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_TABLENAME_NOT_ALLOWED_HERE), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_NOT_SUPPORTED_AUTH_MODE), "08004"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_SPATIAL_CANT_HAVE_NULL), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_COLLATION_CHARSET_MISMATCH), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WARN_TOO_FEW_RECORDS), "01000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WARN_TOO_MANY_RECORDS), "01000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WARN_NULL_TO_NOTNULL), "01000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WARN_DATA_OUT_OF_RANGE), "01000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WARN_DATA_TRUNCATED), "01000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_NAME_FOR_INDEX), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_WRONG_NAME_FOR_CATALOG), "42000"); - mysqlToSql99State.put(new Integer( - MysqlErrorNumbers.ER_UNKNOWN_STORAGE_ENGINE), "42000"); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SELECT_REDUCED, SQL_STATE_WARNING); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WARN_TOO_FEW_RECORDS, SQL_STATE_WARNING); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WARN_TOO_MANY_RECORDS, SQL_STATE_WARNING); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WARN_DATA_TRUNCATED, SQL_STATE_WARNING); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WARN_NULL_TO_NOTNULL, SQL_STATE_WARNING); // legacy, should be SQL_STATE_NULL_VALUE_NOT_ALLOWED + mysqlToSql99State.put(MysqlErrorNumbers.ER_WARN_DATA_OUT_OF_RANGE, SQL_STATE_WARNING); // legacy, should be SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_UNINIT_VAR, SQL_STATE_WARNING); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SIGNAL_WARN, SQL_STATE_WARNING); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_FETCH_NO_DATA, SQL_STATE_NO_DATA); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SIGNAL_NOT_FOUND, SQL_STATE_NO_DATA); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CON_COUNT_ERROR, SQL_STATE_CONNECTION_REJECTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NOT_SUPPORTED_AUTH_MODE, SQL_STATE_CONNECTION_REJECTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_BAD_HOST_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_HANDSHAKE_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_UNKNOWN_COM_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SERVER_SHUTDOWN, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_FORCING_CLOSE, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_IPSOCK_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ABORTING_CONNECTION, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NET_PACKET_TOO_LARGE, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NET_READ_ERROR_FROM_PIPE, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NET_FCNTL_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NET_PACKETS_OUT_OF_ORDER, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NET_UNCOMPRESS_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NET_READ_ERROR, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NET_READ_INTERRUPTED, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NET_ERROR_ON_WRITE, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NET_WRITE_INTERRUPTED, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NEW_ABORTING_CONNECTION, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_MASTER_NET_READ, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_MASTER_NET_WRITE, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CONNECT_TO_MASTER, SQL_STATE_COMMUNICATION_LINK_FAILURE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_BADSELECT, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_BADSTATEMENT, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_SUBSELECT_NYI, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_NO_RETSET, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ALTER_OPERATION_NOT_SUPPORTED, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON, SQL_STATE_FEATURE_NOT_SUPPORTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DBACCESS_DENIED_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_BAD_DB_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_FIELD_WITH_GROUP, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_GROUP_FIELD, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_SUM_SELECT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_LONG_IDENT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DUP_KEYNAME, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_FIELD_SPEC, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_PARSE_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_EMPTY_QUERY, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NONUNIQ_TABLE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_INVALID_DEFAULT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_MULTIPLE_PRI_KEY, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_MANY_KEYS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_MANY_KEY_PARTS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_LONG_KEY, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_KEY_COLUMN_DOES_NOT_EXITS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_BLOB_USED_AS_KEY, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_BIG_FIELDLENGTH, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_AUTO_KEY, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_FIELD_TERMINATORS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_BLOBS_AND_NO_TERMINATED, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CANT_REMOVE_ALL_FIELDS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CANT_DROP_FIELD_OR_KEY, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_BLOB_CANT_HAVE_DEFAULT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_DB_NAME, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_TABLE_NAME, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_BIG_SELECT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_UNKNOWN_PROCEDURE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_PARAMCOUNT_TO_PROCEDURE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_FIELD_SPECIFIED_TWICE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_UNSUPPORTED_EXTENSION, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TABLE_MUST_HAVE_COLUMNS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_UNKNOWN_CHARACTER_SET, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_BIG_ROWSIZE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_OUTER_JOIN, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NULL_COLUMN_IN_INDEX, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_PASSWORD_ANONYMOUS_USER, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_PASSWORD_NOT_ALLOWED, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_PASSWORD_NO_MATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_REGEXP_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_MIX_OF_GROUP_FUNC_AND_FIELDS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NONEXISTING_GRANT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TABLEACCESS_DENIED_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_COLUMNACCESS_DENIED_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ILLEGAL_GRANT_FOR_TABLE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_GRANT_WRONG_HOST_OR_USER, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NONEXISTING_TABLE_GRANT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NOT_ALLOWED_COMMAND, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SYNTAX_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_LONG_STRING, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TABLE_CANT_HANDLE_BLOB, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_COLUMN_NAME, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_KEY_COLUMN, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_BLOB_KEY_WITHOUT_LENGTH, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_PRIMARY_CANT_HAVE_NULL, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_MANY_ROWS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_REQUIRES_PRIMARY_KEY, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_KEY_DOES_NOT_EXITS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CHECK_NO_SUCH_TABLE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CHECK_NOT_IMPLEMENTED, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_MANY_USER_CONNECTIONS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NO_PERMISSION_TO_CREATE_USER, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_USER_LIMIT_REACHED, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SPECIFIC_ACCESS_DENIED_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NO_DEFAULT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_VALUE_FOR_VAR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_TYPE_FOR_VAR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CANT_USE_OPTION_HERE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NOT_SUPPORTED_YET, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_FK_DEF, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DERIVED_MUST_HAVE_ALIAS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TABLENAME_NOT_ALLOWED_HERE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SPATIAL_CANT_HAVE_NULL, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_COLLATION_CHARSET_MISMATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_NAME_FOR_INDEX, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_NAME_FOR_CATALOG, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_UNKNOWN_STORAGE_ENGINE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_ALREADY_EXISTS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_DOES_NOT_EXIST, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_LILABEL_MISMATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_LABEL_REDEFINE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_LABEL_MISMATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_BADRETURN, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_UPDATE_LOG_DEPRECATED_IGNORED, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_UPDATE_LOG_DEPRECATED_TRANSLATED, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_WRONG_NO_OF_ARGS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_COND_MISMATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_NORETURN, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_BAD_CURSOR_QUERY, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_BAD_CURSOR_SELECT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_CURSOR_MISMATCH, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_UNDECLARED_VAR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_DUP_PARAM, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_DUP_VAR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_DUP_COND, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_DUP_CURS, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_VARCOND_AFTER_CURSHNDLR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_CURSOR_AFTER_HANDLER, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_PROCACCESS_DENIED_ERROR, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NONEXISTING_PROC_GRANT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_BAD_SQLSTATE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CANT_CREATE_USER_WITH_GRANT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_DUP_HANDLER, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_NOT_VAR_ARG, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_BIG_SCALE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_BIG_PRECISION, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_M_BIGGER_THAN_D, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_LONG_BODY, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TOO_BIG_DISPLAYWIDTH, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_BAD_VAR_SHADOW, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_WRONG_NAME, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_NO_AGGREGATE, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_MAX_PREPARED_STMT_COUNT_REACHED, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NON_GROUPING_FIELD_USED, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_PARAMETERS_TO_NATIVE_FCT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_PARAMETERS_TO_STORED_FCT, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_FUNC_INEXISTENT_NAME_COLLISION, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DUP_SIGNAL_SET, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SPATIAL_MUST_HAVE_GEOM_COL, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TRUNCATE_ILLEGAL_FK, SQL_STATE_SYNTAX_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, SQL_STATE_CARDINALITY_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_OPERAND_COLUMNS, SQL_STATE_CARDINALITY_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SUBQUERY_NO_1_ROW, SQL_STATE_CARDINALITY_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DUP_KEY, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_BAD_NULL_ERROR, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NON_UNIQ_ERROR, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DUP_ENTRY, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DUP_UNIQUE, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NO_REFERENCED_ROW, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ROW_IS_REFERENCED, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ROW_IS_REFERENCED_2, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NO_REFERENCED_ROW_2, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_FOREIGN_DUPLICATE_KEY, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DUP_ENTRY_WITH_KEY_NAME, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DUP_UNKNOWN_IN_INDEX, SQL_STATE_INTEGRITY_CONSTRAINT_VIOLATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DATA_TOO_LONG, SQL_STATE_STRING_DATA_RIGHT_TRUNCATION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CANT_CREATE_GEOMETRY_OBJECT, SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DATA_OUT_OF_RANGE, SQL_STATE_NUMERIC_VALUE_OUT_OF_RANGE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TRUNCATED_WRONG_VALUE, SQL_STATE_INVALID_DATETIME_FORMAT); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ILLEGAL_VALUE_FOR_TYPE, SQL_STATE_INVALID_DATETIME_FORMAT); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DATETIME_FUNCTION_OVERFLOW, SQL_STATE_DATETIME_FIELD_OVERFLOW); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DIVISION_BY_ZERO, SQL_STATE_DIVISION_BY_ZERO); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_CURSOR_ALREADY_OPEN, SQL_STATE_INVALID_CURSOR_STATE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_CURSOR_NOT_OPEN, SQL_STATE_INVALID_CURSOR_STATE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CANT_DO_THIS_DURING_AN_TRANSACTION, SQL_STATE_INVALID_TRANSACTION_STATE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_READ_ONLY_TRANSACTION, SQL_STATE_INVALID_TRANSACTION_STATE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ACCESS_DENIED_ERROR, SQL_STATE_INVALID_AUTH_SPEC); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ACCESS_DENIED_NO_PASSWORD_ERROR, SQL_STATE_INVALID_AUTH_SPEC); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ACCESS_DENIED_CHANGE_USER_ERROR, SQL_STATE_INVALID_AUTH_SPEC); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DA_INVALID_CONDITION_NUMBER, SQL_STATE_INVALID_CONDITION_NUMBER); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NO_DB_ERROR, SQL_STATE_INVALID_CATALOG_NAME); + mysqlToSql99State.put(MysqlErrorNumbers.ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER, SQL_STATE_RESIGNAL_WHEN_HANDLER_NOT_ACTIVE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_GET_STACKED_DA_WITHOUT_ACTIVE_HANDLER, SQL_STATE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_CASE_NOT_FOUND, SQL_STATE_CASE_NOT_FOUND_FOR_CASE_STATEMENT); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_VALUE_COUNT, SQL_STATE_INSERT_VALUE_LIST_NO_MATCH_COL_LIST); + mysqlToSql99State.put(MysqlErrorNumbers.ER_WRONG_VALUE_COUNT_ON_ROW, SQL_STATE_INSERT_VALUE_LIST_NO_MATCH_COL_LIST); + mysqlToSql99State.put(MysqlErrorNumbers.ER_INVALID_USE_OF_NULL, SQL_STATE_SYNTAX_ERROR); // legacy, must be SQL_STATE_NULL_VALUE_NOT_ALLOWED + mysqlToSql99State.put(MysqlErrorNumbers.ER_INVALID_ARGUMENT_FOR_LOGARITHM, SQL_STATE_INVALID_LOGARITHM_ARGUMENT); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CANT_CHANGE_TX_ISOLATION, SQL_STATE_ACTIVE_SQL_TRANSACTION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, SQL_STATE_READ_ONLY_SQL_TRANSACTION); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_NO_RECURSIVE_CREATE, SQL_STATE_SRE_PROHIBITED_SQL_STATEMENT_ATTEMPTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_SP_NORETURNEND, SQL_STATE_SRE_FUNCTION_EXECUTED_NO_RETURN_STATEMENT); + mysqlToSql99State.put(MysqlErrorNumbers.ER_TABLE_EXISTS_ERROR, SQL_STATE_ER_TABLE_EXISTS_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_BAD_TABLE_ERROR, SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND); + mysqlToSql99State.put(MysqlErrorNumbers.ER_UNKNOWN_TABLE, SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NO_SUCH_TABLE, SQL_STATE_BASE_TABLE_OR_VIEW_NOT_FOUND); + mysqlToSql99State.put(MysqlErrorNumbers.ER_NO_SUCH_INDEX, SQL_STATE_ER_NO_SUCH_INDEX); + mysqlToSql99State.put(MysqlErrorNumbers.ER_DUP_FIELDNAME, SQL_STATE_ER_DUP_FIELDNAME); + mysqlToSql99State.put(MysqlErrorNumbers.ER_BAD_FIELD_ERROR, SQL_STATE_ER_BAD_FIELD_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_ILLEGAL_REFERENCE, SQL_STATE_ER_BAD_FIELD_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_QUERY_INTERRUPTED, SQL_STATE_ER_QUERY_INTERRUPTED); + mysqlToSql99State.put(MysqlErrorNumbers.ER_OUTOFMEMORY, SQL_STATE_MEMORY_ALLOCATION_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_OUT_OF_SORTMEMORY, SQL_STATE_MEMORY_ALLOCATION_ERROR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_XA_RBROLLBACK, SQL_STATE_XA_RBROLLBACK); + mysqlToSql99State.put(MysqlErrorNumbers.ER_XA_RBDEADLOCK, SQL_STATE_XA_RBDEADLOCK); + mysqlToSql99State.put(MysqlErrorNumbers.ER_XA_RBTIMEOUT, SQL_STATE_XA_RBTIMEOUT); + mysqlToSql99State.put(MysqlErrorNumbers.ER_XA_RMERR, SQL_STATE_XA_RMERR); + mysqlToSql99State.put(MysqlErrorNumbers.ER_XAER_NOTA, SQL_STATE_XAER_NOTA); + mysqlToSql99State.put(MysqlErrorNumbers.ER_XAER_INVAL, SQL_STATE_XAER_INVAL); + mysqlToSql99State.put(MysqlErrorNumbers.ER_XAER_RMFAIL, SQL_STATE_XAER_RMFAIL); + mysqlToSql99State.put(MysqlErrorNumbers.ER_XAER_DUPID, SQL_STATE_XAER_DUPID); + mysqlToSql99State.put(MysqlErrorNumbers.ER_XAER_OUTSIDE, SQL_STATE_XAER_OUTSIDE); + mysqlToSql99State.put(MysqlErrorNumbers.ER_LOCK_WAIT_TIMEOUT, SQL_STATE_DEADLOCK); // overriding HY000, why? + mysqlToSql99State.put(MysqlErrorNumbers.ER_LOCK_DEADLOCK, SQL_STATE_DEADLOCK); // legacy, should be SQL_STATE_ROLLBACK_SERIALIZATION_FAILURE } /** @@ -713,9 +762,9 @@ int code = warnRs.getInt("Code"); //$NON-NLS-1$ if (forTruncationOnly) { - if (code == 1265 || code == 1264) { + if (code == MysqlErrorNumbers.ER_WARN_DATA_TRUNCATED || code == MysqlErrorNumbers.ER_WARN_DATA_OUT_OF_RANGE) { DataTruncation newTruncation = new MysqlDataTruncation( - warnRs.getString("Message"), 0, false, false, 0, 0); //$NON-NLS-1$ + warnRs.getString("Message"), 0, false, false, 0, 0, code); //$NON-NLS-1$ if (currentWarning == null) { currentWarning = newTruncation; @@ -724,7 +773,7 @@ } } } else { - String level = warnRs.getString("Level"); //$NON-NLS-1$ + //String level = warnRs.getString("Level"); //$NON-NLS-1$ String message = warnRs.getString("Message"); //$NON-NLS-1$ SQLWarning newWarning = new SQLWarning(message, SQLError @@ -773,24 +822,20 @@ } public static void dumpSqlStatesMappingsAsXml() throws Exception { - TreeMap allErrorNumbers = new TreeMap(); - Map mysqlErrorNumbersToNames = new HashMap(); + TreeMap allErrorNumbers = new TreeMap(); + Map mysqlErrorNumbersToNames = new HashMap(); - Integer errorNumber = null; +// Integer errorNumber = null; // // First create a list of all 'known' error numbers that // are mapped. // - for (Iterator mysqlErrorNumbers = mysqlToSql99State.keySet().iterator(); mysqlErrorNumbers - .hasNext();) { - errorNumber = (Integer) mysqlErrorNumbers.next(); + for (Integer errorNumber : mysqlToSql99State.keySet()) { allErrorNumbers.put(errorNumber, errorNumber); } - for (Iterator mysqlErrorNumbers = mysqlToSqlState.keySet().iterator(); mysqlErrorNumbers - .hasNext();) { - errorNumber = (Integer) mysqlErrorNumbers.next(); + for (Integer errorNumber : mysqlToSqlState.keySet()) { allErrorNumbers.put(errorNumber, errorNumber); } @@ -811,10 +856,7 @@ System.out.println(""); - for (Iterator allErrorNumbersIter = allErrorNumbers.keySet().iterator(); allErrorNumbersIter - .hasNext();) { - errorNumber = (Integer) allErrorNumbersIter.next(); - + for (Integer errorNumber : allErrorNumbers.keySet()) { String sql92State = mysqlToSql99(errorNumber.intValue()); String oldSqlState = mysqlToXOpen(errorNumber.intValue()); @@ -831,17 +873,17 @@ } static String get(String stateCode) { - return (String) sqlStateMessages.get(stateCode); + return sqlStateMessages.get(stateCode); } private static String mysqlToSql99(int errno) { - Integer err = new Integer(errno); + Integer err = Integer.valueOf(errno); if (mysqlToSql99State.containsKey(err)) { - return (String) mysqlToSql99State.get(err); + return mysqlToSql99State.get(err); } - return "HY000"; + return SQL_STATE_CLI_SPECIFIC_CONDITION; } /** @@ -861,10 +903,10 @@ } private static String mysqlToXOpen(int errno) { - Integer err = new Integer(errno); + Integer err = Integer.valueOf(errno); if (mysqlToSqlState.containsKey(err)) { - return (String) mysqlToSqlState.get(err); + return mysqlToSqlState.get(err); } return SQL_STATE_GENERAL_ERROR; @@ -882,67 +924,437 @@ */ public static SQLException createSQLException(String message, - String sqlState) { - if (sqlState != null) { - if (sqlState.startsWith("08")) { - return new MySQLNonTransientConnectionException(message, - sqlState); + String sqlState, ExceptionInterceptor interceptor) { + return createSQLException(message, sqlState, 0, interceptor); + } + + public static SQLException createSQLException(String message, ExceptionInterceptor interceptor) { + return createSQLException(message, interceptor, null); + } + public static SQLException createSQLException(String message, ExceptionInterceptor interceptor, Connection conn) { + SQLException sqlEx = new SQLException(message); + + if (interceptor != null) { + SQLException interceptedEx = interceptor.interceptException(sqlEx, conn); + + if (interceptedEx != null) { + return interceptedEx; } + } + + return sqlEx; + } - if (sqlState.startsWith("22")) { - return new MySQLDataException(message, sqlState); + public static SQLException createSQLException(String message, String sqlState, Throwable cause, ExceptionInterceptor interceptor) { + return createSQLException(message, sqlState, cause, interceptor, null); + } + public static SQLException createSQLException(String message, String sqlState, Throwable cause, ExceptionInterceptor interceptor, + Connection conn) { + if (THROWABLE_INIT_CAUSE_METHOD == null) { + if (cause != null) { + message = message + " due to " + cause.toString(); } + } + + SQLException sqlEx = createSQLException(message, sqlState, interceptor); + + if (cause != null && THROWABLE_INIT_CAUSE_METHOD != null) { + try { + THROWABLE_INIT_CAUSE_METHOD.invoke(sqlEx, new Object[] {cause}); + } catch (Throwable t) { + // we're not going to muck with that here, since it's + // an error condition anyway! + } + } + + if (interceptor != null) { + SQLException interceptedEx = interceptor.interceptException(sqlEx, conn); + + if (interceptedEx != null) { + return interceptedEx; + } + } + + return sqlEx; + } + + public static SQLException createSQLException(String message, + String sqlState, int vendorErrorCode, ExceptionInterceptor interceptor) { + return createSQLException(message, sqlState, vendorErrorCode, false, interceptor); + } + + /** + * + * @param message + * @param sqlState + * @param vendorErrorCode + * @param isTransient + * @param interceptor + * @return + */ + public static SQLException createSQLException(String message, + String sqlState, int vendorErrorCode, boolean isTransient, ExceptionInterceptor interceptor) { + return createSQLException(message, sqlState, vendorErrorCode, isTransient, interceptor, null); + } + public static SQLException createSQLException(String message, + String sqlState, int vendorErrorCode, boolean isTransient, ExceptionInterceptor interceptor, Connection conn) { + try { + SQLException sqlEx = null; + + if (sqlState != null) { + if (sqlState.startsWith("08")) { + if (isTransient) { + 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); + } + } 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); + } + } 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); + } + } else if (sqlState.startsWith("23")) { - if (sqlState.startsWith("23")) { - return new MySQLIntegrityConstraintViolationException(message, - sqlState); + 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); + } + } 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); + } + } 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); + } + } 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); + } + } else { + sqlEx = new SQLException(message, sqlState, vendorErrorCode); + } + } else { + sqlEx = new SQLException(message, sqlState, vendorErrorCode); } + + if (interceptor != null) { + SQLException interceptedEx = interceptor.interceptException(sqlEx, conn); + + if (interceptedEx != null) { + return interceptedEx; + } + } + + return sqlEx; + } 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); + + if (interceptor != null) { + SQLException interceptedEx = interceptor.interceptException(unexpectedEx, conn); + + if (interceptedEx != null) { + return interceptedEx; + } + } + + return unexpectedEx; + } + } + + public static SQLException createCommunicationsException(MySQLConnection conn, long lastPacketSentTimeMs, + long lastPacketReceivedTimeMs, + Exception underlyingException, ExceptionInterceptor interceptor) { + SQLException exToReturn = null; + + if (!Util.isJdbc4()) { + exToReturn = new CommunicationsException(conn, lastPacketSentTimeMs, lastPacketReceivedTimeMs, underlyingException); + } else { + + try { + exToReturn = (SQLException) Util.handleNewInstance(JDBC_4_COMMUNICATIONS_EXCEPTION_CTOR, new Object[] { + conn, Long.valueOf(lastPacketSentTimeMs), Long.valueOf(lastPacketReceivedTimeMs), underlyingException}, interceptor); + } catch (SQLException sqlEx) { + // We should _never_ get this, but let's not swallow it either + + return sqlEx; + } + } + + if (THROWABLE_INIT_CAUSE_METHOD != null && underlyingException != null) { + try { + THROWABLE_INIT_CAUSE_METHOD.invoke(exToReturn, new Object[] {underlyingException}); + } catch (Throwable t) { + // we're not going to muck with that here, since it's + // an error condition anyway! + } + } + + if (interceptor != null) { + SQLException interceptedEx = interceptor.interceptException(exToReturn, conn); + + if (interceptedEx != null) { + return interceptedEx; + } + } + + return exToReturn; + } + + /** + * Creates a communications link failure message to be used + * in CommunicationsException that (hopefully) has some better + * information and suggestions based on heuristics. + * + * @param conn + * @param lastPacketSentTimeMs + * @param underlyingException + * @param streamingResultSetInPlay + * @return + */ + public static String createLinkFailureMessageBasedOnHeuristics( + MySQLConnection conn, + long lastPacketSentTimeMs, + long lastPacketReceivedTimeMs, + Exception underlyingException, + boolean streamingResultSetInPlay) { + long serverTimeoutSeconds = 0; + boolean isInteractiveClient = false; - if (sqlState.startsWith("42")) { - return new MySQLSyntaxErrorException(message, sqlState); + if (conn != null) { + isInteractiveClient = conn.getInteractiveClient(); + + String serverTimeoutSecondsStr = null; + + if (isInteractiveClient) { + serverTimeoutSecondsStr = conn + .getServerVariable("interactive_timeout"); //$NON-NLS-1$ + } else { + serverTimeoutSecondsStr = conn + .getServerVariable("wait_timeout"); //$NON-NLS-1$ } - if (sqlState.startsWith("40")) { - return new MySQLTransactionRollbackException(message, sqlState); + if (serverTimeoutSecondsStr != null) { + try { + serverTimeoutSeconds = Long + .parseLong(serverTimeoutSecondsStr); + } catch (NumberFormatException nfe) { + serverTimeoutSeconds = 0; + } } } - return new SQLException(message, sqlState); - } + StringBuffer exceptionMessageBuf = new StringBuffer(); + + long nowMs = System.currentTimeMillis(); + + if (lastPacketSentTimeMs == 0) { + lastPacketSentTimeMs = nowMs; + } - public static SQLException createSQLException(String message) { - return new SQLException(message); - } + long timeSinceLastPacketSentMs = (nowMs - lastPacketSentTimeMs); + long timeSinceLastPacketSeconds = timeSinceLastPacketSentMs / 1000; + + long timeSinceLastPacketReceivedMs = (nowMs - lastPacketReceivedTimeMs); + + int dueToTimeout = DUE_TO_TIMEOUT_FALSE; - public static SQLException createSQLException(String message, - String sqlState, int vendorErrorCode) { - if (sqlState != null) { - if (sqlState.startsWith("08")) { - return new MySQLNonTransientConnectionException(message, - sqlState, vendorErrorCode); - } + StringBuffer timeoutMessageBuf = null; - if (sqlState.startsWith("22")) { - return new MySQLDataException(message, sqlState, - vendorErrorCode); + if (streamingResultSetInPlay) { + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.ClientWasStreaming")); //$NON-NLS-1$ + } else { + if (serverTimeoutSeconds != 0) { + if (timeSinceLastPacketSeconds > serverTimeoutSeconds) { + dueToTimeout = DUE_TO_TIMEOUT_TRUE; + + timeoutMessageBuf = new StringBuffer(); + + timeoutMessageBuf.append(Messages + .getString("CommunicationsException.2")); //$NON-NLS-1$ + + if (!isInteractiveClient) { + timeoutMessageBuf.append(Messages + .getString("CommunicationsException.3")); //$NON-NLS-1$ + } else { + timeoutMessageBuf.append(Messages + .getString("CommunicationsException.4")); //$NON-NLS-1$ + } + + } + } else if (timeSinceLastPacketSeconds > DEFAULT_WAIT_TIMEOUT_SECONDS) { + dueToTimeout = DUE_TO_TIMEOUT_MAYBE; + + timeoutMessageBuf = new StringBuffer(); + + timeoutMessageBuf.append(Messages + .getString("CommunicationsException.5")); //$NON-NLS-1$ + timeoutMessageBuf.append(Messages + .getString("CommunicationsException.6")); //$NON-NLS-1$ + timeoutMessageBuf.append(Messages + .getString("CommunicationsException.7")); //$NON-NLS-1$ + timeoutMessageBuf.append(Messages + .getString("CommunicationsException.8")); //$NON-NLS-1$ } - if (sqlState.startsWith("23")) { - return new MySQLIntegrityConstraintViolationException(message, - sqlState, vendorErrorCode); + if (dueToTimeout == DUE_TO_TIMEOUT_TRUE + || dueToTimeout == DUE_TO_TIMEOUT_MAYBE) { + + if (lastPacketReceivedTimeMs != 0) { + Object[] timingInfo = { + Long.valueOf(timeSinceLastPacketReceivedMs), + Long.valueOf(timeSinceLastPacketSentMs) + }; + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.ServerPacketTimingInfo", //$NON-NLS-1$ + timingInfo)); + } else { + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.ServerPacketTimingInfoNoRecv", //$NON-NLS-1$ + new Object[] { Long.valueOf(timeSinceLastPacketSentMs)})); + } + + if (timeoutMessageBuf != null) { + exceptionMessageBuf.append(timeoutMessageBuf); + } + + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.11")); //$NON-NLS-1$ + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.12")); //$NON-NLS-1$ + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.13")); //$NON-NLS-1$ + + } else { + // + // Attempt to determine the reason for the underlying exception + // (we can only make a best-guess here) + // + + if (underlyingException instanceof BindException) { + if (conn.getLocalSocketAddress() != null + && !Util.interfaceExists(conn + .getLocalSocketAddress())) { + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.LocalSocketAddressNotAvailable")); //$NON-NLS-1$ + } else { + // too many client connections??? + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.TooManyClientConnections")); //$NON-NLS-1$ + } + } } + } - if (sqlState.startsWith("42")) { - return new MySQLSyntaxErrorException(message, sqlState, - vendorErrorCode); + if (exceptionMessageBuf.length() == 0) { + // We haven't figured out a good reason, so copy it. + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.20")); //$NON-NLS-1$ + + if (THROWABLE_INIT_CAUSE_METHOD == null && + underlyingException != null) { + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.21")); //$NON-NLS-1$ + exceptionMessageBuf.append(Util + .stackTraceToString(underlyingException)); } - if (sqlState.startsWith("40")) { - return new MySQLTransactionRollbackException(message, sqlState, - vendorErrorCode); + if (conn != null && conn.getMaintainTimeStats() + && !conn.getParanoid()) { + exceptionMessageBuf.append("\n\n"); //$NON-NLS-1$ + if (lastPacketReceivedTimeMs != 0) { + Object[] timingInfo = { + Long.valueOf(timeSinceLastPacketReceivedMs), + Long.valueOf(timeSinceLastPacketSentMs) + }; + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.ServerPacketTimingInfo", //$NON-NLS-1$ + timingInfo)); + } else { + exceptionMessageBuf.append(Messages + .getString("CommunicationsException.ServerPacketTimingInfoNoRecv", //$NON-NLS-1$ + new Object[] {Long.valueOf(timeSinceLastPacketSentMs)})); + } } } + + return exceptionMessageBuf.toString(); + } + + public static SQLException notImplemented() { + if (Util.isJdbc4()) { + try { + return (SQLException) Class.forName( + "java.sql.SQLFeatureNotSupportedException") + .newInstance(); + } catch (Throwable t) { + // proceed + } + } - return new SQLException(message, sqlState, vendorErrorCode); + return new NotImplemented(); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Security.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Security.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Security.java 17 Aug 2012 14:57:08 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Security.java 30 Jul 2014 08:37:25 -0000 1.1.2.1 @@ -1,29 +1,29 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; +import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -34,7 +34,7 @@ * * @version $Id$ */ -class Security { +public class Security { private static final char PVERSION41_CHAR = '*'; private static final int SHA1_HASH_SIZE = 20; @@ -231,17 +231,18 @@ * IN Data for encryption * @param to * OUT Encrypt data to the buffer (may be the same) - * @param password - * IN Password used for encryption (same length) + * @param scramble + * IN Scramble used for encryption * @param length * IN Length of data to encrypt */ - static void passwordCrypt(byte[] from, byte[] to, byte[] password, + public static void xorString(byte[] from, byte[] to, byte[] scramble, int length) { int pos = 0; + int scrambleLength = scramble.length; - while ((pos < from.length) && (pos < length)) { - to[pos] = (byte) (from[pos] ^ password[pos]); + while (pos < length) { + to[pos] = (byte) (from[pos] ^ scramble[pos % scrambleLength]); pos++; } } @@ -274,7 +275,7 @@ cleansedPassword.append(c); } - return md.digest(cleansedPassword.toString().getBytes()); + return md.digest(StringUtils.getBytes(cleansedPassword.toString())); } /** @@ -319,17 +320,20 @@ // hash_stage1=xor(reply, sha1(public_seed,hash_stage2)) // candidate_hash2=sha1(hash_stage1) // check(candidate_hash2==hash_stage2) - static byte[] scramble411(String password, String seed) - throws NoSuchAlgorithmException { + public static byte[] scramble411(String password, String seed, String passwordEncoding) + throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest md = MessageDigest.getInstance("SHA-1"); //$NON-NLS-1$ - - byte[] passwordHashStage1 = md.digest(password.getBytes()); + + byte[] passwordHashStage1 = md + .digest((passwordEncoding == null || passwordEncoding.length() == 0) ? + StringUtils.getBytes(password) + : StringUtils.getBytes(password, passwordEncoding)); md.reset(); byte[] passwordHashStage2 = md.digest(passwordHashStage1); md.reset(); - byte[] seedAsBytes = seed.getBytes(); // for debugging + byte[] seedAsBytes = StringUtils.getBytes(seed, "ASCII"); // for debugging md.update(seedAsBytes); md.update(passwordHashStage2); Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/SequentialBalanceStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerPreparedStatement.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerPreparedStatement.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerPreparedStatement.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerPreparedStatement.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,62 +1,57 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; -import com.mysql.jdbc.PreparedStatement.BatchParams; -import com.mysql.jdbc.Statement.CancelTask; -import com.mysql.jdbc.exceptions.MySQLTimeoutException; -import com.mysql.jdbc.profiler.ProfileEventSink; -import com.mysql.jdbc.profiler.ProfilerEvent; - -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.UnsupportedEncodingException; - +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; - import java.net.URL; - import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Date; import java.sql.ParameterMetaData; import java.sql.Ref; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; import java.sql.Types; - import java.util.ArrayList; -import java.util.BitSet; import java.util.Calendar; -import java.util.Locale; +import java.util.GregorianCalendar; import java.util.TimeZone; +import com.mysql.jdbc.exceptions.MySQLStatementCancelledException; +import com.mysql.jdbc.exceptions.MySQLTimeoutException; +import com.mysql.jdbc.log.LogUtils; +import com.mysql.jdbc.profiler.ProfilerEvent; + /** * JDBC Interface for MySQL-4.1 and newer server-side PreparedStatements. * @@ -65,10 +60,31 @@ * mmatthews Exp $ */ public class ServerPreparedStatement extends PreparedStatement { + private static final Constructor JDBC_4_SPS_CTOR; + + static { + if (Util.isJdbc4()) { + try { + JDBC_4_SPS_CTOR = Class.forName("com.mysql.jdbc.JDBC4ServerPreparedStatement") + .getConstructor( + new Class[] { MySQLConnection.class, String.class, String.class, + Integer.TYPE, Integer.TYPE}); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_SPS_CTOR = null; + } + } + protected static final int BLOB_STREAM_READ_BUF_SIZE = 8192; - static class BatchedBindValues { - BindValue[] batchedParameterValues; + public static class BatchedBindValues { + public BindValue[] batchedParameterValues; BatchedBindValues(BindValue[] paramVals) { int numParams = paramVals.length; @@ -81,34 +97,28 @@ } } - static class BindValue { + public static class BindValue { - long boundBeforeExecutionNum = 0; + public long boundBeforeExecutionNum = 0; - long bindLength; /* Default length of data */ + public long bindLength; /* Default length of data */ - int bufferType; /* buffer type */ + public int bufferType; /* buffer type */ - byte byteBinding; + public double doubleBinding; - double doubleBinding; + public float floatBinding; - float floatBinding; + public boolean isLongData; /* long data indicator */ - int intBinding; + public boolean isNull; /* NULL indicator */ - boolean isLongData; /* long data indicator */ + public boolean isSet = false; /* has this parameter been set? */ - boolean isNull; /* NULL indicator */ + public long longBinding; /* all integral values are stored here */ - boolean isSet = false; /* has this parameter been set? */ + public Object value; /* The value to store */ - long longBinding; - - short shortBinding; - - Object value; /* The value to store */ - BindValue() { } @@ -119,9 +129,6 @@ this.isNull = copyMe.isNull; this.bufferType = copyMe.bufferType; this.bindLength = copyMe.bindLength; - this.byteBinding = copyMe.byteBinding; - this.shortBinding = copyMe.shortBinding; - this.intBinding = copyMe.intBinding; this.longBinding = copyMe.longBinding; this.floatBinding = copyMe.floatBinding; this.doubleBinding = copyMe.doubleBinding; @@ -132,9 +139,6 @@ this.value = null; this.isLongData = false; - this.byteBinding = 0; - this.shortBinding = 0; - this.intBinding = 0; this.longBinding = 0L; this.floatBinding = 0; this.doubleBinding = 0D; @@ -151,11 +155,8 @@ switch (this.bufferType) { case MysqlDefs.FIELD_TYPE_TINY: - return String.valueOf(byteBinding); case MysqlDefs.FIELD_TYPE_SHORT: - return String.valueOf(shortBinding); case MysqlDefs.FIELD_TYPE_LONG: - return String.valueOf(intBinding); case MysqlDefs.FIELD_TYPE_LONGLONG: return String.valueOf(longBinding); case MysqlDefs.FIELD_TYPE_FLOAT: @@ -171,20 +172,17 @@ case MysqlDefs.FIELD_TYPE_VARCHAR: if (quoteIfNeeded) { return "'" + String.valueOf(value) + "'"; - } else { - return String.valueOf(value); } + return String.valueOf(value); + default: if (value instanceof byte[]) { return "byte data"; - - } else { - if (quoteIfNeeded) { - return "'" + String.valueOf(value) + "'"; - } else { - return String.valueOf(value); - } } + if (quoteIfNeeded) { + return "'" + String.valueOf(value) + "'"; + } + return String.valueOf(value); } } @@ -225,29 +223,31 @@ case MysqlDefs.FIELD_TYPE_NEW_DECIMAL: if (value instanceof byte[]) { return ((byte[]) value).length; - } else { - return ((String) value).length(); } + return ((String) value).length(); + default: return 0; } } } /* 1 (length) + 2 (year) + 1 (month) + 1 (day) */ - private static final byte MAX_DATE_REP_LENGTH = (byte) 5; + //private static final byte MAX_DATE_REP_LENGTH = (byte) 5; /* * 1 (length) + 2 (year) + 1 (month) + 1 (day) + 1 (hour) + 1 (minute) + 1 * (second) + 4 (microseconds) */ - private static final byte MAX_DATETIME_REP_LENGTH = 12; + //private static final byte MAX_DATETIME_REP_LENGTH = 12; /* * 1 (length) + 1 (is negative) + 4 (day count) + 1 (hour) + 1 (minute) + 1 * (seconds) + 4 (microseconds) */ - private static final byte MAX_TIME_REP_LENGTH = 13; + //private static final byte MAX_TIME_REP_LENGTH = 13; + + private boolean hasOnDuplicateKeyUpdate = false; private void storeTime(Buffer intoBuf, Time tm) throws SQLException { @@ -292,9 +292,6 @@ /** If this statement has been marked invalid, what was the reason? */ private SQLException invalidationException; - /** Does this query modify data? */ - private boolean isSelectQuery; - private Buffer outByteBuffer; /** Bind values for individual fields */ @@ -318,6 +315,42 @@ private boolean serverNeedsResetBeforeEachExecution; /** + * Creates a prepared statement instance -- We need to provide factory-style + * methods so we can support both JDBC3 (and older) and JDBC4 runtimes, + * otherwise the class verifier complains when it tries to load JDBC4-only + * interface classes that are present in JDBC4 method signatures. + */ + + protected static ServerPreparedStatement getInstance(MySQLConnection conn, + String sql, String catalog, int resultSetType, + int resultSetConcurrency) throws SQLException { + if (!Util.isJdbc4()) { + return new ServerPreparedStatement(conn, sql, catalog, + resultSetType, resultSetConcurrency); + } + + try { + 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) { + throw new SQLException(e.toString(), SQLError.SQL_STATE_GENERAL_ERROR); + } catch (IllegalAccessException e) { + throw new SQLException(e.toString(), SQLError.SQL_STATE_GENERAL_ERROR); + } catch (InvocationTargetException e) { + Throwable target = e.getTargetException(); + + if (target instanceof SQLException) { + throw (SQLException)target; + } + + throw new SQLException(target.toString(), SQLError.SQL_STATE_GENERAL_ERROR); + } + } + + /** * Creates a new ServerPreparedStatement object. * * @param conn @@ -330,16 +363,19 @@ * @throws SQLException * If an error occurs */ - public ServerPreparedStatement(Connection conn, String sql, String catalog, + protected ServerPreparedStatement(MySQLConnection conn, String sql, String catalog, int resultSetType, int resultSetConcurrency) throws SQLException { super(conn, catalog); checkNullOrEmptyQuery(sql); - this.isSelectQuery = StringUtils.startsWithIgnoreCaseAndWs(sql, - "SELECT"); //$NON-NLS-1$ + this.hasOnDuplicateKeyUpdate = containsOnDuplicateKeyInString(sql); + int startOfStatement = findStartOfStatement(sql); + + this.firstCharOfStmt = StringUtils.firstAlphaCharUc(sql, startOfStatement); + if (this.connection.versionMeetsMinimum(5, 0, 0)) { this.serverNeedsResetBeforeEachExecution = !this.connection.versionMeetsMinimum(5, 0, 3); @@ -348,11 +384,14 @@ !this.connection.versionMeetsMinimum(4, 1, 10); } + this.useAutoSlowLog = this.connection.getAutoSlowLog(); this.useTrueBoolean = this.connection.versionMeetsMinimum(3, 21, 23); - this.hasLimitClause = (StringUtils.indexOfIgnoreCase(sql, "LIMIT") != -1); //$NON-NLS-1$ - this.firstCharOfStmt = StringUtils.firstNonWsCharUc(sql); - this.originalSql = sql; + + String statementComment = this.connection.getStatementComment(); + this.originalSql = (statementComment == null) ? sql : "/* " + + statementComment + " */ " + sql; + if (this.connection.versionMeetsMinimum(4, 1, 2)) { this.stringTypeCode = MysqlDefs.FIELD_TYPE_VAR_STRING; } else { @@ -368,12 +407,17 @@ } catch (Exception ex) { realClose(false, true); - throw SQLError.createSQLException(ex.toString(), - SQLError.SQL_STATE_GENERAL_ERROR); + SQLException sqlEx = SQLError.createSQLException(ex.toString(), + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + sqlEx.initCause(ex); + + throw sqlEx; } setResultSetType(resultSetType); setResultSetConcurrency(resultSetConcurrency); + + this.parameterTypes = new int[this.parameterCount]; } /** @@ -382,80 +426,80 @@ * @exception SQLException * if a database-access error occurs. * - * @see Statement#addBatch + * @see StatementImpl#addBatch */ - public synchronized void addBatch() throws SQLException { - checkClosed(); + public void addBatch() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { - if (this.batchedArgs == null) { - this.batchedArgs = new ArrayList(); + if (this.batchedArgs == null) { + this.batchedArgs = new ArrayList(); + } + + this.batchedArgs.add(new BatchedBindValues(this.parameterBindings)); } - - this.batchedArgs.add(new BatchedBindValues(this.parameterBindings)); } - protected String asSql(boolean quoteStreamsAndUnknowns) throws SQLException { + public String asSql(boolean quoteStreamsAndUnknowns) throws SQLException { - if (this.isClosed) { - return "statement has been closed, no further internal information available"; - } - - PreparedStatement pStmtForSub = null; - - try { - pStmtForSub = new PreparedStatement(this.connection, - this.originalSql, this.currentCatalog); - - int numParameters = pStmtForSub.parameterCount; - int ourNumParameters = this.parameterCount; - - for (int i = 0; (i < numParameters) && (i < ourNumParameters); i++) { - if (this.parameterBindings[i] != null) { - if (this.parameterBindings[i].isNull) { - pStmtForSub.setNull(i + 1, Types.NULL); - } else { - BindValue bindValue = this.parameterBindings[i]; - - // - // Handle primitives first - // - switch (bindValue.bufferType) { - - case MysqlDefs.FIELD_TYPE_TINY: - pStmtForSub.setByte(i + 1, bindValue.byteBinding); - break; - case MysqlDefs.FIELD_TYPE_SHORT: - pStmtForSub.setShort(i + 1, bindValue.shortBinding); - break; - case MysqlDefs.FIELD_TYPE_LONG: - pStmtForSub.setInt(i + 1, bindValue.intBinding); - break; - case MysqlDefs.FIELD_TYPE_LONGLONG: - pStmtForSub.setLong(i + 1, bindValue.longBinding); - break; - case MysqlDefs.FIELD_TYPE_FLOAT: - pStmtForSub.setFloat(i + 1, bindValue.floatBinding); - break; - case MysqlDefs.FIELD_TYPE_DOUBLE: - pStmtForSub.setDouble(i + 1, - bindValue.doubleBinding); - break; - default: - pStmtForSub.setObject(i + 1, - this.parameterBindings[i].value); - break; + synchronized (checkClosed().getConnectionMutex()) { + + PreparedStatement pStmtForSub = null; + + try { + pStmtForSub = PreparedStatement.getInstance(this.connection, + this.originalSql, this.currentCatalog); + + int numParameters = pStmtForSub.parameterCount; + int ourNumParameters = this.parameterCount; + + for (int i = 0; (i < numParameters) && (i < ourNumParameters); i++) { + if (this.parameterBindings[i] != null) { + if (this.parameterBindings[i].isNull) { + pStmtForSub.setNull(i + 1, Types.NULL); + } else { + BindValue bindValue = this.parameterBindings[i]; + + // + // Handle primitives first + // + switch (bindValue.bufferType) { + + case MysqlDefs.FIELD_TYPE_TINY: + pStmtForSub.setByte(i + 1, (byte)bindValue.longBinding); + break; + case MysqlDefs.FIELD_TYPE_SHORT: + pStmtForSub.setShort(i + 1, (short)bindValue.longBinding); + break; + case MysqlDefs.FIELD_TYPE_LONG: + pStmtForSub.setInt(i + 1, (int)bindValue.longBinding); + break; + case MysqlDefs.FIELD_TYPE_LONGLONG: + pStmtForSub.setLong(i + 1, bindValue.longBinding); + break; + case MysqlDefs.FIELD_TYPE_FLOAT: + pStmtForSub.setFloat(i + 1, bindValue.floatBinding); + break; + case MysqlDefs.FIELD_TYPE_DOUBLE: + pStmtForSub.setDouble(i + 1, + bindValue.doubleBinding); + break; + default: + pStmtForSub.setObject(i + 1, + this.parameterBindings[i].value); + break; + } } } } - } - - return pStmtForSub.asSql(quoteStreamsAndUnknowns); - } finally { - if (pStmtForSub != null) { - try { - pStmtForSub.close(); - } catch (SQLException sqlEx) { - ; // ignore + + return pStmtForSub.asSql(quoteStreamsAndUnknowns); + } finally { + if (pStmtForSub != null) { + try { + pStmtForSub.close(); + } catch (SQLException sqlEx) { + ; // ignore + } } } } @@ -466,20 +510,21 @@ * * @see com.mysql.jdbc.Statement#checkClosed() */ - protected void checkClosed() throws SQLException { + protected MySQLConnection checkClosed() throws SQLException { if (this.invalid) { throw this.invalidationException; } - super.checkClosed(); + return super.checkClosed(); } /** * @see java.sql.PreparedStatement#clearParameters() */ public void clearParameters() throws SQLException { - checkClosed(); - clearParametersInternal(true); + synchronized (checkClosed().getConnectionMutex()) { + clearParametersInternal(true); + } } private void clearParametersInternal(boolean clearServerParameters) @@ -506,107 +551,127 @@ protected boolean isCached = false; + private boolean useAutoSlowLog; + + private Calendar serverTzCalendar; + + private Calendar defaultTzCalendar; + protected void setClosed(boolean flag) { this.isClosed = flag; } + /** * @see java.sql.Statement#close() */ public void close() throws SQLException { - if (this.isCached) { - this.isClosed = true; - this.connection.recachePreparedStatement(this); - return; - } + MySQLConnection locallyScopedConn = this.connection; - realClose(true, true); - } + if (locallyScopedConn == null) return; // already closed - private void dumpCloseForTestcase() { - StringBuffer buf = new StringBuffer(); - this.connection.generateConnectionCommentBlock(buf); - buf.append("DEALLOCATE PREPARE debug_stmt_"); - buf.append(this.statementId); - buf.append(";\n"); + synchronized (locallyScopedConn.getConnectionMutex()) { - this.connection.dumpTestcaseQuery(buf.toString()); + if (this.isCached && !this.isClosed) { + clearParameters(); + + this.isClosed = true; + + this.connection.recachePreparedStatement(this); + return; + } + + realClose(true, true); + } } - private void dumpExecuteForTestcase() throws SQLException { - StringBuffer buf = new StringBuffer(); - - for (int i = 0; i < this.parameterCount; i++) { + private void dumpCloseForTestcase() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + StringBuffer buf = new StringBuffer(); this.connection.generateConnectionCommentBlock(buf); - - buf.append("SET @debug_stmt_param"); + buf.append("DEALLOCATE PREPARE debug_stmt_"); buf.append(this.statementId); - buf.append("_"); - buf.append(i); - buf.append("="); - - if (this.parameterBindings[i].isNull) { - buf.append("NULL"); - } else { - buf.append(this.parameterBindings[i].toString(true)); - } - buf.append(";\n"); + + this.connection.dumpTestcaseQuery(buf.toString()); } + } - this.connection.generateConnectionCommentBlock(buf); - - buf.append("EXECUTE debug_stmt_"); - buf.append(this.statementId); - - if (this.parameterCount > 0) { - buf.append(" USING "); + private void dumpExecuteForTestcase() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < this.parameterCount; i++) { - if (i > 0) { - buf.append(", "); - } - - buf.append("@debug_stmt_param"); + this.connection.generateConnectionCommentBlock(buf); + + buf.append("SET @debug_stmt_param"); buf.append(this.statementId); buf.append("_"); buf.append(i); - + buf.append("="); + + if (this.parameterBindings[i].isNull) { + buf.append("NULL"); + } else { + buf.append(this.parameterBindings[i].toString(true)); + } + + buf.append(";\n"); } + + this.connection.generateConnectionCommentBlock(buf); + + buf.append("EXECUTE debug_stmt_"); + buf.append(this.statementId); + + if (this.parameterCount > 0) { + buf.append(" USING "); + for (int i = 0; i < this.parameterCount; i++) { + if (i > 0) { + buf.append(", "); + } + + buf.append("@debug_stmt_param"); + buf.append(this.statementId); + buf.append("_"); + buf.append(i); + + } + } + + buf.append(";\n"); + + this.connection.dumpTestcaseQuery(buf.toString()); } - - buf.append(";\n"); - - this.connection.dumpTestcaseQuery(buf.toString()); } private void dumpPrepareForTestcase() throws SQLException { - - StringBuffer buf = new StringBuffer(this.originalSql.length() + 64); - - this.connection.generateConnectionCommentBlock(buf); - - buf.append("PREPARE debug_stmt_"); - buf.append(this.statementId); - buf.append(" FROM \""); - buf.append(this.originalSql); - buf.append("\";\n"); - - this.connection.dumpTestcaseQuery(buf.toString()); + synchronized (checkClosed().getConnectionMutex()) { + StringBuffer buf = new StringBuffer(this.originalSql.length() + 64); + + this.connection.generateConnectionCommentBlock(buf); + + buf.append("PREPARE debug_stmt_"); + buf.append(this.statementId); + buf.append(" FROM \""); + buf.append(this.originalSql); + buf.append("\";\n"); + + this.connection.dumpTestcaseQuery(buf.toString()); + } } - /** - * @see java.sql.Statement#executeBatch() - */ - public synchronized int[] executeBatchSerially() throws SQLException { - if (this.connection.isReadOnly()) { - throw SQLError.createSQLException(Messages - .getString("ServerPreparedStatement.2") //$NON-NLS-1$ - + Messages.getString("ServerPreparedStatement.3"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - checkClosed(); - - synchronized (this.connection.getMutex()) { + protected int[] executeBatchSerially(int batchTimeout) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + MySQLConnection locallyScopedConn = this.connection; + + + if (locallyScopedConn.isReadOnly()) { + throw SQLError.createSQLException(Messages + .getString("ServerPreparedStatement.2") //$NON-NLS-1$ + + Messages.getString("ServerPreparedStatement.3"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + clearWarnings(); // Store this for later, we're going to 'swap' them out @@ -621,7 +686,7 @@ updateCounts = new int[nbrCommands]; if (this.retrieveGeneratedKeys) { - this.batchedGeneratedKeys = new ArrayList(nbrCommands); + this.batchedGeneratedKeys = new ArrayList(nbrCommands); } for (int i = 0; i < nbrCommands; i++) { @@ -634,77 +699,100 @@ BindValue[] previousBindValuesForBatch = null; - for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) { - Object arg = this.batchedArgs.get(commandIndex); - - if (arg instanceof String) { - updateCounts[commandIndex] = executeUpdate((String) arg); - } else { - this.parameterBindings = ((BatchedBindValues) arg).batchedParameterValues; - - try { - // We need to check types each time, as - // the user might have bound different - // types in each addBatch() - - if (previousBindValuesForBatch != null) { - for (int j = 0; j < this.parameterBindings.length; j++) { - if (this.parameterBindings[j].bufferType != previousBindValuesForBatch[j].bufferType) { - this.sendTypesToServer = true; - - break; + CancelTask timeoutTask = null; + + try { + if (locallyScopedConn.getEnableQueryTimeouts() && + batchTimeout != 0 + && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) { + timeoutTask = new CancelTask(this); + locallyScopedConn.getCancelTimer().schedule(timeoutTask, + batchTimeout); + } + + for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) { + Object arg = this.batchedArgs.get(commandIndex); + + if (arg instanceof String) { + updateCounts[commandIndex] = executeUpdate((String) arg); + } else { + this.parameterBindings = ((BatchedBindValues) arg).batchedParameterValues; + + try { + // We need to check types each time, as + // the user might have bound different + // types in each addBatch() + + if (previousBindValuesForBatch != null) { + for (int j = 0; j < this.parameterBindings.length; j++) { + if (this.parameterBindings[j].bufferType != previousBindValuesForBatch[j].bufferType) { + this.sendTypesToServer = true; + + break; + } } } - } - - try { - updateCounts[commandIndex] = executeUpdate(false, true); - } finally { - previousBindValuesForBatch = this.parameterBindings; - } - - if (this.retrieveGeneratedKeys) { - java.sql.ResultSet rs = null; - + try { - // we don't want to use our version, - // because we've altered the behavior of - // ours to support batch updates - // (catch-22) - // Ideally, what we need here is - // super.super.getGeneratedKeys() - // but that construct doesn't exist in - // Java, so that's why there's - // this kludge. - rs = getGeneratedKeysInternal(); - - while (rs.next()) { - this.batchedGeneratedKeys - .add(new byte[][] { rs - .getBytes(1) }); - } + updateCounts[commandIndex] = executeUpdate(false, true); } finally { - if (rs != null) { - rs.close(); + previousBindValuesForBatch = this.parameterBindings; + } + + if (this.retrieveGeneratedKeys) { + java.sql.ResultSet rs = null; + + try { + // we don't want to use our version, + // because we've altered the behavior of + // ours to support batch updates + // (catch-22) + // Ideally, what we need here is + // super.super.getGeneratedKeys() + // but that construct doesn't exist in + // Java, so that's why there's + // this kludge. + rs = getGeneratedKeysInternal(); + + while (rs.next()) { + this.batchedGeneratedKeys + .add(new ByteArrayRow(new byte[][] { rs + .getBytes(1) }, getExceptionInterceptor())); + } + } finally { + if (rs != null) { + rs.close(); + } } } + } catch (SQLException ex) { + updateCounts[commandIndex] = EXECUTE_FAILED; + + if (this.continueBatchOnError && + !(ex instanceof MySQLTimeoutException) && + !(ex instanceof MySQLStatementCancelledException) + && !hasDeadlockOrTimeoutRolledBackTx(ex)) { + sqlEx = ex; + } else { + int[] newUpdateCounts = new int[commandIndex]; + System.arraycopy(updateCounts, 0, + newUpdateCounts, 0, commandIndex); + + throw new java.sql.BatchUpdateException(ex + .getMessage(), ex.getSQLState(), ex + .getErrorCode(), newUpdateCounts); + } } - } catch (SQLException ex) { - updateCounts[commandIndex] = EXECUTE_FAILED; - - if (this.continueBatchOnError) { - sqlEx = ex; - } else { - int[] newUpdateCounts = new int[commandIndex]; - System.arraycopy(updateCounts, 0, - newUpdateCounts, 0, commandIndex); - - throw new java.sql.BatchUpdateException(ex - .getMessage(), ex.getSQLState(), ex - .getErrorCode(), newUpdateCounts); - } } } + } finally { + if (timeoutTask != null) { + timeoutTask.cancel(); + + locallyScopedConn.getCancelTimer().purge(); + } + + resetCancelledState(); } if (sqlEx != null) { @@ -728,57 +816,63 @@ * @see com.mysql.jdbc.PreparedStatement#executeInternal(int, * com.mysql.jdbc.Buffer, boolean, boolean) */ - protected com.mysql.jdbc.ResultSet executeInternal(int maxRowsToRetrieve, + protected com.mysql.jdbc.ResultSetInternalMethods executeInternal(int maxRowsToRetrieve, Buffer sendPacket, boolean createStreamingResultSet, - boolean queryIsSelectOnly, boolean unpackFields, Field[] metadataFromCache, + boolean queryIsSelectOnly, Field[] metadataFromCache, boolean isBatch) throws SQLException { - this.numberOfExecutions++; - - // We defer to server-side execution - try { - return serverExecute(maxRowsToRetrieve, createStreamingResultSet, - unpackFields, metadataFromCache); - } catch (SQLException sqlEx) { - // don't wrap SQLExceptions - if (this.connection.getEnablePacketDebug()) { - this.connection.getIO().dumpPacketRingBuffer(); + synchronized (checkClosed().getConnectionMutex()) { + this.numberOfExecutions++; + + // We defer to server-side execution + try { + return serverExecute(maxRowsToRetrieve, createStreamingResultSet, + metadataFromCache); + } catch (SQLException sqlEx) { + // don't wrap SQLExceptions + if (this.connection.getEnablePacketDebug()) { + this.connection.getIO().dumpPacketRingBuffer(); + } + + if (this.connection.getDumpQueriesOnException()) { + String extractedSql = toString(); + StringBuffer messageBuf = new StringBuffer(extractedSql + .length() + 32); + messageBuf + .append("\n\nQuery being executed when exception was thrown:\n"); + messageBuf.append(extractedSql); + messageBuf.append("\n\n"); + + sqlEx = ConnectionImpl.appendMessageToException(sqlEx, messageBuf + .toString(), getExceptionInterceptor()); + } + + throw sqlEx; + } catch (Exception ex) { + if (this.connection.getEnablePacketDebug()) { + this.connection.getIO().dumpPacketRingBuffer(); + } + + SQLException sqlEx = SQLError.createSQLException(ex.toString(), + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + + if (this.connection.getDumpQueriesOnException()) { + String extractedSql = toString(); + StringBuffer messageBuf = new StringBuffer(extractedSql + .length() + 32); + messageBuf + .append("\n\nQuery being executed when exception was thrown:\n"); + messageBuf.append(extractedSql); + messageBuf.append("\n\n"); + + sqlEx = ConnectionImpl.appendMessageToException(sqlEx, messageBuf + .toString(), getExceptionInterceptor()); + } + + sqlEx.initCause(ex); + + throw sqlEx; } - - if (this.connection.getDumpQueriesOnException()) { - String extractedSql = toString(); - StringBuffer messageBuf = new StringBuffer(extractedSql - .length() + 32); - messageBuf - .append("\n\nQuery being executed when exception was thrown:\n\n"); - messageBuf.append(extractedSql); - - sqlEx = Connection.appendMessageToException(sqlEx, messageBuf - .toString()); - } - - throw sqlEx; - } catch (Exception ex) { - if (this.connection.getEnablePacketDebug()) { - this.connection.getIO().dumpPacketRingBuffer(); - } - - SQLException sqlEx = SQLError.createSQLException(ex.toString(), - SQLError.SQL_STATE_GENERAL_ERROR); - - if (this.connection.getDumpQueriesOnException()) { - String extractedSql = toString(); - StringBuffer messageBuf = new StringBuffer(extractedSql - .length() + 32); - messageBuf - .append("\n\nQuery being executed when exception was thrown:\n\n"); - messageBuf.append(extractedSql); - - sqlEx = Connection.appendMessageToException(sqlEx, messageBuf - .toString()); - } - - throw sqlEx; } } @@ -808,104 +902,119 @@ * @return * @throws SQLException */ - private BindValue getBinding(int parameterIndex, boolean forLongData) + protected BindValue getBinding(int parameterIndex, boolean forLongData) throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - if (this.parameterBindings.length == 0) { - throw SQLError.createSQLException(Messages - .getString("ServerPreparedStatement.8"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - parameterIndex--; - - if ((parameterIndex < 0) - || (parameterIndex >= this.parameterBindings.length)) { - throw SQLError.createSQLException(Messages - .getString("ServerPreparedStatement.9") //$NON-NLS-1$ - + (parameterIndex + 1) - + Messages.getString("ServerPreparedStatement.10") //$NON-NLS-1$ - + this.parameterBindings.length, - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - } - - if (this.parameterBindings[parameterIndex] == null) { - this.parameterBindings[parameterIndex] = new BindValue(); - } else { - if (this.parameterBindings[parameterIndex].isLongData - && !forLongData) { - this.detectedLongParameterSwitch = true; + if (this.parameterBindings.length == 0) { + throw SQLError.createSQLException(Messages + .getString("ServerPreparedStatement.8"), //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } + + parameterIndex--; + + if ((parameterIndex < 0) + || (parameterIndex >= this.parameterBindings.length)) { + throw SQLError.createSQLException(Messages + .getString("ServerPreparedStatement.9") //$NON-NLS-1$ + + (parameterIndex + 1) + + Messages.getString("ServerPreparedStatement.10") //$NON-NLS-1$ + + this.parameterBindings.length, + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + } + + if (this.parameterBindings[parameterIndex] == null) { + this.parameterBindings[parameterIndex] = new BindValue(); + } else { + if (this.parameterBindings[parameterIndex].isLongData + && !forLongData) { + this.detectedLongParameterSwitch = true; + } + } + + this.parameterBindings[parameterIndex].isSet = true; + this.parameterBindings[parameterIndex].boundBeforeExecutionNum = this.numberOfExecutions; + + return this.parameterBindings[parameterIndex]; } + } - this.parameterBindings[parameterIndex].isSet = true; - this.parameterBindings[parameterIndex].boundBeforeExecutionNum = this.numberOfExecutions; - - return this.parameterBindings[parameterIndex]; + /** + * Return current bind values for use by Statement Interceptors. + * @return the bind values as set by setXXX and stored by addBatch + * @see #executeBatch() + * @see #addBatch() + */ + public BindValue[] getParameterBindValues() { + return parameterBindings; } /** * @see com.mysql.jdbc.PreparedStatement#getBytes(int) */ byte[] getBytes(int parameterIndex) throws SQLException { - BindValue bindValue = getBinding(parameterIndex, false); - - if (bindValue.isNull) { - return null; - } else if (bindValue.isLongData) { - throw new NotImplemented(); - } else { - if (this.outByteBuffer == null) { - this.outByteBuffer = new Buffer(this.connection - .getNetBufferLength()); + synchronized (checkClosed().getConnectionMutex()) { + BindValue bindValue = getBinding(parameterIndex, false); + + if (bindValue.isNull) { + return null; + } else if (bindValue.isLongData) { + throw SQLError.notImplemented(); + } else { + if (this.outByteBuffer == null) { + this.outByteBuffer = new Buffer(this.connection + .getNetBufferLength()); + } + + this.outByteBuffer.clear(); + + int originalPosition = this.outByteBuffer.getPosition(); + + storeBinding(this.outByteBuffer, bindValue, this.connection.getIO()); + + int newPosition = this.outByteBuffer.getPosition(); + + int length = newPosition - originalPosition; + + byte[] valueAsBytes = new byte[length]; + + System.arraycopy(this.outByteBuffer.getByteBuffer(), + originalPosition, valueAsBytes, 0, length); + + return valueAsBytes; } - - this.outByteBuffer.clear(); - - int originalPosition = this.outByteBuffer.getPosition(); - - storeBinding(this.outByteBuffer, bindValue, this.connection.getIO()); - - int newPosition = this.outByteBuffer.getPosition(); - - int length = newPosition - originalPosition; - - byte[] valueAsBytes = new byte[length]; - - System.arraycopy(this.outByteBuffer.getByteBuffer(), - originalPosition, valueAsBytes, 0, length); - - return valueAsBytes; } } /** * @see java.sql.PreparedStatement#getMetaData() */ public java.sql.ResultSetMetaData getMetaData() throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - if (this.resultFields == null) { - return null; + if (resultFields == null) { + return null; + } + + return new ResultSetMetaData(resultFields, connection.getUseOldAliasMetadataBehavior(), + connection.getYearIsDateType(), getExceptionInterceptor()); } - - return new ResultSetMetaData(this.resultFields, - this.connection.getUseOldAliasMetadataBehavior()); } /** * @see java.sql.PreparedStatement#getParameterMetaData() */ public ParameterMetaData getParameterMetaData() throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - if (this.parameterMetaData == null) { - this.parameterMetaData = new MysqlParameterMetadata( - this.parameterFields, this.parameterCount); + if (this.parameterMetaData == null) { + this.parameterMetaData = new MysqlParameterMetadata( + this.parameterFields, this.parameterCount, getExceptionInterceptor()); + } + + return this.parameterMetaData; } - - return this.parameterMetaData; } /** @@ -927,16 +1036,16 @@ */ protected void realClose(boolean calledExplicitly, boolean closeOpenResults) throws SQLException { - if (this.isClosed) { - return; - } + MySQLConnection locallyScopedConn = this.connection; - if (this.connection != null) { - if (this.connection.getAutoGenerateTestcaseScript()) { - dumpCloseForTestcase(); - } - - synchronized (this.connection.getMutex()) { + if (locallyScopedConn == null) return; // already closed + + synchronized (locallyScopedConn.getConnectionMutex()) { + + if (this.connection != null) { + if (this.connection.getAutoGenerateTestcaseScript()) { + dumpCloseForTestcase(); + } // // Don't communicate with the server if we're being @@ -948,36 +1057,39 @@ // called with). Well-behaved programs won't rely on finalizers // to clean up their statements. // - + SQLException exceptionDuringClose = null; - - - if (calledExplicitly) { - try { - - MysqlIO mysql = this.connection.getIO(); - - Buffer packet = mysql.getSharedSendPacket(); - - packet.writeByte((byte) MysqlDefs.COM_CLOSE_STATEMENT); - packet.writeLong(this.serverStatementId); - - mysql.sendCommand(MysqlDefs.COM_CLOSE_STATEMENT, null, - packet, true, null); - } catch (SQLException sqlEx) { - exceptionDuringClose = sqlEx; + + if (calledExplicitly && !this.connection.isClosed()) { + synchronized (this.connection.getConnectionMutex()) { + try { + + MysqlIO mysql = this.connection.getIO(); + + Buffer packet = mysql.getSharedSendPacket(); + + packet.writeByte((byte) MysqlDefs.COM_CLOSE_STATEMENT); + packet.writeLong(this.serverStatementId); + + mysql.sendCommand(MysqlDefs.COM_CLOSE_STATEMENT, null, + packet, true, null, 0); + } catch (SQLException sqlEx) { + exceptionDuringClose = sqlEx; + } } - } - + + if (this.isCached) { + this.connection.decachePreparedStatement(this); + } super.realClose(calledExplicitly, closeOpenResults); - + clearParametersInternal(false); this.parameterBindings = null; - + this.parameterFields = null; this.resultFields = null; - + if (exceptionDuringClose != null) { throw exceptionDuringClose; } @@ -993,42 +1105,55 @@ * if an error occurs. */ protected void rePrepare() throws SQLException { - this.invalidationException = null; + synchronized (checkClosed().getConnectionMutex()) { + this.invalidationException = null; + + try { + serverPrepare(this.originalSql); + } catch (SQLException sqlEx) { + // don't wrap SQLExceptions + this.invalidationException = sqlEx; + } catch (Exception ex) { + this.invalidationException = SQLError.createSQLException(ex.toString(), + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + this.invalidationException.initCause(ex); + } + + if (this.invalidationException != null) { + this.invalid = true; + + this.parameterBindings = null; + + this.parameterFields = null; + this.resultFields = null; + + if (this.results != null) { + try { + this.results.close(); + } catch (Exception ex) { + ; + } + } - try { - serverPrepare(this.originalSql); - } catch (SQLException sqlEx) { - // don't wrap SQLExceptions - this.invalidationException = sqlEx; - } catch (Exception ex) { - this.invalidationException = SQLError.createSQLException(ex.toString(), - SQLError.SQL_STATE_GENERAL_ERROR); - } + if (this.generatedKeysResults != null) { + try { + this.generatedKeysResults.close(); + } catch (Exception ex) { + ; + } + } - if (this.invalidationException != null) { - this.invalid = true; - - this.parameterBindings = null; - - this.parameterFields = null; - this.resultFields = null; - - if (this.results != null) { try { - this.results.close(); - } catch (Exception ex) { + closeAllOpenResults(); + } catch (Exception e) { ; } - } - - if (this.connection != null) { - if (this.maxRowsChanged) { - this.connection.unsetMaxRows(this); + + if (this.connection != null) { + if (!this.connection.getDontTrackOpenResources()) { + this.connection.unregisterStatement(this); + } } - - if (!this.connection.getDontTrackOpenResources()) { - this.connection.unregisterStatement(this); - } } } } @@ -1066,10 +1191,21 @@ * * @throws SQLException */ - private com.mysql.jdbc.ResultSet serverExecute(int maxRowsToRetrieve, - boolean createStreamingResultSet, boolean unpackFields, + private com.mysql.jdbc.ResultSetInternalMethods serverExecute(int maxRowsToRetrieve, + boolean createStreamingResultSet, Field[] metadataFromCache) throws SQLException { - synchronized (this.connection.getMutex()) { + synchronized (checkClosed().getConnectionMutex()) { + MysqlIO mysql = this.connection.getIO(); + + if (mysql.shouldIntercept()) { + ResultSetInternalMethods interceptedResults = + mysql.invokeStatementInterceptorsPre(this.originalSql, this, true); + + if (interceptedResults != null) { + return interceptedResults; + } + } + if (this.detectedLongParameterSwitch) { // Check when values were bound boolean firstFound = false; @@ -1082,11 +1218,10 @@ throw SQLError.createSQLException(Messages .getString("ServerPreparedStatement.11") //$NON-NLS-1$ + Messages.getString("ServerPreparedStatement.12"), //$NON-NLS-1$ - SQLError.SQL_STATE_DRIVER_NOT_CAPABLE); - } else { - firstFound = true; - boundTimeToCheck = this.parameterBindings[i].boundBeforeExecutionNum; + SQLError.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor()); } + firstFound = true; + boundTimeToCheck = this.parameterBindings[i].boundBeforeExecutionNum; } } @@ -1103,7 +1238,7 @@ throw SQLError.createSQLException(Messages .getString("ServerPreparedStatement.13") + (i + 1) //$NON-NLS-1$ + Messages.getString("ServerPreparedStatement.14"), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); //$NON-NLS-1$ } } @@ -1123,15 +1258,14 @@ // // store the parameter values // - MysqlIO mysql = this.connection.getIO(); Buffer packet = mysql.getSharedSendPacket(); packet.clear(); packet.writeByte((byte) MysqlDefs.COM_EXECUTE); packet.writeLong(this.serverStatementId); - boolean usingCursor = false; +// boolean usingCursor = false; if (this.connection.versionMeetsMinimum(4, 1, 2)) { // we only create cursor-backed result sets if @@ -1146,7 +1280,7 @@ && getResultSetConcurrency() == ResultSet.CONCUR_READ_ONLY && getFetchSize() > 0) { packet.writeByte(MysqlDefs.OPEN_CURSOR_FLAG); - usingCursor = true; +// usingCursor = true; } else { packet.writeByte((byte) 0); // placeholder for flags } @@ -1214,23 +1348,23 @@ begin = mysql.getCurrentTimeNanosOrMillis(); } - synchronized (this.cancelTimeoutMutex) { - this.wasCancelled = false; - } + resetCancelledState(); CancelTask timeoutTask = null; try { if (this.connection.getEnableQueryTimeouts() && this.timeoutInMillis != 0 && this.connection.versionMeetsMinimum(5, 0, 0)) { - timeoutTask = new CancelTask(); + timeoutTask = new CancelTask(this); this.connection.getCancelTimer().schedule(timeoutTask, this.timeoutInMillis); } + statementBegins(); + Buffer resultPacket = mysql.sendCommand(MysqlDefs.COM_EXECUTE, - null, packet, false, null); + null, packet, false, null, 0); long queryEndTime = 0L; @@ -1241,6 +1375,8 @@ if (timeoutTask != null) { timeoutTask.cancel(); + this.connection.getCancelTimer().purge(); + if (timeoutTask.caughtWhileCancelling != null) { throw timeoutTask.caughtWhileCancelling; } @@ -1250,8 +1386,17 @@ synchronized (this.cancelTimeoutMutex) { if (this.wasCancelled) { - this.wasCancelled = false; - throw new MySQLTimeoutException(); + SQLException cause = null; + + if (this.wasCancelledByTimeout) { + cause = new MySQLTimeoutException(); + } else { + cause = new MySQLStatementCancelledException(); + } + + resetCancelledState(); + + throw cause; } } @@ -1260,9 +1405,17 @@ if (logSlowQueries || gatherPerformanceMetrics) { long elapsedTime = queryEndTime - begin; - if (logSlowQueries - && (elapsedTime >= mysql.getSlowQueryThreshold())) { - queryWasSlow = true; + if (logSlowQueries) { + if (this.useAutoSlowLog) { + queryWasSlow = elapsedTime > this.connection.getSlowQueryThresholdMillis(); + } else { + queryWasSlow = this.connection.isAbonormallyLongQuery(elapsedTime); + + this.connection.reportQueryTime(elapsedTime); + } + } + + if (queryWasSlow) { StringBuffer mesgBuf = new StringBuffer( 48 + this.originalSql.length()); @@ -1287,7 +1440,7 @@ getId(), 0, System.currentTimeMillis(), elapsedTime, mysql .getQueryTimingUnits(), null, - new Throwable(), mesgBuf.toString())); + LogUtils.findCallingClassAndMethod(new Throwable()), mesgBuf.toString())); } if (gatherPerformanceMetrics) { @@ -1298,41 +1451,50 @@ this.connection.incrementNumberOfPreparedExecutes(); if (this.profileSQL) { - this.eventSink = ProfileEventSink + this.eventSink = ProfilerEventHandlerFactory .getInstance(this.connection); this.eventSink.consumeEvent(new ProfilerEvent( ProfilerEvent.TYPE_EXECUTE, "", this.currentCatalog, //$NON-NLS-1$ this.connectionId, this.statementId, -1, System - .currentTimeMillis(), (int) (mysql - .getCurrentTimeNanosOrMillis() - begin), - mysql.getQueryTimingUnits(), null, new Throwable(), + .currentTimeMillis(), mysql + .getCurrentTimeNanosOrMillis() - begin, + mysql.getQueryTimingUnits(), null, LogUtils.findCallingClassAndMethod(new Throwable()), truncateQueryToLog(asSql(true)))); } - com.mysql.jdbc.ResultSet rs = mysql.readAllResults(this, + com.mysql.jdbc.ResultSetInternalMethods rs = mysql.readAllResults(this, maxRowsToRetrieve, this.resultSetType, this.resultSetConcurrency, createStreamingResultSet, this.currentCatalog, resultPacket, true, this.fieldCount, - unpackFields, metadataFromCache); + metadataFromCache); + if (mysql.shouldIntercept()) { + ResultSetInternalMethods interceptedResults = + mysql.invokeStatementInterceptorsPost(this.originalSql, this, rs, true, null); + + if (interceptedResults != null) { + rs = interceptedResults; + } + } + if (this.profileSQL) { long fetchEndTime = mysql.getCurrentTimeNanosOrMillis(); this.eventSink.consumeEvent(new ProfilerEvent( ProfilerEvent.TYPE_FETCH, "", this.currentCatalog, this.connection.getId(), //$NON-NLS-1$ - getId(), rs.resultId, System.currentTimeMillis(), + getId(), 0 /* FIXME rs.resultId */, System.currentTimeMillis(), (fetchEndTime - queryEndTime), mysql .getQueryTimingUnits(), null, - new Throwable(), null)); + LogUtils.findCallingClassAndMethod(new Throwable()), null)); } if (queryWasSlow && this.connection.getExplainSlowQueries()) { String queryAsString = asSql(true); - mysql.explainSlowQuery(queryAsString.getBytes(), + mysql.explainSlowQuery(StringUtils.getBytes(queryAsString), queryAsString); } @@ -1350,9 +1512,18 @@ } return rs; + } catch (SQLException sqlEx) { + if (mysql.shouldIntercept()) { + mysql.invokeStatementInterceptorsPost(this.originalSql, this, null, true, sqlEx); + } + + throw sqlEx; } finally { + this.statementExecuting.set(false); + if (timeoutTask != null) { timeoutTask.cancel(); + this.connection.getCancelTimer().purge(); } } } @@ -1387,7 +1558,7 @@ */ private void serverLongData(int parameterIndex, BindValue longData) throws SQLException { - synchronized (this.connection.getMutex()) { + synchronized (checkClosed().getConnectionMutex()) { MysqlIO mysql = this.connection.getIO(); Buffer packet = mysql.getSharedSendPacket(); @@ -1403,7 +1574,7 @@ packet.writeBytesNoNull((byte[]) longData.value); mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true, - null); + null, 0); } else if (value instanceof InputStream) { storeStream(mysql, parameterIndex, packet, (InputStream) value); } else if (value instanceof java.sql.Blob) { @@ -1415,13 +1586,13 @@ throw SQLError.createSQLException(Messages .getString("ServerPreparedStatement.18") //$NON-NLS-1$ + value.getClass().getName() + "'", //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); } } } private void serverPrepare(String sql) throws SQLException { - synchronized (this.connection.getMutex()) { + synchronized (checkClosed().getConnectionMutex()) { MysqlIO mysql = this.connection.getIO(); if (this.connection.getAutoGenerateTestcaseScript()) { @@ -1438,7 +1609,7 @@ } if (this.connection.getProfileSql()) { - begin = mysql.getCurrentTimeNanosOrMillis(); + begin = System.currentTimeMillis(); } String characterEncoding = null; @@ -1451,7 +1622,7 @@ Buffer prepareResultPacket = mysql.sendCommand( MysqlDefs.COM_PREPARE, sql, null, false, - characterEncoding); + characterEncoding, 0); if (this.connection.versionMeetsMinimum(4, 1, 1)) { // 4.1.1 and newer use the first byte @@ -1484,7 +1655,7 @@ System.currentTimeMillis(), mysql.getCurrentTimeNanosOrMillis() - begin, mysql.getQueryTimingUnits(), null, - new Throwable(), truncateQueryToLog(sql))); + LogUtils.findCallingClassAndMethod(new Throwable()), truncateQueryToLog(sql))); } if (this.parameterCount > 0) { @@ -1528,8 +1699,8 @@ .append("\n\nQuery being prepared when exception was thrown:\n\n"); messageBuf.append(this.originalSql); - sqlEx = Connection.appendMessageToException(sqlEx, - messageBuf.toString()); + sqlEx = ConnectionImpl.appendMessageToException(sqlEx, + messageBuf.toString(), getExceptionInterceptor()); } throw sqlEx; @@ -1542,25 +1713,27 @@ } } - private String truncateQueryToLog(String sql) { - String query = null; - - if (sql.length() > this.connection.getMaxQuerySizeToLog()) { - StringBuffer queryBuf = new StringBuffer( - this.connection.getMaxQuerySizeToLog() + 12); - queryBuf.append(sql.substring(0, this.connection.getMaxQuerySizeToLog())); - queryBuf.append(Messages.getString("MysqlIO.25")); + private String truncateQueryToLog(String sql) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + String query = null; - query = queryBuf.toString(); - } else { - query = sql; + if (sql.length() > this.connection.getMaxQuerySizeToLog()) { + StringBuffer queryBuf = new StringBuffer( + this.connection.getMaxQuerySizeToLog() + 12); + queryBuf.append(sql.substring(0, this.connection.getMaxQuerySizeToLog())); + queryBuf.append(Messages.getString("MysqlIO.25")); + + query = queryBuf.toString(); + } else { + query = sql; + } + + return query; } - - return query; } private void serverResetStatement() throws SQLException { - synchronized (this.connection.getMutex()) { + synchronized (checkClosed().getConnectionMutex()) { MysqlIO mysql = this.connection.getIO(); @@ -1572,12 +1745,15 @@ try { mysql.sendCommand(MysqlDefs.COM_RESET_STMT, null, packet, - !this.connection.versionMeetsMinimum(4, 1, 2), null); + !this.connection.versionMeetsMinimum(4, 1, 2), null, 0); } catch (SQLException sqlEx) { throw sqlEx; } catch (Exception ex) { - throw SQLError.createSQLException(ex.toString(), - SQLError.SQL_STATE_GENERAL_ERROR); + SQLException sqlEx = SQLError.createSQLException(ex.toString(), + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + sqlEx.initCause(ex); + + throw sqlEx; } finally { mysql.clearInputStream(); } @@ -1588,7 +1764,7 @@ * @see java.sql.PreparedStatement#setArray(int, java.sql.Array) */ public void setArray(int i, Array x) throws SQLException { - throw new NotImplemented(); + throw SQLError.notImplemented(); } /** @@ -1597,22 +1773,22 @@ */ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { - checkClosed(); - - if (x == null) { - setNull(parameterIndex, java.sql.Types.BINARY); - } else { - BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); - - binding.value = x; - binding.isNull = false; - binding.isLongData = true; - - if (this.connection.getUseStreamLengthsInPrepStmts()) { - binding.bindLength = length; + synchronized (checkClosed().getConnectionMutex()) { + if (x == null) { + setNull(parameterIndex, java.sql.Types.BINARY); } else { - binding.bindLength = -1; + BindValue binding = getBinding(parameterIndex, true); + setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + + binding.value = x; + binding.isNull = false; + binding.isLongData = true; + + if (this.connection.getUseStreamLengthsInPrepStmts()) { + binding.bindLength = length; + } else { + binding.bindLength = -1; + } } } } @@ -1622,24 +1798,25 @@ */ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - if (x == null) { - setNull(parameterIndex, java.sql.Types.DECIMAL); - } else { - - BindValue binding = getBinding(parameterIndex, false); - - if (this.connection.versionMeetsMinimum(5, 0, 3)) { - setType(binding, MysqlDefs.FIELD_TYPE_NEW_DECIMAL); + if (x == null) { + setNull(parameterIndex, java.sql.Types.DECIMAL); } else { - setType(binding, this.stringTypeCode); + + BindValue binding = getBinding(parameterIndex, false); + + if (this.connection.versionMeetsMinimum(5, 0, 3)) { + setType(binding, MysqlDefs.FIELD_TYPE_NEW_DECIMAL); + } else { + setType(binding, this.stringTypeCode); + } + + binding.value = StringUtils + .fixDecimalExponent(StringUtils.consistentToString(x)); + binding.isNull = false; + binding.isLongData = false; } - - binding.value = StringUtils - .fixDecimalExponent(StringUtils.consistentToString(x)); - binding.isNull = false; - binding.isLongData = false; } } @@ -1649,22 +1826,23 @@ */ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - if (x == null) { - setNull(parameterIndex, java.sql.Types.BINARY); - } else { - BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); - - binding.value = x; - binding.isNull = false; - binding.isLongData = true; - - if (this.connection.getUseStreamLengthsInPrepStmts()) { - binding.bindLength = length; + if (x == null) { + setNull(parameterIndex, java.sql.Types.BINARY); } else { - binding.bindLength = -1; + BindValue binding = getBinding(parameterIndex, true); + setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + + binding.value = x; + binding.isNull = false; + binding.isLongData = true; + + if (this.connection.getUseStreamLengthsInPrepStmts()) { + binding.bindLength = length; + } else { + binding.bindLength = -1; + } } } } @@ -1673,22 +1851,23 @@ * @see java.sql.PreparedStatement#setBlob(int, java.sql.Blob) */ public void setBlob(int parameterIndex, Blob x) throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - if (x == null) { - setNull(parameterIndex, java.sql.Types.BINARY); - } else { - BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); - - binding.value = x; - binding.isNull = false; - binding.isLongData = true; - - if (this.connection.getUseStreamLengthsInPrepStmts()) { - binding.bindLength = x.length(); + if (x == null) { + setNull(parameterIndex, java.sql.Types.BINARY); } else { - binding.bindLength = -1; + BindValue binding = getBinding(parameterIndex, true); + setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + + binding.value = x; + binding.isNull = false; + binding.isLongData = true; + + if (this.connection.getUseStreamLengthsInPrepStmts()) { + binding.bindLength = x.length(); + } else { + binding.bindLength = -1; + } } } } @@ -1710,7 +1889,7 @@ setType(binding, MysqlDefs.FIELD_TYPE_TINY); binding.value = null; - binding.byteBinding = x; + binding.longBinding = x; binding.isNull = false; binding.isLongData = false; } @@ -1739,22 +1918,23 @@ */ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - if (reader == null) { - setNull(parameterIndex, java.sql.Types.BINARY); - } else { - BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); - - binding.value = reader; - binding.isNull = false; - binding.isLongData = true; - - if (this.connection.getUseStreamLengthsInPrepStmts()) { - binding.bindLength = length; + if (reader == null) { + setNull(parameterIndex, java.sql.Types.BINARY); } else { - binding.bindLength = -1; + BindValue binding = getBinding(parameterIndex, true); + setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + + binding.value = reader; + binding.isNull = false; + binding.isLongData = true; + + if (this.connection.getUseStreamLengthsInPrepStmts()) { + binding.bindLength = length; + } else { + binding.bindLength = -1; + } } } } @@ -1763,22 +1943,23 @@ * @see java.sql.PreparedStatement#setClob(int, java.sql.Clob) */ public void setClob(int parameterIndex, Clob x) throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - if (x == null) { - setNull(parameterIndex, java.sql.Types.BINARY); - } else { - BindValue binding = getBinding(parameterIndex, true); - setType(binding, MysqlDefs.FIELD_TYPE_BLOB); - - binding.value = x.getCharacterStream(); - binding.isNull = false; - binding.isLongData = true; - - if (this.connection.getUseStreamLengthsInPrepStmts()) { - binding.bindLength = x.length(); + if (x == null) { + setNull(parameterIndex, java.sql.Types.BINARY); } else { - binding.bindLength = -1; + BindValue binding = getBinding(parameterIndex, true); + setType(binding, MysqlDefs.FIELD_TYPE_BLOB); + + binding.value = x.getCharacterStream(); + binding.isNull = false; + binding.isLongData = true; + + if (this.connection.getUseStreamLengthsInPrepStmts()) { + binding.bindLength = x.length(); + } else { + binding.bindLength = -1; + } } } } @@ -1831,24 +2012,25 @@ * @see java.sql.PreparedStatement#setDouble(int, double) */ public void setDouble(int parameterIndex, double x) throws SQLException { - checkClosed(); + synchronized (checkClosed().getConnectionMutex()) { - if (!this.connection.getAllowNanAndInf() - && (x == Double.POSITIVE_INFINITY - || x == Double.NEGATIVE_INFINITY || Double.isNaN(x))) { - throw SQLError.createSQLException("'" + x - + "' is not a valid numeric or approximate numeric value", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); - + if (!this.connection.getAllowNanAndInf() + && (x == Double.POSITIVE_INFINITY + || x == Double.NEGATIVE_INFINITY || Double.isNaN(x))) { + throw SQLError.createSQLException("'" + x + + "' is not a valid numeric or approximate numeric value", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); + + } + + BindValue binding = getBinding(parameterIndex, false); + setType(binding, MysqlDefs.FIELD_TYPE_DOUBLE); + + binding.value = null; + binding.doubleBinding = x; + binding.isNull = false; + binding.isLongData = false; } - - BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_DOUBLE); - - binding.value = null; - binding.doubleBinding = x; - binding.isNull = false; - binding.isLongData = false; } /** @@ -1876,7 +2058,7 @@ setType(binding, MysqlDefs.FIELD_TYPE_LONG); binding.value = null; - binding.intBinding = x; + binding.longBinding = x; binding.isNull = false; binding.isLongData = false; } @@ -1943,7 +2125,7 @@ * @see java.sql.PreparedStatement#setRef(int, java.sql.Ref) */ public void setRef(int i, Ref x) throws SQLException { - throw new NotImplemented(); + throw SQLError.notImplemented(); } /** @@ -1956,7 +2138,7 @@ setType(binding, MysqlDefs.FIELD_TYPE_SHORT); binding.value = null; - binding.shortBinding = x; + binding.longBinding = x; binding.isNull = false; binding.isLongData = false; } @@ -1993,7 +2175,9 @@ */ public void setTime(int parameterIndex, java.sql.Time x) throws SQLException { - setTimeInternal(parameterIndex, x, null, this.connection.getDefaultTimeZone(), false); + synchronized (checkClosed().getConnectionMutex()) { + setTimeInternal(parameterIndex, x, null, this.connection.getDefaultTimeZone(), false); + } } /** @@ -2031,28 +2215,32 @@ * @throws SQLException * if a database access error occurs */ - public void setTimeInternal(int parameterIndex, java.sql.Time x, + protected void setTimeInternal(int parameterIndex, java.sql.Time x, Calendar targetCalendar, TimeZone tz, boolean rollForward) throws SQLException { - if (x == null) { - setNull(parameterIndex, java.sql.Types.TIME); - } else { - BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_TIME); + synchronized (checkClosed().getConnectionMutex()) { + if (x == null) { + setNull(parameterIndex, java.sql.Types.TIME); + } else { + BindValue binding = getBinding(parameterIndex, false); + setType(binding, MysqlDefs.FIELD_TYPE_TIME); + + if (!this.useLegacyDatetimeCode) { + binding.value = x; + } else { + Calendar sessionCalendar = getCalendarInstanceForSessionOrNew(); - Calendar sessionCalendar = getCalendarInstanceForSessionOrNew(); - - synchronized (sessionCalendar) { - binding.value = TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - x, tz, - this.connection.getServerTimezoneTZ(), - rollForward); + binding.value = TimeUtil.changeTimezone(this.connection, + sessionCalendar, + targetCalendar, + x, tz, + this.connection.getServerTimezoneTZ(), + rollForward); + } + + binding.isNull = false; + binding.isLongData = false; } - - binding.isNull = false; - binding.isLongData = false; } } @@ -2070,7 +2258,9 @@ */ public void setTimestamp(int parameterIndex, java.sql.Timestamp x) throws SQLException { - setTimestampInternal(parameterIndex, x, null, this.connection.getDefaultTimeZone(), false); + synchronized (checkClosed().getConnectionMutex()) { + setTimestampInternal(parameterIndex, x, null, this.connection.getDefaultTimeZone(), false); + } } /** @@ -2089,43 +2279,51 @@ */ public void setTimestamp(int parameterIndex, java.sql.Timestamp x, Calendar cal) throws SQLException { - setTimestampInternal(parameterIndex, x, cal, cal.getTimeZone(), true); + synchronized (checkClosed().getConnectionMutex()) { + setTimestampInternal(parameterIndex, x, cal, cal.getTimeZone(), true); + } } protected void setTimestampInternal(int parameterIndex, java.sql.Timestamp x, Calendar targetCalendar, TimeZone tz, boolean rollForward) throws SQLException { - if (x == null) { - setNull(parameterIndex, java.sql.Types.TIMESTAMP); - } else { - BindValue binding = getBinding(parameterIndex, false); - setType(binding, MysqlDefs.FIELD_TYPE_DATETIME); + synchronized (checkClosed().getConnectionMutex()) { + if (x == null) { + setNull(parameterIndex, java.sql.Types.TIMESTAMP); + } else { + BindValue binding = getBinding(parameterIndex, false); + setType(binding, MysqlDefs.FIELD_TYPE_DATETIME); + + if (!this.useLegacyDatetimeCode) { + binding.value = x; + } else { + Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ? + this.connection.getUtcCalendar() : + getCalendarInstanceForSessionOrNew(); + + binding.value = TimeUtil.changeTimezone(this.connection, + sessionCalendar, + targetCalendar, + x, tz, + this.connection.getServerTimezoneTZ(), + rollForward); - Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ? - this.connection.getUtcCalendar() : - getCalendarInstanceForSessionOrNew(); - - synchronized (sessionCalendar) { - binding.value = TimeUtil.changeTimezone(this.connection, - sessionCalendar, - targetCalendar, - x, tz, - this.connection.getServerTimezoneTZ(), - rollForward); + binding.isNull = false; + binding.isLongData = false; + } } - - binding.isNull = false; - binding.isLongData = false; } } - private void setType(BindValue oldValue, int bufferType) { - if (oldValue.bufferType != bufferType) { - this.sendTypesToServer = true; + protected void setType(BindValue oldValue, int bufferType) throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (oldValue.bufferType != bufferType) { + this.sendTypesToServer = true; + } + + oldValue.bufferType = bufferType; } - - oldValue.bufferType = bufferType; } /** @@ -2151,7 +2349,7 @@ throws SQLException { checkClosed(); - throw new NotImplemented(); + throw SQLError.notImplemented(); } /** @@ -2176,80 +2374,93 @@ */ private void storeBinding(Buffer packet, BindValue bindValue, MysqlIO mysql) throws SQLException { - try { - Object value = bindValue.value; - - // - // Handle primitives first - // - switch (bindValue.bufferType) { - - case MysqlDefs.FIELD_TYPE_TINY: - packet.writeByte(bindValue.byteBinding); - return; - case MysqlDefs.FIELD_TYPE_SHORT: - packet.ensureCapacity(2); - packet.writeInt(bindValue.shortBinding); - return; - case MysqlDefs.FIELD_TYPE_LONG: - packet.ensureCapacity(4); - packet.writeLong(bindValue.intBinding); - return; - case MysqlDefs.FIELD_TYPE_LONGLONG: - packet.ensureCapacity(8); - packet.writeLongLong(bindValue.longBinding); - return; - case MysqlDefs.FIELD_TYPE_FLOAT: - packet.ensureCapacity(4); - packet.writeFloat(bindValue.floatBinding); - return; - case MysqlDefs.FIELD_TYPE_DOUBLE: - packet.ensureCapacity(8); - packet.writeDouble(bindValue.doubleBinding); - return; - case MysqlDefs.FIELD_TYPE_TIME: - storeTime(packet, (Time) value); - return; - case MysqlDefs.FIELD_TYPE_DATE: - case MysqlDefs.FIELD_TYPE_DATETIME: - case MysqlDefs.FIELD_TYPE_TIMESTAMP: - storeDateTime(packet, (java.util.Date) value, mysql); - return; - case MysqlDefs.FIELD_TYPE_VAR_STRING: - case MysqlDefs.FIELD_TYPE_STRING: - case MysqlDefs.FIELD_TYPE_VARCHAR: - case MysqlDefs.FIELD_TYPE_DECIMAL: - case MysqlDefs.FIELD_TYPE_NEW_DECIMAL: - if (value instanceof byte[]) { - packet.writeLenBytes((byte[]) value); - } else if (!this.isLoadDataQuery) { - packet.writeLenString((String) value, this.charEncoding, - this.connection.getServerCharacterEncoding(), - this.charConverter, this.connection - .parserKnowsUnicode(), - this.connection); - } else { - packet.writeLenBytes(((String) value).getBytes()); + synchronized (checkClosed().getConnectionMutex()) { + try { + Object value = bindValue.value; + + // + // Handle primitives first + // + switch (bindValue.bufferType) { + + case MysqlDefs.FIELD_TYPE_TINY: + packet.writeByte((byte)bindValue.longBinding); + return; + case MysqlDefs.FIELD_TYPE_SHORT: + packet.ensureCapacity(2); + packet.writeInt((int)bindValue.longBinding); + return; + case MysqlDefs.FIELD_TYPE_LONG: + packet.ensureCapacity(4); + packet.writeLong((int)bindValue.longBinding); + return; + case MysqlDefs.FIELD_TYPE_LONGLONG: + packet.ensureCapacity(8); + packet.writeLongLong(bindValue.longBinding); + return; + case MysqlDefs.FIELD_TYPE_FLOAT: + packet.ensureCapacity(4); + packet.writeFloat(bindValue.floatBinding); + return; + case MysqlDefs.FIELD_TYPE_DOUBLE: + packet.ensureCapacity(8); + packet.writeDouble(bindValue.doubleBinding); + return; + case MysqlDefs.FIELD_TYPE_TIME: + storeTime(packet, (Time) value); + return; + case MysqlDefs.FIELD_TYPE_DATE: + case MysqlDefs.FIELD_TYPE_DATETIME: + case MysqlDefs.FIELD_TYPE_TIMESTAMP: + storeDateTime(packet, (java.util.Date) value, mysql, bindValue.bufferType); + return; + case MysqlDefs.FIELD_TYPE_VAR_STRING: + case MysqlDefs.FIELD_TYPE_STRING: + case MysqlDefs.FIELD_TYPE_VARCHAR: + case MysqlDefs.FIELD_TYPE_DECIMAL: + case MysqlDefs.FIELD_TYPE_NEW_DECIMAL: + if (value instanceof byte[]) { + packet.writeLenBytes((byte[]) value); + } else if (!this.isLoadDataQuery) { + packet.writeLenString((String) value, this.charEncoding, + this.connection.getServerCharacterEncoding(), + this.charConverter, this.connection + .parserKnowsUnicode(), + this.connection); + } else { + packet.writeLenBytes(StringUtils.getBytes((String) value)); + } + + return; } - - return; + + + } catch (UnsupportedEncodingException uEE) { + throw SQLError.createSQLException(Messages + .getString("ServerPreparedStatement.22") //$NON-NLS-1$ + + this.connection.getEncoding() + "'", //$NON-NLS-1$ + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); } - - - } catch (UnsupportedEncodingException uEE) { - throw SQLError.createSQLException(Messages - .getString("ServerPreparedStatement.22") //$NON-NLS-1$ - + this.connection.getEncoding() + "'", //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); } } - private void storeDataTime412AndOlder(Buffer intoBuf, java.util.Date dt) + private void storeDateTime412AndOlder(Buffer intoBuf, java.util.Date dt, int bufferType) throws SQLException { - - Calendar sessionCalendar = getCalendarInstanceForSessionOrNew(); - - synchronized (sessionCalendar) { + synchronized (checkClosed().getConnectionMutex()) { + Calendar sessionCalendar = null; + + if (!this.useLegacyDatetimeCode) { + if (bufferType == MysqlDefs.FIELD_TYPE_DATE) { + sessionCalendar = getDefaultTzCalendar(); + } else { + sessionCalendar = getServerTzCalendar(); + } + } else { + sessionCalendar = (dt instanceof Timestamp && + this.connection.getUseJDBCCompliantTimezoneShift()) ? + this.connection.getUtcCalendar() : getCalendarInstanceForSessionOrNew(); + } + java.util.Date oldTime = sessionCalendar.getTime(); try { @@ -2284,25 +2495,45 @@ } } - private void storeDateTime(Buffer intoBuf, java.util.Date dt, MysqlIO mysql) + /** + * + * @param intoBuf + * @param dt + * @param mysql + * @param bufferType + * @throws SQLException + */ + private void storeDateTime(Buffer intoBuf, java.util.Date dt, MysqlIO mysql, int bufferType) throws SQLException { - if (this.connection.versionMeetsMinimum(4, 1, 3)) { - storeDateTime413AndNewer(intoBuf, dt); - } else { - storeDataTime412AndOlder(intoBuf, dt); + synchronized (checkClosed().getConnectionMutex()) { + if (this.connection.versionMeetsMinimum(4, 1, 3)) { + storeDateTime413AndNewer(intoBuf, dt, bufferType); + } else { + storeDateTime412AndOlder(intoBuf, dt, bufferType); + } } } - private void storeDateTime413AndNewer(Buffer intoBuf, java.util.Date dt) + private void storeDateTime413AndNewer(Buffer intoBuf, java.util.Date dt, int bufferType) throws SQLException { - Calendar sessionCalendar = (dt instanceof Timestamp && - this.connection.getUseJDBCCompliantTimezoneShift()) ? - this.connection.getUtcCalendar() : getCalendarInstanceForSessionOrNew(); - - synchronized (sessionCalendar) { + synchronized (checkClosed().getConnectionMutex()) { + Calendar sessionCalendar = null; + + if (!this.useLegacyDatetimeCode) { + if (bufferType == MysqlDefs.FIELD_TYPE_DATE) { + sessionCalendar = getDefaultTzCalendar(); + } else { + sessionCalendar = getServerTzCalendar(); + } + } else { + sessionCalendar = (dt instanceof Timestamp && + this.connection.getUseJDBCCompliantTimezoneShift()) ? + this.connection.getUtcCalendar() : getCalendarInstanceForSessionOrNew(); + } + + java.util.Date oldTime = sessionCalendar.getTime(); - - + try { sessionCalendar.setTime(dt); @@ -2344,7 +2575,7 @@ } if (length == 11) { - // MySQL expects microseconds, not nanos + // MySQL expects microseconds, not nanos intoBuf.writeLong(((java.sql.Timestamp) dt).getNanos() / 1000); } @@ -2354,163 +2585,193 @@ } } + private Calendar getServerTzCalendar() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (serverTzCalendar == null) { + serverTzCalendar = new GregorianCalendar(this.connection.getServerTimezoneTZ()); + } + + return this.serverTzCalendar; + } + } + + private Calendar getDefaultTzCalendar() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (defaultTzCalendar == null) { + defaultTzCalendar = new GregorianCalendar(TimeZone.getDefault()); + } + + return this.defaultTzCalendar; + } + } + // // TO DO: Investigate using NIO to do this faster // private void storeReader(MysqlIO mysql, int parameterIndex, Buffer packet, Reader inStream) throws SQLException { - String forcedEncoding = this.connection.getClobCharacterEncoding(); - - String clobEncoding = - (forcedEncoding == null ? this.connection.getEncoding() : forcedEncoding); - - int maxBytesChar = 2; + synchronized (checkClosed().getConnectionMutex()) { + String forcedEncoding = this.connection.getClobCharacterEncoding(); - if (clobEncoding != null) { - if (!clobEncoding.equals("UTF-16")) { - maxBytesChar = this.connection.getMaxBytesPerChar(clobEncoding); + String clobEncoding = + (forcedEncoding == null ? this.connection.getEncoding() : forcedEncoding); + + int maxBytesChar = 2; - if (maxBytesChar == 1) { - maxBytesChar = 2; // for safety + if (clobEncoding != null) { + if (!clobEncoding.equals("UTF-16")) { + maxBytesChar = this.connection.getMaxBytesPerChar(clobEncoding); + + if (maxBytesChar == 1) { + maxBytesChar = 2; // for safety + } + } else { + maxBytesChar = 4; } - } else { - maxBytesChar = 4; } - } + + char[] buf = new char[BLOB_STREAM_READ_BUF_SIZE / maxBytesChar]; - char[] buf = new char[BLOB_STREAM_READ_BUF_SIZE / maxBytesChar]; - - int numRead = 0; - - int bytesInPacket = 0; - int totalBytesRead = 0; - int bytesReadAtLastSend = 0; - int packetIsFullAt = this.connection.getBlobSendChunkSize(); - - - - try { - packet.clear(); - packet.writeByte((byte) MysqlDefs.COM_LONG_DATA); - packet.writeLong(this.serverStatementId); - packet.writeInt((parameterIndex)); - - boolean readAny = false; + int numRead = 0; + + int bytesInPacket = 0; + int totalBytesRead = 0; + int bytesReadAtLastSend = 0; + int packetIsFullAt = this.connection.getBlobSendChunkSize(); - while ((numRead = inStream.read(buf)) != -1) { - readAny = true; - byte[] valueAsBytes = StringUtils.getBytes(buf, null, - clobEncoding, this.connection - .getServerCharacterEncoding(), 0, numRead, - this.connection.parserKnowsUnicode()); - - packet.writeBytesNoNull(valueAsBytes, 0, valueAsBytes.length); - - bytesInPacket += valueAsBytes.length; - totalBytesRead += valueAsBytes.length; - - if (bytesInPacket >= packetIsFullAt) { - bytesReadAtLastSend = totalBytesRead; - - mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, - true, null); - - bytesInPacket = 0; - packet.clear(); - packet.writeByte((byte) MysqlDefs.COM_LONG_DATA); - packet.writeLong(this.serverStatementId); - packet.writeInt((parameterIndex)); - } - } - - if (totalBytesRead != bytesReadAtLastSend) { - mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true, - null); - } - if (!readAny) { - mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true, - null); - } - } catch (IOException ioEx) { - throw SQLError.createSQLException(Messages - .getString("ServerPreparedStatement.24") //$NON-NLS-1$ - + ioEx.toString(), SQLError.SQL_STATE_GENERAL_ERROR); - } finally { - if (this.connection.getAutoClosePStmtStreams()) { - if (inStream != null) { - try { - inStream.close(); - } catch (IOException ioEx) { - ; // ignore + try { + packet.clear(); + packet.writeByte((byte) MysqlDefs.COM_LONG_DATA); + packet.writeLong(this.serverStatementId); + packet.writeInt((parameterIndex)); + + boolean readAny = false; + + while ((numRead = inStream.read(buf)) != -1) { + readAny = true; + + byte[] valueAsBytes = StringUtils.getBytes(buf, null, + clobEncoding, this.connection + .getServerCharacterEncoding(), 0, numRead, + this.connection.parserKnowsUnicode(), getExceptionInterceptor()); + + packet.writeBytesNoNull(valueAsBytes, 0, valueAsBytes.length); + + bytesInPacket += valueAsBytes.length; + totalBytesRead += valueAsBytes.length; + + if (bytesInPacket >= packetIsFullAt) { + bytesReadAtLastSend = totalBytesRead; + + mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, + true, null, 0); + + bytesInPacket = 0; + packet.clear(); + packet.writeByte((byte) MysqlDefs.COM_LONG_DATA); + packet.writeLong(this.serverStatementId); + packet.writeInt((parameterIndex)); } } + + if (totalBytesRead != bytesReadAtLastSend) { + mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true, + null, 0); + } + + if (!readAny) { + mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true, + null, 0); + } + } catch (IOException ioEx) { + SQLException sqlEx = SQLError.createSQLException(Messages + .getString("ServerPreparedStatement.24") //$NON-NLS-1$ + + ioEx.toString(), SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + sqlEx.initCause(ioEx); + + throw sqlEx; + } finally { + if (this.connection.getAutoClosePStmtStreams()) { + if (inStream != null) { + try { + inStream.close(); + } catch (IOException ioEx) { + ; // ignore + } + } + } } } } private void storeStream(MysqlIO mysql, int parameterIndex, Buffer packet, InputStream inStream) throws SQLException { - byte[] buf = new byte[BLOB_STREAM_READ_BUF_SIZE]; - - int numRead = 0; - - try { - int bytesInPacket = 0; - int totalBytesRead = 0; - int bytesReadAtLastSend = 0; - int packetIsFullAt = this.connection.getBlobSendChunkSize(); - - packet.clear(); - packet.writeByte((byte) MysqlDefs.COM_LONG_DATA); - packet.writeLong(this.serverStatementId); - packet.writeInt((parameterIndex)); - - boolean readAny = false; + synchronized (checkClosed().getConnectionMutex()) { + byte[] buf = new byte[BLOB_STREAM_READ_BUF_SIZE]; + + int numRead = 0; - while ((numRead = inStream.read(buf)) != -1) { - - readAny = true; + try { + int bytesInPacket = 0; + int totalBytesRead = 0; + int bytesReadAtLastSend = 0; + int packetIsFullAt = this.connection.getBlobSendChunkSize(); + + packet.clear(); + packet.writeByte((byte) MysqlDefs.COM_LONG_DATA); + packet.writeLong(this.serverStatementId); + packet.writeInt((parameterIndex)); + + boolean readAny = false; - packet.writeBytesNoNull(buf, 0, numRead); - bytesInPacket += numRead; - totalBytesRead += numRead; - - if (bytesInPacket >= packetIsFullAt) { - bytesReadAtLastSend = totalBytesRead; - - mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, - true, null); - - bytesInPacket = 0; - packet.clear(); - packet.writeByte((byte) MysqlDefs.COM_LONG_DATA); - packet.writeLong(this.serverStatementId); - packet.writeInt((parameterIndex)); + while ((numRead = inStream.read(buf)) != -1) { + + readAny = true; + + packet.writeBytesNoNull(buf, 0, numRead); + bytesInPacket += numRead; + totalBytesRead += numRead; + + if (bytesInPacket >= packetIsFullAt) { + bytesReadAtLastSend = totalBytesRead; + + mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, + true, null, 0); + + bytesInPacket = 0; + packet.clear(); + packet.writeByte((byte) MysqlDefs.COM_LONG_DATA); + packet.writeLong(this.serverStatementId); + packet.writeInt((parameterIndex)); + } } - } - - if (totalBytesRead != bytesReadAtLastSend) { - mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true, - null); - } - - if (!readAny) { - mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true, - null); - } - } catch (IOException ioEx) { - throw SQLError.createSQLException(Messages - .getString("ServerPreparedStatement.25") //$NON-NLS-1$ - + ioEx.toString(), SQLError.SQL_STATE_GENERAL_ERROR); - } finally { - if (this.connection.getAutoClosePStmtStreams()) { - if (inStream != null) { - try { - inStream.close(); - } catch (IOException ioEx) { - ; // ignore + + if (totalBytesRead != bytesReadAtLastSend) { + mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true, + null, 0); + } + + if (!readAny) { + mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true, + null, 0); + } + } catch (IOException ioEx) { + SQLException sqlEx = SQLError.createSQLException(Messages + .getString("ServerPreparedStatement.25") //$NON-NLS-1$ + + ioEx.toString(), SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + sqlEx.initCause(ioEx); + + throw sqlEx; + } finally { + if (this.connection.getAutoClosePStmtStreams()) { + if (inStream != null) { + try { + inStream.close(); + } catch (IOException ioEx) { + ; // ignore + } } } } @@ -2541,96 +2802,141 @@ return serverStatementId; } - public synchronized boolean canRewriteAsMultivalueInsertStatement() { - if (!super.canRewriteAsMultivalueInsertStatement()) { - return false; + private boolean hasCheckedRewrite = false; + private boolean canRewrite = false; + + public boolean canRewriteAsMultiValueInsertAtSqlLevel() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!hasCheckedRewrite) { + this.hasCheckedRewrite = true; + this.canRewrite = canRewrite(this.originalSql, isOnDuplicateKeyUpdate(), getLocationOfOnDuplicateKeyUpdate(), 0); + // We need to client-side parse this to get the VALUES clause, etc. + this.parseInfo = new ParseInfo(this.originalSql, this.connection, this.connection.getMetaData(), this.charEncoding, this.charConverter); + } + + return this.canRewrite; } + } - BindValue[] currentBindValues = null; - BindValue[] previousBindValues = null; - - int nbrCommands = this.batchedArgs.size(); - - // Can't have type changes between sets of bindings for this to work... - - for (int commandIndex = 0; commandIndex < nbrCommands; commandIndex++) { - Object arg = this.batchedArgs.get(commandIndex); - - if (!(arg instanceof String)) { - - currentBindValues = ((BatchedBindValues) arg).batchedParameterValues; - - // We need to check types each time, as - // the user might have bound different - // types in each addBatch() - - if (previousBindValues != null) { - for (int j = 0; j < this.parameterBindings.length; j++) { - if (currentBindValues[j].bufferType != previousBindValues[j].bufferType) { - return false; + + public boolean canRewriteAsMultivalueInsertStatement() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (!canRewriteAsMultiValueInsertAtSqlLevel()) { + return false; + } + + BindValue[] currentBindValues = null; + BindValue[] previousBindValues = null; + + int nbrCommands = this.batchedArgs.size(); + + // Can't have type changes between sets of bindings for this to work... + + for (int commandIndex = 0; commandIndex < nbrCommands; commandIndex++) { + Object arg = this.batchedArgs.get(commandIndex); + + if (!(arg instanceof String)) { + + currentBindValues = ((BatchedBindValues) arg).batchedParameterValues; + + // We need to check types each time, as + // the user might have bound different + // types in each addBatch() + + if (previousBindValues != null) { + for (int j = 0; j < this.parameterBindings.length; j++) { + if (currentBindValues[j].bufferType != previousBindValues[j].bufferType) { + return false; + } } } } } + + + + return true; } - - return true; } + + private int locationOfOnDuplicateKeyUpdate = -2; + + protected int getLocationOfOnDuplicateKeyUpdate() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + if (this.locationOfOnDuplicateKeyUpdate == -2) { + this.locationOfOnDuplicateKeyUpdate = getOnDuplicateKeyLocation(this.originalSql); + } + + return this.locationOfOnDuplicateKeyUpdate; + } + } + + protected boolean isOnDuplicateKeyUpdate() throws SQLException { + synchronized (checkClosed().getConnectionMutex()) { + return getLocationOfOnDuplicateKeyUpdate() != -1; + } + } + + + /** * Computes the maximum parameter set size, and entire batch size given * the number of arguments in the batch. + * @throws SQLException */ - protected long[] computeMaxParameterSetSizeAndBatchSize(int numBatchedArgs) { - long sizeOfEntireBatch = 1 + /* com_execute */ + 4 /* stmt id */ + 1 /* flags */ + 4 /* batch count padding */; - long maxSizeOfParameterSet = 0; - - for (int i = 0; i < numBatchedArgs; i++) { - BindValue[] paramArg = ((BatchedBindValues) this.batchedArgs.get(i)).batchedParameterValues; - - long sizeOfParameterSet = 0; + 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 maxSizeOfParameterSet = 0; - sizeOfParameterSet += (this.parameterCount + 7) / 8; // for isNull - - sizeOfParameterSet += this.parameterCount * 2; // have to send types - - for (int j = 0; j < this.parameterBindings.length; j++) { - if (!paramArg[j].isNull) { - - long size = paramArg[j].getBoundLength(); - - if (paramArg[j].isLongData) { - if (size != -1) { + for (int i = 0; i < numBatchedArgs; i++) { + BindValue[] paramArg = ((BatchedBindValues) this.batchedArgs.get(i)).batchedParameterValues; + + long sizeOfParameterSet = 0; + + sizeOfParameterSet += (this.parameterCount + 7) / 8; // for isNull + + sizeOfParameterSet += this.parameterCount * 2; // have to send types + + for (int j = 0; j < this.parameterBindings.length; j++) { + if (!paramArg[j].isNull) { + + long size = paramArg[j].getBoundLength(); + + if (paramArg[j].isLongData) { + if (size != -1) { + sizeOfParameterSet += size; + } + } else { sizeOfParameterSet += size; } - } else { - sizeOfParameterSet += size; } } - } + + sizeOfEntireBatch += sizeOfParameterSet; + + if (sizeOfParameterSet > maxSizeOfParameterSet) { + maxSizeOfParameterSet = sizeOfParameterSet; + } + } - sizeOfEntireBatch += sizeOfParameterSet; - - if (sizeOfParameterSet > maxSizeOfParameterSet) { - maxSizeOfParameterSet = sizeOfParameterSet; - } - } - - return new long[] {maxSizeOfParameterSet, sizeOfEntireBatch}; + return new long[] {maxSizeOfParameterSet, sizeOfEntireBatch}; + } } - + protected int setOneBatchedParameterSet( java.sql.PreparedStatement batchedStatement, int batchedParamIndex, Object paramSet) throws SQLException { BindValue[] paramArg = ((BatchedBindValues) paramSet).batchedParameterValues; - + for (int j = 0; j < paramArg.length; j++) { if (paramArg[j].isNull) { batchedStatement.setNull(batchedParamIndex++, Types.NULL); } else { if (paramArg[j].isLongData) { Object value = paramArg[j].value; - + if (value instanceof InputStream) { batchedStatement.setBinaryStream(batchedParamIndex++, (InputStream) value, @@ -2641,20 +2947,20 @@ (int) paramArg[j].bindLength); } } else { - + switch (paramArg[j].bufferType) { - + case MysqlDefs.FIELD_TYPE_TINY: batchedStatement.setByte(batchedParamIndex++, - paramArg[j].byteBinding); + (byte)paramArg[j].longBinding); break; case MysqlDefs.FIELD_TYPE_SHORT: batchedStatement.setShort(batchedParamIndex++, - paramArg[j].shortBinding); + (short)paramArg[j].longBinding); break; case MysqlDefs.FIELD_TYPE_LONG: batchedStatement.setInt(batchedParamIndex++, - paramArg[j].intBinding); + (int)paramArg[j].longBinding); break; case MysqlDefs.FIELD_TYPE_LONGLONG: batchedStatement.setLong(batchedParamIndex++, @@ -2687,26 +2993,27 @@ case MysqlDefs.FIELD_TYPE_DECIMAL: case MysqlDefs.FIELD_TYPE_NEW_DECIMAL: Object value = paramArg[j].value; - + if (value instanceof byte[]) { batchedStatement.setBytes(batchedParamIndex, (byte[]) value); } else { batchedStatement.setString(batchedParamIndex, (String) value); } - - BindValue asBound = ((ServerPreparedStatement) batchedStatement) - .getBinding( - batchedParamIndex + 1 /* - * uses 1-based - * offset - */, - false); - asBound.bufferType = paramArg[j].bufferType; - + + // If we ended up here as a multi-statement, we're not working with a server prepared statement + + if (batchedStatement instanceof ServerPreparedStatement) { + BindValue asBound = ((ServerPreparedStatement) batchedStatement) + .getBinding( + batchedParamIndex, + false); + asBound.bufferType = paramArg[j].bufferType; + } + batchedParamIndex++; - + break; default: throw new IllegalArgumentException( @@ -2719,4 +3026,24 @@ return batchedParamIndex; } + + protected boolean containsOnDuplicateKeyUpdateInSQL() { + return this.hasOnDuplicateKeyUpdate; + } + + 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); + pstmt.setRetrieveGeneratedKeys(this.retrieveGeneratedKeys); + + return pstmt; + } catch (UnsupportedEncodingException e) { + SQLException sqlEx = SQLError.createSQLException("Unable to prepare batch statement", SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); + sqlEx.initCause(e); + + throw sqlEx; + } + } + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/SingleByteCharsetConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/SingleByteCharsetConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/SingleByteCharsetConverter.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/SingleByteCharsetConverter.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,31 +1,29 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.UnsupportedEncodingException; - import java.sql.SQLException; import java.util.HashMap; import java.util.Map; @@ -43,7 +41,7 @@ private static final int BYTE_RANGE = (1 + Byte.MAX_VALUE) - Byte.MIN_VALUE; private static byte[] allBytes = new byte[BYTE_RANGE]; - private static final Map CONVERTER_MAP = new HashMap(); + private static final Map CONVERTER_MAP = new HashMap(); private final static byte[] EMPTY_BYTE_ARRAY = new byte[0]; @@ -71,6 +69,7 @@ * * @param encodingName * the Java character encoding name + * @param conn * * @return a converter for the given encoding name * @throws UnsupportedEncodingException @@ -79,7 +78,7 @@ public static synchronized SingleByteCharsetConverter getInstance( String encodingName, Connection conn) throws UnsupportedEncodingException, SQLException { - SingleByteCharsetConverter instance = (SingleByteCharsetConverter) CONVERTER_MAP + SingleByteCharsetConverter instance = CONVERTER_MAP .get(encodingName); if (instance == null) { @@ -101,8 +100,14 @@ */ public static SingleByteCharsetConverter initCharset(String javaEncodingName) throws UnsupportedEncodingException, SQLException { - if (CharsetMapping.isMultibyteCharset(javaEncodingName)) { - return null; + try { + if (CharsetMapping.isMultibyteCharset(javaEncodingName)) { + return null; + } + } catch (RuntimeException ex) { + SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null); + sqlEx.initCause(ex); + throw sqlEx; } SingleByteCharsetConverter converter = new SingleByteCharsetConverter( @@ -178,7 +183,27 @@ return bytes; } + + public final byte[] toBytesWrapped(char[] c, char beginWrap, char endWrap) { + if (c == null) { + return null; + } + int length = c.length + 2; + int charLength = c.length; + + byte[] bytes = new byte[length]; + bytes[0] = this.charToByteMap[beginWrap]; + + for (int i = 0; i < charLength; i++) { + bytes[i + 1] = this.charToByteMap[c[i]]; + } + + bytes[length - 1] = this.charToByteMap[endWrap]; + + return bytes; + } + public final byte[] toBytes(char[] chars, int offset, int length) { if (chars == null) { return null; @@ -218,7 +243,29 @@ return bytes; } + + public final byte[] toBytesWrapped(String s, char beginWrap, char endWrap) { + if (s == null) { + return null; + } + int stringLength = s.length(); + + int length = stringLength + 2; + + byte[] bytes = new byte[length]; + + bytes[0] = this.charToByteMap[beginWrap]; + + for (int i = 0; i < stringLength; i++) { + bytes[i + 1] = this.charToByteMap[s.charAt(i)]; + } + + bytes[length - 1] = this.charToByteMap[endWrap]; + + return bytes; + } + /** * Convert the given string to an array of bytes. * Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/SocketFactory.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/SocketFactory.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/SocketFactory.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/SocketFactory.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,34 +1,31 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.IOException; - import java.net.Socket; import java.net.SocketException; - import java.util.Properties; /** Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/SocketMetadata.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/StandardLoadBalanceExceptionChecker.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/StandardSocketFactory.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/StandardSocketFactory.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/StandardSocketFactory.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/StandardSocketFactory.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,47 +1,49 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.IOException; - import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; - import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketAddress; import java.net.SocketException; - +import java.net.UnknownHostException; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.Properties; /** * Socket factory for vanilla TCP/IP sockets (the standard) - * + * * @author Mark Matthews */ -public class StandardSocketFactory implements SocketFactory { +public class StandardSocketFactory implements SocketFactory, SocketMetadata { public static final String TCP_NO_DELAY_PROPERTY_NAME = "tcpNoDelay"; @@ -87,40 +89,54 @@ /** The underlying TCP/IP socket to use */ protected Socket rawSocket = null; + /** The remaining login time in milliseconds. Initial value set from defined DriverManager.setLoginTimeout() */ + protected int loginTimeoutCountdown = DriverManager.getLoginTimeout() * 1000; + + /** Time when last Login Timeout check occurred */ + protected long loginTimeoutCheckTimestamp = System.currentTimeMillis(); + + /** Backup original Socket timeout to be restored after handshake */ + protected int socketTimeoutBackup = 0; + /** * Called by the driver after issuing the MySQL protocol handshake and * reading the results of the handshake. - * + * * @throws SocketException * if a socket error occurs * @throws IOException * if an I/O error occurs - * + * * @return The socket to use after the handshake */ public Socket afterHandshake() throws SocketException, IOException { + resetLoginTimeCountdown(); + this.rawSocket.setSoTimeout(this.socketTimeoutBackup); return this.rawSocket; } /** * Called by the driver before issuing the MySQL protocol handshake. Should * return the socket instance that should be used during the handshake. - * + * * @throws SocketException * if a socket error occurs * @throws IOException * if an I/O error occurs - * + * * @return the socket to use before the handshake */ public Socket beforeHandshake() throws SocketException, IOException { + resetLoginTimeCountdown(); + this.socketTimeoutBackup = this.rawSocket.getSoTimeout(); + this.rawSocket.setSoTimeout(getRealTimeout(this.socketTimeoutBackup)); return this.rawSocket; } /** * Configures socket properties based on properties from the connection * (tcpNoDelay, snd/rcv buf, traffic class, etc). - * + * * @param props * @throws SocketException * @throws IOException @@ -160,7 +176,7 @@ if (trafficClass > 0 && setTraficClassMethod != null) { setTraficClassMethod.invoke(sock, - new Object[] { new Integer(trafficClass) }); + new Object[] { Integer.valueOf(trafficClass) }); } } catch (Throwable t) { unwrapExceptionToProperClassAndThrowIt(t); @@ -170,8 +186,7 @@ /** * @see com.mysql.jdbc.SocketFactory#createSocket(Properties) */ - public Socket connect(String hostname, int portNumber, Properties props) - throws SocketException, IOException { + public Socket connect(String hostname, int portNumber, Properties props) throws SocketException, IOException { if (props != null) { this.host = hostname; @@ -180,47 +195,38 @@ Method connectWithTimeoutMethod = null; Method socketBindMethod = null; - Class socketAddressClass = null; + Class socketAddressClass = null; - String localSocketHostname = props - .getProperty("localSocketAddress"); + String localSocketHostname = props.getProperty("localSocketAddress"); String connectTimeoutStr = props.getProperty("connectTimeout"); int connectTimeout = 0; - boolean wantsTimeout = (connectTimeoutStr != null - && connectTimeoutStr.length() > 0 && !connectTimeoutStr - .equals("0")); + boolean wantsTimeout = (connectTimeoutStr != null && connectTimeoutStr.length() > 0 && !connectTimeoutStr + .equals("0")) || this.loginTimeoutCountdown > 0; - boolean wantsLocalBind = (localSocketHostname != null && localSocketHostname - .length() > 0); + boolean wantsLocalBind = (localSocketHostname != null && localSocketHostname.length() > 0); boolean needsConfigurationBeforeConnect = socketNeedsConfigurationBeforeConnect(props); - - if (wantsTimeout || wantsLocalBind || needsConfigurationBeforeConnect) { + if (wantsTimeout || wantsLocalBind || needsConfigurationBeforeConnect) { if (connectTimeoutStr != null) { try { connectTimeout = Integer.parseInt(connectTimeoutStr); } catch (NumberFormatException nfe) { - throw new SocketException("Illegal value '" - + connectTimeoutStr + "' for connectTimeout"); + throw new SocketException("Illegal value '" + connectTimeoutStr + "' for connectTimeout"); } } try { - // Have to do this with reflection, otherwise older JVMs - // croak - socketAddressClass = Class - .forName("java.net.SocketAddress"); + // Have to do this with reflection, otherwise older JVMs croak + socketAddressClass = Class.forName("java.net.SocketAddress"); - connectWithTimeoutMethod = Socket.class.getMethod( - "connect", new Class[] { socketAddressClass, - Integer.TYPE }); + connectWithTimeoutMethod = Socket.class.getMethod("connect", new Class[] { socketAddressClass, + Integer.TYPE }); - socketBindMethod = Socket.class.getMethod("bind", - new Class[] { socketAddressClass }); + socketBindMethod = Socket.class.getMethod("bind", new Class[] { socketAddressClass }); } catch (NoClassDefFoundError noClassDefFound) { // ignore, we give a better error below if needed @@ -231,107 +237,87 @@ } if (wantsLocalBind && socketBindMethod == null) { - throw new SocketException( - "Can't specify \"localSocketAddress\" on JVMs older than 1.4"); + throw new SocketException("Can't specify \"localSocketAddress\" on JVMs older than 1.4"); } if (wantsTimeout && connectWithTimeoutMethod == null) { - throw new SocketException( - "Can't specify \"connectTimeout\" on JVMs older than 1.4"); + throw new SocketException("Can't specify \"connectTimeout\" on JVMs older than 1.4"); } } if (this.host != null) { if (!(wantsLocalBind || wantsTimeout || needsConfigurationBeforeConnect)) { - InetAddress[] possibleAddresses = InetAddress - .getAllByName(this.host); + InetAddress[] possibleAddresses = InetAddress.getAllByName(this.host); Throwable caughtWhileConnecting = null; - // Need to loop through all possible addresses, in case - // someone has IPV6 configured (SuSE, for example...) - + // Need to loop through all possible addresses, in case someone has IPV6 configured (SuSE, for + // example...) for (int i = 0; i < possibleAddresses.length; i++) { try { - this.rawSocket = new Socket(possibleAddresses[i], - port); + this.rawSocket = new Socket(possibleAddresses[i], this.port); configureSocket(this.rawSocket, props); break; } catch (Exception ex) { + resetLoginTimeCountdown(); caughtWhileConnecting = ex; } } - if (rawSocket == null) { + if (this.rawSocket == null) { unwrapExceptionToProperClassAndThrowIt(caughtWhileConnecting); } } else { - // must explicitly state this due to classloader issues - // when running on older JVMs :( + // must explicitly state this due to classloader issues when running on older JVMs :( try { + InetAddress[] possibleAddresses = InetAddress.getAllByName(this.host); - InetAddress[] possibleAddresses = InetAddress - .getAllByName(this.host); - Throwable caughtWhileConnecting = null; Object localSockAddr = null; - Class inetSocketAddressClass = null; + Class inetSocketAddressClass = null; - Constructor addrConstructor = null; + Constructor addrConstructor = null; try { - inetSocketAddressClass = Class - .forName("java.net.InetSocketAddress"); + inetSocketAddressClass = Class.forName("java.net.InetSocketAddress"); - addrConstructor = inetSocketAddressClass - .getConstructor(new Class[] { - InetAddress.class, Integer.TYPE }); + addrConstructor = inetSocketAddressClass.getConstructor(new Class[] { InetAddress.class, + Integer.TYPE }); if (wantsLocalBind) { - localSockAddr = addrConstructor - .newInstance(new Object[] { - InetAddress - .getByName(localSocketHostname), - new Integer(0 /* - * use ephemeral - * port - */) }); - + localSockAddr = addrConstructor.newInstance(new Object[] { + InetAddress.getByName(localSocketHostname), + new Integer(0 /* use ephemeral port */) }); } } catch (Throwable ex) { unwrapExceptionToProperClassAndThrowIt(ex); } - // Need to loop through all possible addresses, in case - // someone has IPV6 configured (SuSE, for example...) - + // Need to loop through all possible addresses, in case someone has IPV6 configured (SuSE, for + // example...) for (int i = 0; i < possibleAddresses.length; i++) { - try { this.rawSocket = new Socket(); configureSocket(this.rawSocket, props); - Object sockAddr = addrConstructor - .newInstance(new Object[] { - possibleAddresses[i], - new Integer(port) }); - // bind to the local port, null is 'ok', it - // means - // use the ephemeral port - socketBindMethod.invoke(rawSocket, - new Object[] { localSockAddr }); + Object sockAddr = addrConstructor.newInstance(new Object[] { possibleAddresses[i], + Integer.valueOf(this.port) }); + // bind to the local port if not using the ephemeral port + if (localSockAddr != null) { + socketBindMethod.invoke(this.rawSocket, new Object[] { localSockAddr }); + } - connectWithTimeoutMethod.invoke(rawSocket, - new Object[] { sockAddr, - new Integer(connectTimeout) }); + connectWithTimeoutMethod.invoke(this.rawSocket, + new Object[] { sockAddr, Integer.valueOf(getRealTimeout(connectTimeout)) }); break; } catch (Exception ex) { + resetLoginTimeCountdown(); this.rawSocket = null; caughtWhileConnecting = ex; @@ -346,6 +332,7 @@ unwrapExceptionToProperClassAndThrowIt(t); } } + resetLoginTimeCountdown(); return this.rawSocket; } @@ -357,7 +344,6 @@ /** * Does the configureSocket() need to be called before the socket is * connect()d based on the properties supplied? - * */ private boolean socketNeedsConfigurationBeforeConnect(Properties props) { int receiveBufferSize = Integer.parseInt(props.getProperty( @@ -406,4 +392,101 @@ throw new SocketException(caughtWhileConnecting.toString()); } -} + + public static final String IS_LOCAL_HOSTNAME_REPLACEMENT_PROPERTY_NAME = "com.mysql.jdbc.test.isLocalHostnameReplacement"; + + public boolean isLocallyConnected(com.mysql.jdbc.ConnectionImpl conn) + throws SQLException { + long threadId = conn.getId(); + java.sql.Statement processListStmt = conn.getMetadataSafeStatement(); + ResultSet rs = null; + + try { + String processHost = null; + + rs = processListStmt.executeQuery("SHOW PROCESSLIST"); + + while (rs.next()) { + long id = rs.getLong(1); + + if (threadId == id) { + + processHost = rs.getString(3); + + break; + } + } + + // "inject" for tests + if (System.getProperty(IS_LOCAL_HOSTNAME_REPLACEMENT_PROPERTY_NAME) != null) { + processHost = System + .getProperty(IS_LOCAL_HOSTNAME_REPLACEMENT_PROPERTY_NAME); + } else if (conn.getProperties().getProperty(IS_LOCAL_HOSTNAME_REPLACEMENT_PROPERTY_NAME) != null) { + processHost = conn.getProperties().getProperty(IS_LOCAL_HOSTNAME_REPLACEMENT_PROPERTY_NAME); + } + + if (processHost != null) { + if (processHost.indexOf(":") != -1) { + processHost = processHost.split(":")[0]; + + try { + boolean isLocal = false; + + InetAddress whereMysqlThinksIConnectedFrom = InetAddress.getByName(processHost); + SocketAddress remoteSocketAddr = this.rawSocket.getRemoteSocketAddress(); + + if (remoteSocketAddr instanceof InetSocketAddress) { + InetAddress whereIConnectedTo = ((InetSocketAddress)remoteSocketAddr).getAddress(); + + isLocal = whereMysqlThinksIConnectedFrom.equals(whereIConnectedTo); + } + + return isLocal; + } catch (UnknownHostException e) { + conn.getLog().logWarn( + Messages.getString( + "Connection.CantDetectLocalConnect", + new Object[] { this.host }), e); + + return false; + } + } + } + + return false; + } finally { + processListStmt.close(); + } + } + + /** + * Decrements elapsed time since last reset from login timeout count down. + * + * @throws SocketException + * If the login timeout is reached or exceeded. + */ + protected void resetLoginTimeCountdown() throws SocketException { + if (this.loginTimeoutCountdown > 0) { + long now = System.currentTimeMillis(); + this.loginTimeoutCountdown -= now - this.loginTimeoutCheckTimestamp; + if (this.loginTimeoutCountdown <= 0) { + throw new SocketException(Messages.getString("Connection.LoginTimeout")); + } + this.loginTimeoutCheckTimestamp = now; + } + } + + /** + * Validates the connection/socket timeout that must really be used. + * + * @param expectedTimeout + * The timeout to validate. + * @return The timeout to be used. + */ + protected int getRealTimeout(int expectedTimeout) { + if (this.loginTimeoutCountdown > 0 && (expectedTimeout == 0 || expectedTimeout > this.loginTimeoutCountdown)) { + return this.loginTimeoutCountdown; + } + return expectedTimeout; + } +} \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Statement.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Statement.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Statement.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Statement.java 30 Jul 2014 08:37:25 -0000 1.1.2.1 @@ -1,2368 +1,105 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; -import com.mysql.jdbc.exceptions.MySQLTimeoutException; -import com.mysql.jdbc.profiler.ProfileEventSink; -import com.mysql.jdbc.profiler.ProfilerEvent; -import com.mysql.jdbc.util.LRUCache; - -import java.sql.DataTruncation; +import java.io.InputStream; import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Types; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.TimerTask; - /** - * A Statement object is used for executing a static SQL statement and obtaining - * the results produced by it. - * - *

- * Only one ResultSet per Statement can be open at any point in time. Therefore, - * if the reading of one ResultSet is interleaved with the reading of another, - * each must have been generated by different Statements. All statement execute - * methods implicitly close a statement's current ResultSet if an open one - * exists. - *

- * - * @author Mark Matthews - * @version $Id: Statement.java 4624 2005-11-28 14:24:29 -0600 (Mon, 28 Nov - * 2005) mmatthews $ - * - * @see java.sql.Statement - * @see ResultSet + * This interface contains methods that are considered the "vendor extension" + * to the JDBC API for MySQL's implementation of java.sql.Statement. + * + * For those looking further into the driver implementation, it is not + * an API that is used for plugability of implementations inside our driver + * (which is why there are still references to StatementImpl throughout the + * code). + * + * @version $Id$ + * */ -public class Statement implements java.sql.Statement { - protected static final String PING_MARKER = "/* ping */"; +public interface Statement extends java.sql.Statement { /** - * Thread used to implement query timeouts...Eventually we could be more - * efficient and have one thread with timers, but this is a straightforward - * and simple way to implement a feature that isn't used all that often. - */ - class CancelTask extends TimerTask { - - long connectionId = 0; - SQLException caughtWhileCancelling = null; - - CancelTask() throws SQLException { - connectionId = connection.getIO().getThreadId(); - } - - public void run() { - - Thread cancelThread = new Thread() { - - public void run() { - Connection cancelConn = null; - java.sql.Statement cancelStmt = null; - - try { - synchronized (cancelTimeoutMutex) { - cancelConn = connection.duplicate(); - cancelStmt = cancelConn.createStatement(); - cancelStmt.execute("KILL QUERY " + connectionId); - wasCancelled = true; - } - } catch (SQLException sqlEx) { - 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. - } finally { - if (cancelStmt != null) { - try { - cancelStmt.close(); - } catch (SQLException sqlEx) { - throw new RuntimeException(sqlEx.toString()); - } - } - - if (cancelConn != null) { - try { - cancelConn.close(); - } catch (SQLException sqlEx) { - throw new RuntimeException(sqlEx.toString()); - } - } - } - } - }; - - cancelThread.start(); - } - } - - /** Mutex to prevent race between returning query results and noticing - that we're timed-out or cancelled. */ - - protected Object cancelTimeoutMutex = new Object(); - - /** Used to generate IDs when profiling. */ - protected static int statementCounter = 1; - - public final static byte USES_VARIABLES_FALSE = 0; - - public final static byte USES_VARIABLES_TRUE = 1; - - public final static byte USES_VARIABLES_UNKNOWN = -1; - - protected boolean wasCancelled = false; - - /** Holds batched commands */ - protected List batchedArgs; - - /** The character converter to use (if available) */ - protected SingleByteCharsetConverter charConverter = null; - - /** The character encoding to use (if available) */ - protected String charEncoding = null; - - /** The connection that created us */ - protected Connection connection = null; - - protected long connectionId = 0; - - /** The catalog in use */ - protected String currentCatalog = null; - - /** Should we process escape codes? */ - protected boolean doEscapeProcessing = true; - - /** If we're profiling, where should events go to? */ - protected ProfileEventSink eventSink = null; - - /** The number of rows to fetch at a time (currently ignored) */ - private int fetchSize = 0; - - /** Has this statement been closed? */ - protected boolean isClosed = false; - - /** The auto_increment value for the last insert */ - protected long lastInsertId = -1; - - /** The max field size for this statement */ - protected int maxFieldSize = MysqlIO.getMaxBuf(); - - /** - * The maximum number of rows to return for this statement (-1 means _all_ - * rows) - */ - protected int maxRows = -1; - - /** Has someone changed this for this statement? */ - protected boolean maxRowsChanged = false; - - /** List of currently-open ResultSets */ - protected List openResults = new ArrayList(); - - /** Are we in pedantic mode? */ - protected boolean pedantic = false; - - /** - * Where this statement was created, only used if profileSql or - * useUsageAdvisor set to true. - */ - protected Throwable pointOfOrigin; - - /** Should we profile? */ - protected boolean profileSQL = false; - - /** The current results */ - protected ResultSet results = null; - - /** The concurrency for this result set (updatable or not) */ - protected int resultSetConcurrency = 0; - - /** The type of this result set (scroll sensitive or in-sensitive) */ - protected int resultSetType = 0; - - /** Used to identify this statement when profiling. */ - protected int statementId; - - /** The timeout for a query */ - protected int timeoutInMillis = 0; - - /** The update count for this statement */ - protected long updateCount = -1; - - /** Should we use the usage advisor? */ - protected boolean useUsageAdvisor = false; - - /** The warnings chain. */ - protected SQLWarning warningChain = null; - - /** - * Should this statement hold results open over .close() irregardless of - * connection's setting? - */ - protected boolean holdResultsOpenOverClose = false; - - protected ArrayList batchedGeneratedKeys = null; - - protected boolean retrieveGeneratedKeys = false; - - protected boolean continueBatchOnError = false; - - protected PingTarget pingTarget = null; - - - /** - * Constructor for a Statement. - * - * @param c - * the Connection instantation that creates us - * @param catalog - * the database name in use when we were created - * - * @throws SQLException - * if an error occurs. - */ - public Statement(Connection c, String catalog) throws SQLException { - if ((c == null) || c.isClosed()) { - throw SQLError.createSQLException( - Messages.getString("Statement.0"), //$NON-NLS-1$ - SQLError.SQL_STATE_CONNECTION_NOT_OPEN); //$NON-NLS-1$ //$NON-NLS-2$ - } - - this.connection = c; - this.connectionId = this.connection.getId(); - - this.currentCatalog = catalog; - this.pedantic = this.connection.getPedantic(); - this.continueBatchOnError = this.connection.getContinueBatchOnError(); - - if (!this.connection.getDontTrackOpenResources()) { - this.connection.registerStatement(this); - } - - // - // Adjust, if we know it - // - - if (this.connection != null) { - this.maxFieldSize = this.connection.getMaxAllowedPacket(); - - int defaultFetchSize = this.connection.getDefaultFetchSize(); - - if (defaultFetchSize != 0) { - setFetchSize(defaultFetchSize); - } - } - - if (this.connection.getUseUnicode()) { - this.charEncoding = this.connection.getEncoding(); - - this.charConverter = this.connection - .getCharsetConverter(this.charEncoding); - } - - boolean profiling = this.connection.getProfileSql() - || this.connection.getUseUsageAdvisor(); - - if (this.connection.getAutoGenerateTestcaseScript() || profiling) { - this.statementId = statementCounter++; - } - - if (profiling) { - this.pointOfOrigin = new Throwable(); - this.profileSQL = this.connection.getProfileSql(); - this.useUsageAdvisor = this.connection.getUseUsageAdvisor(); - this.eventSink = ProfileEventSink.getInstance(this.connection); - } - - int maxRowsConn = this.connection.getMaxRows(); - - if (maxRowsConn != -1) { - setMaxRows(maxRowsConn); - } - } - - /** - * DOCUMENT ME! - * - * @param sql - * DOCUMENT ME! - * - * @throws SQLException - * DOCUMENT ME! - */ - public synchronized void addBatch(String sql) throws SQLException { - if (this.batchedArgs == null) { - this.batchedArgs = new ArrayList(); - } - - if (sql != null) { - this.batchedArgs.add(sql); - } - } - - /** - * Cancels this Statement object if both the DBMS and driver support - * aborting an SQL statement. This method can be used by one thread to - * cancel a statement that is being executed by another thread. - */ - public void cancel() throws SQLException { - if (!this.isClosed && - this.connection != null && - this.connection.versionMeetsMinimum(5, 0, 0)) { - Connection cancelConn = null; - java.sql.Statement cancelStmt = null; - - try { - synchronized (this.cancelTimeoutMutex) { - cancelConn = this.connection.duplicate(); - cancelStmt = cancelConn.createStatement(); - cancelStmt.execute("KILL QUERY " - + this.connection.getIO().getThreadId()); - this.wasCancelled = true; - } - } 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 - - throw SQLError.createSQLException(Messages - .getString("Statement.49"), //$NON-NLS-1$ - SQLError.SQL_STATE_CONNECTION_NOT_OPEN); //$NON-NLS-1$ - } finally { - if (cancelStmt != null) { - cancelStmt.close(); - } - - if (cancelConn != null) { - cancelConn.close(); - } - } - - } - } - - // --------------------------JDBC 2.0----------------------------- - - /** - * Checks if closed() has been called, and throws an exception if so - * - * @throws SQLException - * if this statement has been closed - */ - protected void checkClosed() throws SQLException { - if (this.isClosed) { - throw SQLError.createSQLException(Messages - .getString("Statement.49"), //$NON-NLS-1$ - SQLError.SQL_STATE_CONNECTION_NOT_OPEN); //$NON-NLS-1$ - } - } - - /** - * Checks if the given SQL query with the given first non-ws char is a DML - * statement. Throws an exception if it is. - * - * @param sql - * the SQL to check - * @param firstStatementChar - * the UC first non-ws char of the statement - * - * @throws SQLException - * if the statement contains DML - */ - protected void checkForDml(String sql, char firstStatementChar) - throws SQLException { - if ((firstStatementChar == 'I') || (firstStatementChar == 'U') - || (firstStatementChar == 'D') || (firstStatementChar == 'A') - || (firstStatementChar == 'C')) { - String noCommentSql = StringUtils.stripComments(sql, - "'\"", "'\"", true, false, true, true); - - if (StringUtils.startsWithIgnoreCaseAndWs(noCommentSql, "INSERT") //$NON-NLS-1$ - || StringUtils.startsWithIgnoreCaseAndWs(noCommentSql, "UPDATE") //$NON-NLS-1$ - || StringUtils.startsWithIgnoreCaseAndWs(noCommentSql, "DELETE") //$NON-NLS-1$ - || StringUtils.startsWithIgnoreCaseAndWs(noCommentSql, "DROP") //$NON-NLS-1$ - || StringUtils.startsWithIgnoreCaseAndWs(noCommentSql, "CREATE") //$NON-NLS-1$ - || StringUtils.startsWithIgnoreCaseAndWs(noCommentSql, "ALTER")) { //$NON-NLS-1$ - throw SQLError.createSQLException(Messages - .getString("Statement.57"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } - } - } - - /** - * Method checkNullOrEmptyQuery. - * - * @param sql - * the SQL to check - * - * @throws SQLException - * if query is null or empty. - */ - protected void checkNullOrEmptyQuery(String sql) throws SQLException { - if (sql == null) { - throw SQLError.createSQLException(Messages - .getString("Statement.59"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$ - } - - if (sql.length() == 0) { - throw SQLError.createSQLException(Messages - .getString("Statement.61"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - /** - * JDBC 2.0 Make the set of commands in the current batch empty. This method - * is optional. - * - * @exception SQLException - * if a database-access error occurs, or the driver does not - * support batch statements - */ - public synchronized void clearBatch() throws SQLException { - if (this.batchedArgs != null) { - this.batchedArgs.clear(); - } - } - - /** - * After this call, getWarnings returns null until a new warning is reported - * for this Statement. - * - * @exception SQLException - * if a database access error occurs (why?) - */ - public void clearWarnings() throws SQLException { - this.warningChain = null; - } - - /** - * In many cases, it is desirable to immediately release a Statement's - * database and JDBC resources instead of waiting for this to happen when it - * is automatically closed. The close method provides this immediate - * release. - * - *

- * Note: A Statement is automatically closed when it is garbage - * collected. When a Statement is closed, its current ResultSet, if one - * exists, is also closed. - *

- * - * @exception SQLException - * if a database access error occurs - */ - public void close() throws SQLException { - realClose(true, true); - } - - /** - * Close any open result sets that have been 'held open' - */ - protected void closeAllOpenResults() { - if (this.openResults != null) { - for (Iterator iter = this.openResults.iterator(); iter.hasNext();) { - ResultSet element = (ResultSet) iter.next(); - - try { - element.realClose(false); - } catch (SQLException sqlEx) { - AssertionFailedException.shouldNotHappen(sqlEx); - } - } - - this.openResults.clear(); - } - } - - /** - * @param sql - * @return - */ - private ResultSet createResultSetUsingServerFetch(String sql) - throws SQLException { - java.sql.PreparedStatement pStmt = this.connection.prepareStatement( - sql, this.resultSetType, this.resultSetConcurrency); - - pStmt.setFetchSize(this.fetchSize); - - if (this.maxRows > -1) { - pStmt.setMaxRows(this.maxRows); - } - - pStmt.execute(); - - // - // Need to be able to get resultset irrespective if we issued DML or - // not to make this work. - // - ResultSet rs = ((com.mysql.jdbc.Statement) pStmt) - .getResultSetInternal(); - - rs - .setStatementUsedForFetchingRows((com.mysql.jdbc.PreparedStatement) pStmt); - - this.results = rs; - - return rs; - } - - /** - * We only stream result sets when they are forward-only, read-only, and the - * fetch size has been set to Integer.MIN_VALUE - * - * @return true if this result set should be streamed row at-a-time, rather - * 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)); - } - - /** * Workaround for containers that 'check' for sane values of - * Statement.setFetchSize(). - * + * Statement.setFetchSize() so that applications can use + * the Java variant of libmysql's mysql_use_result() behavior. + * * @throws SQLException */ - public void enableStreamingResults() throws SQLException { - setFetchSize(Integer.MIN_VALUE); - setResultSetType(ResultSet.TYPE_FORWARD_ONLY); - } + public abstract void enableStreamingResults() throws SQLException; /** - * Execute a SQL statement that may return multiple results. We don't have - * to worry about this since we do not support multiple ResultSets. You can - * use getResultSet or getUpdateCount to retrieve the result. - * - * @param sql - * any SQL statement - * - * @return true if the next result is a ResulSet, false if it is an update - * count or there are no more results - * - * @exception SQLException - * if a database access error occurs - */ - public boolean execute(String sql) throws SQLException { - checkClosed(); - - Connection locallyScopedConn = this.connection; - - synchronized (locallyScopedConn.getMutex()) { - synchronized (this.cancelTimeoutMutex) { - this.wasCancelled = false; - } - - checkNullOrEmptyQuery(sql); - - checkClosed(); - - char firstNonWsChar = StringUtils.firstNonWsCharUc(sql); - - boolean isSelect = true; - - if (firstNonWsChar != 'S') { - isSelect = false; - - if (locallyScopedConn.isReadOnly()) { - throw SQLError.createSQLException(Messages - .getString("Statement.27") //$NON-NLS-1$ - + Messages.getString("Statement.28"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } - } - - if (this.doEscapeProcessing) { - Object escapedSqlResult = EscapeProcessor.escapeSQL(sql, - locallyScopedConn.serverSupportsConvertFn(), locallyScopedConn); - - if (escapedSqlResult instanceof String) { - sql = (String) escapedSqlResult; - } else { - sql = ((EscapeProcessorResult) escapedSqlResult).escapedSql; - } - } - - if (this.results != null) { - if (!locallyScopedConn.getHoldResultsOpenOverStatementClose()) { - this.results.realClose(false); - } - } - - if (firstNonWsChar == '/') { - if (sql.startsWith(PING_MARKER)) { - doPingInstead(); - - return true; - } - } - - CachedResultSetMetaData cachedMetaData = null; - - ResultSet rs = null; - - // If there isn't a limit clause in the SQL - // then limit the number of rows to return in - // an efficient manner. Only do this if - // setMaxRows() hasn't been used on any Statements - // generated from the current Connection (saves - // a query, and network traffic). - - this.batchedGeneratedKeys = null; - - if (useServerFetch()) { - rs = createResultSetUsingServerFetch(sql); - } else { - CancelTask timeoutTask = null; - - String oldCatalog = null; - - try { - if (locallyScopedConn.getEnableQueryTimeouts() && - this.timeoutInMillis != 0 - && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) { - timeoutTask = new CancelTask(); - Connection.getCancelTimer().schedule(timeoutTask, - this.timeoutInMillis); - } - - - - if (!locallyScopedConn.getCatalog().equals( - this.currentCatalog)) { - oldCatalog = locallyScopedConn.getCatalog(); - locallyScopedConn.setCatalog(this.currentCatalog); - } - - // - // Check if we have cached metadata for this query... - // - if (locallyScopedConn.getCacheResultSetMetadata()) { - cachedMetaData = locallyScopedConn.getCachedMetaData(sql); - } - - // - // Only apply max_rows to selects - // - if (locallyScopedConn.useMaxRows()) { - int rowLimit = -1; - - if (isSelect) { - if (StringUtils.indexOfIgnoreCase(sql, "LIMIT") != -1) { //$NON-NLS-1$ - rowLimit = this.maxRows; - } else { - if (this.maxRows <= 0) { - locallyScopedConn - .execSQL( - this, - "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, //$NON-NLS-1$ - null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, - false, - this.currentCatalog, true); //$NON-NLS-1$ - } else { - locallyScopedConn - .execSQL( - this, - "SET OPTION SQL_SELECT_LIMIT=" + this.maxRows, //$NON-NLS-1$ - -1, - null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, - false, - this.currentCatalog, true); //$NON-NLS-1$ - } - } - } else { - locallyScopedConn - .execSQL( - this, - "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, //$NON-NLS-1$ - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, - false, this.currentCatalog, - true); //$NON-NLS-1$ - } - - // Finally, execute the query - rs = locallyScopedConn.execSQL(this, sql, rowLimit, null, - this.resultSetType, this.resultSetConcurrency, - createStreamingResultSet(), - this.currentCatalog, (cachedMetaData == null)); - } else { - rs = locallyScopedConn.execSQL(this, sql, -1, null, - this.resultSetType, this.resultSetConcurrency, - createStreamingResultSet(), - this.currentCatalog, (cachedMetaData == null)); - } - - if (timeoutTask != null) { - if (timeoutTask.caughtWhileCancelling != null) { - throw timeoutTask.caughtWhileCancelling; - } - - timeoutTask.cancel(); - timeoutTask = null; - } - - synchronized (this.cancelTimeoutMutex) { - if (this.wasCancelled) { - this.wasCancelled = false; - throw new MySQLTimeoutException(); - } - } - } finally { - if (timeoutTask != null) { - timeoutTask.cancel(); - } - - if (oldCatalog != null) { - locallyScopedConn.setCatalog(oldCatalog); - } - } - } - - this.lastInsertId = rs.getUpdateID(); - - if (rs != null) { - this.results = rs; - - rs.setFirstCharOfQuery(firstNonWsChar); - - if (rs.reallyResult()) { - if (cachedMetaData != null) { - locallyScopedConn.initializeResultsMetadataFromCache(sql, cachedMetaData, - this.results); - } else { - if (this.connection.getCacheResultSetMetadata()) { - locallyScopedConn.initializeResultsMetadataFromCache(sql, - null /* will be created */, this.results); - } - } - } - } - - return ((rs != null) && rs.reallyResult()); - } - } - - /** - * @see Statement#execute(String, int) - */ - public boolean execute(String sql, int returnGeneratedKeys) - throws SQLException { - - - if (returnGeneratedKeys == java.sql.Statement.RETURN_GENERATED_KEYS) { - checkClosed(); - - Connection locallyScopedConn = this.connection; - - synchronized (locallyScopedConn.getMutex()) { - // If this is a 'REPLACE' query, we need to be able to parse - // the 'info' message returned from the server to determine - // the actual number of keys generated. - boolean readInfoMsgState = this.connection - .isReadInfoMsgEnabled(); - locallyScopedConn.setReadInfoMsgEnabled(true); - - try { - return execute(sql); - } finally { - locallyScopedConn.setReadInfoMsgEnabled(readInfoMsgState); - } - } - } - - return execute(sql); - } - - /** - * @see Statement#execute(String, int[]) - */ - public boolean execute(String sql, int[] generatedKeyIndices) - throws SQLException { - if ((generatedKeyIndices != null) && (generatedKeyIndices.length > 0)) { - checkClosed(); - - Connection locallyScopedConn = this.connection; - - synchronized (locallyScopedConn.getMutex()) { - // If this is a 'REPLACE' query, we need to be able to parse - // the 'info' message returned from the server to determine - // the actual number of keys generated. - boolean readInfoMsgState = locallyScopedConn - .isReadInfoMsgEnabled(); - locallyScopedConn.setReadInfoMsgEnabled(true); - - try { - return execute(sql); - } finally { - locallyScopedConn.setReadInfoMsgEnabled(readInfoMsgState); - } - } - } - - return execute(sql); - } - - /** - * @see Statement#execute(String, String[]) - */ - public boolean execute(String sql, String[] generatedKeyNames) - throws SQLException { - if ((generatedKeyNames != null) && (generatedKeyNames.length > 0)) { - checkClosed(); - - Connection locallyScopedConn = this.connection; - - synchronized (locallyScopedConn.getMutex()) { - // If this is a 'REPLACE' query, we need to be able to parse - // the 'info' message returned from the server to determine - // the actual number of keys generated. - boolean readInfoMsgState = this.connection - .isReadInfoMsgEnabled(); - locallyScopedConn.setReadInfoMsgEnabled(true); - - try { - return execute(sql); - } finally { - locallyScopedConn.setReadInfoMsgEnabled(readInfoMsgState); - } - } - } - - return execute(sql); - } - - /** - * JDBC 2.0 Submit a batch of commands to the database for execution. This - * method is optional. - * - * @return an array of update counts containing one element for each command - * in the batch. The array is ordered according to the order in - * which commands were inserted into the batch - * - * @exception SQLException - * if a database-access error occurs, or the driver does not - * support batch statements - * @throws java.sql.BatchUpdateException - * DOCUMENT ME! - */ - public synchronized int[] executeBatch() throws SQLException { - checkClosed(); - - Connection locallyScopedConn = this.connection; - - if (locallyScopedConn.isReadOnly()) { - throw SQLError.createSQLException(Messages - .getString("Statement.34") //$NON-NLS-1$ - + Messages.getString("Statement.35"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } - - if (this.results != null) { - if (!locallyScopedConn.getHoldResultsOpenOverStatementClose()) { - this.results.realClose(false); - } - } - - synchronized (locallyScopedConn.getMutex()) { - if (this.batchedArgs == null || this.batchedArgs.size() == 0) { - return new int[0]; - } - - try { - this.retrieveGeneratedKeys = true; - - int[] updateCounts = null; - - if (this.batchedArgs != null) { - int nbrCommands = this.batchedArgs.size(); - - this.batchedGeneratedKeys = new ArrayList(this.batchedArgs.size()); - - boolean multiQueriesEnabled = locallyScopedConn.getAllowMultiQueries(); - - if (locallyScopedConn.versionMeetsMinimum(4, 1, 1) && - (multiQueriesEnabled || - (locallyScopedConn.getRewriteBatchedStatements() && - nbrCommands > 4))) { - return executeBatchUsingMultiQueries(multiQueriesEnabled, nbrCommands); - } - - updateCounts = new int[nbrCommands]; - - for (int i = 0; i < nbrCommands; i++) { - updateCounts[i] = -3; - } - - SQLException sqlEx = null; - - int commandIndex = 0; - - for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) { - try { - updateCounts[commandIndex] = executeUpdate((String) this.batchedArgs - .get(commandIndex), true); - getBatchedGeneratedKeys(); - } catch (SQLException ex) { - updateCounts[commandIndex] = EXECUTE_FAILED; - - if (this.continueBatchOnError) { - sqlEx = ex; - } else { - int[] newUpdateCounts = new int[commandIndex]; - System.arraycopy(updateCounts, 0, - newUpdateCounts, 0, commandIndex); - - throw new java.sql.BatchUpdateException(ex - .getMessage(), ex.getSQLState(), ex - .getErrorCode(), newUpdateCounts); - } - } - } - - if (sqlEx != null) { - throw new java.sql.BatchUpdateException(sqlEx - .getMessage(), sqlEx.getSQLState(), sqlEx - .getErrorCode(), updateCounts); - } - } - - return (updateCounts != null) ? updateCounts : new int[0]; - } finally { - this.retrieveGeneratedKeys = false; - - clearBatch(); - } - } - } - - /** - * Rewrites batch into a single query to send to the server. This method - * will constrain each batch to be shorter than max_allowed_packet on the - * server. - * - * @return update counts in the same manner as executeBatch() + * Resets this statements fetch size and result set type to the values + * they had before enableStreamingResults() was called. + * * @throws SQLException */ - private int[] executeBatchUsingMultiQueries(boolean multiQueriesEnabled, - int nbrCommands) throws SQLException { + public abstract void disableStreamingResults() throws SQLException; - Connection locallyScopedConn = this.connection; - - if (!multiQueriesEnabled) { - locallyScopedConn.getIO().enableMultiQueries(); - } - - java.sql.Statement batchStmt = null; - - try { - int[] updateCounts = new int[nbrCommands]; - - for (int i = 0; i < nbrCommands; i++) { - updateCounts[i] = -3; - } - - int commandIndex = 0; - - StringBuffer queryBuf = new StringBuffer(); - - - - batchStmt = locallyScopedConn.createStatement(); - - - int counter = 0; - - int numberOfBytesPerChar = 1; - - String connectionEncoding = locallyScopedConn.getEncoding(); - - if (StringUtils.startsWithIgnoreCase(connectionEncoding, "utf")) { - numberOfBytesPerChar = 3; - } else if (CharsetMapping.isMultibyteCharset(connectionEncoding)) { - numberOfBytesPerChar = 2; - } - - int escapeAdjust = 1; - - if (this.doEscapeProcessing) { - escapeAdjust = 2; /* We assume packet _could_ grow by this amount, as we're not - sure how big statement will end up after - escape processing */ - } - - for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) { - String nextQuery = (String) this.batchedArgs.get(commandIndex); - - if (((((queryBuf.length() + nextQuery.length()) - * numberOfBytesPerChar) + 1 /* for semicolon */ - + MysqlIO.HEADER_LENGTH) * escapeAdjust) + 32 > this.connection - .getMaxAllowedPacket()) { - batchStmt.execute(queryBuf.toString()); - - updateCounts[counter++] = batchStmt.getUpdateCount(); - long generatedKeyStart = ((com.mysql.jdbc.Statement)batchStmt).getLastInsertID(); - byte[][] row = new byte[1][]; - row[0] = Long.toString(generatedKeyStart++).getBytes(); - this.batchedGeneratedKeys.add(row); - - while (batchStmt.getMoreResults() - || batchStmt.getUpdateCount() != -1) { - updateCounts[counter++] = batchStmt.getUpdateCount(); - row = new byte[1][]; - row[0] = Long.toString(generatedKeyStart++).getBytes(); - this.batchedGeneratedKeys.add(row); - } - - queryBuf = new StringBuffer(); - } - - queryBuf.append(nextQuery); - queryBuf.append(";"); - } - - if (queryBuf.length() > 0) { - batchStmt.execute(queryBuf.toString()); - - long generatedKeyStart = ((com.mysql.jdbc.Statement)batchStmt).getLastInsertID(); - byte[][] row = new byte[1][]; - row[0] = Long.toString(generatedKeyStart++).getBytes(); - this.batchedGeneratedKeys.add(row); - - updateCounts[counter++] = batchStmt.getUpdateCount(); - - while (batchStmt.getMoreResults() - || batchStmt.getUpdateCount() != -1) { - updateCounts[counter++] = batchStmt.getUpdateCount(); - row = new byte[1][]; - row[0] = Long.toString(generatedKeyStart++).getBytes(); - this.batchedGeneratedKeys.add(row); - } - } - - return (updateCounts != null) ? updateCounts : new int[0]; - } finally { - try { - if (batchStmt != null) { - batchStmt.close(); - } - } finally { - if (!multiQueriesEnabled) { - locallyScopedConn.getIO().disableMultiQueries(); - } - } - } - } - /** - * Execute a SQL statement that retruns a single ResultSet - * - * @param sql - * typically a static SQL SELECT statement - * - * @return a ResulSet that contains the data produced by the query - * - * @exception SQLException - * if a database access error occurs + * Sets an InputStream instance that will be used to send data + * to the MySQL server for a "LOAD DATA LOCAL INFILE" statement + * rather than a FileInputStream or URLInputStream that represents + * the path given as an argument to the statement. + * + * This stream will be read to completion upon execution of a + * "LOAD DATA LOCAL INFILE" statement, and will automatically + * be closed by the driver, so it needs to be reset + * before each call to execute*() that would cause the MySQL + * server to request data to fulfill the request for + * "LOAD DATA LOCAL INFILE". + * + * If this value is set to NULL, the driver will revert to using + * a FileInputStream or URLInputStream as required. */ - public java.sql.ResultSet executeQuery(String sql) - throws SQLException { - checkClosed(); - - Connection locallyScopedConn = this.connection; - - synchronized (locallyScopedConn.getMutex()) { - synchronized (this.cancelTimeoutMutex) { - this.wasCancelled = false; - } - - checkNullOrEmptyQuery(sql); + public abstract void setLocalInfileInputStream(InputStream stream); - if (this.doEscapeProcessing) { - Object escapedSqlResult = EscapeProcessor.escapeSQL(sql, - locallyScopedConn.serverSupportsConvertFn(), this.connection); - - if (escapedSqlResult instanceof String) { - sql = (String) escapedSqlResult; - } else { - sql = ((EscapeProcessorResult) escapedSqlResult).escapedSql; - } - } - - char firstStatementChar = StringUtils.firstNonWsCharUc(sql, - findStartOfStatement(sql)); - - if (sql.charAt(0) == '/') { - if (sql.startsWith(PING_MARKER)) { - doPingInstead(); - - return this.results; - } - } - - checkForDml(sql, firstStatementChar); - - if (this.results != null) { - if (!locallyScopedConn.getHoldResultsOpenOverStatementClose()) { - this.results.realClose(false); - } - } - - CachedResultSetMetaData cachedMetaData = null; - - // If there isn't a limit clause in the SQL - // then limit the number of rows to return in - // an efficient manner. Only do this if - // setMaxRows() hasn't been used on any Statements - // generated from the current Connection (saves - // a query, and network traffic). - - if (useServerFetch()) { - this.results = createResultSetUsingServerFetch(sql); - - return this.results; - } - - CancelTask timeoutTask = null; - - String oldCatalog = null; - - try { - if (locallyScopedConn.getEnableQueryTimeouts() && - this.timeoutInMillis != 0 - && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) { - timeoutTask = new CancelTask(); - Connection.getCancelTimer().schedule(timeoutTask, - this.timeoutInMillis); - } - - if (!locallyScopedConn.getCatalog().equals(this.currentCatalog)) { - oldCatalog = locallyScopedConn.getCatalog(); - locallyScopedConn.setCatalog(this.currentCatalog); - } - - // - // Check if we have cached metadata for this query... - // - if (locallyScopedConn.getCacheResultSetMetadata()) { - cachedMetaData = locallyScopedConn.getCachedMetaData(sql); - } - - if (locallyScopedConn.useMaxRows()) { - // We need to execute this all together - // So synchronize on the Connection's mutex (because - // even queries going through there synchronize - // on the connection - if (StringUtils.indexOfIgnoreCase(sql, "LIMIT") != -1) { //$NON-NLS-1$ - this.results = locallyScopedConn.execSQL(this, sql, - this.maxRows, null, this.resultSetType, - this.resultSetConcurrency, - createStreamingResultSet(), - this.currentCatalog, (cachedMetaData == null)); - } else { - if (this.maxRows <= 0) { - locallyScopedConn - .execSQL( - this, - "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, //$NON-NLS-1$ - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, - false, this.currentCatalog, - true); //$NON-NLS-1$ - } else { - locallyScopedConn - .execSQL( - this, - "SET OPTION SQL_SELECT_LIMIT=" + this.maxRows, -1, //$NON-NLS-1$ - null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, - false, this.currentCatalog, - true); //$NON-NLS-1$ - } - - this.results = locallyScopedConn.execSQL(this, sql, -1, - null, this.resultSetType, - this.resultSetConcurrency, - createStreamingResultSet(), - this.currentCatalog, (cachedMetaData == null)); - - if (oldCatalog != null) { - locallyScopedConn.setCatalog(oldCatalog); - } - } - } else { - this.results = locallyScopedConn.execSQL(this, sql, -1, null, - this.resultSetType, this.resultSetConcurrency, - createStreamingResultSet(), - this.currentCatalog, (cachedMetaData == null)); - } - - if (timeoutTask != null) { - if (timeoutTask.caughtWhileCancelling != null) { - throw timeoutTask.caughtWhileCancelling; - } - - timeoutTask.cancel(); - timeoutTask = null; - } - - synchronized (this.cancelTimeoutMutex) { - if (this.wasCancelled) { - this.wasCancelled = false; - throw new MySQLTimeoutException(); - } - } - } finally { - if (timeoutTask != null) { - timeoutTask.cancel(); - } - - if (oldCatalog != null) { - locallyScopedConn.setCatalog(oldCatalog); - } - } - - this.lastInsertId = this.results.getUpdateID(); - - if (cachedMetaData != null) { - locallyScopedConn.initializeResultsMetadataFromCache(sql, cachedMetaData, - this.results); - } else { - if (this.connection.getCacheResultSetMetadata()) { - locallyScopedConn.initializeResultsMetadataFromCache(sql, - null /* will be created */, this.results); - } - } - - return this.results; - } - } - - protected void doPingInstead() throws SQLException { - if (this.pingTarget != null) { - this.pingTarget.doPing(); - } else { - this.connection.ping(); - } - - ResultSet fakeSelectOneResultSet = generatePingResultSet(); - this.results = fakeSelectOneResultSet; - } - - protected ResultSet generatePingResultSet() throws SQLException { - Field[] fields = { new Field(null, "1", Types.BIGINT, 1) }; - ArrayList rows = new ArrayList(); - byte[] colVal = new byte[] { (byte) '1' }; - - rows.add(new byte[][] { colVal }); - - return (ResultSet) DatabaseMetaData.buildResultSet(fields, rows, - this.connection); - } - /** - * Execute a SQL INSERT, UPDATE or DELETE statement. In addition SQL - * statements that return nothing such as SQL DDL statements can be executed - * Any IDs generated for AUTO_INCREMENT fields can be retrieved by casting - * this Statement to org.gjt.mm.mysql.Statement and calling the - * getLastInsertID() method. - * - * @param sql - * a SQL statement - * - * @return either a row count, or 0 for SQL commands - * - * @exception SQLException - * if a database access error occurs + * Returns the InputStream instance that will be used to send + * data in response to a "LOAD DATA LOCAL INFILE" statement. + * + * This method returns NULL if no such stream has been set + * via setLocalInfileInputStream(). */ - public int executeUpdate(String sql) throws SQLException { - return executeUpdate(sql, false); - } + public abstract InputStream getLocalInfileInputStream(); - protected int executeUpdate(String sql, boolean isBatch) - throws SQLException { - checkClosed(); - - Connection locallyScopedConn = this.connection; - - char firstStatementChar = StringUtils.firstNonWsCharUc(sql, - findStartOfStatement(sql)); + public void setPingTarget(PingTarget pingTarget); - ResultSet rs = null; - - synchronized (locallyScopedConn.getMutex()) { - synchronized (this.cancelTimeoutMutex) { - this.wasCancelled = false; - } + public ExceptionInterceptor getExceptionInterceptor(); - checkNullOrEmptyQuery(sql); - - if (this.doEscapeProcessing) { - Object escapedSqlResult = EscapeProcessor.escapeSQL(sql, - this.connection.serverSupportsConvertFn(), this.connection); - - if (escapedSqlResult instanceof String) { - sql = (String) escapedSqlResult; - } else { - sql = ((EscapeProcessorResult) escapedSqlResult).escapedSql; - } - } - - if (locallyScopedConn.isReadOnly()) { - throw SQLError.createSQLException(Messages - .getString("Statement.42") //$NON-NLS-1$ - + Messages.getString("Statement.43"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } - - if (StringUtils.startsWithIgnoreCaseAndWs(sql, "select")) { //$NON-NLS-1$ - throw SQLError.createSQLException(Messages - .getString("Statement.46"), //$NON-NLS-1$ - "01S03"); //$NON-NLS-1$ - } - - if (this.results != null) { - if (!locallyScopedConn.getHoldResultsOpenOverStatementClose()) { - this.results.realClose(false); - } - } - - // The checking and changing of catalogs - // must happen in sequence, so synchronize - // on the same mutex that _conn is using - - CancelTask timeoutTask = null; - - String oldCatalog = null; - - try { - if (locallyScopedConn.getEnableQueryTimeouts() && - this.timeoutInMillis != 0 - && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) { - timeoutTask = new CancelTask(); - Connection.getCancelTimer().schedule(timeoutTask, - this.timeoutInMillis); - } - - if (!locallyScopedConn.getCatalog().equals(this.currentCatalog)) { - oldCatalog = locallyScopedConn.getCatalog(); - locallyScopedConn.setCatalog(this.currentCatalog); - } - - // - // Only apply max_rows to selects - // - if (locallyScopedConn.useMaxRows()) { - locallyScopedConn.execSQL( - this, - "SET OPTION SQL_SELECT_LIMIT=DEFAULT", //$NON-NLS-1$ - -1, null, java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.currentCatalog, true); - } - - rs = locallyScopedConn.execSQL(this, sql, -1, null, - java.sql.ResultSet.TYPE_FORWARD_ONLY, - java.sql.ResultSet.CONCUR_READ_ONLY, false, - this.currentCatalog, - true /* force read of field info on DML */, - isBatch); - - if (timeoutTask != null) { - if (timeoutTask.caughtWhileCancelling != null) { - throw timeoutTask.caughtWhileCancelling; - } - - timeoutTask.cancel(); - timeoutTask = null; - } - - synchronized (this.cancelTimeoutMutex) { - if (this.wasCancelled) { - this.wasCancelled = false; - throw new MySQLTimeoutException(); - } - } - } finally { - if (timeoutTask != null) { - timeoutTask.cancel(); - } - - if (oldCatalog != null) { - locallyScopedConn.setCatalog(oldCatalog); - } - } - } - - this.results = rs; - - rs.setFirstCharOfQuery(firstStatementChar); - - this.updateCount = rs.getUpdateCount(); - - int truncatedUpdateCount = 0; - - if (this.updateCount > Integer.MAX_VALUE) { - truncatedUpdateCount = Integer.MAX_VALUE; - } else { - truncatedUpdateCount = (int) this.updateCount; - } - - this.lastInsertId = rs.getUpdateID(); - - return truncatedUpdateCount; - } - - /** - * @see Statement#executeUpdate(String, int) + /** + * Callback for result set instances to remove them from the Set that + * tracks them per-statement */ - public int executeUpdate(String sql, int returnGeneratedKeys) - throws SQLException { - if (returnGeneratedKeys == java.sql.Statement.RETURN_GENERATED_KEYS) { - checkClosed(); - - Connection locallyScopedConn = this.connection; - - synchronized (locallyScopedConn.getMutex()) { - // If this is a 'REPLACE' query, we need to be able to parse - // the 'info' message returned from the server to determine - // the actual number of keys generated. - boolean readInfoMsgState = locallyScopedConn - .isReadInfoMsgEnabled(); - locallyScopedConn.setReadInfoMsgEnabled(true); - - try { - return executeUpdate(sql); - } finally { - locallyScopedConn.setReadInfoMsgEnabled(readInfoMsgState); - } - } - } - - return executeUpdate(sql); - } - - /** - * @see Statement#executeUpdate(String, int[]) - */ - public int executeUpdate(String sql, int[] generatedKeyIndices) - throws SQLException { - if ((generatedKeyIndices != null) && (generatedKeyIndices.length > 0)) { - checkClosed(); - - Connection locallyScopedConn = this.connection; - - synchronized (locallyScopedConn.getMutex()) { - // If this is a 'REPLACE' query, we need to be able to parse - // the 'info' message returned from the server to determine - // the actual number of keys generated. - boolean readInfoMsgState = locallyScopedConn - .isReadInfoMsgEnabled(); - locallyScopedConn.setReadInfoMsgEnabled(true); - - try { - return executeUpdate(sql); - } finally { - locallyScopedConn.setReadInfoMsgEnabled(readInfoMsgState); - } - } - } - - return executeUpdate(sql); - } - - /** - * @see Statement#executeUpdate(String, String[]) - */ - public int executeUpdate(String sql, String[] generatedKeyNames) - throws SQLException { - if ((generatedKeyNames != null) && (generatedKeyNames.length > 0)) { - checkClosed(); - - Connection locallyScopedConn = this.connection; - - synchronized (locallyScopedConn.getMutex()) { - // If this is a 'REPLACE' query, we need to be able to parse - // the 'info' message returned from the server to determine - // the actual number of keys generated. - boolean readInfoMsgState = this.connection - .isReadInfoMsgEnabled(); - locallyScopedConn.setReadInfoMsgEnabled(true); - - try { - return executeUpdate(sql); - } finally { - locallyScopedConn.setReadInfoMsgEnabled(readInfoMsgState); - } - } - } - - return executeUpdate(sql); - } - - - - /** - * Optimization to only use one calendar per-session, or calculate it for - * each call, depending on user configuration - */ - protected Calendar getCalendarInstanceForSessionOrNew() { - if (this.connection != null) { - return this.connection.getCalendarInstanceForSessionOrNew(); - } else { - // punt, no connection around - return new GregorianCalendar(); - } - } - - /** - * JDBC 2.0 Return the Connection that produced the Statement. - * - * @return the Connection that produced the Statement - * - * @throws SQLException - * if an error occurs - */ - public java.sql.Connection getConnection() throws SQLException { - return this.connection; - } - - /** - * JDBC 2.0 Determine the fetch direction. - * - * @return the default fetch direction - * - * @exception SQLException - * if a database-access error occurs - */ - public int getFetchDirection() throws SQLException { - return java.sql.ResultSet.FETCH_FORWARD; - } - - /** - * JDBC 2.0 Determine the default fetch size. - * - * @return the number of rows to fetch at a time - * - * @throws SQLException - * if an error occurs - */ - public int getFetchSize() throws SQLException { - return this.fetchSize; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - * - * @throws SQLException - * DOCUMENT ME! - */ - public java.sql.ResultSet getGeneratedKeys() - throws SQLException { - if (this.batchedGeneratedKeys == null) { - return getGeneratedKeysInternal(); - } - - Field[] fields = new Field[1]; - fields[0] = new Field("", "GENERATED_KEY", Types.BIGINT, 17); //$NON-NLS-1$ //$NON-NLS-2$ - fields[0].setConnection(this.connection); - - return new com.mysql.jdbc.ResultSet(this.currentCatalog, fields, - new RowDataStatic(this.batchedGeneratedKeys), this.connection, - this); - } + + public abstract void removeOpenResultSet(ResultSetInternalMethods rs); - /* - * Needed because there's no concept of super.super to get to this - * implementation from ServerPreparedStatement when dealing with batched - * updates. - */ - protected java.sql.ResultSet getGeneratedKeysInternal() - throws SQLException { - Field[] fields = new Field[1]; - fields[0] = new Field("", "GENERATED_KEY", Types.BIGINT, 17); //$NON-NLS-1$ //$NON-NLS-2$ - fields[0].setConnection(this.connection); - - ArrayList rowSet = new ArrayList(); - - long beginAt = getLastInsertID(); - int numKeys = getUpdateCount(); - - if (this.results != null) { - String serverInfo = this.results.getServerInfo(); - - // - // Only parse server info messages for 'REPLACE' - // queries - // - if ((numKeys > 0) && (this.results.getFirstCharOfQuery() == 'R') - && (serverInfo != null) && (serverInfo.length() > 0)) { - numKeys = getRecordCountFromInfo(serverInfo); - } - - if ((beginAt > 0) && (numKeys > 0)) { - for (int i = 0; i < numKeys; i++) { - byte[][] row = new byte[1][]; - row[0] = Long.toString(beginAt++).getBytes(); - rowSet.add(row); - } - } - } - - return new com.mysql.jdbc.ResultSet(this.currentCatalog, fields, - new RowDataStatic(rowSet), this.connection, this); - } - /** - * Returns the id used when profiling - * - * @return the id used when profiling. - */ - protected int getId() { - return this.statementId; - } - - /** - * getLastInsertID returns the value of the auto_incremented key after an - * executeQuery() or excute() call. - * - *

- * This gets around the un-threadsafe behavior of "select LAST_INSERT_ID()" - * which is tied to the Connection that created this Statement, and - * therefore could have had many INSERTS performed before one gets a chance - * to call "select LAST_INSERT_ID()". - *

- * - * @return the last update ID. - */ - public long getLastInsertID() { - return this.lastInsertId; - } - - /** - * getLongUpdateCount returns the current result as an update count, if the - * result is a ResultSet or there are no more results, -1 is returned. It - * should only be called once per result. - * - *

- * This method returns longs as MySQL server versions newer than 3.22.4 - * return 64-bit values for update counts - *

- * - * @return the current update count. - */ - public long getLongUpdateCount() { - if (this.results == null) { - return -1; - } - - if (this.results.reallyResult()) { - return -1; - } - - return this.updateCount; - } - - /** - * The maxFieldSize limit (in bytes) is the maximum amount of data returned - * for any column value; it only applies to BINARY, VARBINARY, - * LONGVARBINARY, CHAR, VARCHAR and LONGVARCHAR columns. If the limit is - * exceeded, the excess data is silently discarded. - * - * @return the current max column size limit; zero means unlimited - * - * @exception SQLException - * if a database access error occurs - */ - public int getMaxFieldSize() throws SQLException { - return this.maxFieldSize; - } - - /** - * The maxRows limit is set to limit the number of rows that any ResultSet - * can contain. If the limit is exceeded, the excess rows are silently - * dropped. - * - * @return the current maximum row limit; zero means unlimited - * - * @exception SQLException - * if a database access error occurs - */ - public int getMaxRows() throws SQLException { - if (this.maxRows <= 0) { - return 0; - } - - return this.maxRows; - } - - /** - * getMoreResults moves to a Statement's next result. If it returns true, - * this result is a ResulSet. - * - * @return true if the next ResultSet is valid - * - * @exception SQLException - * if a database access error occurs - */ - public boolean getMoreResults() throws SQLException { - return getMoreResults(CLOSE_CURRENT_RESULT); - } - - /** - * @see Statement#getMoreResults(int) - */ - public boolean getMoreResults(int current) throws SQLException { - - if (this.results == null) { - return false; - } - - ResultSet nextResultSet = this.results.getNextResultSet(); - - switch (current) { - case java.sql.Statement.CLOSE_CURRENT_RESULT: - - if (this.results != null) { - this.results.close(); - this.results.clearNextResult(); - } - - break; - - case java.sql.Statement.CLOSE_ALL_RESULTS: - - if (this.results != null) { - this.results.close(); - this.results.clearNextResult(); - } - - closeAllOpenResults(); - - break; - - case java.sql.Statement.KEEP_CURRENT_RESULT: - if (!this.connection.getDontTrackOpenResources()) { - this.openResults.add(this.results); - } - - this.results.clearNextResult(); // nobody besides us should - // ever need this value... - break; - - default: - throw SQLError.createSQLException(Messages - .getString("Statement.19"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } - - this.results = nextResultSet; - - if (this.results == null) { - this.updateCount = -1; - this.lastInsertId = -1; - } else if (this.results.reallyResult()) { - this.updateCount = -1; - this.lastInsertId = -1; - } else { - this.updateCount = this.results.getUpdateCount(); - this.lastInsertId = this.results.getUpdateID(); - } - - return ((this.results != null) && this.results.reallyResult()) ? true - : false; - } - - /** - * The queryTimeout limit is the number of seconds the driver will wait for - * a Statement to execute. If the limit is exceeded, a SQLException is - * thrown. - * - * @return the current query timeout limit in seconds; 0 = unlimited - * - * @exception SQLException - * if a database access error occurs - */ - public int getQueryTimeout() throws SQLException { - return this.timeoutInMillis / 1000; - } - - /** - * Parses actual record count from 'info' message - * - * @param serverInfo - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - private int getRecordCountFromInfo(String serverInfo) { - StringBuffer recordsBuf = new StringBuffer(); - int recordsCount = 0; - int duplicatesCount = 0; - - char c = (char) 0; - - int length = serverInfo.length(); - int i = 0; - - for (; i < length; i++) { - c = serverInfo.charAt(i); - - if (Character.isDigit(c)) { - break; - } - } - - recordsBuf.append(c); - i++; - - for (; i < length; i++) { - c = serverInfo.charAt(i); - - if (!Character.isDigit(c)) { - break; - } - - recordsBuf.append(c); - } - - recordsCount = Integer.parseInt(recordsBuf.toString()); - - StringBuffer duplicatesBuf = new StringBuffer(); - - for (; i < length; i++) { - c = serverInfo.charAt(i); - - if (Character.isDigit(c)) { - break; - } - } - - duplicatesBuf.append(c); - i++; - - for (; i < length; i++) { - c = serverInfo.charAt(i); - - if (!Character.isDigit(c)) { - break; - } - - duplicatesBuf.append(c); - } - - duplicatesCount = Integer.parseInt(duplicatesBuf.toString()); - - return recordsCount - duplicatesCount; - } - - /** - * getResultSet returns the current result as a ResultSet. It should only be - * called once per result. - * - * @return the current result set; null if there are no more - * - * @exception SQLException - * if a database access error occurs (why?) - */ - public java.sql.ResultSet getResultSet() throws SQLException { - return ((this.results != null) && this.results.reallyResult()) ? (java.sql.ResultSet) this.results - : null; - } - - /** - * JDBC 2.0 Determine the result set concurrency. - * - * @return CONCUR_UPDATABLE or CONCUR_READONLY - * - * @throws SQLException - * if an error occurs - */ - public int getResultSetConcurrency() throws SQLException { - return this.resultSetConcurrency; - } - - /** - * @see Statement#getResultSetHoldability() - */ - public int getResultSetHoldability() throws SQLException { - return java.sql.ResultSet.HOLD_CURSORS_OVER_COMMIT; - } - - protected ResultSet getResultSetInternal() { - return this.results; - } - - /** - * JDBC 2.0 Determine the result set type. - * - * @return the ResultSet type (SCROLL_SENSITIVE or SCROLL_INSENSITIVE) - * - * @throws SQLException - * if an error occurs. - */ - public int getResultSetType() throws SQLException { - return this.resultSetType; - } - - /** - * getUpdateCount returns the current result as an update count, if the - * result is a ResultSet or there are no more results, -1 is returned. It - * should only be called once per result. - * - * @return the current result as an update count. - * - * @exception SQLException - * if a database access error occurs - */ - public int getUpdateCount() throws SQLException { - if (this.results == null) { - return -1; - } - - if (this.results.reallyResult()) { - return -1; - } - - int truncatedUpdateCount = 0; - - if (this.results.getUpdateCount() > Integer.MAX_VALUE) { - truncatedUpdateCount = Integer.MAX_VALUE; - } else { - truncatedUpdateCount = (int) this.results.getUpdateCount(); - } - - return truncatedUpdateCount; - } - - /** - * The first warning reported by calls on this Statement is returned. A - * Statement's execute methods clear its java.sql.SQLWarning chain. - * Subsequent Statement warnings will be chained to this - * java.sql.SQLWarning. - * - *

- * The Warning chain is automatically cleared each time a statement is - * (re)executed. - *

- * - *

- * Note: If you are processing a ResultSet then any warnings - * associated with ResultSet reads will be chained on the ResultSet object. - *

- * - * @return the first java.sql.SQLWarning or null - * - * @exception SQLException - * if a database access error occurs - */ - public java.sql.SQLWarning getWarnings() throws SQLException { - checkClosed(); - - if (this.connection != null && !this.connection.isClosed() - && this.connection.versionMeetsMinimum(4, 1, 0)) { - SQLWarning pendingWarningsFromServer = SQLError - .convertShowWarningsToSQLWarnings(this.connection); - - if (this.warningChain != null) { - this.warningChain.setNextWarning(pendingWarningsFromServer); - } else { - this.warningChain = pendingWarningsFromServer; - } - - return this.warningChain; - } - - return this.warningChain; - } - - - - /** - * Closes this statement, and frees resources. - * - * @param calledExplicitly - * was this called from close()? - * - * @throws SQLException - * if an error occurs - */ - protected void realClose(boolean calledExplicitly, boolean closeOpenResults) - throws SQLException { - if (this.isClosed) { - return; - } - - if (this.useUsageAdvisor) { - if (!calledExplicitly) { - String message = Messages.getString("Statement.63") //$NON-NLS-1$ - + Messages.getString("Statement.64"); //$NON-NLS-1$ - - this.eventSink.consumeEvent(new ProfilerEvent( - ProfilerEvent.TYPE_WARN, - "", //$NON-NLS-1$ - this.currentCatalog, this.connectionId, this.getId(), - -1, System.currentTimeMillis(), 0, - Constants.MILLIS_I18N, null, this.pointOfOrigin, - message)); - } - } - - if (this.results != null) { - if (closeOpenResults) { - closeOpenResults = !this.holdResultsOpenOverClose; - } - - if (closeOpenResults && this.connection != null - && !this.connection.getHoldResultsOpenOverStatementClose()) { - try { - this.results.close(); - } catch (Exception ex) { - ; - } - - this.closeAllOpenResults(); - } - } - - if (this.connection != null) { - if (this.maxRowsChanged) { - this.connection.unsetMaxRows(this); - } - - if (!this.connection.getDontTrackOpenResources()) { - this.connection.unregisterStatement(this); - } - } - - this.isClosed = true; - - this.results = null; - this.connection = null; - this.warningChain = null; - this.openResults = null; - this.batchedGeneratedKeys = null; - this.cancelTimeoutMutex = null; - this.pingTarget = null; - } - - /** - * setCursorName defines the SQL cursor name that will be used by subsequent - * execute methods. This name can then be used in SQL positioned - * update/delete statements to identify the current row in the ResultSet - * generated by this statement. If a database doesn't support positioned - * update/delete, this method is a no-op. - * - *

- * Note: This MySQL driver does not support cursors. - *

- * - * @param name - * the new cursor name - * - * @exception SQLException - * if a database access error occurs - */ - public void setCursorName(String name) throws SQLException { - // No-op - } - - /** - * If escape scanning is on (the default), the driver will do escape - * substitution before sending the SQL to the database. - * - * @param enable - * true to enable; false to disable - * - * @exception SQLException - * if a database access error occurs - */ - public void setEscapeProcessing(boolean enable) - throws SQLException { - this.doEscapeProcessing = enable; - } - - /** - * JDBC 2.0 Give a hint as to the direction in which the rows in a result - * set will be processed. The hint applies only to result sets created using - * this Statement object. The default value is ResultSet.FETCH_FORWARD. - * - * @param direction - * the initial direction for processing rows - * - * @exception SQLException - * if a database-access error occurs or direction is not one - * of ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, or - * ResultSet.FETCH_UNKNOWN - */ - public void setFetchDirection(int direction) throws SQLException { - switch (direction) { - case java.sql.ResultSet.FETCH_FORWARD: - case java.sql.ResultSet.FETCH_REVERSE: - case java.sql.ResultSet.FETCH_UNKNOWN: - break; - - default: - throw SQLError.createSQLException( - Messages.getString("Statement.5"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } - } - - /** - * JDBC 2.0 Give the JDBC driver a hint as to the number of rows that should - * be fetched from the database when more rows are needed. The number of - * rows specified only affects result sets created using this statement. If - * the value specified is zero, then the hint is ignored. The default value - * is zero. - * - * @param rows - * the number of rows to fetch - * - * @exception SQLException - * if a database-access error occurs, or the condition 0 - * <= rows <= this.getMaxRows() is not satisfied. - */ - public void setFetchSize(int rows) throws SQLException { - if (((rows < 0) && (rows != Integer.MIN_VALUE)) - || ((this.maxRows != 0) && (this.maxRows != -1) && (rows > this - .getMaxRows()))) { - throw SQLError.createSQLException( - Messages.getString("Statement.7"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$ - } - - this.fetchSize = rows; - } - - protected void setHoldResultsOpenOverClose(boolean holdResultsOpenOverClose) { - this.holdResultsOpenOverClose = holdResultsOpenOverClose; - } - - /** - * Sets the maxFieldSize - * - * @param max - * the new max column size limit; zero means unlimited - * - * @exception SQLException - * if size exceeds buffer size - */ - public void setMaxFieldSize(int max) throws SQLException { - if (max < 0) { - throw SQLError.createSQLException(Messages - .getString("Statement.11"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } - - int maxBuf = (this.connection != null) ? this.connection - .getMaxAllowedPacket() : MysqlIO.getMaxBuf(); - - if (max > maxBuf) { - throw SQLError.createSQLException(Messages.getString( - "Statement.13", //$NON-NLS-1$ - new Object[] { new Long(maxBuf) }), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } - - this.maxFieldSize = max; - } - - /** - * Set the maximum number of rows - * - * @param max - * the new max rows limit; zero means unlimited - * - * @exception SQLException - * if a database access error occurs - * - * @see getMaxRows - */ - public void setMaxRows(int max) throws SQLException { - if ((max > MysqlDefs.MAX_ROWS) || (max < 0)) { - throw SQLError - .createSQLException( - Messages.getString("Statement.15") + max //$NON-NLS-1$ - + " > " //$NON-NLS-1$ //$NON-NLS-2$ - + MysqlDefs.MAX_ROWS + ".", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$ - } - - if (max == 0) { - max = -1; - } - - this.maxRows = max; - this.maxRowsChanged = true; - - if (this.maxRows == -1) { - this.connection.unsetMaxRows(this); - this.maxRowsChanged = false; - } else { - // Most people don't use setMaxRows() - // so don't penalize them - // with the extra query it takes - // to do it efficiently unless we need - // to. - this.connection.maxRowsChanged(this); - } - } - - /** - * Sets the queryTimeout limit - * - * @param seconds - - * the new query timeout limit in seconds - * - * @exception SQLException - * if a database access error occurs - */ - public void setQueryTimeout(int seconds) throws SQLException { - if (seconds < 0) { - throw SQLError.createSQLException(Messages - .getString("Statement.21"), //$NON-NLS-1$ - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ - } - - this.timeoutInMillis = seconds * 1000; - } - - /** - * Sets the concurrency for result sets generated by this statement - * - * @param concurrencyFlag - * DOCUMENT ME! - */ - void setResultSetConcurrency(int concurrencyFlag) { - this.resultSetConcurrency = concurrencyFlag; - } - - /** - * Sets the result set type for result sets generated by this statement - * - * @param typeFlag - * DOCUMENT ME! - */ - void setResultSetType(int typeFlag) { - this.resultSetType = typeFlag; - } - - protected void getBatchedGeneratedKeys(java.sql.Statement batchedStatement) throws SQLException { - if (this.retrieveGeneratedKeys) { - java.sql.ResultSet rs = null; - - try { - rs = batchedStatement.getGeneratedKeys(); - - while (rs.next()) { - this.batchedGeneratedKeys - .add(new byte[][] { rs.getBytes(1) }); - } - } finally { - if (rs != null) { - rs.close(); - } - } - } - } - - protected void getBatchedGeneratedKeys() throws SQLException { - if (this.retrieveGeneratedKeys) { - java.sql.ResultSet rs = null; - - try { - rs = getGeneratedKeysInternal(); - - while (rs.next()) { - this.batchedGeneratedKeys - .add(new byte[][] { rs.getBytes(1) }); - } - } finally { - if (rs != null) { - rs.close(); - } - } - } - } - - /** + * Returns the number of open result sets for this statement. * @return */ - private boolean useServerFetch() throws SQLException { + public abstract int getOpenResultSetCount(); - return this.connection.isCursorFetchEnabled() && this.fetchSize > 0 - && this.resultSetConcurrency == ResultSet.CONCUR_READ_ONLY - && this.resultSetType == ResultSet.TYPE_FORWARD_ONLY; - } - - protected int findStartOfStatement(String sql) { - int statementStartPos = 0; - - if (StringUtils.startsWithIgnoreCaseAndWs(sql, "/*")) { - statementStartPos = sql.indexOf("*/"); - - if (statementStartPos == -1) { - statementStartPos = 0; - } else { - statementStartPos += 2; - } - } else if (StringUtils.startsWithIgnoreCaseAndWs(sql, "--") - || StringUtils.startsWithIgnoreCaseAndWs(sql, "#")) { - statementStartPos = sql.indexOf('\n'); - - if (statementStartPos == -1) { - statementStartPos = sql.indexOf('\r'); - - if (statementStartPos == -1) { - statementStartPos = 0; - } - } - } - - return statementStartPos; - } - - protected synchronized void setPingTarget(PingTarget pingTarget) { - this.pingTarget = pingTarget; - } + public void setHoldResultsOpenOverClose(boolean holdResultsOpenOverClose); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/StatementImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/StatementInterceptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/StatementInterceptorV2.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/StreamingNotifiable.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/StringUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/StringUtils.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/StringUtils.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/StringUtils.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.ByteArrayOutputStream; @@ -31,12 +30,16 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; - +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; import java.sql.SQLException; - import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import java.util.concurrent.ConcurrentHashMap; /** * Various utility methods for converting to/from byte arrays in the platform @@ -60,6 +63,34 @@ static final int WILD_COMPARE_NO_MATCH = -1; + private static final ConcurrentHashMap charsetsByAlias = + new ConcurrentHashMap(); + + private static final String platformEncoding = System.getProperty("file.encoding"); + + private static final String VALID_ID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ0123456789$_#@"; + + static Charset findCharset(String alias) throws UnsupportedEncodingException { + try { + Charset cs = charsetsByAlias.get(alias); + + if (cs == null) { + cs = Charset.forName(alias); + charsetsByAlias.putIfAbsent(alias, cs); + } + + return cs; + + // We re-throw these runtimes for compatibility with java.io + } catch (UnsupportedCharsetException uce) { + throw new UnsupportedEncodingException(alias); + } catch (IllegalCharsetNameException icne) { + throw new UnsupportedEncodingException(alias); + } catch (IllegalArgumentException iae) { + throw new UnsupportedEncodingException(alias); + } + } + static { for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) { allBytes[i - Byte.MIN_VALUE] = (byte) i; @@ -99,7 +130,7 @@ if (toPlainStringMethod != null) { try { - return (String) toPlainStringMethod.invoke(decimal, null); + return (String) toPlainStringMethod.invoke(decimal, (Object[])null); } catch (InvocationTargetException invokeEx) { // that's okay, we fall-through to decimal.toString() } catch (IllegalAccessException accessEx) { @@ -120,8 +151,8 @@ * * @return ... */ - public static final String dumpAsHex(byte[] byteBuffer, int length) { - StringBuffer outputBuf = new StringBuffer(length * 4); + public static String dumpAsHex(byte[] byteBuffer, int length) { + StringBuilder outputBuilder = new StringBuilder(length * 4); int p = 0; int rows = length / 8; @@ -133,26 +164,28 @@ String hexVal = Integer.toHexString(byteBuffer[ptemp] & 0xff); if (hexVal.length() == 1) { - hexVal = "0" + hexVal; //$NON-NLS-1$ + hexVal = "0" + hexVal; } - outputBuf.append(hexVal + " "); //$NON-NLS-1$ + outputBuilder.append(hexVal + " "); ptemp++; } - outputBuf.append(" "); //$NON-NLS-1$ + outputBuilder.append(" "); for (int j = 0; j < 8; j++) { - if ((byteBuffer[p] > 32) && (byteBuffer[p] < 127)) { - outputBuf.append((char) byteBuffer[p] + " "); //$NON-NLS-1$ + int b = 0xff & byteBuffer[p]; + + if (b > 32 && b < 127) { + outputBuilder.append((char) b + " "); } else { - outputBuf.append(". "); //$NON-NLS-1$ + outputBuilder.append(". "); } p++; } - outputBuf.append("\n"); //$NON-NLS-1$ + outputBuilder.append("\n"); } int n = 0; @@ -161,30 +194,32 @@ String hexVal = Integer.toHexString(byteBuffer[i] & 0xff); if (hexVal.length() == 1) { - hexVal = "0" + hexVal; //$NON-NLS-1$ + hexVal = "0" + hexVal; } - outputBuf.append(hexVal + " "); //$NON-NLS-1$ + outputBuilder.append(hexVal + " "); n++; } for (int i = n; i < 8; i++) { - outputBuf.append(" "); //$NON-NLS-1$ + outputBuilder.append(" "); } - outputBuf.append(" "); //$NON-NLS-1$ + outputBuilder.append(" "); for (int i = p; i < length; i++) { - if ((byteBuffer[i] > 32) && (byteBuffer[i] < 127)) { - outputBuf.append((char) byteBuffer[i] + " "); //$NON-NLS-1$ + int b = 0xff & byteBuffer[i]; + + if (b > 32 && b < 127) { + outputBuilder.append((char) b + " "); } else { - outputBuf.append(". "); //$NON-NLS-1$ + outputBuilder.append(". "); } } - outputBuf.append("\n"); //$NON-NLS-1$ + outputBuilder.append("\n"); - return outputBuf.toString(); + return outputBuilder.toString(); } private static boolean endsWith(byte[] dataFrom, String suffix) { @@ -206,18 +241,16 @@ * the original bytes in SJIS format * @param origString * the string that had .getBytes() called on it - * @param offset - * where to start converting from - * @param length - * how many characters to convert. * * @return byte[] with 0x5c escaped */ - public static byte[] escapeEasternUnicodeByteStream(byte[] origBytes, - String origString, int offset, int length) { - if ((origBytes == null) || (origBytes.length == 0)) { - return origBytes; + public static byte[] escapeEasternUnicodeByteStream(byte[] origBytes, String origString) { + if (origBytes == null) { + return null; } + if (origBytes.length == 0) { + return new byte[0]; + } int bytesLen = origBytes.length; int bufIndex = 0; @@ -337,6 +370,24 @@ return 0; } + public static char firstAlphaCharUc(String searchIn, int startAt) { + if (searchIn == null) { + return 0; + } + + int length = searchIn.length(); + + for (int i = startAt; i < length; i++) { + char c = searchIn.charAt(i); + + if (Character.isLetter(c)) { + return Character.toUpperCase(c); + } + } + + return 0; + } + /** * Adds '+' to decimal numbers that are positive (MySQL doesn't understand * them otherwise @@ -346,298 +397,289 @@ * * @return String the string with a '+' added (if needed) */ - public static final String fixDecimalExponent(String dString) { - int ePos = dString.indexOf("E"); //$NON-NLS-1$ + public static String fixDecimalExponent(String dString) { + int ePos = dString.indexOf('E'); if (ePos == -1) { - ePos = dString.indexOf("e"); //$NON-NLS-1$ + ePos = dString.indexOf('e'); } if (ePos != -1) { if (dString.length() > (ePos + 1)) { char maybeMinusChar = dString.charAt(ePos + 1); if (maybeMinusChar != '-' && maybeMinusChar != '+') { - StringBuffer buf = new StringBuffer(dString.length() + 1); - buf.append(dString.substring(0, ePos + 1)); - buf.append('+'); - buf.append(dString.substring(ePos + 1, dString.length())); - dString = buf.toString(); + StringBuilder strBuilder = new StringBuilder(dString.length() + 1); + strBuilder.append(dString.substring(0, ePos + 1)); + strBuilder.append('+'); + strBuilder.append(dString.substring(ePos + 1, dString.length())); + dString = strBuilder.toString(); } } } return dString; } - public static final byte[] getBytes(char[] c, - SingleByteCharsetConverter converter, String encoding, - String serverEncoding, boolean parserKnowsUnicode) + /** + * Returns the byte[] representation of the given char[] (re)using the given charset converter, and the given + * encoding. + */ + public static byte[] getBytes(char[] c, SingleByteCharsetConverter converter, String encoding, + String serverEncoding, boolean parserKnowsUnicode, ExceptionInterceptor exceptionInterceptor) throws SQLException { try { - byte[] b = null; + byte[] b; if (converter != null) { b = converter.toBytes(c); } else if (encoding == null) { - b = new String(c).getBytes(); + b = getBytes(c); } else { - String s = new String(c); + b = getBytes(c, encoding); - b = s.getBytes(encoding); + if (!parserKnowsUnicode + && (encoding.equalsIgnoreCase("SJIS") || encoding.equalsIgnoreCase("BIG5") || encoding + .equalsIgnoreCase("GBK"))) { - if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$ - || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$ - || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$ - if (!encoding.equalsIgnoreCase(serverEncoding)) { - b = escapeEasternUnicodeByteStream(b, s, 0, s.length()); + b = escapeEasternUnicodeByteStream(b, new String(c)); } } } return b; } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException(Messages.getString("StringUtils.5") //$NON-NLS-1$ - + encoding + Messages.getString("StringUtils.6"), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError.createSQLException( + Messages.getString("StringUtils.0") + encoding + Messages.getString("StringUtils.1"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } } - public static final byte[] getBytes(char[] c, - SingleByteCharsetConverter converter, String encoding, - String serverEncoding, int offset, int length, - boolean parserKnowsUnicode) throws SQLException { + /** + * Returns the byte[] representation of subset of the given char[] (re)using the given charset converter, and the + * given encoding. + */ + public static byte[] getBytes(char[] c, SingleByteCharsetConverter converter, String encoding, + String serverEncoding, int offset, int length, boolean parserKnowsUnicode, + ExceptionInterceptor exceptionInterceptor) throws SQLException { try { - byte[] b = null; + byte[] b; if (converter != null) { b = converter.toBytes(c, offset, length); } else if (encoding == null) { - byte[] temp = new String(c, offset, length).getBytes(); - - length = temp.length; - - b = new byte[length]; - System.arraycopy(temp, 0, b, 0, length); + b = getBytes(c, offset, length); } else { - String s = new String(c, offset, length); + b = getBytes(c, offset, length, encoding); - byte[] temp = s.getBytes(encoding); + if (!parserKnowsUnicode + && (encoding.equalsIgnoreCase("SJIS") || encoding.equalsIgnoreCase("BIG5") || encoding + .equalsIgnoreCase("GBK"))) { - length = temp.length; - - b = new byte[length]; - System.arraycopy(temp, 0, b, 0, length); - - if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$ - || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$ - || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$ - if (!encoding.equalsIgnoreCase(serverEncoding)) { - b = escapeEasternUnicodeByteStream(b, s, offset, length); + b = escapeEasternUnicodeByteStream(b, new String(c, offset, length)); } } } return b; } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException(Messages.getString("StringUtils.10") //$NON-NLS-1$ - + encoding + Messages.getString("StringUtils.11"), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError.createSQLException( + Messages.getString("StringUtils.0") + encoding + Messages.getString("StringUtils.1"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } } - public static final byte[] getBytes(char[] c, String encoding, - String serverEncoding, boolean parserKnowsUnicode, Connection conn) - throws SQLException { + /** + * Returns the byte[] representation of the given char[] (re)using a cached charset converter, and the given + * encoding. + */ + public static byte[] getBytes(char[] c, String encoding, String serverEncoding, boolean parserKnowsUnicode, + MySQLConnection conn, ExceptionInterceptor exceptionInterceptor) throws SQLException { try { - - SingleByteCharsetConverter converter = null; - - if (conn != null) { - converter = conn.getCharsetConverter(encoding); - } else { - converter = SingleByteCharsetConverter.getInstance(encoding, null); - } + SingleByteCharsetConverter converter = conn != null ? conn.getCharsetConverter(encoding) + : SingleByteCharsetConverter.getInstance(encoding, null); - return getBytes(c, converter, encoding, serverEncoding, - parserKnowsUnicode); + return getBytes(c, converter, encoding, serverEncoding, parserKnowsUnicode, exceptionInterceptor); } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException(Messages.getString("StringUtils.0") //$NON-NLS-1$ - + encoding + Messages.getString("StringUtils.1"), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError.createSQLException( + Messages.getString("StringUtils.0") + encoding + Messages.getString("StringUtils.1"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } } /** - * Returns the byte[] representation of the given string (re)using the given - * charset converter, and the given encoding. - * - * @param s - * the string to convert - * @param converter - * the converter to reuse - * @param encoding - * the character encoding to use - * @param serverEncoding - * DOCUMENT ME! - * @param parserKnowsUnicode - * DOCUMENT ME! - * - * @return byte[] representation of the string - * - * @throws SQLException - * if an encoding unsupported by the JVM is supplied. + * Returns the byte[] representation of the given string (re)using the given charset converter, and the given + * encoding. */ - public static final byte[] getBytes(String s, - SingleByteCharsetConverter converter, String encoding, - String serverEncoding, boolean parserKnowsUnicode) + public static byte[] getBytes(String s, SingleByteCharsetConverter converter, String encoding, + String serverEncoding, boolean parserKnowsUnicode, ExceptionInterceptor exceptionInterceptor) throws SQLException { try { - byte[] b = null; + byte[] b; if (converter != null) { b = converter.toBytes(s); } else if (encoding == null) { - b = s.getBytes(); + b = getBytes(s); } else { - b = s.getBytes(encoding); + b = getBytes(s, encoding); - if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$ - || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$ - || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$ + if (!parserKnowsUnicode + && (encoding.equalsIgnoreCase("SJIS") || encoding.equalsIgnoreCase("BIG5") || encoding + .equalsIgnoreCase("GBK"))) { if (!encoding.equalsIgnoreCase(serverEncoding)) { - b = escapeEasternUnicodeByteStream(b, s, 0, s.length()); + b = escapeEasternUnicodeByteStream(b, s); } } } return b; } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException(Messages.getString("StringUtils.5") //$NON-NLS-1$ - + encoding + Messages.getString("StringUtils.6"), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError.createSQLException( + Messages.getString("StringUtils.5") + encoding + Messages.getString("StringUtils.6"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } } /** - * DOCUMENT ME! - * - * @param s - * DOCUMENT ME! - * @param converter - * DOCUMENT ME! - * @param encoding - * DOCUMENT ME! - * @param serverEncoding - * DOCUMENT ME! - * @param offset - * DOCUMENT ME! - * @param length - * DOCUMENT ME! - * @param parserKnowsUnicode - * DOCUMENT ME! - * - * @return DOCUMENT ME! - * - * @throws SQLException - * DOCUMENT ME! + * Returns the byte[] representation of a substring of the given string (re)using the given charset converter, and + * the given encoding. */ - public static final byte[] getBytes(String s, - SingleByteCharsetConverter converter, String encoding, - String serverEncoding, int offset, int length, - boolean parserKnowsUnicode) throws SQLException { + public static byte[] getBytes(String s, SingleByteCharsetConverter converter, String encoding, + String serverEncoding, int offset, int length, boolean parserKnowsUnicode, + ExceptionInterceptor exceptionInterceptor) throws SQLException { try { - byte[] b = null; + byte[] b; if (converter != null) { b = converter.toBytes(s, offset, length); } else if (encoding == null) { - byte[] temp = s.substring(offset, offset + length).getBytes(); - - length = temp.length; - - b = new byte[length]; - System.arraycopy(temp, 0, b, 0, length); + b = getBytes(s, offset, length); } else { + s = s.substring(offset, offset + length); + b = getBytes(s, encoding); - byte[] temp = s.substring(offset, offset + length) - .getBytes(encoding); + if (!parserKnowsUnicode + && (encoding.equalsIgnoreCase("SJIS") || encoding.equalsIgnoreCase("BIG5") || encoding + .equalsIgnoreCase("GBK"))) { - length = temp.length; - - b = new byte[length]; - System.arraycopy(temp, 0, b, 0, length); - - if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$ - || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$ - || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$ - if (!encoding.equalsIgnoreCase(serverEncoding)) { - b = escapeEasternUnicodeByteStream(b, s, offset, length); + b = escapeEasternUnicodeByteStream(b, s); } } } return b; } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException(Messages.getString("StringUtils.10") //$NON-NLS-1$ - + encoding + Messages.getString("StringUtils.11"), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError.createSQLException( + Messages.getString("StringUtils.5") + encoding + Messages.getString("StringUtils.6"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } } /** - * Returns the byte[] representation of the given string using given + * Returns the byte[] representation of the given string (re)using a cached charset converter, and the given * encoding. - * - * @param s - * the string to convert - * @param encoding - * the character encoding to use - * @param parserKnowsUnicode - * DOCUMENT ME! - * - * @return byte[] representation of the string - * - * @throws SQLException - * if an encoding unsupported by the JVM is supplied. */ - public static final byte[] getBytes(String s, String encoding, - String serverEncoding, boolean parserKnowsUnicode, Connection conn) + public static byte[] getBytes(String s, String encoding, String serverEncoding, boolean parserKnowsUnicode, + MySQLConnection conn, ExceptionInterceptor exceptionInterceptor) throws SQLException { + try { + SingleByteCharsetConverter converter = conn != null ? conn.getCharsetConverter(encoding) + : SingleByteCharsetConverter.getInstance(encoding, null); + + return getBytes(s, converter, encoding, serverEncoding, parserKnowsUnicode, exceptionInterceptor); + } catch (UnsupportedEncodingException uee) { + throw SQLError.createSQLException( + Messages.getString("StringUtils.5") + encoding + Messages.getString("StringUtils.6"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + } + } + + /** + * Returns the byte[] representation of a substring of the given string (re)using a cached charset converter, and + * the given encoding. + */ + public static final byte[] getBytes(String s, String encoding, String serverEncoding, int offset, int length, + boolean parserKnowsUnicode, MySQLConnection conn, ExceptionInterceptor exceptionInterceptor) throws SQLException { try { - SingleByteCharsetConverter converter = null; - - if (conn != null) { - converter = conn.getCharsetConverter(encoding); + SingleByteCharsetConverter converter = conn != null ? conn.getCharsetConverter(encoding) + : SingleByteCharsetConverter.getInstance(encoding, null); + + return getBytes(s, converter, encoding, serverEncoding, offset, length, parserKnowsUnicode, + exceptionInterceptor); + } catch (UnsupportedEncodingException uee) { + throw SQLError.createSQLException( + Messages.getString("StringUtils.5") + encoding + Messages.getString("StringUtils.6"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + } + } + + /** + * Returns the byte[] representation of the given string properly wrapped between the given char delimiters, + * (re)using the given charset converter, and the given encoding. + */ + public static byte[] getBytesWrapped(String s, char beginWrap, char endWrap, SingleByteCharsetConverter converter, + String encoding, String serverEncoding, boolean parserKnowsUnicode, + ExceptionInterceptor exceptionInterceptor) throws SQLException { + try { + byte[] b; + + if (converter != null) { + b = converter.toBytesWrapped(s, beginWrap, endWrap); + } else if (encoding == null) { + StringBuilder strBuilder = new StringBuilder(s.length() + 2); + strBuilder.append(beginWrap); + strBuilder.append(s); + strBuilder.append(endWrap); + + b = getBytes(strBuilder.toString()); } else { - converter = SingleByteCharsetConverter.getInstance(encoding, null); + StringBuilder strBuilder = new StringBuilder(s.length() + 2); + strBuilder.append(beginWrap); + strBuilder.append(s); + strBuilder.append(endWrap); + + s = strBuilder.toString(); + b = getBytes(s, encoding); + + if (!parserKnowsUnicode + && (encoding.equalsIgnoreCase("SJIS") || encoding.equalsIgnoreCase("BIG5") || encoding + .equalsIgnoreCase("GBK"))) { + + if (!encoding.equalsIgnoreCase(serverEncoding)) { + b = escapeEasternUnicodeByteStream(b, s); + } + } } - return getBytes(s, converter, encoding, serverEncoding, - parserKnowsUnicode); + return b; } catch (UnsupportedEncodingException uee) { - throw SQLError.createSQLException(Messages.getString("StringUtils.0") //$NON-NLS-1$ - + encoding + Messages.getString("StringUtils.1"), - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ + throw SQLError.createSQLException( + Messages.getString("StringUtils.10") + encoding + Messages.getString("StringUtils.11"), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } } + public static int getInt(byte[] buf) throws NumberFormatException { + return getInt(buf, 0, buf.length); + } + public static int getInt(byte[] buf, int offset, int endPos) throws NumberFormatException { int base = 10; int s = offset; /* Skip white space. */ - while (Character.isWhitespace((char) buf[s]) && (s < endPos)) { + while (s < endPos && Character.isWhitespace((char) buf[s])) { ++s; } if (s == endPos) { - throw new NumberFormatException(new String(buf)); + throw new NumberFormatException(StringUtils.toString(buf)); } /* Check for a sign. */ @@ -689,33 +731,33 @@ } if (s == save) { - throw new NumberFormatException(new String(buf)); + throw new NumberFormatException(StringUtils.toString(buf)); } if (overflow) { - throw new NumberFormatException(new String(buf)); + throw new NumberFormatException(StringUtils.toString(buf)); } /* Return the result of the appropriate sign. */ return (negative ? (-i) : i); } - public static int getInt(byte[] buf) throws NumberFormatException { - return getInt(buf, 0, buf.length); - } - public static long getLong(byte[] buf) throws NumberFormatException { + return getLong(buf, 0, buf.length); + } + + public static long getLong(byte[] buf, int offset, int endpos) throws NumberFormatException { int base = 10; - int s = 0; + int s = offset; /* Skip white space. */ - while (Character.isWhitespace((char) buf[s]) && (s < buf.length)) { + while (s < endpos && Character.isWhitespace((char) buf[s])) { ++s; } - if (s == buf.length) { - throw new NumberFormatException(new String(buf)); + if (s == endpos) { + throw new NumberFormatException(StringUtils.toString(buf)); } /* Check for a sign. */ @@ -741,7 +783,7 @@ boolean overflow = false; long i = 0; - for (; s < buf.length; s++) { + for (; s < endpos; s++) { char c = (char) buf[s]; if (Character.isDigit(c)) { @@ -766,29 +808,33 @@ } if (s == save) { - throw new NumberFormatException(new String(buf)); + throw new NumberFormatException(StringUtils.toString(buf)); } if (overflow) { - throw new NumberFormatException(new String(buf)); + throw new NumberFormatException(StringUtils.toString(buf)); } /* Return the result of the appropriate sign. */ return (negative ? (-i) : i); } public static short getShort(byte[] buf) throws NumberFormatException { + return getShort(buf, 0, buf.length); + } + + public static short getShort(byte[] buf, int offset, int endpos) throws NumberFormatException { short base = 10; - int s = 0; + int s = offset; /* Skip white space. */ - while (Character.isWhitespace((char) buf[s]) && (s < buf.length)) { + while (s < endpos && Character.isWhitespace((char) buf[s])) { ++s; } - if (s == buf.length) { - throw new NumberFormatException(new String(buf)); + if (s == endpos) { + throw new NumberFormatException(StringUtils.toString(buf)); } /* Check for a sign. */ @@ -814,7 +860,7 @@ boolean overflow = false; short i = 0; - for (; s < buf.length; s++) { + for (; s < endpos; s++) { char c = (char) buf[s]; if (Character.isDigit(c)) { @@ -839,11 +885,11 @@ } if (s == save) { - throw new NumberFormatException(new String(buf)); + throw new NumberFormatException(StringUtils.toString(buf)); } if (overflow) { - throw new NumberFormatException(new String(buf)); + throw new NumberFormatException(StringUtils.toString(buf)); } /* Return the result of the appropriate sign. */ @@ -861,8 +907,6 @@ int stringLength = searchIn.length(); int stopSearchingAt = stringLength - patternLength; - int i = startingPosition; - if (patternLength == 0) { return -1; } @@ -872,49 +916,38 @@ char firstCharOfPatternUc = Character.toUpperCase(searchFor.charAt(0)); char firstCharOfPatternLc = Character.toLowerCase(searchFor.charAt(0)); - lookForFirstChar: while (true) { - while ((i < stopSearchingAt) - && (Character.toUpperCase(searchIn.charAt(i)) != firstCharOfPatternUc) - && Character.toLowerCase(searchIn.charAt(i)) != firstCharOfPatternLc) { - i++; - } + // note, this also catches the case where patternLength > stringLength + for (int i = startingPosition; i <= stopSearchingAt; i++) { + if (isNotEqualIgnoreCharCase(searchIn, firstCharOfPatternUc, + firstCharOfPatternLc, i)) { + // find the first occurrence of the first character of searchFor in searchIn + while (++i <= stopSearchingAt && (isNotEqualIgnoreCharCase(searchIn, firstCharOfPatternUc, + firstCharOfPatternLc, i))); + } - if (i > stopSearchingAt) { - return -1; - } + if (i <= stopSearchingAt /* searchFor might be one character long! */) { + // walk searchIn and searchFor in lock-step starting just past the first match,bail out if not + // a match, or we've hit the end of searchFor... + int j = i + 1; + int end = j + patternLength - 1; + for (int k = 1; j < end && (Character.toLowerCase(searchIn.charAt(j)) == + Character.toLowerCase(searchFor.charAt(k)) || Character.toUpperCase(searchIn.charAt(j)) == + Character.toUpperCase(searchFor.charAt(k))); j++, k++); - int j = i + 1; - int end = (j + patternLength) - 1; + if (j == end) { + return i; + } + } + } + + return -1; + } - int k = 1; // start at second char of pattern - - while (j < end) { - int searchInPos = j++; - int searchForPos = k++; - - if (Character.toUpperCase(searchIn.charAt(searchInPos)) != Character - .toUpperCase(searchFor.charAt(searchForPos))) { - i++; - - // start over - continue lookForFirstChar; - } - - // Georgian and Turkish locales don't have same convention, so - // need to check lowercase - // too! - if (Character.toLowerCase(searchIn.charAt(searchInPos)) != Character - .toLowerCase(searchFor.charAt(searchForPos))) { - i++; - - // start over - continue lookForFirstChar; - } - } - - return i; // found entire pattern - } + private final static boolean isNotEqualIgnoreCharCase(String searchIn, + char firstCharOfPatternUc, char firstCharOfPatternLc, int i) { + return Character.toLowerCase(searchIn.charAt(i)) != firstCharOfPatternLc && Character.toUpperCase(searchIn.charAt(i)) != firstCharOfPatternUc; } + /** * DOCUMENT ME! @@ -935,7 +968,7 @@ boolean allowBackslashEscapes) { char contextMarker = Character.MIN_VALUE; boolean escaped = false; - int markerTypeFound = -1; + int markerTypeFound = 0; int srcLength = src.length(); int ind = 0; @@ -944,16 +977,16 @@ if (allowBackslashEscapes && c == '\\') { escaped = !escaped; - } else if (markerTypeFound != -1 && c == markerCloses.charAt(markerTypeFound) && !escaped) { + } else if (contextMarker != Character.MIN_VALUE && c == markerCloses.charAt(markerTypeFound) && !escaped) { contextMarker = Character.MIN_VALUE; - markerTypeFound = -1; } else if ((ind = marker.indexOf(c)) != -1 && !escaped && contextMarker == Character.MIN_VALUE) { markerTypeFound = ind; contextMarker = c; - } else if (c == target.charAt(0) && !escaped + } else if ((Character.toUpperCase(c) == Character.toUpperCase(target.charAt(0)) || + Character.toLowerCase(c) == Character.toLowerCase(target.charAt(0))) && !escaped && contextMarker == Character.MIN_VALUE) { - if (indexOfIgnoreCase(i, src, target) != -1) + if (startsWithIgnoreCase(src, i, target)) return i; } } @@ -1008,10 +1041,10 @@ * @throws IllegalArgumentException * DOCUMENT ME! */ - public static final List split(String stringToSplit, String delimitter, + public static final List split(String stringToSplit, String delimitter, boolean trim) { if (stringToSplit == null) { - return new ArrayList(); + return new ArrayList(); } if (delimitter == null) { @@ -1021,7 +1054,7 @@ StringTokenizer tokenizer = new StringTokenizer(stringToSplit, delimitter, false); - List splitTokens = new ArrayList(tokenizer.countTokens()); + List splitTokens = new ArrayList(tokenizer.countTokens()); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); @@ -1051,10 +1084,10 @@ * @throws IllegalArgumentException * DOCUMENT ME! */ - public static final List split(String stringToSplit, String delimiter, + public static final List split(String stringToSplit, String delimiter, String markers, String markerCloses, boolean trim) { if (stringToSplit == null) { - return new ArrayList(); + return new ArrayList(); } if (delimiter == null) { @@ -1064,7 +1097,7 @@ int delimPos = 0; int currentPos = 0; - List splitTokens = new ArrayList(); + List splitTokens = new ArrayList(); while ((delimPos = indexOfIgnoreCaseRespectMarker(currentPos, stringToSplit, delimiter, markers, markerCloses, false)) != -1) { @@ -1136,7 +1169,7 @@ } /** - * Determines whether or not the sting 'searchIn' contains the string + * Determines whether or not the string 'searchIn' contains the string * 'searchFor', disregarding case,leading whitespace and non-alphanumeric * characters. * @@ -1169,7 +1202,7 @@ } /** - * Determines whether or not the sting 'searchIn' contains the string + * Determines whether or not the string 'searchIn' contains the string * 'searchFor', disregarding case and leading whitespace * * @param searchIn @@ -1185,7 +1218,7 @@ } /** - * Determines whether or not the sting 'searchIn' contains the string + * Determines whether or not the string 'searchIn' contains the string * 'searchFor', disregarding case and leading whitespace * * @param searchIn @@ -1216,6 +1249,26 @@ } /** + * Determines whether or not the string 'searchIn' starts with one of the strings in 'searchFor', disregarding case + * and leading whitespace + * + * @param searchIn + * the string to search in + * @param searchFor + * the string array to search for + * + * @return the 'searchFor' array index that matched or -1 if none matches + */ + public static int startsWithIgnoreCaseAndWs(String searchIn, String[] searchFor) { + for (int i = 0; i < searchFor.length; i++) { + if (startsWithIgnoreCaseAndWs(searchIn, searchFor[i], 0)) { + return i; + } + } + return -1; + } + + /** * @param bytesToStrip * @param prefix * @param suffix @@ -1431,7 +1484,7 @@ : WILD_COMPARE_MATCH_NO_WILD); } - static byte[] s2b(String s, Connection conn) throws SQLException { + static byte[] s2b(String s, MySQLConnection conn) throws SQLException { if (s == null) { return null; } @@ -1459,7 +1512,7 @@ return s.getBytes(); } - + public static int lastIndexOf(byte[] s, char c) { if (s == null) { return -1; @@ -1490,6 +1543,10 @@ return -1; } + public static boolean isNullOrEmpty(String toTest) { + return (toTest == null || toTest.length() == 0); + } + /** * Returns the given string, with comments removed * @@ -1518,7 +1575,7 @@ return null; } - StringBuffer buf = new StringBuffer(src.length()); + StringBuilder strBuilder = new StringBuilder(src.length()); // It's just more natural to deal with this as a stream // when parsing..This code is currently only called when @@ -1592,10 +1649,10 @@ currentChar = sourceReader.read(); if (currentChar == -1 || currentChar != '-') { - buf.append('-'); + strBuilder.append('-'); if (currentChar != -1) { - buf.append(currentChar); + strBuilder.append(currentChar); } continue; @@ -1609,13 +1666,468 @@ } if (currentChar != -1) { - buf.append((char) currentChar); + strBuilder.append((char) currentChar); } } } catch (IOException ioEx) { // we'll never see this from a StringReader } - return buf.toString(); + return strBuilder.toString(); } + + /** + * Next two functions are to help DBMD check if + * the given string is in form of database.name and return it + * as "database";"name" with comments removed. + * If string is NULL or wildcard (%), returns null and exits. + * + * First, we sanitize... + * + * @param src + * the source string + * @return the input string with all comment-delimited data removed + */ + public static String sanitizeProcOrFuncName(String src) { + if ((src == null) || (src.equals("%"))) { + return null; + } + + return src; + } + + /** + * 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. + * + * @param src + * the source string + * @param cat + * Catalog, if available + * @param quotId + * quoteId as defined on server + * @param isNoBslashEscSet + * Is our connection in 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(); + } + + 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, "."); + } + } else { + trueDotIndex = retval.indexOf("."); + } + + 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); + } + } else { + //No catalog attached, strip retval and return + retval = StringUtils.toString(StringUtils.stripEnclosure(retval + .getBytes(), quotId, quotId)); + } + + retTokens.add(tmpCat); + retTokens.add(retval); + return retTokens; + } + + public static final boolean isEmptyOrWhitespaceOnly(String str) { + if (str == null || str.length() == 0) { + return true; + } + + int length = str.length(); + + for (int i = 0; i < length; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + return false; + } + } + + return true; + } + + public static String escapeQuote(String src, String quotChar) { + if (src == null) { + return null; + } + + src = StringUtils.toString(stripEnclosure(src.getBytes(), quotChar, quotChar)); + + int lastNdx = src.indexOf(quotChar); + String tmpSrc; + String tmpRest; + + tmpSrc = src.substring(0, lastNdx); + tmpSrc = tmpSrc + quotChar + quotChar; + + tmpRest = src.substring(lastNdx+1, src.length()); + + lastNdx = tmpRest.indexOf(quotChar); + while (lastNdx > -1) { + + tmpSrc = tmpSrc + tmpRest.substring(0, lastNdx); + tmpSrc = tmpSrc + quotChar + quotChar; + tmpRest = tmpRest.substring(lastNdx+1, tmpRest.length()); + + lastNdx = tmpRest.indexOf(quotChar); + } + + tmpSrc = tmpSrc + tmpRest; + src = tmpSrc; + + return src; + } + + /** + * Surrounds identifier with quoteChar and duplicates these symbols inside the identifier. + * + * @param quoteChar ` or " + * @param identifier in pedantic mode (connection property pedantic=true) identifier is treated as unquoted + * (as it is stored in the database) even if it starts and ends with quoteChar; + * in non-pedantic mode if identifier starts and ends with quoteChar method treats it as already quoted and doesn't modify. + * @param isPedantic are we in pedantic mode + * + * @return + * With quoteChar="`":
+ *
  • null -> null
  • + *
  • abc -> `abc`
  • + *
  • ab`c -> `ab``c`
  • + *
  • ab"c -> `ab"c`
  • + *
  • `ab``c` -> `ab``c` in non-pedantic mode or ```ab````c``` in pedantic mode
  • + * With quoteChar="\"":
    + *
  • null -> null
  • + *
  • abc -> "abc"
  • + *
  • ab`c -> "ab`c"
  • + *
  • ab"c -> "ab""c"
  • + *
  • "ab""c" -> "ab""c" in non-pedantic mode or """ab""""c""" in pedantic mode
  • + */ + public static String quoteIdentifier(String identifier, String quoteChar, boolean isPedantic) { + if (identifier == null) { + return null; + } + + if (!isPedantic && identifier.startsWith(quoteChar) && identifier.endsWith(quoteChar)) { + return identifier; + } + + return quoteChar + identifier.replaceAll(quoteChar, quoteChar+quoteChar) + quoteChar; + } + + /** + * Surrounds identifier with "`" and duplicates these symbols inside the identifier. + * + * @param identifier in pedantic mode (connection property pedantic=true) identifier is treated as unquoted + * (as it is stored in the database) even if it starts and ends with "`"; + * in non-pedantic mode if identifier starts and ends with "`" method treats it as already quoted and doesn't modify. + * @param isPedantic are we in pedantic mode + * + * @return + *
  • null -> null
  • + *
  • abc -> `abc`
  • + *
  • ab`c -> `ab``c`
  • + *
  • ab"c -> `ab"c`
  • + *
  • `ab``c` -> `ab``c` in non-pedantic mode or ```ab````c``` in pedantic mode
  • + */ + public static String quoteIdentifier(String identifier, boolean isPedantic) { + return quoteIdentifier(identifier, "`", isPedantic); + } + + /** + * Trims identifier, removes quote chars from first and last positions + * and replaces double occurrences of quote char from entire identifier, + * i.e converts quoted identifier into form as it is stored in database. + * + * @param identifier + * @param useAnsiQuotedIdentifiers should we check for " quotes too. + * @return + *
  • null -> null
  • + *
  • abc -> abc
  • + *
  • `abc` -> abc
  • + *
  • `ab``c` -> ab`c
  • + *
  • `"ab`c"` -> "ab`c"
  • + *
  • `ab"c` -> ab"c
  • + *
  • "abc" -> abc
  • + *
  • "`ab""c`" -> `ab"c`
  • + *
  • "ab`c" -> ab`c
  • + */ + public static String unQuoteIdentifier(String identifier, boolean useAnsiQuotedIdentifiers) { + if (identifier == null) { + return null; + } + + identifier = identifier.trim(); + + String quoteChar = null; + + // Backquotes are always valid identifier quotes + if (identifier.startsWith("`") && identifier.endsWith("`")) { + quoteChar = "`"; + } + + if (quoteChar== null && useAnsiQuotedIdentifiers) { + if (identifier.startsWith("\"") && identifier.endsWith("\"")) { + quoteChar = "\""; + } + } + + if (quoteChar != null) { + identifier = identifier.substring(1, (identifier.length() - 1)); + return identifier.replaceAll(quoteChar+quoteChar, quoteChar); + } + + return identifier; + } + + public static int indexOfQuoteDoubleAware(String line, String quoteChar, int startFrom) { + int lastIndex = line.length() -1; + + int beginPos = startFrom; + int pos = -1; + + boolean next = true; + while (next) { + pos = line.indexOf(quoteChar, beginPos); + if (pos == -1 || pos == lastIndex || !line.substring(pos+1).startsWith(quoteChar)) { + next = false; + } else { + beginPos = pos + 2; + } + } + + return pos; + } + + // The following methods all exist because of the Java bug + // + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6790402 + // + // which has been observed by users and reported as MySQL Bug#61105 + // + // We can turn around and replace them with their java.lang.String + // equivalents if/when that bug is ever fixed. + + public static String toString(byte[] value, int offset, int length, + String encoding) throws UnsupportedEncodingException { + Charset cs = findCharset(encoding); + + return cs.decode(ByteBuffer.wrap(value, offset, length)).toString(); + } + + public static String toString(byte[] value, String encoding) + throws UnsupportedEncodingException { + Charset cs = findCharset(encoding); + + return cs.decode(ByteBuffer.wrap(value)).toString(); + } + + public static String toString(byte[] value, int offset, int length) { + try { + Charset cs = findCharset(platformEncoding); + + return cs.decode(ByteBuffer.wrap(value, offset, length)).toString(); + } catch (UnsupportedEncodingException e) { + // can't happen, emulating new String(byte[]) + } + + return null; + } + + public static String toString(byte[] value) { + try { + Charset cs = findCharset(platformEncoding); + + return cs.decode(ByteBuffer.wrap(value)).toString(); + } catch (UnsupportedEncodingException e) { + // can't happen, emulating new String(byte[]) + } + + return null; + } + + public static byte[] getBytes(char[] value) { + try { + return getBytes(value, 0, value.length, platformEncoding); + } catch (UnsupportedEncodingException e) { + // can't happen, emulating new String(byte[]) + } + + return null; + } + + public static byte[] getBytes(char[] value, int offset, int length) { + try { + return getBytes(value, offset, length, platformEncoding); + } catch (UnsupportedEncodingException e) { + // can't happen, emulating new String(byte[]) + } + + return null; + } + + public static byte[] getBytes(char[] value, String encoding) throws UnsupportedEncodingException { + return getBytes(value, 0, value.length, encoding); + } + + public static byte[] getBytes(char[] value, int offset, int length, String encoding) + throws UnsupportedEncodingException { + Charset cs = findCharset(encoding); + + ByteBuffer buf = cs.encode(CharBuffer.wrap(value, offset, length)); + + // can't simply .array() this to get the bytes + // especially with variable-length charsets the + // buffer is sometimes larger than the actual encoded data + int encodedLen = buf.limit(); + byte[] asBytes = new byte[encodedLen]; + buf.get(asBytes, 0, encodedLen); + + return asBytes; + } + + public static byte[] getBytes(String value) { + try { + return getBytes(value, 0, value.length(), platformEncoding); + } catch (UnsupportedEncodingException e) { + // can't happen, emulating new String(byte[]) + } + + return null; + } + + public static byte[] getBytes(String value, int offset, int length) { + try { + return getBytes(value, offset, length, platformEncoding); + } catch (UnsupportedEncodingException e) { + // can't happen, emulating new String(byte[]) + } + + return null; + } + + public static byte[] getBytes(String value, String encoding) throws UnsupportedEncodingException { + return getBytes(value, 0, value.length(), encoding); + } + + public static byte[] getBytes(String value, int offset, int length, String encoding) + throws UnsupportedEncodingException { + // Some CharsetEncoders (e.g. CP942, CP943, CP948, CP950, CP1381, CP1383, x-COMPOUND_TEXT or ISO-2022-JP) can't + // handle correctly when encoding directly from its methods while calling the encoder from String object works + // just fine. Most of these problems occur only in Java 1.5. + // CharsetEncoder#encode() may be used in Java 1.6+ but only the method that receives a char[] as argument as + // the one that receives a String argument doesn't always behaves correctly. + if (!Util.isJdbc4()) { + if (offset != 0 || length != value.length()) { + return value.substring(offset, offset + length).getBytes(encoding); + } + return value.getBytes(encoding); + } + + Charset cs = findCharset(encoding); + + ByteBuffer buf = cs.encode(CharBuffer.wrap(value.toCharArray(), offset, offset + length)); + + // can't simply .array() this to get the bytes + // especially with variable-length charsets the + // buffer is sometimes larger than the actual encoded data + int encodedLen = buf.limit(); + byte[] asBytes = new byte[encodedLen]; + buf.get(asBytes, 0, encodedLen); + + return asBytes; + } + + public static final boolean isValidIdChar(char c) { + return VALID_ID_CHARS.indexOf(c) != -1; + } + + private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', + 'e', 'f' }; + + public static void appendAsHex(StringBuilder builder, byte[] bytes) { + builder.append("0x"); + for (byte b : bytes) { + builder.append(HEX_DIGITS[(b >>> 4) & 0xF]).append(HEX_DIGITS[b & 0xF]); + } + } + + public static void appendAsHex(StringBuilder builder, int value) { + if (value == 0) { + builder.append("0x0"); + return; + } + + int shift = 32; + byte nibble; + boolean nonZeroFound = false; + + builder.append("0x"); + do { + shift -= 4; + nibble = (byte) ((value >>> shift) & 0xF); + if (nonZeroFound) { + builder.append(HEX_DIGITS[nibble]); + } else if (nibble != 0) { + builder.append(HEX_DIGITS[nibble]); + nonZeroFound = true; + } + } while (shift != 0); + } + + public static byte[] getBytesNullTerminated(String value) { + try { + Charset cs = findCharset(platformEncoding); + ByteBuffer buf = cs.encode(value); + int encodedLen = buf.limit(); + byte[] asBytes = new byte[encodedLen+1]; + buf.get(asBytes, 0, encodedLen); + asBytes[encodedLen] = 0; + + return asBytes; + } catch (UnsupportedEncodingException e) { + // can't happen, emulating new String(byte[]) + } + + return null; + } + } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/TimeUtil.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/TimeUtil.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/TimeUtil.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/TimeUtil.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,39 +1,37 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.sql.Date; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; - import java.util.Calendar; import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; -import java.util.Locale; +import java.util.Iterator; import java.util.Map; import java.util.TimeZone; @@ -43,220 +41,230 @@ * @author Mark Matthews */ public class TimeUtil { - static final Map ABBREVIATED_TIMEZONES; + static final Map ABBREVIATED_TIMEZONES; static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT"); - static final Map TIMEZONE_MAPPINGS; + static final Map TIMEZONE_MAPPINGS; static { - HashMap tempMap = new HashMap(); + HashMap tempTzMap = new HashMap(); // // Windows Mappings // - tempMap.put("Romance", "Europe/Paris"); - tempMap.put("Romance Standard Time", "Europe/Paris"); - tempMap.put("Warsaw", "Europe/Warsaw"); - tempMap.put("Central Europe", "Europe/Prague"); - tempMap.put("Central Europe Standard Time", "Europe/Prague"); - tempMap.put("Prague Bratislava", "Europe/Prague"); - tempMap.put("W. Central Africa Standard Time", "Africa/Luanda"); - tempMap.put("FLE", "Europe/Helsinki"); - tempMap.put("FLE Standard Time", "Europe/Helsinki"); - tempMap.put("GFT", "Europe/Athens"); - tempMap.put("GFT Standard Time", "Europe/Athens"); - tempMap.put("GTB", "Europe/Athens"); - tempMap.put("GTB Standard Time", "Europe/Athens"); - tempMap.put("Israel", "Asia/Jerusalem"); - tempMap.put("Israel Standard Time", "Asia/Jerusalem"); - tempMap.put("Arab", "Asia/Riyadh"); - tempMap.put("Arab Standard Time", "Asia/Riyadh"); - tempMap.put("Arabic Standard Time", "Asia/Baghdad"); - tempMap.put("E. Africa", "Africa/Nairobi"); - tempMap.put("E. Africa Standard Time", "Africa/Nairobi"); - tempMap.put("Saudi Arabia", "Asia/Riyadh"); - tempMap.put("Saudi Arabia Standard Time", "Asia/Riyadh"); - tempMap.put("Iran", "Asia/Tehran"); - tempMap.put("Iran Standard Time", "Asia/Tehran"); - tempMap.put("Afghanistan", "Asia/Kabul"); - tempMap.put("Afghanistan Standard Time", "Asia/Kabul"); - tempMap.put("India", "Asia/Calcutta"); - tempMap.put("India Standard Time", "Asia/Calcutta"); - tempMap.put("Myanmar Standard Time", "Asia/Rangoon"); - tempMap.put("Nepal Standard Time", "Asia/Katmandu"); - tempMap.put("Sri Lanka", "Asia/Colombo"); - tempMap.put("Sri Lanka Standard Time", "Asia/Colombo"); - tempMap.put("Beijing", "Asia/Shanghai"); - tempMap.put("China", "Asia/Shanghai"); - tempMap.put("China Standard Time", "Asia/Shanghai"); - tempMap.put("AUS Central", "Australia/Darwin"); - tempMap.put("AUS Central Standard Time", "Australia/Darwin"); - tempMap.put("Cen. Australia", "Australia/Adelaide"); - tempMap.put("Cen. Australia Standard Time", "Australia/Adelaide"); - tempMap.put("Vladivostok", "Asia/Vladivostok"); - tempMap.put("Vladivostok Standard Time", "Asia/Vladivostok"); - tempMap.put("West Pacific", "Pacific/Guam"); - tempMap.put("West Pacific Standard Time", "Pacific/Guam"); - tempMap.put("E. South America", "America/Sao_Paulo"); - tempMap.put("E. South America Standard Time", "America/Sao_Paulo"); - tempMap.put("Greenland Standard Time", "America/Godthab"); - tempMap.put("Newfoundland", "America/St_Johns"); - tempMap.put("Newfoundland Standard Time", "America/St_Johns"); - tempMap.put("Pacific SA", "America/Caracas"); - tempMap.put("Pacific SA Standard Time", "America/Caracas"); - tempMap.put("SA Western", "America/Caracas"); - tempMap.put("SA Western Standard Time", "America/Caracas"); - tempMap.put("SA Pacific", "America/Bogota"); - tempMap.put("SA Pacific Standard Time", "America/Bogota"); - tempMap.put("US Eastern", "America/Indianapolis"); - tempMap.put("US Eastern Standard Time", "America/Indianapolis"); - tempMap.put("Central America Standard Time", "America/Regina"); - tempMap.put("Mexico", "America/Mexico_City"); - tempMap.put("Mexico Standard Time", "America/Mexico_City"); - tempMap.put("Canada Central", "America/Regina"); - tempMap.put("Canada Central Standard Time", "America/Regina"); - tempMap.put("US Mountain", "America/Phoenix"); - tempMap.put("US Mountain Standard Time", "America/Phoenix"); - tempMap.put("GMT", "Europe/London"); - tempMap.put("GMT Standard Time", "Europe/London"); - tempMap.put("Ekaterinburg", "Asia/Yekaterinburg"); - tempMap.put("Ekaterinburg Standard Time", "Asia/Yekaterinburg"); - tempMap.put("West Asia", "Asia/Karachi"); - tempMap.put("West Asia Standard Time", "Asia/Karachi"); - tempMap.put("Central Asia", "Asia/Dhaka"); - tempMap.put("Central Asia Standard Time", "Asia/Dhaka"); - tempMap.put("N. Central Asia Standard Time", "Asia/Novosibirsk"); - tempMap.put("Bangkok", "Asia/Bangkok"); - tempMap.put("Bangkok Standard Time", "Asia/Bangkok"); - tempMap.put("North Asia Standard Time", "Asia/Krasnoyarsk"); - tempMap.put("SE Asia", "Asia/Bangkok"); - tempMap.put("SE Asia Standard Time", "Asia/Bangkok"); - tempMap.put("North Asia East Standard Time", "Asia/Ulaanbaatar"); - tempMap.put("Singapore", "Asia/Singapore"); - tempMap.put("Singapore Standard Time", "Asia/Singapore"); - tempMap.put("Taipei", "Asia/Taipei"); - tempMap.put("Taipei Standard Time", "Asia/Taipei"); - tempMap.put("W. Australia", "Australia/Perth"); - tempMap.put("W. Australia Standard Time", "Australia/Perth"); - tempMap.put("Korea", "Asia/Seoul"); - tempMap.put("Korea Standard Time", "Asia/Seoul"); - tempMap.put("Tokyo", "Asia/Tokyo"); - tempMap.put("Tokyo Standard Time", "Asia/Tokyo"); - tempMap.put("Yakutsk", "Asia/Yakutsk"); - tempMap.put("Yakutsk Standard Time", "Asia/Yakutsk"); - tempMap.put("Central European", "Europe/Belgrade"); - tempMap.put("Central European Standard Time", "Europe/Belgrade"); - tempMap.put("W. Europe", "Europe/Berlin"); - tempMap.put("W. Europe Standard Time", "Europe/Berlin"); - tempMap.put("Tasmania", "Australia/Hobart"); - tempMap.put("Tasmania Standard Time", "Australia/Hobart"); - tempMap.put("AUS Eastern", "Australia/Sydney"); - tempMap.put("AUS Eastern Standard Time", "Australia/Sydney"); - tempMap.put("E. Australia", "Australia/Brisbane"); - tempMap.put("E. Australia Standard Time", "Australia/Brisbane"); - tempMap.put("Sydney Standard Time", "Australia/Sydney"); - tempMap.put("Central Pacific", "Pacific/Guadalcanal"); - tempMap.put("Central Pacific Standard Time", "Pacific/Guadalcanal"); - tempMap.put("Dateline", "Pacific/Majuro"); - tempMap.put("Dateline Standard Time", "Pacific/Majuro"); - tempMap.put("Fiji", "Pacific/Fiji"); - tempMap.put("Fiji Standard Time", "Pacific/Fiji"); - tempMap.put("Samoa", "Pacific/Apia"); - tempMap.put("Samoa Standard Time", "Pacific/Apia"); - tempMap.put("Hawaiian", "Pacific/Honolulu"); - tempMap.put("Hawaiian Standard Time", "Pacific/Honolulu"); - tempMap.put("Alaskan", "America/Anchorage"); - tempMap.put("Alaskan Standard Time", "America/Anchorage"); - tempMap.put("Pacific", "America/Los_Angeles"); - tempMap.put("Pacific Standard Time", "America/Los_Angeles"); - tempMap.put("Mexico Standard Time 2", "America/Chihuahua"); - tempMap.put("Mountain", "America/Denver"); - tempMap.put("Mountain Standard Time", "America/Denver"); - tempMap.put("Central", "America/Chicago"); - tempMap.put("Central Standard Time", "America/Chicago"); - tempMap.put("Eastern", "America/New_York"); - tempMap.put("Eastern Standard Time", "America/New_York"); - tempMap.put("E. Europe", "Europe/Bucharest"); - tempMap.put("E. Europe Standard Time", "Europe/Bucharest"); - tempMap.put("Egypt", "Africa/Cairo"); - tempMap.put("Egypt Standard Time", "Africa/Cairo"); - tempMap.put("South Africa", "Africa/Harare"); - tempMap.put("South Africa Standard Time", "Africa/Harare"); - tempMap.put("Atlantic", "America/Halifax"); - tempMap.put("Atlantic Standard Time", "America/Halifax"); - tempMap.put("SA Eastern", "America/Buenos_Aires"); - tempMap.put("SA Eastern Standard Time", "America/Buenos_Aires"); - tempMap.put("Mid-Atlantic", "Atlantic/South_Georgia"); - tempMap.put("Mid-Atlantic Standard Time", "Atlantic/South_Georgia"); - tempMap.put("Azores", "Atlantic/Azores"); - tempMap.put("Azores Standard Time", "Atlantic/Azores"); - tempMap.put("Cape Verde Standard Time", "Atlantic/Cape_Verde"); - tempMap.put("Russian", "Europe/Moscow"); - tempMap.put("Russian Standard Time", "Europe/Moscow"); - tempMap.put("New Zealand", "Pacific/Auckland"); - tempMap.put("New Zealand Standard Time", "Pacific/Auckland"); - tempMap.put("Tonga Standard Time", "Pacific/Tongatapu"); - tempMap.put("Arabian", "Asia/Muscat"); - tempMap.put("Arabian Standard Time", "Asia/Muscat"); - tempMap.put("Caucasus", "Asia/Tbilisi"); - tempMap.put("Caucasus Standard Time", "Asia/Tbilisi"); - tempMap.put("GMT Standard Time", "GMT"); - tempMap.put("Greenwich", "GMT"); - tempMap.put("Greenwich Standard Time", "GMT"); - tempMap.put("UTC", "GMT"); + tempTzMap.put("Romance", "Europe/Paris"); + tempTzMap.put("Romance Standard Time", "Europe/Paris"); + tempTzMap.put("Warsaw", "Europe/Warsaw"); + tempTzMap.put("Central Europe", "Europe/Prague"); + tempTzMap.put("Central Europe Standard Time", "Europe/Prague"); + tempTzMap.put("Prague Bratislava", "Europe/Prague"); + tempTzMap.put("W. Central Africa Standard Time", "Africa/Luanda"); + tempTzMap.put("FLE", "Europe/Helsinki"); + tempTzMap.put("FLE Standard Time", "Europe/Helsinki"); + tempTzMap.put("GFT", "Europe/Athens"); + tempTzMap.put("GFT Standard Time", "Europe/Athens"); + tempTzMap.put("GTB", "Europe/Athens"); + tempTzMap.put("GTB Standard Time", "Europe/Athens"); + tempTzMap.put("Israel", "Asia/Jerusalem"); + tempTzMap.put("Israel Standard Time", "Asia/Jerusalem"); + tempTzMap.put("Arab", "Asia/Riyadh"); + tempTzMap.put("Arab Standard Time", "Asia/Riyadh"); + tempTzMap.put("Arabic Standard Time", "Asia/Baghdad"); + tempTzMap.put("E. Africa", "Africa/Nairobi"); + tempTzMap.put("E. Africa Standard Time", "Africa/Nairobi"); + tempTzMap.put("Saudi Arabia", "Asia/Riyadh"); + tempTzMap.put("Saudi Arabia Standard Time", "Asia/Riyadh"); + tempTzMap.put("Iran", "Asia/Tehran"); + tempTzMap.put("Iran Standard Time", "Asia/Tehran"); + tempTzMap.put("Afghanistan", "Asia/Kabul"); + tempTzMap.put("Afghanistan Standard Time", "Asia/Kabul"); + tempTzMap.put("India", "Asia/Calcutta"); + tempTzMap.put("India Standard Time", "Asia/Calcutta"); + tempTzMap.put("Myanmar Standard Time", "Asia/Rangoon"); + tempTzMap.put("Nepal Standard Time", "Asia/Katmandu"); + tempTzMap.put("Sri Lanka", "Asia/Colombo"); + tempTzMap.put("Sri Lanka Standard Time", "Asia/Colombo"); + tempTzMap.put("Beijing", "Asia/Shanghai"); + tempTzMap.put("China", "Asia/Shanghai"); + tempTzMap.put("China Standard Time", "Asia/Shanghai"); + tempTzMap.put("AUS Central", "Australia/Darwin"); + tempTzMap.put("AUS Central Standard Time", "Australia/Darwin"); + tempTzMap.put("Cen. Australia", "Australia/Adelaide"); + tempTzMap.put("Cen. Australia Standard Time", "Australia/Adelaide"); + tempTzMap.put("Vladivostok", "Asia/Vladivostok"); + tempTzMap.put("Vladivostok Standard Time", "Asia/Vladivostok"); + tempTzMap.put("West Pacific", "Pacific/Guam"); + tempTzMap.put("West Pacific Standard Time", "Pacific/Guam"); + tempTzMap.put("E. South America", "America/Sao_Paulo"); + tempTzMap.put("E. South America Standard Time", "America/Sao_Paulo"); + tempTzMap.put("Greenland Standard Time", "America/Godthab"); + tempTzMap.put("Newfoundland", "America/St_Johns"); + tempTzMap.put("Newfoundland Standard Time", "America/St_Johns"); + tempTzMap.put("Pacific SA", "America/Caracas"); + tempTzMap.put("Pacific SA Standard Time", "America/Caracas"); + tempTzMap.put("SA Western", "America/Caracas"); + tempTzMap.put("SA Western Standard Time", "America/Caracas"); + tempTzMap.put("SA Pacific", "America/Bogota"); + tempTzMap.put("SA Pacific Standard Time", "America/Bogota"); + tempTzMap.put("US Eastern", "America/Indianapolis"); + tempTzMap.put("US Eastern Standard Time", "America/Indianapolis"); + tempTzMap.put("Central America Standard Time", "America/Regina"); + tempTzMap.put("Mexico", "America/Mexico_City"); + tempTzMap.put("Mexico Standard Time", "America/Mexico_City"); + tempTzMap.put("Canada Central", "America/Regina"); + tempTzMap.put("Canada Central Standard Time", "America/Regina"); + tempTzMap.put("US Mountain", "America/Phoenix"); + tempTzMap.put("US Mountain Standard Time", "America/Phoenix"); + tempTzMap.put("GMT", "GMT"); + tempTzMap.put("Ekaterinburg", "Asia/Yekaterinburg"); + tempTzMap.put("Ekaterinburg Standard Time", "Asia/Yekaterinburg"); + tempTzMap.put("West Asia", "Asia/Karachi"); + tempTzMap.put("West Asia Standard Time", "Asia/Karachi"); + tempTzMap.put("Central Asia", "Asia/Dhaka"); + tempTzMap.put("Central Asia Standard Time", "Asia/Dhaka"); + tempTzMap.put("N. Central Asia Standard Time", "Asia/Novosibirsk"); + tempTzMap.put("Bangkok", "Asia/Bangkok"); + tempTzMap.put("Bangkok Standard Time", "Asia/Bangkok"); + tempTzMap.put("North Asia Standard Time", "Asia/Krasnoyarsk"); + tempTzMap.put("SE Asia", "Asia/Bangkok"); + tempTzMap.put("SE Asia Standard Time", "Asia/Bangkok"); + tempTzMap.put("North Asia East Standard Time", "Asia/Ulaanbaatar"); + tempTzMap.put("Singapore", "Asia/Singapore"); + tempTzMap.put("Singapore Standard Time", "Asia/Singapore"); + tempTzMap.put("Taipei", "Asia/Taipei"); + tempTzMap.put("Taipei Standard Time", "Asia/Taipei"); + tempTzMap.put("W. Australia", "Australia/Perth"); + tempTzMap.put("W. Australia Standard Time", "Australia/Perth"); + tempTzMap.put("Korea", "Asia/Seoul"); + tempTzMap.put("Korea Standard Time", "Asia/Seoul"); + tempTzMap.put("Tokyo", "Asia/Tokyo"); + tempTzMap.put("Tokyo Standard Time", "Asia/Tokyo"); + tempTzMap.put("Yakutsk", "Asia/Yakutsk"); + tempTzMap.put("Yakutsk Standard Time", "Asia/Yakutsk"); + tempTzMap.put("Central European", "Europe/Belgrade"); + tempTzMap.put("Central European Standard Time", "Europe/Belgrade"); + tempTzMap.put("W. Europe", "Europe/Berlin"); + tempTzMap.put("W. Europe Standard Time", "Europe/Berlin"); + tempTzMap.put("Tasmania", "Australia/Hobart"); + tempTzMap.put("Tasmania Standard Time", "Australia/Hobart"); + tempTzMap.put("AUS Eastern", "Australia/Sydney"); + tempTzMap.put("AUS Eastern Standard Time", "Australia/Sydney"); + tempTzMap.put("E. Australia", "Australia/Brisbane"); + tempTzMap.put("E. Australia Standard Time", "Australia/Brisbane"); + tempTzMap.put("Sydney Standard Time", "Australia/Sydney"); + tempTzMap.put("Central Pacific", "Pacific/Guadalcanal"); + tempTzMap.put("Central Pacific Standard Time", "Pacific/Guadalcanal"); + tempTzMap.put("Dateline", "Pacific/Majuro"); + tempTzMap.put("Dateline Standard Time", "Pacific/Majuro"); + tempTzMap.put("Fiji", "Pacific/Fiji"); + tempTzMap.put("Fiji Standard Time", "Pacific/Fiji"); + tempTzMap.put("Samoa", "Pacific/Apia"); + tempTzMap.put("Samoa Standard Time", "Pacific/Apia"); + tempTzMap.put("Hawaiian", "Pacific/Honolulu"); + tempTzMap.put("Hawaiian Standard Time", "Pacific/Honolulu"); + tempTzMap.put("Alaskan", "America/Anchorage"); + tempTzMap.put("Alaskan Standard Time", "America/Anchorage"); + tempTzMap.put("Pacific", "America/Los_Angeles"); + tempTzMap.put("Pacific Standard Time", "America/Los_Angeles"); + tempTzMap.put("Mexico Standard Time 2", "America/Chihuahua"); + tempTzMap.put("Mountain", "America/Denver"); + tempTzMap.put("Mountain Standard Time", "America/Denver"); + tempTzMap.put("Central", "America/Chicago"); + tempTzMap.put("Central Standard Time", "America/Chicago"); + tempTzMap.put("Eastern", "America/New_York"); + tempTzMap.put("Eastern Standard Time", "America/New_York"); + tempTzMap.put("E. Europe", "Europe/Bucharest"); + tempTzMap.put("E. Europe Standard Time", "Europe/Bucharest"); + tempTzMap.put("Egypt", "Africa/Cairo"); + tempTzMap.put("Egypt Standard Time", "Africa/Cairo"); + tempTzMap.put("South Africa", "Africa/Harare"); + tempTzMap.put("South Africa Standard Time", "Africa/Harare"); + tempTzMap.put("Atlantic", "America/Halifax"); + tempTzMap.put("Atlantic Standard Time", "America/Halifax"); + tempTzMap.put("SA Eastern", "America/Buenos_Aires"); + tempTzMap.put("SA Eastern Standard Time", "America/Buenos_Aires"); + tempTzMap.put("Mid-Atlantic", "Atlantic/South_Georgia"); + tempTzMap.put("Mid-Atlantic Standard Time", "Atlantic/South_Georgia"); + tempTzMap.put("Azores", "Atlantic/Azores"); + tempTzMap.put("Azores Standard Time", "Atlantic/Azores"); + tempTzMap.put("Cape Verde Standard Time", "Atlantic/Cape_Verde"); + tempTzMap.put("Russian", "Europe/Moscow"); + tempTzMap.put("Russian Standard Time", "Europe/Moscow"); + tempTzMap.put("New Zealand", "Pacific/Auckland"); + tempTzMap.put("New Zealand Standard Time", "Pacific/Auckland"); + tempTzMap.put("Tonga Standard Time", "Pacific/Tongatapu"); + tempTzMap.put("Arabian", "Asia/Muscat"); + tempTzMap.put("Arabian Standard Time", "Asia/Muscat"); + tempTzMap.put("Caucasus", "Asia/Tbilisi"); + tempTzMap.put("Caucasus Standard Time", "Asia/Tbilisi"); + tempTzMap.put("GMT Standard Time", "GMT"); + tempTzMap.put("Greenwich", "GMT"); + tempTzMap.put("Greenwich Standard Time", "GMT"); + tempTzMap.put("UTC", "GMT"); - TIMEZONE_MAPPINGS = Collections.unmodifiableMap(tempMap); + // MySQL understands the Continent/City/region as well + Iterator> entries = tempTzMap.entrySet().iterator(); + Map entryMap = new HashMap(tempTzMap.size()); // to avoid ConcurrentModificationException + + while (entries.hasNext()) { + String name = entries.next().getValue(); + entryMap.put(name, name); + } + + tempTzMap.putAll(entryMap); + + TIMEZONE_MAPPINGS = Collections.unmodifiableMap(tempTzMap); // // Handle abbreviated mappings // - tempMap = new HashMap(); + HashMap tempAbbrMap = new HashMap(); - tempMap.put("ACST", new String[] { "America/Porto_Acre" }); - tempMap.put("ACT", new String[] { "America/Porto_Acre" }); - tempMap.put("ADDT", new String[] { "America/Pangnirtung" }); - tempMap.put("ADMT", new String[] { "Africa/Asmera", + tempAbbrMap.put("ACST", new String[] { "America/Porto_Acre" }); + tempAbbrMap.put("ACT", new String[] { "America/Porto_Acre" }); + tempAbbrMap.put("ADDT", new String[] { "America/Pangnirtung" }); + tempAbbrMap.put("ADMT", new String[] { "Africa/Asmera", "Africa/Addis_Ababa" }); - tempMap.put("ADT", new String[] { "Atlantic/Bermuda", "Asia/Baghdad", + tempAbbrMap.put("ADT", new String[] { "Atlantic/Bermuda", "Asia/Baghdad", "America/Thule", "America/Goose_Bay", "America/Halifax", "America/Glace_Bay", "America/Pangnirtung", "America/Barbados", "America/Martinique" }); - tempMap.put("AFT", new String[] { "Asia/Kabul" }); - tempMap.put("AHDT", new String[] { "America/Anchorage" }); - tempMap.put("AHST", new String[] { "America/Anchorage" }); - tempMap.put("AHWT", new String[] { "America/Anchorage" }); - tempMap.put("AKDT", new String[] { "America/Juneau", "America/Yakutat", + tempAbbrMap.put("AFT", new String[] { "Asia/Kabul" }); + tempAbbrMap.put("AHDT", new String[] { "America/Anchorage" }); + tempAbbrMap.put("AHST", new String[] { "America/Anchorage" }); + tempAbbrMap.put("AHWT", new String[] { "America/Anchorage" }); + tempAbbrMap.put("AKDT", new String[] { "America/Juneau", "America/Yakutat", "America/Anchorage", "America/Nome" }); - tempMap.put("AKST", new String[] { "Asia/Aqtobe", "America/Juneau", + tempAbbrMap.put("AKST", new String[] { "Asia/Aqtobe", "America/Juneau", "America/Yakutat", "America/Anchorage", "America/Nome" }); - tempMap.put("AKT", new String[] { "Asia/Aqtobe" }); - tempMap.put("AKTST", new String[] { "Asia/Aqtobe" }); - tempMap.put("AKWT", new String[] { "America/Juneau", "America/Yakutat", + tempAbbrMap.put("AKT", new String[] { "Asia/Aqtobe" }); + tempAbbrMap.put("AKTST", new String[] { "Asia/Aqtobe" }); + tempAbbrMap.put("AKWT", new String[] { "America/Juneau", "America/Yakutat", "America/Anchorage", "America/Nome" }); - tempMap.put("ALMST", new String[] { "Asia/Almaty" }); - tempMap.put("ALMT", new String[] { "Asia/Almaty" }); - tempMap.put("AMST", new String[] { "Asia/Yerevan", "America/Cuiaba", + tempAbbrMap.put("ALMST", new String[] { "Asia/Almaty" }); + tempAbbrMap.put("ALMT", new String[] { "Asia/Almaty" }); + tempAbbrMap.put("AMST", new String[] { "Asia/Yerevan", "America/Cuiaba", "America/Porto_Velho", "America/Boa_Vista", "America/Manaus" }); - tempMap.put("AMT", new String[] { "Europe/Athens", "Europe/Amsterdam", + tempAbbrMap.put("AMT", new String[] { "Europe/Athens", "Europe/Amsterdam", "Asia/Yerevan", "Africa/Asmera", "America/Cuiaba", "America/Porto_Velho", "America/Boa_Vista", "America/Manaus", "America/Asuncion" }); - tempMap.put("ANAMT", new String[] { "Asia/Anadyr" }); - tempMap.put("ANAST", new String[] { "Asia/Anadyr" }); - tempMap.put("ANAT", new String[] { "Asia/Anadyr" }); - tempMap.put("ANT", new String[] { "America/Aruba", "America/Curacao" }); - tempMap.put("AQTST", new String[] { "Asia/Aqtobe", "Asia/Aqtau" }); - tempMap.put("AQTT", new String[] { "Asia/Aqtobe", "Asia/Aqtau" }); - tempMap.put("ARST", new String[] { "Antarctica/Palmer", + tempAbbrMap.put("ANAMT", new String[] { "Asia/Anadyr" }); + tempAbbrMap.put("ANAST", new String[] { "Asia/Anadyr" }); + tempAbbrMap.put("ANAT", new String[] { "Asia/Anadyr" }); + tempAbbrMap.put("ANT", new String[] { "America/Aruba", "America/Curacao" }); + tempAbbrMap.put("AQTST", new String[] { "Asia/Aqtobe", "Asia/Aqtau" }); + tempAbbrMap.put("AQTT", new String[] { "Asia/Aqtobe", "Asia/Aqtau" }); + tempAbbrMap.put("ARST", new String[] { "Antarctica/Palmer", "America/Buenos_Aires", "America/Rosario", "America/Cordoba", "America/Jujuy", "America/Catamarca", "America/Mendoza" }); - tempMap.put("ART", new String[] { "Antarctica/Palmer", + tempAbbrMap.put("ART", new String[] { "Antarctica/Palmer", "America/Buenos_Aires", "America/Rosario", "America/Cordoba", "America/Jujuy", "America/Catamarca", "America/Mendoza" }); - tempMap.put("ASHST", new String[] { "Asia/Ashkhabad" }); - tempMap.put("ASHT", new String[] { "Asia/Ashkhabad" }); - tempMap.put("AST", new String[] { "Atlantic/Bermuda", "Asia/Bahrain", + tempAbbrMap.put("ASHST", new String[] { "Asia/Ashkhabad" }); + tempAbbrMap.put("ASHT", new String[] { "Asia/Ashkhabad" }); + tempAbbrMap.put("AST", new String[] { "Atlantic/Bermuda", "Asia/Bahrain", "Asia/Baghdad", "Asia/Kuwait", "Asia/Qatar", "Asia/Riyadh", "Asia/Aden", "America/Thule", "America/Goose_Bay", "America/Halifax", "America/Glace_Bay", "America/Pangnirtung", @@ -267,51 +275,51 @@ "America/St_Kitts", "America/St_Lucia", "America/Miquelon", "America/St_Vincent", "America/Tortola", "America/St_Thomas", "America/Aruba", "America/Curacao", "America/Port_of_Spain" }); - tempMap.put("AWT", new String[] { "America/Puerto_Rico" }); - tempMap.put("AZOST", new String[] { "Atlantic/Azores" }); - tempMap.put("AZOT", new String[] { "Atlantic/Azores" }); - tempMap.put("AZST", new String[] { "Asia/Baku" }); - tempMap.put("AZT", new String[] { "Asia/Baku" }); - tempMap.put("BAKST", new String[] { "Asia/Baku" }); - tempMap.put("BAKT", new String[] { "Asia/Baku" }); - tempMap.put("BDT", new String[] { "Asia/Dacca", "America/Nome", + tempAbbrMap.put("AWT", new String[] { "America/Puerto_Rico" }); + tempAbbrMap.put("AZOST", new String[] { "Atlantic/Azores" }); + tempAbbrMap.put("AZOT", new String[] { "Atlantic/Azores" }); + tempAbbrMap.put("AZST", new String[] { "Asia/Baku" }); + tempAbbrMap.put("AZT", new String[] { "Asia/Baku" }); + tempAbbrMap.put("BAKST", new String[] { "Asia/Baku" }); + tempAbbrMap.put("BAKT", new String[] { "Asia/Baku" }); + tempAbbrMap.put("BDT", new String[] { "Asia/Dacca", "America/Nome", "America/Adak" }); - tempMap.put("BEAT", new String[] { "Africa/Nairobi", + tempAbbrMap.put("BEAT", new String[] { "Africa/Nairobi", "Africa/Mogadishu", "Africa/Kampala" }); - tempMap.put("BEAUT", new String[] { "Africa/Nairobi", + tempAbbrMap.put("BEAUT", new String[] { "Africa/Nairobi", "Africa/Dar_es_Salaam", "Africa/Kampala" }); - tempMap.put("BMT", new String[] { "Europe/Brussels", "Europe/Chisinau", + tempAbbrMap.put("BMT", new String[] { "Europe/Brussels", "Europe/Chisinau", "Europe/Tiraspol", "Europe/Bucharest", "Europe/Zurich", "Asia/Baghdad", "Asia/Bangkok", "Africa/Banjul", "America/Barbados", "America/Bogota" }); - tempMap.put("BNT", new String[] { "Asia/Brunei" }); - tempMap.put("BORT", + tempAbbrMap.put("BNT", new String[] { "Asia/Brunei" }); + tempAbbrMap.put("BORT", new String[] { "Asia/Ujung_Pandang", "Asia/Kuching" }); - tempMap.put("BOST", new String[] { "America/La_Paz" }); - tempMap.put("BOT", new String[] { "America/La_Paz" }); - tempMap.put("BRST", new String[] { "America/Belem", + tempAbbrMap.put("BOST", new String[] { "America/La_Paz" }); + tempAbbrMap.put("BOT", new String[] { "America/La_Paz" }); + tempAbbrMap.put("BRST", new String[] { "America/Belem", "America/Fortaleza", "America/Araguaina", "America/Maceio", "America/Sao_Paulo" }); - tempMap.put("BRT", new String[] { "America/Belem", "America/Fortaleza", + tempAbbrMap.put("BRT", new String[] { "America/Belem", "America/Fortaleza", "America/Araguaina", "America/Maceio", "America/Sao_Paulo" }); - tempMap.put("BST", new String[] { "Europe/London", "Europe/Belfast", + tempAbbrMap.put("BST", new String[] { "Europe/London", "Europe/Belfast", "Europe/Dublin", "Europe/Gibraltar", "Pacific/Pago_Pago", "Pacific/Midway", "America/Nome", "America/Adak" }); - tempMap.put("BTT", new String[] { "Asia/Thimbu" }); - tempMap.put("BURT", new String[] { "Asia/Dacca", "Asia/Rangoon", + tempAbbrMap.put("BTT", new String[] { "Asia/Thimbu" }); + tempAbbrMap.put("BURT", new String[] { "Asia/Dacca", "Asia/Rangoon", "Asia/Calcutta" }); - tempMap.put("BWT", new String[] { "America/Nome", "America/Adak" }); - tempMap.put("CANT", new String[] { "Atlantic/Canary" }); - tempMap.put("CAST", + tempAbbrMap.put("BWT", new String[] { "America/Nome", "America/Adak" }); + tempAbbrMap.put("CANT", new String[] { "Atlantic/Canary" }); + tempAbbrMap.put("CAST", new String[] { "Africa/Gaborone", "Africa/Khartoum" }); - tempMap.put("CAT", new String[] { "Africa/Gaborone", + tempAbbrMap.put("CAT", new String[] { "Africa/Gaborone", "Africa/Bujumbura", "Africa/Lubumbashi", "Africa/Blantyre", "Africa/Maputo", "Africa/Windhoek", "Africa/Kigali", "Africa/Khartoum", "Africa/Lusaka", "Africa/Harare", "America/Anchorage" }); - tempMap.put("CCT", new String[] { "Indian/Cocos" }); - tempMap.put("CDDT", new String[] { "America/Rankin_Inlet" }); - tempMap.put("CDT", new String[] { "Asia/Harbin", "Asia/Shanghai", + tempAbbrMap.put("CCT", new String[] { "Indian/Cocos" }); + tempAbbrMap.put("CDDT", new String[] { "America/Rankin_Inlet" }); + tempAbbrMap.put("CDT", new String[] { "Asia/Harbin", "Asia/Shanghai", "Asia/Chungking", "Asia/Urumqi", "Asia/Kashgar", "Asia/Taipei", "Asia/Macao", "America/Chicago", "America/Indianapolis", "America/Indiana/Marengo", "America/Indiana/Knox", @@ -323,7 +331,7 @@ "America/Belize", "America/Costa_Rica", "America/Havana", "America/El_Salvador", "America/Guatemala", "America/Tegucigalpa", "America/Managua" }); - tempMap.put("CEST", new String[] { "Europe/Tirane", "Europe/Andorra", + tempAbbrMap.put("CEST", new String[] { "Europe/Tirane", "Europe/Andorra", "Europe/Vienna", "Europe/Minsk", "Europe/Brussels", "Europe/Sofia", "Europe/Prague", "Europe/Copenhagen", "Europe/Tallinn", "Europe/Berlin", "Europe/Gibraltar", @@ -337,7 +345,7 @@ "Europe/Zaporozhye", "Europe/Simferopol", "Europe/Belgrade", "Africa/Algiers", "Africa/Tripoli", "Africa/Tunis", "Africa/Ceuta" }); - tempMap.put("CET", new String[] { "Europe/Tirane", "Europe/Andorra", + tempAbbrMap.put("CET", new String[] { "Europe/Tirane", "Europe/Andorra", "Europe/Vienna", "Europe/Minsk", "Europe/Brussels", "Europe/Sofia", "Europe/Prague", "Europe/Copenhagen", "Europe/Tallinn", "Europe/Berlin", "Europe/Gibraltar", @@ -351,25 +359,25 @@ "Europe/Zaporozhye", "Europe/Simferopol", "Europe/Belgrade", "Africa/Algiers", "Africa/Tripoli", "Africa/Casablanca", "Africa/Tunis", "Africa/Ceuta" }); - tempMap.put("CGST", new String[] { "America/Scoresbysund" }); - tempMap.put("CGT", new String[] { "America/Scoresbysund" }); - tempMap.put("CHDT", new String[] { "America/Belize" }); - tempMap.put("CHUT", new String[] { "Asia/Chungking" }); - tempMap.put("CJT", new String[] { "Asia/Tokyo" }); - tempMap.put("CKHST", new String[] { "Pacific/Rarotonga" }); - tempMap.put("CKT", new String[] { "Pacific/Rarotonga" }); - tempMap.put("CLST", new String[] { "Antarctica/Palmer", + tempAbbrMap.put("CGST", new String[] { "America/Scoresbysund" }); + tempAbbrMap.put("CGT", new String[] { "America/Scoresbysund" }); + tempAbbrMap.put("CHDT", new String[] { "America/Belize" }); + tempAbbrMap.put("CHUT", new String[] { "Asia/Chungking" }); + tempAbbrMap.put("CJT", new String[] { "Asia/Tokyo" }); + tempAbbrMap.put("CKHST", new String[] { "Pacific/Rarotonga" }); + tempAbbrMap.put("CKT", new String[] { "Pacific/Rarotonga" }); + tempAbbrMap.put("CLST", new String[] { "Antarctica/Palmer", "America/Santiago" }); - tempMap.put("CLT", new String[] { "Antarctica/Palmer", + tempAbbrMap.put("CLT", new String[] { "Antarctica/Palmer", "America/Santiago" }); - tempMap.put("CMT", new String[] { "Europe/Copenhagen", + tempAbbrMap.put("CMT", new String[] { "Europe/Copenhagen", "Europe/Chisinau", "Europe/Tiraspol", "America/St_Lucia", "America/Buenos_Aires", "America/Rosario", "America/Cordoba", "America/Jujuy", "America/Catamarca", "America/Mendoza", "America/Caracas" }); - tempMap.put("COST", new String[] { "America/Bogota" }); - tempMap.put("COT", new String[] { "America/Bogota" }); - tempMap + tempAbbrMap.put("COST", new String[] { "America/Bogota" }); + tempAbbrMap.put("COT", new String[] { "America/Bogota" }); + tempAbbrMap .put("CST", new String[] { "Asia/Harbin", "Asia/Shanghai", "Asia/Chungking", "Asia/Urumqi", "Asia/Kashgar", "Asia/Taipei", "Asia/Macao", "Asia/Jayapura", @@ -389,51 +397,51 @@ "America/Havana", "America/El_Salvador", "America/Guatemala", "America/Tegucigalpa", "America/Managua" }); - tempMap.put("CUT", new String[] { "Europe/Zaporozhye" }); - tempMap.put("CVST", new String[] { "Atlantic/Cape_Verde" }); - tempMap.put("CVT", new String[] { "Atlantic/Cape_Verde" }); - tempMap.put("CWT", new String[] { "America/Chicago", + tempAbbrMap.put("CUT", new String[] { "Europe/Zaporozhye" }); + tempAbbrMap.put("CVST", new String[] { "Atlantic/Cape_Verde" }); + tempAbbrMap.put("CVT", new String[] { "Atlantic/Cape_Verde" }); + tempAbbrMap.put("CWT", new String[] { "America/Chicago", "America/Indianapolis", "America/Indiana/Marengo", "America/Indiana/Knox", "America/Indiana/Vevay", "America/Louisville", "America/Menominee" }); - tempMap.put("CXT", new String[] { "Indian/Christmas" }); - tempMap.put("DACT", new String[] { "Asia/Dacca" }); - tempMap.put("DAVT", new String[] { "Antarctica/Davis" }); - tempMap.put("DDUT", new String[] { "Antarctica/DumontDUrville" }); - tempMap.put("DFT", new String[] { "Europe/Oslo", "Europe/Paris" }); - tempMap.put("DMT", new String[] { "Europe/Belfast", "Europe/Dublin" }); - tempMap.put("DUSST", new String[] { "Asia/Dushanbe" }); - tempMap.put("DUST", new String[] { "Asia/Dushanbe" }); - tempMap.put("EASST", new String[] { "Pacific/Easter" }); - tempMap.put("EAST", new String[] { "Indian/Antananarivo", + tempAbbrMap.put("CXT", new String[] { "Indian/Christmas" }); + tempAbbrMap.put("DACT", new String[] { "Asia/Dacca" }); + tempAbbrMap.put("DAVT", new String[] { "Antarctica/Davis" }); + tempAbbrMap.put("DDUT", new String[] { "Antarctica/DumontDUrville" }); + tempAbbrMap.put("DFT", new String[] { "Europe/Oslo", "Europe/Paris" }); + tempAbbrMap.put("DMT", new String[] { "Europe/Belfast", "Europe/Dublin" }); + tempAbbrMap.put("DUSST", new String[] { "Asia/Dushanbe" }); + tempAbbrMap.put("DUST", new String[] { "Asia/Dushanbe" }); + tempAbbrMap.put("EASST", new String[] { "Pacific/Easter" }); + tempAbbrMap.put("EAST", new String[] { "Indian/Antananarivo", "Pacific/Easter" }); - tempMap.put("EAT", new String[] { "Indian/Comoro", + tempAbbrMap.put("EAT", new String[] { "Indian/Comoro", "Indian/Antananarivo", "Indian/Mayotte", "Africa/Djibouti", "Africa/Asmera", "Africa/Addis_Ababa", "Africa/Nairobi", "Africa/Mogadishu", "Africa/Khartoum", "Africa/Dar_es_Salaam", "Africa/Kampala" }); - tempMap.put("ECT", new String[] { "Pacific/Galapagos", + tempAbbrMap.put("ECT", new String[] { "Pacific/Galapagos", "America/Guayaquil" }); - tempMap.put("EDDT", new String[] { "America/Iqaluit" }); - tempMap.put("EDT", new String[] { "America/New_York", + tempAbbrMap.put("EDDT", new String[] { "America/Iqaluit" }); + tempAbbrMap.put("EDT", new String[] { "America/New_York", "America/Indianapolis", "America/Indiana/Marengo", "America/Indiana/Vevay", "America/Louisville", "America/Detroit", "America/Montreal", "America/Thunder_Bay", "America/Nipigon", "America/Pangnirtung", "America/Iqaluit", "America/Cancun", "America/Nassau", "America/Santo_Domingo", "America/Port-au-Prince", "America/Jamaica", "America/Grand_Turk" }); - tempMap.put("EEMT", new String[] { "Europe/Minsk", "Europe/Chisinau", + tempAbbrMap.put("EEMT", new String[] { "Europe/Minsk", "Europe/Chisinau", "Europe/Tiraspol", "Europe/Kaliningrad", "Europe/Moscow" }); - tempMap.put("EEST", new String[] { "Europe/Minsk", "Europe/Sofia", + tempAbbrMap.put("EEST", new String[] { "Europe/Minsk", "Europe/Sofia", "Europe/Tallinn", "Europe/Helsinki", "Europe/Athens", "Europe/Riga", "Europe/Vilnius", "Europe/Chisinau", "Europe/Tiraspol", "Europe/Warsaw", "Europe/Bucharest", "Europe/Kaliningrad", "Europe/Moscow", "Europe/Istanbul", "Europe/Kiev", "Europe/Uzhgorod", "Europe/Zaporozhye", "Asia/Nicosia", "Asia/Amman", "Asia/Beirut", "Asia/Gaza", "Asia/Damascus", "Africa/Cairo" }); - tempMap.put("EET", new String[] { "Europe/Minsk", "Europe/Sofia", + tempAbbrMap.put("EET", new String[] { "Europe/Minsk", "Europe/Sofia", "Europe/Tallinn", "Europe/Helsinki", "Europe/Athens", "Europe/Riga", "Europe/Vilnius", "Europe/Chisinau", "Europe/Tiraspol", "Europe/Warsaw", "Europe/Bucharest", @@ -442,11 +450,11 @@ "Europe/Simferopol", "Asia/Nicosia", "Asia/Amman", "Asia/Beirut", "Asia/Gaza", "Asia/Damascus", "Africa/Cairo", "Africa/Tripoli" }); - tempMap.put("EGST", new String[] { "America/Scoresbysund" }); - tempMap.put("EGT", new String[] { "Atlantic/Jan_Mayen", + tempAbbrMap.put("EGST", new String[] { "America/Scoresbysund" }); + tempAbbrMap.put("EGT", new String[] { "Atlantic/Jan_Mayen", "America/Scoresbysund" }); - tempMap.put("EHDT", new String[] { "America/Santo_Domingo" }); - tempMap.put("EST", new String[] { "Australia/Brisbane", + tempAbbrMap.put("EHDT", new String[] { "America/Santo_Domingo" }); + tempAbbrMap.put("EST", new String[] { "Australia/Brisbane", "Australia/Lindeman", "Australia/Hobart", "Australia/Melbourne", "Australia/Sydney", "Australia/Broken_Hill", "Australia/Lord_Howe", @@ -460,30 +468,30 @@ "America/Santo_Domingo", "America/Port-au-Prince", "America/Jamaica", "America/Managua", "America/Panama", "America/Grand_Turk" }); - tempMap.put("EWT", new String[] { "America/New_York", + tempAbbrMap.put("EWT", new String[] { "America/New_York", "America/Indianapolis", "America/Indiana/Marengo", "America/Indiana/Vevay", "America/Louisville", "America/Detroit", "America/Jamaica" }); - tempMap.put("FFMT", new String[] { "America/Martinique" }); - tempMap.put("FJST", new String[] { "Pacific/Fiji" }); - tempMap.put("FJT", new String[] { "Pacific/Fiji" }); - tempMap.put("FKST", new String[] { "Atlantic/Stanley" }); - tempMap.put("FKT", new String[] { "Atlantic/Stanley" }); - tempMap.put("FMT", + tempAbbrMap.put("FFMT", new String[] { "America/Martinique" }); + tempAbbrMap.put("FJST", new String[] { "Pacific/Fiji" }); + tempAbbrMap.put("FJT", new String[] { "Pacific/Fiji" }); + tempAbbrMap.put("FKST", new String[] { "Atlantic/Stanley" }); + tempAbbrMap.put("FKT", new String[] { "Atlantic/Stanley" }); + tempAbbrMap.put("FMT", new String[] { "Atlantic/Madeira", "Africa/Freetown" }); - tempMap.put("FNST", new String[] { "America/Noronha" }); - tempMap.put("FNT", new String[] { "America/Noronha" }); - tempMap.put("FRUST", new String[] { "Asia/Bishkek" }); - tempMap.put("FRUT", new String[] { "Asia/Bishkek" }); - tempMap.put("GALT", new String[] { "Pacific/Galapagos" }); - tempMap.put("GAMT", new String[] { "Pacific/Gambier" }); - tempMap.put("GBGT", new String[] { "America/Guyana" }); - tempMap.put("GEST", new String[] { "Asia/Tbilisi" }); - tempMap.put("GET", new String[] { "Asia/Tbilisi" }); - tempMap.put("GFT", new String[] { "America/Cayenne" }); - tempMap.put("GHST", new String[] { "Africa/Accra" }); - tempMap.put("GILT", new String[] { "Pacific/Tarawa" }); - tempMap.put("GMT", new String[] { "Atlantic/St_Helena", + tempAbbrMap.put("FNST", new String[] { "America/Noronha" }); + tempAbbrMap.put("FNT", new String[] { "America/Noronha" }); + tempAbbrMap.put("FRUST", new String[] { "Asia/Bishkek" }); + tempAbbrMap.put("FRUT", new String[] { "Asia/Bishkek" }); + tempAbbrMap.put("GALT", new String[] { "Pacific/Galapagos" }); + tempAbbrMap.put("GAMT", new String[] { "Pacific/Gambier" }); + tempAbbrMap.put("GBGT", new String[] { "America/Guyana" }); + tempAbbrMap.put("GEST", new String[] { "Asia/Tbilisi" }); + tempAbbrMap.put("GET", new String[] { "Asia/Tbilisi" }); + tempAbbrMap.put("GFT", new String[] { "America/Cayenne" }); + tempAbbrMap.put("GHST", new String[] { "Africa/Accra" }); + tempAbbrMap.put("GILT", new String[] { "Pacific/Tarawa" }); + tempAbbrMap.put("GMT", new String[] { "Atlantic/St_Helena", "Atlantic/Reykjavik", "Europe/London", "Europe/Belfast", "Europe/Dublin", "Europe/Gibraltar", "Africa/Porto-Novo", "Africa/Ouagadougou", "Africa/Abidjan", "Africa/Malabo", @@ -492,90 +500,90 @@ "Africa/Timbuktu", "Africa/Nouakchott", "Africa/Niamey", "Africa/Sao_Tome", "Africa/Dakar", "Africa/Freetown", "Africa/Lome" }); - tempMap.put("GST", new String[] { "Atlantic/South_Georgia", + tempAbbrMap.put("GST", new String[] { "Atlantic/South_Georgia", "Asia/Bahrain", "Asia/Muscat", "Asia/Qatar", "Asia/Dubai", "Pacific/Guam" }); - tempMap.put("GYT", new String[] { "America/Guyana" }); - tempMap.put("HADT", new String[] { "America/Adak" }); - tempMap.put("HART", new String[] { "Asia/Harbin" }); - tempMap.put("HAST", new String[] { "America/Adak" }); - tempMap.put("HAWT", new String[] { "America/Adak" }); - tempMap.put("HDT", new String[] { "Pacific/Honolulu" }); - tempMap.put("HKST", new String[] { "Asia/Hong_Kong" }); - tempMap.put("HKT", new String[] { "Asia/Hong_Kong" }); - tempMap.put("HMT", new String[] { "Atlantic/Azores", "Europe/Helsinki", + tempAbbrMap.put("GYT", new String[] { "America/Guyana" }); + tempAbbrMap.put("HADT", new String[] { "America/Adak" }); + tempAbbrMap.put("HART", new String[] { "Asia/Harbin" }); + tempAbbrMap.put("HAST", new String[] { "America/Adak" }); + tempAbbrMap.put("HAWT", new String[] { "America/Adak" }); + tempAbbrMap.put("HDT", new String[] { "Pacific/Honolulu" }); + tempAbbrMap.put("HKST", new String[] { "Asia/Hong_Kong" }); + tempAbbrMap.put("HKT", new String[] { "Asia/Hong_Kong" }); + tempAbbrMap.put("HMT", new String[] { "Atlantic/Azores", "Europe/Helsinki", "Asia/Dacca", "Asia/Calcutta", "America/Havana" }); - tempMap.put("HOVST", new String[] { "Asia/Hovd" }); - tempMap.put("HOVT", new String[] { "Asia/Hovd" }); - tempMap.put("HST", new String[] { "Pacific/Johnston", + tempAbbrMap.put("HOVST", new String[] { "Asia/Hovd" }); + tempAbbrMap.put("HOVT", new String[] { "Asia/Hovd" }); + tempAbbrMap.put("HST", new String[] { "Pacific/Johnston", "Pacific/Honolulu" }); - tempMap.put("HWT", new String[] { "Pacific/Honolulu" }); - tempMap.put("ICT", new String[] { "Asia/Phnom_Penh", "Asia/Vientiane", + tempAbbrMap.put("HWT", new String[] { "Pacific/Honolulu" }); + tempAbbrMap.put("ICT", new String[] { "Asia/Phnom_Penh", "Asia/Vientiane", "Asia/Bangkok", "Asia/Saigon" }); - tempMap.put("IDDT", new String[] { "Asia/Jerusalem", "Asia/Gaza" }); - tempMap.put("IDT", new String[] { "Asia/Jerusalem", "Asia/Gaza" }); - tempMap.put("IHST", new String[] { "Asia/Colombo" }); - tempMap.put("IMT", new String[] { "Europe/Sofia", "Europe/Istanbul", + tempAbbrMap.put("IDDT", new String[] { "Asia/Jerusalem", "Asia/Gaza" }); + tempAbbrMap.put("IDT", new String[] { "Asia/Jerusalem", "Asia/Gaza" }); + tempAbbrMap.put("IHST", new String[] { "Asia/Colombo" }); + tempAbbrMap.put("IMT", new String[] { "Europe/Sofia", "Europe/Istanbul", "Asia/Irkutsk" }); - tempMap.put("IOT", new String[] { "Indian/Chagos" }); - tempMap.put("IRKMT", new String[] { "Asia/Irkutsk" }); - tempMap.put("IRKST", new String[] { "Asia/Irkutsk" }); - tempMap.put("IRKT", new String[] { "Asia/Irkutsk" }); - tempMap.put("IRST", new String[] { "Asia/Tehran" }); - tempMap.put("IRT", new String[] { "Asia/Tehran" }); - tempMap.put("ISST", new String[] { "Atlantic/Reykjavik" }); - tempMap.put("IST", new String[] { "Atlantic/Reykjavik", + tempAbbrMap.put("IOT", new String[] { "Indian/Chagos" }); + tempAbbrMap.put("IRKMT", new String[] { "Asia/Irkutsk" }); + tempAbbrMap.put("IRKST", new String[] { "Asia/Irkutsk" }); + tempAbbrMap.put("IRKT", new String[] { "Asia/Irkutsk" }); + tempAbbrMap.put("IRST", new String[] { "Asia/Tehran" }); + tempAbbrMap.put("IRT", new String[] { "Asia/Tehran" }); + tempAbbrMap.put("ISST", new String[] { "Atlantic/Reykjavik" }); + tempAbbrMap.put("IST", new String[] { "Atlantic/Reykjavik", "Europe/Belfast", "Europe/Dublin", "Asia/Dacca", "Asia/Thimbu", "Asia/Calcutta", "Asia/Jerusalem", "Asia/Katmandu", "Asia/Karachi", "Asia/Gaza", "Asia/Colombo" }); - tempMap.put("JAYT", new String[] { "Asia/Jayapura" }); - tempMap.put("JMT", new String[] { "Atlantic/St_Helena", + tempAbbrMap.put("JAYT", new String[] { "Asia/Jayapura" }); + tempAbbrMap.put("JMT", new String[] { "Atlantic/St_Helena", "Asia/Jerusalem" }); - tempMap.put("JST", new String[] { "Asia/Rangoon", "Asia/Dili", + tempAbbrMap.put("JST", new String[] { "Asia/Rangoon", "Asia/Dili", "Asia/Ujung_Pandang", "Asia/Tokyo", "Asia/Kuala_Lumpur", "Asia/Kuching", "Asia/Manila", "Asia/Singapore", "Pacific/Nauru" }); - tempMap.put("KART", new String[] { "Asia/Karachi" }); - tempMap.put("KAST", new String[] { "Asia/Kashgar" }); - tempMap.put("KDT", new String[] { "Asia/Seoul" }); - tempMap.put("KGST", new String[] { "Asia/Bishkek" }); - tempMap.put("KGT", new String[] { "Asia/Bishkek" }); - tempMap.put("KMT", new String[] { "Europe/Vilnius", "Europe/Kiev", + tempAbbrMap.put("KART", new String[] { "Asia/Karachi" }); + tempAbbrMap.put("KAST", new String[] { "Asia/Kashgar" }); + tempAbbrMap.put("KDT", new String[] { "Asia/Seoul" }); + tempAbbrMap.put("KGST", new String[] { "Asia/Bishkek" }); + tempAbbrMap.put("KGT", new String[] { "Asia/Bishkek" }); + tempAbbrMap.put("KMT", new String[] { "Europe/Vilnius", "Europe/Kiev", "America/Cayman", "America/Jamaica", "America/St_Vincent", "America/Grand_Turk" }); - tempMap.put("KOST", new String[] { "Pacific/Kosrae" }); - tempMap.put("KRAMT", new String[] { "Asia/Krasnoyarsk" }); - tempMap.put("KRAST", new String[] { "Asia/Krasnoyarsk" }); - tempMap.put("KRAT", new String[] { "Asia/Krasnoyarsk" }); - tempMap.put("KST", new String[] { "Asia/Seoul", "Asia/Pyongyang" }); - tempMap.put("KUYMT", new String[] { "Europe/Samara" }); - tempMap.put("KUYST", new String[] { "Europe/Samara" }); - tempMap.put("KUYT", new String[] { "Europe/Samara" }); - tempMap.put("KWAT", new String[] { "Pacific/Kwajalein" }); - tempMap.put("LHST", new String[] { "Australia/Lord_Howe" }); - tempMap.put("LINT", new String[] { "Pacific/Kiritimati" }); - tempMap.put("LKT", new String[] { "Asia/Colombo" }); - tempMap.put("LPMT", new String[] { "America/La_Paz" }); - tempMap.put("LRT", new String[] { "Africa/Monrovia" }); - tempMap.put("LST", new String[] { "Europe/Riga" }); - tempMap.put("M", new String[] { "Europe/Moscow" }); - tempMap.put("MADST", new String[] { "Atlantic/Madeira" }); - tempMap.put("MAGMT", new String[] { "Asia/Magadan" }); - tempMap.put("MAGST", new String[] { "Asia/Magadan" }); - tempMap.put("MAGT", new String[] { "Asia/Magadan" }); - tempMap.put("MALT", new String[] { "Asia/Kuala_Lumpur", + tempAbbrMap.put("KOST", new String[] { "Pacific/Kosrae" }); + tempAbbrMap.put("KRAMT", new String[] { "Asia/Krasnoyarsk" }); + tempAbbrMap.put("KRAST", new String[] { "Asia/Krasnoyarsk" }); + tempAbbrMap.put("KRAT", new String[] { "Asia/Krasnoyarsk" }); + tempAbbrMap.put("KST", new String[] { "Asia/Seoul", "Asia/Pyongyang" }); + tempAbbrMap.put("KUYMT", new String[] { "Europe/Samara" }); + tempAbbrMap.put("KUYST", new String[] { "Europe/Samara" }); + tempAbbrMap.put("KUYT", new String[] { "Europe/Samara" }); + tempAbbrMap.put("KWAT", new String[] { "Pacific/Kwajalein" }); + tempAbbrMap.put("LHST", new String[] { "Australia/Lord_Howe" }); + tempAbbrMap.put("LINT", new String[] { "Pacific/Kiritimati" }); + tempAbbrMap.put("LKT", new String[] { "Asia/Colombo" }); + tempAbbrMap.put("LPMT", new String[] { "America/La_Paz" }); + tempAbbrMap.put("LRT", new String[] { "Africa/Monrovia" }); + tempAbbrMap.put("LST", new String[] { "Europe/Riga" }); + tempAbbrMap.put("M", new String[] { "Europe/Moscow" }); + tempAbbrMap.put("MADST", new String[] { "Atlantic/Madeira" }); + tempAbbrMap.put("MAGMT", new String[] { "Asia/Magadan" }); + tempAbbrMap.put("MAGST", new String[] { "Asia/Magadan" }); + tempAbbrMap.put("MAGT", new String[] { "Asia/Magadan" }); + tempAbbrMap.put("MALT", new String[] { "Asia/Kuala_Lumpur", "Asia/Singapore" }); - tempMap.put("MART", new String[] { "Pacific/Marquesas" }); - tempMap.put("MAWT", new String[] { "Antarctica/Mawson" }); - tempMap.put("MDDT", new String[] { "America/Cambridge_Bay", + tempAbbrMap.put("MART", new String[] { "Pacific/Marquesas" }); + tempAbbrMap.put("MAWT", new String[] { "Antarctica/Mawson" }); + tempAbbrMap.put("MDDT", new String[] { "America/Cambridge_Bay", "America/Yellowknife", "America/Inuvik" }); - tempMap.put("MDST", new String[] { "Europe/Moscow" }); - tempMap.put("MDT", new String[] { "America/Denver", "America/Phoenix", + tempAbbrMap.put("MDST", new String[] { "Europe/Moscow" }); + tempAbbrMap.put("MDT", new String[] { "America/Denver", "America/Phoenix", "America/Boise", "America/Regina", "America/Swift_Current", "America/Edmonton", "America/Cambridge_Bay", "America/Yellowknife", "America/Inuvik", "America/Chihuahua", "America/Hermosillo", "America/Mazatlan" }); - tempMap.put("MET", new String[] { "Europe/Tirane", "Europe/Andorra", + tempAbbrMap.put("MEST", new String[] { "Europe/Tirane", "Europe/Andorra", "Europe/Vienna", "Europe/Minsk", "Europe/Brussels", "Europe/Sofia", "Europe/Prague", "Europe/Copenhagen", "Europe/Tallinn", "Europe/Berlin", "Europe/Gibraltar", @@ -587,212 +595,226 @@ "Europe/Kaliningrad", "Europe/Madrid", "Europe/Stockholm", "Europe/Zurich", "Europe/Kiev", "Europe/Uzhgorod", "Europe/Zaporozhye", "Europe/Simferopol", "Europe/Belgrade", + "Africa/Algiers", "Africa/Tripoli", "Africa/Tunis", + "Africa/Ceuta" }); + tempAbbrMap.put("MET", new String[] { "Europe/Tirane", "Europe/Andorra", + "Europe/Vienna", "Europe/Minsk", "Europe/Brussels", + "Europe/Sofia", "Europe/Prague", "Europe/Copenhagen", + "Europe/Tallinn", "Europe/Berlin", "Europe/Gibraltar", + "Europe/Athens", "Europe/Budapest", "Europe/Rome", + "Europe/Riga", "Europe/Vaduz", "Europe/Vilnius", + "Europe/Luxembourg", "Europe/Malta", "Europe/Chisinau", + "Europe/Tiraspol", "Europe/Monaco", "Europe/Amsterdam", + "Europe/Oslo", "Europe/Warsaw", "Europe/Lisbon", + "Europe/Kaliningrad", "Europe/Madrid", "Europe/Stockholm", + "Europe/Zurich", "Europe/Kiev", "Europe/Uzhgorod", + "Europe/Zaporozhye", "Europe/Simferopol", "Europe/Belgrade", "Africa/Algiers", "Africa/Tripoli", "Africa/Casablanca", "Africa/Tunis", "Africa/Ceuta" }); - tempMap.put("MHT", + tempAbbrMap.put("MHT", new String[] { "Pacific/Majuro", "Pacific/Kwajalein" }); - tempMap.put("MMT", new String[] { "Indian/Maldives", "Europe/Minsk", + tempAbbrMap.put("MMT", new String[] { "Indian/Maldives", "Europe/Minsk", "Europe/Moscow", "Asia/Rangoon", "Asia/Ujung_Pandang", "Asia/Colombo", "Pacific/Easter", "Africa/Monrovia", "America/Managua", "America/Montevideo" }); - tempMap.put("MOST", new String[] { "Asia/Macao" }); - tempMap.put("MOT", new String[] { "Asia/Macao" }); - tempMap.put("MPT", new String[] { "Pacific/Saipan" }); - tempMap.put("MSK", new String[] { "Europe/Minsk", "Europe/Tallinn", + tempAbbrMap.put("MOST", new String[] { "Asia/Macao" }); + tempAbbrMap.put("MOT", new String[] { "Asia/Macao" }); + tempAbbrMap.put("MPT", new String[] { "Pacific/Saipan" }); + tempAbbrMap.put("MSK", new String[] { "Europe/Minsk", "Europe/Tallinn", "Europe/Riga", "Europe/Vilnius", "Europe/Chisinau", "Europe/Kiev", "Europe/Uzhgorod", "Europe/Zaporozhye", "Europe/Simferopol" }); - tempMap.put("MST", new String[] { "Europe/Moscow", "America/Denver", + tempAbbrMap.put("MST", new String[] { "Europe/Moscow", "America/Denver", "America/Phoenix", "America/Boise", "America/Regina", "America/Swift_Current", "America/Edmonton", "America/Dawson_Creek", "America/Cambridge_Bay", "America/Yellowknife", "America/Inuvik", "America/Mexico_City", "America/Chihuahua", "America/Hermosillo", "America/Mazatlan", "America/Tijuana" }); - tempMap.put("MUT", new String[] { "Indian/Mauritius" }); - tempMap.put("MVT", new String[] { "Indian/Maldives" }); - tempMap.put("MWT", new String[] { "America/Denver", "America/Phoenix", + tempAbbrMap.put("MUT", new String[] { "Indian/Mauritius" }); + tempAbbrMap.put("MVT", new String[] { "Indian/Maldives" }); + tempAbbrMap.put("MWT", new String[] { "America/Denver", "America/Phoenix", "America/Boise" }); - tempMap + tempAbbrMap .put("MYT", new String[] { "Asia/Kuala_Lumpur", "Asia/Kuching" }); - tempMap.put("NCST", new String[] { "Pacific/Noumea" }); - tempMap.put("NCT", new String[] { "Pacific/Noumea" }); - tempMap.put("NDT", new String[] { "America/Nome", "America/Adak", + tempAbbrMap.put("NCST", new String[] { "Pacific/Noumea" }); + tempAbbrMap.put("NCT", new String[] { "Pacific/Noumea" }); + tempAbbrMap.put("NDT", new String[] { "America/Nome", "America/Adak", "America/St_Johns", "America/Goose_Bay" }); - tempMap.put("NEGT", new String[] { "America/Paramaribo" }); - tempMap.put("NFT", new String[] { "Europe/Paris", "Europe/Oslo", + tempAbbrMap.put("NEGT", new String[] { "America/Paramaribo" }); + tempAbbrMap.put("NFT", new String[] { "Europe/Paris", "Europe/Oslo", "Pacific/Norfolk" }); - tempMap.put("NMT", new String[] { "Pacific/Norfolk" }); - tempMap.put("NOVMT", new String[] { "Asia/Novosibirsk" }); - tempMap.put("NOVST", new String[] { "Asia/Novosibirsk" }); - tempMap.put("NOVT", new String[] { "Asia/Novosibirsk" }); - tempMap.put("NPT", new String[] { "Asia/Katmandu" }); - tempMap.put("NRT", new String[] { "Pacific/Nauru" }); - tempMap.put("NST", new String[] { "Europe/Amsterdam", + tempAbbrMap.put("NMT", new String[] { "Pacific/Norfolk" }); + tempAbbrMap.put("NOVMT", new String[] { "Asia/Novosibirsk" }); + tempAbbrMap.put("NOVST", new String[] { "Asia/Novosibirsk" }); + tempAbbrMap.put("NOVT", new String[] { "Asia/Novosibirsk" }); + tempAbbrMap.put("NPT", new String[] { "Asia/Katmandu" }); + tempAbbrMap.put("NRT", new String[] { "Pacific/Nauru" }); + tempAbbrMap.put("NST", new String[] { "Europe/Amsterdam", "Pacific/Pago_Pago", "Pacific/Midway", "America/Nome", "America/Adak", "America/St_Johns", "America/Goose_Bay" }); - tempMap.put("NUT", new String[] { "Pacific/Niue" }); - tempMap.put("NWT", new String[] { "America/Nome", "America/Adak" }); - tempMap.put("NZDT", new String[] { "Antarctica/McMurdo" }); - tempMap.put("NZHDT", new String[] { "Pacific/Auckland" }); - tempMap.put("NZST", new String[] { "Antarctica/McMurdo", + tempAbbrMap.put("NUT", new String[] { "Pacific/Niue" }); + tempAbbrMap.put("NWT", new String[] { "America/Nome", "America/Adak" }); + tempAbbrMap.put("NZDT", new String[] { "Antarctica/McMurdo" }); + tempAbbrMap.put("NZHDT", new String[] { "Pacific/Auckland" }); + tempAbbrMap.put("NZST", new String[] { "Antarctica/McMurdo", "Pacific/Auckland" }); - tempMap.put("OMSMT", new String[] { "Asia/Omsk" }); - tempMap.put("OMSST", new String[] { "Asia/Omsk" }); - tempMap.put("OMST", new String[] { "Asia/Omsk" }); - tempMap.put("PDDT", new String[] { "America/Inuvik", + tempAbbrMap.put("OMSMT", new String[] { "Asia/Omsk" }); + tempAbbrMap.put("OMSST", new String[] { "Asia/Omsk" }); + tempAbbrMap.put("OMST", new String[] { "Asia/Omsk" }); + tempAbbrMap.put("PDDT", new String[] { "America/Inuvik", "America/Whitehorse", "America/Dawson" }); - tempMap.put("PDT", new String[] { "America/Los_Angeles", + tempAbbrMap.put("PDT", new String[] { "America/Los_Angeles", "America/Juneau", "America/Boise", "America/Vancouver", "America/Dawson_Creek", "America/Inuvik", "America/Whitehorse", "America/Dawson", "America/Tijuana" }); - tempMap.put("PEST", new String[] { "America/Lima" }); - tempMap.put("PET", new String[] { "America/Lima" }); - tempMap.put("PETMT", new String[] { "Asia/Kamchatka" }); - tempMap.put("PETST", new String[] { "Asia/Kamchatka" }); - tempMap.put("PETT", new String[] { "Asia/Kamchatka" }); - tempMap.put("PGT", new String[] { "Pacific/Port_Moresby" }); - tempMap.put("PHOT", new String[] { "Pacific/Enderbury" }); - tempMap.put("PHST", new String[] { "Asia/Manila" }); - tempMap.put("PHT", new String[] { "Asia/Manila" }); - tempMap.put("PKT", new String[] { "Asia/Karachi" }); - tempMap.put("PMDT", new String[] { "America/Miquelon" }); - tempMap.put("PMMT", new String[] { "Pacific/Port_Moresby" }); - tempMap.put("PMST", new String[] { "America/Miquelon" }); - tempMap.put("PMT", new String[] { "Antarctica/DumontDUrville", + tempAbbrMap.put("PEST", new String[] { "America/Lima" }); + tempAbbrMap.put("PET", new String[] { "America/Lima" }); + tempAbbrMap.put("PETMT", new String[] { "Asia/Kamchatka" }); + tempAbbrMap.put("PETST", new String[] { "Asia/Kamchatka" }); + tempAbbrMap.put("PETT", new String[] { "Asia/Kamchatka" }); + tempAbbrMap.put("PGT", new String[] { "Pacific/Port_Moresby" }); + tempAbbrMap.put("PHOT", new String[] { "Pacific/Enderbury" }); + tempAbbrMap.put("PHST", new String[] { "Asia/Manila" }); + tempAbbrMap.put("PHT", new String[] { "Asia/Manila" }); + tempAbbrMap.put("PKT", new String[] { "Asia/Karachi" }); + tempAbbrMap.put("PMDT", new String[] { "America/Miquelon" }); + tempAbbrMap.put("PMMT", new String[] { "Pacific/Port_Moresby" }); + tempAbbrMap.put("PMST", new String[] { "America/Miquelon" }); + tempAbbrMap.put("PMT", new String[] { "Antarctica/DumontDUrville", "Europe/Prague", "Europe/Paris", "Europe/Monaco", "Africa/Algiers", "Africa/Tunis", "America/Panama", "America/Paramaribo" }); - tempMap.put("PNT", new String[] { "Pacific/Pitcairn" }); - tempMap.put("PONT", new String[] { "Pacific/Ponape" }); - tempMap.put("PPMT", new String[] { "America/Port-au-Prince" }); - tempMap.put("PST", new String[] { "Pacific/Pitcairn", + tempAbbrMap.put("PNT", new String[] { "Pacific/Pitcairn" }); + tempAbbrMap.put("PONT", new String[] { "Pacific/Ponape" }); + tempAbbrMap.put("PPMT", new String[] { "America/Port-au-Prince" }); + tempAbbrMap.put("PST", new String[] { "Pacific/Pitcairn", "America/Los_Angeles", "America/Juneau", "America/Boise", "America/Vancouver", "America/Dawson_Creek", "America/Inuvik", "America/Whitehorse", "America/Dawson", "America/Hermosillo", "America/Mazatlan", "America/Tijuana" }); - tempMap.put("PWT", new String[] { "Pacific/Palau", + tempAbbrMap.put("PWT", new String[] { "Pacific/Palau", "America/Los_Angeles", "America/Juneau", "America/Boise", "America/Tijuana" }); - tempMap.put("PYST", new String[] { "America/Asuncion" }); - tempMap.put("PYT", new String[] { "America/Asuncion" }); - tempMap.put("QMT", new String[] { "America/Guayaquil" }); - tempMap.put("RET", new String[] { "Indian/Reunion" }); - tempMap.put("RMT", new String[] { "Atlantic/Reykjavik", "Europe/Rome", + tempAbbrMap.put("PYST", new String[] { "America/Asuncion" }); + tempAbbrMap.put("PYT", new String[] { "America/Asuncion" }); + tempAbbrMap.put("QMT", new String[] { "America/Guayaquil" }); + tempAbbrMap.put("RET", new String[] { "Indian/Reunion" }); + tempAbbrMap.put("RMT", new String[] { "Atlantic/Reykjavik", "Europe/Rome", "Europe/Riga", "Asia/Rangoon" }); - tempMap.put("S", new String[] { "Europe/Moscow" }); - tempMap.put("SAMMT", new String[] { "Europe/Samara" }); - tempMap + tempAbbrMap.put("S", new String[] { "Europe/Moscow" }); + tempAbbrMap.put("SAMMT", new String[] { "Europe/Samara" }); + tempAbbrMap .put("SAMST", new String[] { "Europe/Samara", "Asia/Samarkand" }); - tempMap.put("SAMT", new String[] { "Europe/Samara", "Asia/Samarkand", + tempAbbrMap.put("SAMT", new String[] { "Europe/Samara", "Asia/Samarkand", "Pacific/Pago_Pago", "Pacific/Apia" }); - tempMap.put("SAST", new String[] { "Africa/Maseru", "Africa/Windhoek", + tempAbbrMap.put("SAST", new String[] { "Africa/Maseru", "Africa/Windhoek", "Africa/Johannesburg", "Africa/Mbabane" }); - tempMap.put("SBT", new String[] { "Pacific/Guadalcanal" }); - tempMap.put("SCT", new String[] { "Indian/Mahe" }); - tempMap.put("SDMT", new String[] { "America/Santo_Domingo" }); - tempMap.put("SGT", new String[] { "Asia/Singapore" }); - tempMap.put("SHEST", new String[] { "Asia/Aqtau" }); - tempMap.put("SHET", new String[] { "Asia/Aqtau" }); - tempMap.put("SJMT", new String[] { "America/Costa_Rica" }); - tempMap.put("SLST", new String[] { "Africa/Freetown" }); - tempMap.put("SMT", new String[] { "Atlantic/Stanley", + tempAbbrMap.put("SBT", new String[] { "Pacific/Guadalcanal" }); + tempAbbrMap.put("SCT", new String[] { "Indian/Mahe" }); + tempAbbrMap.put("SDMT", new String[] { "America/Santo_Domingo" }); + tempAbbrMap.put("SGT", new String[] { "Asia/Singapore" }); + tempAbbrMap.put("SHEST", new String[] { "Asia/Aqtau" }); + tempAbbrMap.put("SHET", new String[] { "Asia/Aqtau" }); + tempAbbrMap.put("SJMT", new String[] { "America/Costa_Rica" }); + tempAbbrMap.put("SLST", new String[] { "Africa/Freetown" }); + tempAbbrMap.put("SMT", new String[] { "Atlantic/Stanley", "Europe/Stockholm", "Europe/Simferopol", "Asia/Phnom_Penh", "Asia/Vientiane", "Asia/Kuala_Lumpur", "Asia/Singapore", "Asia/Saigon", "America/Santiago" }); - tempMap.put("SRT", new String[] { "America/Paramaribo" }); - tempMap.put("SST", + tempAbbrMap.put("SRT", new String[] { "America/Paramaribo" }); + tempAbbrMap.put("SST", new String[] { "Pacific/Pago_Pago", "Pacific/Midway" }); - tempMap.put("SVEMT", new String[] { "Asia/Yekaterinburg" }); - tempMap.put("SVEST", new String[] { "Asia/Yekaterinburg" }); - tempMap.put("SVET", new String[] { "Asia/Yekaterinburg" }); - tempMap.put("SWAT", new String[] { "Africa/Windhoek" }); - tempMap.put("SYOT", new String[] { "Antarctica/Syowa" }); - tempMap.put("TAHT", new String[] { "Pacific/Tahiti" }); - tempMap + tempAbbrMap.put("SVEMT", new String[] { "Asia/Yekaterinburg" }); + tempAbbrMap.put("SVEST", new String[] { "Asia/Yekaterinburg" }); + tempAbbrMap.put("SVET", new String[] { "Asia/Yekaterinburg" }); + tempAbbrMap.put("SWAT", new String[] { "Africa/Windhoek" }); + tempAbbrMap.put("SYOT", new String[] { "Antarctica/Syowa" }); + tempAbbrMap.put("TAHT", new String[] { "Pacific/Tahiti" }); + tempAbbrMap .put("TASST", new String[] { "Asia/Samarkand", "Asia/Tashkent" }); - tempMap.put("TAST", new String[] { "Asia/Samarkand", "Asia/Tashkent" }); - tempMap.put("TBIST", new String[] { "Asia/Tbilisi" }); - tempMap.put("TBIT", new String[] { "Asia/Tbilisi" }); - tempMap.put("TBMT", new String[] { "Asia/Tbilisi" }); - tempMap.put("TFT", new String[] { "Indian/Kerguelen" }); - tempMap.put("TJT", new String[] { "Asia/Dushanbe" }); - tempMap.put("TKT", new String[] { "Pacific/Fakaofo" }); - tempMap.put("TMST", new String[] { "Asia/Ashkhabad" }); - tempMap.put("TMT", new String[] { "Europe/Tallinn", "Asia/Tehran", + tempAbbrMap.put("TAST", new String[] { "Asia/Samarkand", "Asia/Tashkent" }); + tempAbbrMap.put("TBIST", new String[] { "Asia/Tbilisi" }); + tempAbbrMap.put("TBIT", new String[] { "Asia/Tbilisi" }); + tempAbbrMap.put("TBMT", new String[] { "Asia/Tbilisi" }); + tempAbbrMap.put("TFT", new String[] { "Indian/Kerguelen" }); + tempAbbrMap.put("TJT", new String[] { "Asia/Dushanbe" }); + tempAbbrMap.put("TKT", new String[] { "Pacific/Fakaofo" }); + tempAbbrMap.put("TMST", new String[] { "Asia/Ashkhabad" }); + tempAbbrMap.put("TMT", new String[] { "Europe/Tallinn", "Asia/Tehran", "Asia/Ashkhabad" }); - tempMap.put("TOST", new String[] { "Pacific/Tongatapu" }); - tempMap.put("TOT", new String[] { "Pacific/Tongatapu" }); - tempMap.put("TPT", new String[] { "Asia/Dili" }); - tempMap.put("TRST", new String[] { "Europe/Istanbul" }); - tempMap.put("TRT", new String[] { "Europe/Istanbul" }); - tempMap.put("TRUT", new String[] { "Pacific/Truk" }); - tempMap.put("TVT", new String[] { "Pacific/Funafuti" }); - tempMap.put("ULAST", new String[] { "Asia/Ulaanbaatar" }); - tempMap.put("ULAT", new String[] { "Asia/Ulaanbaatar" }); - tempMap.put("URUT", new String[] { "Asia/Urumqi" }); - tempMap.put("UYHST", new String[] { "America/Montevideo" }); - tempMap.put("UYT", new String[] { "America/Montevideo" }); - tempMap.put("UZST", new String[] { "Asia/Samarkand", "Asia/Tashkent" }); - tempMap.put("UZT", new String[] { "Asia/Samarkand", "Asia/Tashkent" }); - tempMap.put("VET", new String[] { "America/Caracas" }); - tempMap.put("VLAMT", new String[] { "Asia/Vladivostok" }); - tempMap.put("VLAST", new String[] { "Asia/Vladivostok" }); - tempMap.put("VLAT", new String[] { "Asia/Vladivostok" }); - tempMap.put("VUST", new String[] { "Pacific/Efate" }); - tempMap.put("VUT", new String[] { "Pacific/Efate" }); - tempMap.put("WAKT", new String[] { "Pacific/Wake" }); - tempMap.put("WARST", + tempAbbrMap.put("TOST", new String[] { "Pacific/Tongatapu" }); + tempAbbrMap.put("TOT", new String[] { "Pacific/Tongatapu" }); + tempAbbrMap.put("TPT", new String[] { "Asia/Dili" }); + tempAbbrMap.put("TRST", new String[] { "Europe/Istanbul" }); + tempAbbrMap.put("TRT", new String[] { "Europe/Istanbul" }); + tempAbbrMap.put("TRUT", new String[] { "Pacific/Truk" }); + tempAbbrMap.put("TVT", new String[] { "Pacific/Funafuti" }); + tempAbbrMap.put("ULAST", new String[] { "Asia/Ulaanbaatar" }); + tempAbbrMap.put("ULAT", new String[] { "Asia/Ulaanbaatar" }); + tempAbbrMap.put("URUT", new String[] { "Asia/Urumqi" }); + tempAbbrMap.put("UYHST", new String[] { "America/Montevideo" }); + tempAbbrMap.put("UYT", new String[] { "America/Montevideo" }); + tempAbbrMap.put("UZST", new String[] { "Asia/Samarkand", "Asia/Tashkent" }); + tempAbbrMap.put("UZT", new String[] { "Asia/Samarkand", "Asia/Tashkent" }); + tempAbbrMap.put("VET", new String[] { "America/Caracas" }); + tempAbbrMap.put("VLAMT", new String[] { "Asia/Vladivostok" }); + tempAbbrMap.put("VLAST", new String[] { "Asia/Vladivostok" }); + tempAbbrMap.put("VLAT", new String[] { "Asia/Vladivostok" }); + tempAbbrMap.put("VUST", new String[] { "Pacific/Efate" }); + tempAbbrMap.put("VUT", new String[] { "Pacific/Efate" }); + tempAbbrMap.put("WAKT", new String[] { "Pacific/Wake" }); + tempAbbrMap.put("WARST", new String[] { "America/Jujuy", "America/Mendoza" }); - tempMap + tempAbbrMap .put("WART", new String[] { "America/Jujuy", "America/Mendoza" }); - tempMap.put("WAST", + tempAbbrMap.put("WAST", new String[] { "Africa/Ndjamena", "Africa/Windhoek" }); - tempMap.put("WAT", new String[] { "Africa/Luanda", "Africa/Porto-Novo", + tempAbbrMap.put("WAT", new String[] { "Africa/Luanda", "Africa/Porto-Novo", "Africa/Douala", "Africa/Bangui", "Africa/Ndjamena", "Africa/Kinshasa", "Africa/Brazzaville", "Africa/Malabo", "Africa/Libreville", "Africa/Banjul", "Africa/Conakry", "Africa/Bissau", "Africa/Bamako", "Africa/Nouakchott", "Africa/El_Aaiun", "Africa/Windhoek", "Africa/Niamey", "Africa/Lagos", "Africa/Dakar", "Africa/Freetown" }); - tempMap.put("WEST", new String[] { "Atlantic/Faeroe", + tempAbbrMap.put("WEST", new String[] { "Atlantic/Faeroe", "Atlantic/Azores", "Atlantic/Madeira", "Atlantic/Canary", "Europe/Brussels", "Europe/Luxembourg", "Europe/Monaco", "Europe/Lisbon", "Europe/Madrid", "Africa/Algiers", "Africa/Casablanca", "Africa/Ceuta" }); - tempMap.put("WET", new String[] { "Atlantic/Faeroe", "Atlantic/Azores", + tempAbbrMap.put("WET", new String[] { "Atlantic/Faeroe", "Atlantic/Azores", "Atlantic/Madeira", "Atlantic/Canary", "Europe/Andorra", "Europe/Brussels", "Europe/Luxembourg", "Europe/Monaco", "Europe/Lisbon", "Europe/Madrid", "Africa/Algiers", "Africa/Casablanca", "Africa/El_Aaiun", "Africa/Ceuta" }); - tempMap.put("WFT", new String[] { "Pacific/Wallis" }); - tempMap.put("WGST", new String[] { "America/Godthab" }); - tempMap.put("WGT", new String[] { "America/Godthab" }); - tempMap.put("WMT", new String[] { "Europe/Vilnius", "Europe/Warsaw" }); - tempMap.put("WST", new String[] { "Antarctica/Casey", "Pacific/Apia", + tempAbbrMap.put("WFT", new String[] { "Pacific/Wallis" }); + tempAbbrMap.put("WGST", new String[] { "America/Godthab" }); + tempAbbrMap.put("WGT", new String[] { "America/Godthab" }); + tempAbbrMap.put("WMT", new String[] { "Europe/Vilnius", "Europe/Warsaw" }); + tempAbbrMap.put("WST", new String[] { "Antarctica/Casey", "Pacific/Apia", "Australia/Perth" }); - tempMap.put("YAKMT", new String[] { "Asia/Yakutsk" }); - tempMap.put("YAKST", new String[] { "Asia/Yakutsk" }); - tempMap.put("YAKT", new String[] { "Asia/Yakutsk" }); - tempMap.put("YAPT", new String[] { "Pacific/Yap" }); - tempMap.put("YDDT", new String[] { "America/Whitehorse", + tempAbbrMap.put("YAKMT", new String[] { "Asia/Yakutsk" }); + tempAbbrMap.put("YAKST", new String[] { "Asia/Yakutsk" }); + tempAbbrMap.put("YAKT", new String[] { "Asia/Yakutsk" }); + tempAbbrMap.put("YAPT", new String[] { "Pacific/Yap" }); + tempAbbrMap.put("YDDT", new String[] { "America/Whitehorse", "America/Dawson" }); - tempMap.put("YDT", new String[] { "America/Yakutat", + tempAbbrMap.put("YDT", new String[] { "America/Yakutat", "America/Whitehorse", "America/Dawson" }); - tempMap.put("YEKMT", new String[] { "Asia/Yekaterinburg" }); - tempMap.put("YEKST", new String[] { "Asia/Yekaterinburg" }); - tempMap.put("YEKT", new String[] { "Asia/Yekaterinburg" }); - tempMap.put("YERST", new String[] { "Asia/Yerevan" }); - tempMap.put("YERT", new String[] { "Asia/Yerevan" }); - tempMap.put("YST", new String[] { "America/Yakutat", + tempAbbrMap.put("YEKMT", new String[] { "Asia/Yekaterinburg" }); + tempAbbrMap.put("YEKST", new String[] { "Asia/Yekaterinburg" }); + tempAbbrMap.put("YEKT", new String[] { "Asia/Yekaterinburg" }); + tempAbbrMap.put("YERST", new String[] { "Asia/Yerevan" }); + tempAbbrMap.put("YERT", new String[] { "Asia/Yerevan" }); + tempAbbrMap.put("YST", new String[] { "America/Yakutat", "America/Whitehorse", "America/Dawson" }); - tempMap.put("YWT", new String[] { "America/Yakutat" }); + tempAbbrMap.put("YWT", new String[] { "America/Yakutat" }); - ABBREVIATED_TIMEZONES = Collections.unmodifiableMap(tempMap); + ABBREVIATED_TIMEZONES = Collections.unmodifiableMap(tempAbbrMap); } /** @@ -809,7 +831,7 @@ * * @return the times changed to the timezone 'toTz' */ - public static Time changeTimezone(Connection conn, + public static Time changeTimezone(MySQLConnection conn, Calendar sessionCalendar, Calendar targetCalendar, Time t, @@ -871,7 +893,7 @@ * * @return the timestamp changed to the timezone 'toTz' */ - public static Timestamp changeTimezone(Connection conn, + public static Timestamp changeTimezone(MySQLConnection conn, Calendar sessionCalendar, Calendar targetCalendar, Timestamp tstamp, @@ -975,11 +997,38 @@ } dateCal.clear(); + dateCal.set(Calendar.MILLISECOND, 0); + + // why-oh-why is this different than java.util.date, + // in the year part, but it still keeps the silly '0' + // for the start month???? + dateCal.set(year, month - 1, day, 0, 0, 0); + + long dateAsMillis = 0; + try { + dateAsMillis = dateCal.getTimeInMillis(); + } catch (IllegalAccessError iae) { + // Must be on JDK-1.3.1 or older.... + dateAsMillis = dateCal.getTime().getTime(); + } + + return new Date(dateAsMillis); + } + + final static Date fastDateCreate(int year, int month, int day, Calendar targetCalendar) { + + + Calendar dateCal = (targetCalendar == null) ? new GregorianCalendar() : targetCalendar; + + dateCal.clear(); + + // why-oh-why is this different than java.util.date, // in the year part, but it still keeps the silly '0' // for the start month???? dateCal.set(year, month - 1, day, 0, 0, 0); + dateCal.set(Calendar.MILLISECOND, 0); long dateAsMillis = 0; @@ -994,23 +1043,23 @@ } final static Time fastTimeCreate(Calendar cal, int hour, int minute, - int second) throws SQLException { - if (hour < 0 || hour > 23) { + 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); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } if (minute < 0 || minute > 59) { throw SQLError.createSQLException("Illegal minute value '" + minute + "'" + "' for java.sql.Time type in value '" + timeFormattedString(hour, minute, second) + ".", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } if (second < 0 || second > 59) { throw SQLError.createSQLException("Illegal minute value '" + second + "'" + "' for java.sql.Time type in value '" + timeFormattedString(hour, minute, second) + ".", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } cal.clear(); @@ -1030,6 +1079,44 @@ return new Time(timeAsMillis); } + 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); + } + + if (minute < 0 || minute > 59) { + throw SQLError.createSQLException("Illegal minute value '" + minute + "'" + "' for java.sql.Time type in value '" + + timeFormattedString(hour, minute, second) + ".", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + } + + if (second < 0 || second > 59) { + throw SQLError.createSQLException("Illegal minute value '" + second + "'" + "' for java.sql.Time type in value '" + + timeFormattedString(hour, minute, second) + ".", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + } + + Calendar cal = (targetCalendar == null) ? new GregorianCalendar() : targetCalendar; + cal.clear(); + + // Set 'date' to epoch of Jan 1, 1970 + cal.set(1970, 0, 1, hour, minute, second); + + long timeAsMillis = 0; + + try { + timeAsMillis = cal.getTimeInMillis(); + } catch (IllegalAccessError iae) { + // Must be on JDK-1.3.1 or older.... + timeAsMillis = cal.getTime().getTime(); + } + + return new Time(timeAsMillis); + } + final static Timestamp fastTimestampCreate(boolean useGmtConversion, Calendar gmtCalIfNeeded, Calendar cal, int year, @@ -1060,8 +1147,13 @@ offsetDiff = fromOffset - toOffset; } + if (secondsPart != 0) { + cal.set(Calendar.MILLISECOND, secondsPart / 1000000); + } + long tsAsMillis = 0; + try { tsAsMillis = cal.getTimeInMillis(); } catch (IllegalAccessError iae) { @@ -1070,29 +1162,65 @@ } Timestamp ts = new Timestamp(tsAsMillis + offsetDiff); + ts.setNanos(secondsPart); return ts; } + + final static Timestamp fastTimestampCreate(TimeZone tz, int year, + int month, int day, int hour, int minute, int seconds, + int secondsPart) { + Calendar cal = (tz == null) ? new GregorianCalendar() : new GregorianCalendar(tz); + cal.clear(); + + // why-oh-why is this different than java.util.date, + // in the year part, but it still keeps the silly '0' + // for the start month???? + cal.set(year, month - 1, day, hour, minute, seconds); + long tsAsMillis = 0; + + try { + tsAsMillis = cal.getTimeInMillis(); + } catch (IllegalAccessError iae) { + // Must be on JDK-1.3.1 or older.... + tsAsMillis = cal.getTime().getTime(); + } + + Timestamp ts = new Timestamp(tsAsMillis); + ts.setNanos(secondsPart); + + return ts; + } + /** * Returns the 'official' Java timezone name for the given timezone * * @param timezoneStr * the 'common' timezone name * * @return the Java timezone name for the given timezone + * @throws SQLException * * @throws IllegalArgumentException * DOCUMENT ME! */ - public static String getCanoncialTimezone(String timezoneStr) { + public static String getCanoncialTimezone(String timezoneStr, ExceptionInterceptor exceptionInterceptor) throws SQLException { if (timezoneStr == null) { return null; } timezoneStr = timezoneStr.trim(); + // handle '+/-hh:mm' form ... + + if (timezoneStr.length() > 2) { + if ((timezoneStr.charAt(0) == '+' || timezoneStr.charAt(0) == '-') && + Character.isDigit(timezoneStr.charAt(1))) { + return "GMT" + timezoneStr; + } + } // Fix windows Daylight/Standard shift JDK doesn't map these (doh) int daylightIndex = StringUtils.indexOfIgnoreCase(timezoneStr, @@ -1107,38 +1235,29 @@ timezoneStr = timezoneBuf.toString(); } - String canonicalTz = (String) TIMEZONE_MAPPINGS.get(timezoneStr); + String canonicalTz = TIMEZONE_MAPPINGS.get(timezoneStr); // if we didn't find it, try abbreviated timezones if (canonicalTz == null) { - String[] abbreviatedTimezone = (String[]) ABBREVIATED_TIMEZONES + String[] abbreviatedTimezone = ABBREVIATED_TIMEZONES .get(timezoneStr); if (abbreviatedTimezone != null) { // If there's only one mapping use that if (abbreviatedTimezone.length == 1) { canonicalTz = abbreviatedTimezone[0]; } else { - StringBuffer errorMsg = new StringBuffer( - "The server timezone value '"); - errorMsg.append(timezoneStr); - errorMsg - .append("' represents more than one timezone. You must "); - errorMsg - .append("configure either the server or client to use a "); - errorMsg - .append("more specifc timezone value if you want to enable "); - errorMsg.append("timezone support. The timezones that '"); - errorMsg.append(timezoneStr); - errorMsg.append("' maps to are: "); - errorMsg.append(abbreviatedTimezone[0]); - + StringBuffer possibleTimezones = new StringBuffer(128); + + possibleTimezones.append(abbreviatedTimezone[0]); + for (int i = 1; i < abbreviatedTimezone.length; i++) { - errorMsg.append(", "); - errorMsg.append(abbreviatedTimezone[i]); + possibleTimezones.append(", "); + possibleTimezones.append(abbreviatedTimezone[i]); } - throw new IllegalArgumentException(errorMsg.toString()); + throw SQLError.createSQLException(Messages.getString("TimeUtil.TooGenericTimezoneId", + new Object[] {timezoneStr, possibleTimezones}), SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, exceptionInterceptor); } } } @@ -1153,7 +1272,6 @@ private static String timeFormattedString(int hours, int minutes, int seconds) { StringBuffer buf = new StringBuffer(8); - if (hours < 10) { buf.append("0"); } @@ -1176,4 +1294,39 @@ return buf.toString(); } + + public static String formatNanos(int nanos, boolean serverSupportsFracSecs, boolean usingMicros) { + + // get only last 9 digits + if (nanos > 999999999) { + nanos %= 100000000; + } + + if (usingMicros) { + nanos /= 1000; + } + + if (!serverSupportsFracSecs || nanos == 0) { + return "0"; + } + + final int digitCount = usingMicros ? 6 : 9; + + String nanosString = Integer.toString(nanos); + final String zeroPadding = usingMicros ? "000000" : "000000000"; + + nanosString = zeroPadding.substring(0, (digitCount-nanosString.length())) + + nanosString; + + int pos = digitCount-1; // the end, we're padded to the end by the code above + + while (nanosString.charAt(pos) == '0') { + pos--; + } + + nanosString = nanosString.substring(0, pos + 1); + + return nanosString; + } + } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/UpdatableResultSet.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/UpdatableResultSet.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/UpdatableResultSet.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/UpdatableResultSet.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,51 +1,49 @@ /* - Copyright (C) 2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; -import com.mysql.jdbc.profiler.ProfileEventSink; -import com.mysql.jdbc.profiler.ProfilerEvent; - import java.math.BigDecimal; - import java.sql.SQLException; - +import java.sql.Types; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import com.mysql.jdbc.profiler.ProfilerEvent; + /** * A result set that is updatable. - * + * * @author Mark Matthews */ -public class UpdatableResultSet extends ResultSet { +public class UpdatableResultSet extends ResultSetImpl { /** Marker for 'stream' data when doing INSERT rows */ - private final static byte[] STREAM_DATA_MARKER = "** STREAM DATA **" //$NON-NLS-1$ - .getBytes(); + final static byte[] STREAM_DATA_MARKER = StringUtils.getBytes("** STREAM DATA **"); //$NON-NLS-1$ - private SingleByteCharsetConverter charConverter; + protected SingleByteCharsetConverter charConverter; private String charEncoding; @@ -60,7 +58,7 @@ private boolean initializedCharConverter = false; /** PreparedStatement used to insert data */ - private com.mysql.jdbc.PreparedStatement inserter = null; + protected com.mysql.jdbc.PreparedStatement inserter = null; private String insertSQL = null; @@ -71,7 +69,7 @@ private String notUpdatableReason = null; /** List of primary keys */ - private List primaryKeyIndicies = null; + private List primaryKeyIndicies = null; private String qualifiedAndQuotedTableName; @@ -83,42 +81,22 @@ private String refreshSQL = null; /** The binary data for the 'current' row */ - private Object[] savedCurrentRow; + private ResultSetRow savedCurrentRow; - private String tableOnlyName; - /** PreparedStatement used to delete data */ - private com.mysql.jdbc.PreparedStatement updater = null; + protected com.mysql.jdbc.PreparedStatement updater = null; /** SQL for in-place modifcation */ private String updateSQL = null; - + private boolean populateInserterWithDefaultValues = false; - /** - * Create a result set for an executeUpdate statement. - * - * @param updateCount - * the number of rows affected by the update - * @param updateID - * the autoincrement value (if any) - * @param conn - * DOCUMENT ME! - * @param creatorStmt - * DOCUMENT ME! - * - * @throws SQLException - * DOCUMENT ME! - */ - public UpdatableResultSet(long updateCount, long updateID, Connection conn, - Statement creatorStmt) throws SQLException { - super(updateCount, updateID, conn, creatorStmt); - checkUpdatability(); - } + private Map>> databasesUsedToTablesUsed = null; + /** * Creates a new ResultSet object. - * + * * @param catalog * the database in use when we were created * @param fields @@ -129,52 +107,52 @@ * the Connection that created us. * @param creatorStmt * DOCUMENT ME! - * + * * @throws SQLException * DOCUMENT ME! */ - public UpdatableResultSet(String catalog, Field[] fields, RowData tuples, - Connection conn, Statement creatorStmt) throws SQLException { + protected UpdatableResultSet(String catalog, Field[] fields, RowData tuples, + MySQLConnection conn, StatementImpl creatorStmt) throws SQLException { super(catalog, fields, tuples, conn, creatorStmt); checkUpdatability(); - this.populateInserterWithDefaultValues = + this.populateInserterWithDefaultValues = this.connection.getPopulateInsertRowWithDefaultValues(); } /** * JDBC 2.0 - * + * *

    * Move to an absolute row number in the result set. *

    - * + * *

    * If row is positive, moves to an absolute row with respect to the * beginning of the result set. The first row is row 1, the second is row 2, * etc. *

    - * + * *

    * If row is negative, moves to an absolute row position with respect to the * end of result set. For example, calling absolute(-1) positions the cursor * on the last row, absolute(-2) indicates the next-to-last row, etc. *

    - * + * *

    * An attempt to position the cursor beyond the first/last row in the result * set, leaves the cursor before/after the first/last row, respectively. *

    - * + * *

    * Note: Calling absolute(1) is the same as calling first(). Calling * absolute(-1) is the same as calling last(). *

    - * + * * @param row * DOCUMENT ME! - * + * * @return true if on the result set, false if off. - * + * * @exception SQLException * if a database-access error occurs, or row is 0, or result * set type is TYPE_FORWARD_ONLY. @@ -185,12 +163,12 @@ /** * JDBC 2.0 - * + * *

    * Moves to the end of the result set, just after the last row. Has no * effect if the result set contains no rows. *

    - * + * * @exception SQLException * if a database-access error occurs, or result set type is * TYPE_FORWARD_ONLY. @@ -201,12 +179,12 @@ /** * JDBC 2.0 - * + * *

    * Moves to the front of the result set, just before the first row. Has no * effect if the result set contains no rows. *

    - * + * * @exception SQLException * if a database-access error occurs, or result set type is * TYPE_FORWARD_ONLY @@ -220,7 +198,7 @@ * updateXXX() method(s) and before calling updateRow() to rollback the * updates made to a row. If no updates have been made or updateRow() has * already been called, then this method has no effect. - * + * * @exception SQLException * if a database-access error occurs, or if called when on * the insert row. @@ -236,10 +214,10 @@ /* * (non-Javadoc) - * + * * @see com.mysql.jdbc.ResultSet#checkRowPos() */ - protected void checkRowPos() throws SQLException { + protected synchronized void checkRowPos() throws SQLException { checkClosed(); if (!this.onInsertRow) { @@ -249,210 +227,215 @@ /** * Is this ResultSet updateable? - * + * * @throws SQLException * DOCUMENT ME! */ protected void checkUpdatability() throws SQLException { - if (this.fields == null) { - // we've been created to be populated with cached - // metadata, and we don't have the metadata yet, - // we'll be called again by - // Connection.initializeResultsMetadataFromCache() - // when the metadata has been made available - - return; - } - - String singleTableName = null; - String catalogName = null; - - int primaryKeyCount = 0; - - // We can only do this if we know that there is a currently - // selected database, or if we're talking to a > 4.1 version - // of MySQL server (as it returns database names in field - // info) - // - if ((this.catalog == null) || (this.catalog.length() == 0)) { - this.catalog = this.fields[0].getDatabaseName(); - - if ((this.catalog == null) || (this.catalog.length() == 0)) { - throw SQLError.createSQLException(Messages - .getString("UpdatableResultSet.43") //$NON-NLS-1$ - , SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - if (this.fields.length > 0) { - singleTableName = this.fields[0].getOriginalTableName(); - catalogName = this.fields[0].getDatabaseName(); - - if (singleTableName == null) { - singleTableName = this.fields[0].getTableName(); - catalogName = this.catalog; - } - - if (singleTableName != null && singleTableName.length() == 0) { - this.isUpdatable = false; - this.notUpdatableReason = Messages.getString("NotUpdatableReason.3"); - + try { + if (this.fields == null) { + // we've been created to be populated with cached + // metadata, and we don't have the metadata yet, + // we'll be called again by + // Connection.initializeResultsMetadataFromCache() + // when the metadata has been made available + return; } - - if (this.fields[0].isPrimaryKey()) { - primaryKeyCount++; - } - + + String singleTableName = null; + String catalogName = null; + + int primaryKeyCount = 0; + + // We can only do this if we know that there is a currently + // selected database, or if we're talking to a > 4.1 version + // of MySQL server (as it returns database names in field + // info) // - // References only one table? - // - for (int i = 1; i < this.fields.length; i++) { - String otherTableName = this.fields[i].getOriginalTableName(); - String otherCatalogName = this.fields[i].getDatabaseName(); - - if (otherTableName == null) { - otherTableName = this.fields[i].getTableName(); - otherCatalogName = this.catalog; + if ((this.catalog == null) || (this.catalog.length() == 0)) { + this.catalog = this.fields[0].getDatabaseName(); + + if ((this.catalog == null) || (this.catalog.length() == 0)) { + throw SQLError.createSQLException(Messages + .getString("UpdatableResultSet.43") //$NON-NLS-1$ + , SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); //$NON-NLS-1$ //$NON-NLS-2$ } - - if (otherTableName != null && otherTableName.length() == 0) { + } + + if (this.fields.length > 0) { + singleTableName = this.fields[0].getOriginalTableName(); + catalogName = this.fields[0].getDatabaseName(); + + if (singleTableName == null) { + singleTableName = this.fields[0].getTableName(); + catalogName = this.catalog; + } + + if (singleTableName != null && singleTableName.length() == 0) { this.isUpdatable = false; this.notUpdatableReason = Messages.getString("NotUpdatableReason.3"); - + return; } - - if ((singleTableName == null) - || !otherTableName.equals(singleTableName)) { - this.isUpdatable = false; - this.notUpdatableReason = Messages.getString("NotUpdatableReason.0"); - - return; + + if (this.fields[0].isPrimaryKey()) { + primaryKeyCount++; } - - // Can't reference more than one database - if ((catalogName == null) - || !otherCatalogName.equals(catalogName)) { + + // + // References only one table? + // + for (int i = 1; i < this.fields.length; i++) { + String otherTableName = this.fields[i].getOriginalTableName(); + String otherCatalogName = this.fields[i].getDatabaseName(); + + if (otherTableName == null) { + otherTableName = this.fields[i].getTableName(); + otherCatalogName = this.catalog; + } + + if (otherTableName != null && otherTableName.length() == 0) { + this.isUpdatable = false; + this.notUpdatableReason = Messages.getString("NotUpdatableReason.3"); + + return; + } + + if ((singleTableName == null) + || !otherTableName.equals(singleTableName)) { + this.isUpdatable = false; + this.notUpdatableReason = Messages.getString("NotUpdatableReason.0"); + + return; + } + + // Can't reference more than one database + if ((catalogName == null) + || !otherCatalogName.equals(catalogName)) { + this.isUpdatable = false; + this.notUpdatableReason = Messages.getString("NotUpdatableReason.1"); + + return; + } + + if (this.fields[i].isPrimaryKey()) { + primaryKeyCount++; + } + } + + if ((singleTableName == null) || (singleTableName.length() == 0)) { this.isUpdatable = false; - this.notUpdatableReason = Messages.getString("NotUpdatableReason.1"); - + this.notUpdatableReason = Messages.getString("NotUpdatableReason.2"); + return; } - - if (this.fields[i].isPrimaryKey()) { - primaryKeyCount++; - } - } - - if ((singleTableName == null) || (singleTableName.length() == 0)) { + } else { this.isUpdatable = false; - this.notUpdatableReason = Messages.getString("NotUpdatableReason.2"); - + this.notUpdatableReason = Messages.getString("NotUpdatableReason.3"); + return; } - } else { - this.isUpdatable = false; - this.notUpdatableReason = Messages.getString("NotUpdatableReason.3"); - - return; - } - - if (this.connection.getStrictUpdates()) { - java.sql.DatabaseMetaData dbmd = this.connection.getMetaData(); - - java.sql.ResultSet rs = null; - HashMap primaryKeyNames = new HashMap(); - - try { - rs = dbmd.getPrimaryKeys(catalogName, null, singleTableName); - - while (rs.next()) { - String keyName = rs.getString(4); - keyName = keyName.toUpperCase(); - primaryKeyNames.put(keyName, keyName); - } - } finally { - if (rs != null) { - try { - rs.close(); - } catch (Exception ex) { - AssertionFailedException.shouldNotHappen(ex); + + if (this.connection.getStrictUpdates()) { + java.sql.DatabaseMetaData dbmd = this.connection.getMetaData(); + + java.sql.ResultSet rs = null; + HashMap primaryKeyNames = new HashMap(); + + try { + rs = dbmd.getPrimaryKeys(catalogName, null, singleTableName); + + while (rs.next()) { + String keyName = rs.getString(4); + keyName = keyName.toUpperCase(); + primaryKeyNames.put(keyName, keyName); } - - rs = null; + } finally { + if (rs != null) { + try { + rs.close(); + } catch (Exception ex) { + AssertionFailedException.shouldNotHappen(ex); + } + + rs = null; + } } - } - - int existingPrimaryKeysCount = primaryKeyNames.size(); - - if (existingPrimaryKeysCount == 0) { - this.isUpdatable = false; - this.notUpdatableReason = Messages.getString("NotUpdatableReason.5"); - - return; // we can't update tables w/o keys - } - - // - // Contains all primary keys? - // - for (int i = 0; i < this.fields.length; i++) { - if (this.fields[i].isPrimaryKey()) { - String columnNameUC = this.fields[i].getName() - .toUpperCase(); - - if (primaryKeyNames.remove(columnNameUC) == null) { - // try original name - String originalName = this.fields[i].getOriginalName(); - - if (originalName != null) { - if (primaryKeyNames.remove(originalName - .toUpperCase()) == null) { - // we don't know about this key, so give up :( - this.isUpdatable = false; - this.notUpdatableReason = Messages.getString("NotUpdatableReason.6", - new Object[] {originalName}); - - return; + + int existingPrimaryKeysCount = primaryKeyNames.size(); + + if (existingPrimaryKeysCount == 0) { + this.isUpdatable = false; + this.notUpdatableReason = Messages.getString("NotUpdatableReason.5"); + + return; // we can't update tables w/o keys + } + + // + // Contains all primary keys? + // + for (int i = 0; i < this.fields.length; i++) { + if (this.fields[i].isPrimaryKey()) { + String columnNameUC = this.fields[i].getName() + .toUpperCase(); + + if (primaryKeyNames.remove(columnNameUC) == null) { + // try original name + String originalName = this.fields[i].getOriginalName(); + + if (originalName != null) { + if (primaryKeyNames.remove(originalName + .toUpperCase()) == null) { + // we don't know about this key, so give up :( + this.isUpdatable = false; + this.notUpdatableReason = Messages.getString("NotUpdatableReason.6", + new Object[] {originalName}); + + return; + } } } } } - } - - this.isUpdatable = primaryKeyNames.isEmpty(); - - if (!this.isUpdatable) { - if (existingPrimaryKeysCount > 1) { - this.notUpdatableReason = Messages.getString("NotUpdatableReason.7"); - } else { - this.notUpdatableReason = Messages.getString("NotUpdatableReason.4"); + + this.isUpdatable = primaryKeyNames.isEmpty(); + + if (!this.isUpdatable) { + if (existingPrimaryKeysCount > 1) { + this.notUpdatableReason = Messages.getString("NotUpdatableReason.7"); + } else { + this.notUpdatableReason = Messages.getString("NotUpdatableReason.4"); + } + + return; } - + } + + // + // Must have at least one primary key + // + if (primaryKeyCount == 0) { + this.isUpdatable = false; + this.notUpdatableReason = Messages.getString("NotUpdatableReason.4"); + return; } - } - - // - // Must have at least one primary key - // - if (primaryKeyCount == 0) { - this.isUpdatable = false; - this.notUpdatableReason = Messages.getString("NotUpdatableReason.4"); - + + this.isUpdatable = true; + this.notUpdatableReason = null; + return; + } catch (SQLException sqlEx) { + this.isUpdatable = false; + this.notUpdatableReason = sqlEx.getMessage(); } - - this.isUpdatable = true; - this.notUpdatableReason = null; - - return; } /** * JDBC 2.0 Delete the current row from the result set and the underlying * database. Cannot be called when on the insert row. - * + * * @exception SQLException * if a database-access error occurs, or if called when on * the insert row. @@ -467,122 +450,150 @@ } if (this.onInsertRow) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.1")); //$NON-NLS-1$ + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.1"), getExceptionInterceptor()); //$NON-NLS-1$ } else if (this.rowData.size() == 0) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.2")); //$NON-NLS-1$ + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.2"), getExceptionInterceptor()); //$NON-NLS-1$ } else if (isBeforeFirst()) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.3")); //$NON-NLS-1$ + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.3"), getExceptionInterceptor()); //$NON-NLS-1$ } else if (isAfterLast()) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.4")); //$NON-NLS-1$ + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.4"), getExceptionInterceptor()); //$NON-NLS-1$ } if (this.deleter == null) { if (this.deleteSQL == null) { generateStatements(); } - this.deleter = this.connection + this.deleter = (PreparedStatement) this.connection .clientPrepareStatement(this.deleteSQL); } this.deleter.clearParameters(); - String characterEncoding = null; + int numKeys = this.primaryKeyIndicies.size(); - if (this.connection.getUseUnicode()) { - characterEncoding = this.connection.getEncoding(); - } - - // - // FIXME: Use internal routines where possible for character - // conversion! - try { - int numKeys = this.primaryKeyIndicies.size(); - - if (numKeys == 1) { - int index = ((Integer) this.primaryKeyIndicies.get(0)) + 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(); - String currentVal = ((characterEncoding == null) ? new String( - (byte[]) this.thisRow[index]) : new String( - (byte[]) this.thisRow[index], characterEncoding)); - this.deleter.setString(1, currentVal); - } else { - for (int i = 0; i < numKeys; i++) { - int index = ((Integer) this.primaryKeyIndicies.get(i)) - .intValue(); - String currentVal = ((characterEncoding == null) ? new String( - (byte[]) this.thisRow[index]) - : new String((byte[]) this.thisRow[index], - characterEncoding)); - this.deleter.setString(i + 1, currentVal); - } + this.setParamValue(this.deleter, i + 1, this.thisRow, + index, this.fields[index].getSQLType()); + } + } - this.deleter.executeUpdate(); - this.rowData.removeRow(this.rowData.getCurrentRowNumber()); - } catch (java.io.UnsupportedEncodingException encodingEx) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.39", //$NON-NLS-1$ - new Object[] { this.charEncoding }) //$NON-NLS-1$ - , SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$ + this.deleter.executeUpdate(); + this.rowData.removeRow(this.rowData.getCurrentRowNumber()); + + // position on previous row - Bug#27431 + previous(); + + } + + private synchronized 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); + return; } + switch (sqlType) { + case Types.NULL: + ps.setNull(psIdx, Types.NULL); + break; + case Types.TINYINT: + case Types.SMALLINT: + case Types.INTEGER: + ps.setInt(psIdx, row.getInt(rsIdx)); + break; + case Types.BIGINT: + ps.setLong(psIdx, row.getLong(rsIdx)); + break; + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + case Types.DECIMAL: + case Types.NUMERIC: + ps.setString(psIdx, row.getString(rsIdx, this.charEncoding, this.connection)); + break; + case Types.DATE: + ps.setDate(psIdx, row.getDateFast(rsIdx, this.connection, this, this.fastDateCal), this.fastDateCal); + break; + case Types.TIMESTAMP: + ps.setTimestamp(psIdx, row.getTimestampFast(rsIdx, this.fastDateCal, this.defaultTimeZone, false, this.connection, this)); + break; + case Types.TIME: + ps.setTime(psIdx, row.getTimeFast(rsIdx, this.fastDateCal, this.defaultTimeZone, false, this.connection, this)); + break; + case Types.FLOAT: + case Types.DOUBLE: + case Types.REAL: + case Types.BOOLEAN: + ps.setBytesNoEscapeNoQuotes(psIdx, val); + break; + /* default, but also explicitly for following types: + case Types.BINARY: + case Types.BLOB: + */ + default: + ps.setBytes(psIdx, val); + break; + } + } private synchronized void extractDefaultValues() throws SQLException { java.sql.DatabaseMetaData dbmd = this.connection.getMetaData(); - + this.defaultColumnValue = new byte[this.fields.length][]; + java.sql.ResultSet columnsResultSet = null; + + for (Map.Entry>> dbEntry : this.databasesUsedToTablesUsed.entrySet()) { + //String databaseName = dbEntry.getKey().toString(); + for (Map.Entry> tableEntry : dbEntry.getValue().entrySet()) { + String tableName = tableEntry.getKey(); + Map columnNamesToIndices = tableEntry.getValue(); - try { - columnsResultSet = dbmd.getColumns(this.catalog, null, - this.tableOnlyName, "%"); //$NON-NLS-1$ + try { + columnsResultSet = dbmd.getColumns(this.catalog, null, + tableName, "%"); //$NON-NLS-1$ - HashMap columnNameToDefaultValueMap = new HashMap( - this.fields.length /* at least this big... */); + while (columnsResultSet.next()) { + String columnName = columnsResultSet.getString("COLUMN_NAME"); //$NON-NLS-1$ + byte[] defaultValue = columnsResultSet.getBytes("COLUMN_DEF"); //$NON-NLS-1$ - while (columnsResultSet.next()) { - String columnName = columnsResultSet.getString("COLUMN_NAME"); //$NON-NLS-1$ - byte[] defaultValue = columnsResultSet.getBytes("COLUMN_DEF"); //$NON-NLS-1$ + if (columnNamesToIndices.containsKey(columnName)) { + int localColumnIndex = columnNamesToIndices.get(columnName).intValue(); - columnNameToDefaultValueMap.put(columnName, defaultValue); - } + this.defaultColumnValue[localColumnIndex] = defaultValue; + } // else assert? + } + } finally { + if (columnsResultSet != null) { + columnsResultSet.close(); - int numFields = this.fields.length; - - this.defaultColumnValue = new byte[numFields][]; - - for (int i = 0; i < numFields; i++) { - String defValTableName = this.fields[i].getOriginalName(); - - if ((defValTableName == null) - || (defValTableName.length() == 0)) { - defValTableName = this.fields[i].getName(); - } - - if (defValTableName != null) { - byte[] defaultVal = (byte[]) columnNameToDefaultValueMap - .get(defValTableName); - - this.defaultColumnValue[i] = defaultVal; - } - } - } finally { - if (columnsResultSet != null) { - columnsResultSet.close(); - - columnsResultSet = null; - } + columnsResultSet = null; + } + } + } } } /** * JDBC 2.0 - * + * *

    * Moves to the first row in the result set. *

    - * + * * @return true if on a valid row, false if no rows in the result set. - * + * * @exception SQLException * if a database-access error occurs, or result set type is * TYPE_FORWARD_ONLY. @@ -594,7 +605,7 @@ /** * Figure out whether or not this ResultSet is updateable, and if so, * generate the PreparedStatements to support updates. - * + * * @throws SQLException * DOCUMENT ME! * @throws NotUpdatable @@ -610,50 +621,92 @@ String quotedId = getQuotedIdChar(); - if (this.fields[0].getOriginalTableName() != null) { - StringBuffer tableNameBuffer = new StringBuffer(); + Map tableNamesSoFar = null; - String databaseName = this.fields[0].getDatabaseName(); - - if ((databaseName != null) && (databaseName.length() > 0)) { - tableNameBuffer.append(quotedId); - tableNameBuffer.append(databaseName); - tableNameBuffer.append(quotedId); - tableNameBuffer.append('.'); - } - - this.tableOnlyName = this.fields[0].getOriginalTableName(); - - tableNameBuffer.append(quotedId); - tableNameBuffer.append(this.tableOnlyName); - tableNameBuffer.append(quotedId); - - this.qualifiedAndQuotedTableName = tableNameBuffer.toString(); + if (this.connection.lowerCaseTableNames()) { + tableNamesSoFar = new TreeMap(String.CASE_INSENSITIVE_ORDER); + this.databasesUsedToTablesUsed = new TreeMap>>(String.CASE_INSENSITIVE_ORDER); } else { - StringBuffer tableNameBuffer = new StringBuffer(); - - this.tableOnlyName = this.fields[0].getTableName(); - - tableNameBuffer.append(quotedId); - tableNameBuffer.append(this.tableOnlyName); - tableNameBuffer.append(quotedId); - - this.qualifiedAndQuotedTableName = tableNameBuffer.toString(); + tableNamesSoFar = new TreeMap(); + this.databasesUsedToTablesUsed = new TreeMap>>(); } - this.primaryKeyIndicies = new ArrayList(); + this.primaryKeyIndicies = new ArrayList(); StringBuffer fieldValues = new StringBuffer(); StringBuffer keyValues = new StringBuffer(); StringBuffer columnNames = new StringBuffer(); StringBuffer insertPlaceHolders = new StringBuffer(); + StringBuffer allTablesBuf = new StringBuffer(); + Map columnIndicesToTable = new HashMap(); + boolean firstTime = true; boolean keysFirstTime = true; String equalsStr = this.connection.versionMeetsMinimum(3, 23, 0) ? "<=>" : "="; for (int i = 0; i < this.fields.length; i++) { + StringBuffer tableNameBuffer = new StringBuffer(); + Map updColumnNameToIndex = null; + + // FIXME: What about no table? + if (this.fields[i].getOriginalTableName() != null) { + + String databaseName = this.fields[i].getDatabaseName(); + + if ((databaseName != null) && (databaseName.length() > 0)) { + tableNameBuffer.append(quotedId); + tableNameBuffer.append(databaseName); + tableNameBuffer.append(quotedId); + tableNameBuffer.append('.'); + } + + String tableOnlyName = this.fields[i].getOriginalTableName(); + + tableNameBuffer.append(quotedId); + tableNameBuffer.append(tableOnlyName); + tableNameBuffer.append(quotedId); + + String fqTableName = tableNameBuffer.toString(); + + if (!tableNamesSoFar.containsKey(fqTableName)) { + if (!tableNamesSoFar.isEmpty()) { + allTablesBuf.append(','); + } + + allTablesBuf.append(fqTableName); + tableNamesSoFar.put(fqTableName, fqTableName); + } + + columnIndicesToTable.put(Integer.valueOf(i), fqTableName); + + updColumnNameToIndex = getColumnsToIndexMapForTableAndDB(databaseName, tableOnlyName); + } else { + String tableOnlyName = this.fields[i].getTableName(); + + if (tableOnlyName != null) { + tableNameBuffer.append(quotedId); + tableNameBuffer.append(tableOnlyName); + tableNameBuffer.append(quotedId); + + String fqTableName = tableNameBuffer.toString(); + + if (!tableNamesSoFar.containsKey(fqTableName)) { + if (!tableNamesSoFar.isEmpty()) { + allTablesBuf.append(','); + } + + allTablesBuf.append(fqTableName); + tableNamesSoFar.put(fqTableName, fqTableName); + } + + columnIndicesToTable.put(Integer.valueOf(i), fqTableName); + + updColumnNameToIndex = getColumnsToIndexMapForTableAndDB(this.catalog, tableOnlyName); + } + } + String originalColumnName = this.fields[i].getOriginalName(); String columnName = null; @@ -665,18 +718,51 @@ columnName = this.fields[i].getName(); } + if (updColumnNameToIndex != null && columnName != null) { + updColumnNameToIndex.put(columnName, Integer.valueOf(i)); + } + + String originalTableName = this.fields[i].getOriginalTableName(); + String tableName = null; + + if (this.connection.getIO().hasLongColumnInfo() + && (originalTableName != null) + && (originalTableName.length() > 0)) { + tableName = originalTableName; + } else { + tableName = this.fields[i].getTableName(); + } + + StringBuffer fqcnBuf = new StringBuffer(); + String databaseName = this.fields[i].getDatabaseName(); + + if (databaseName != null && databaseName.length() > 0) { + fqcnBuf.append(quotedId); + fqcnBuf.append(databaseName); + fqcnBuf.append(quotedId); + fqcnBuf.append('.'); + } + + fqcnBuf.append(quotedId); + fqcnBuf.append(tableName); + fqcnBuf.append(quotedId); + fqcnBuf.append('.'); + fqcnBuf.append(quotedId); + fqcnBuf.append(columnName); + fqcnBuf.append(quotedId); + + String qualifiedColumnName = fqcnBuf.toString(); + if (this.fields[i].isPrimaryKey()) { - this.primaryKeyIndicies.add(new Integer(i)); + this.primaryKeyIndicies.add(Integer.valueOf(i)); if (!keysFirstTime) { keyValues.append(" AND "); //$NON-NLS-1$ } else { keysFirstTime = false; } - keyValues.append(quotedId); - keyValues.append(columnName); - keyValues.append(quotedId); + keyValues.append(qualifiedColumnName); keyValues.append(equalsStr); keyValues.append("?"); //$NON-NLS-1$ } @@ -692,16 +778,14 @@ insertPlaceHolders.append("?"); //$NON-NLS-1$ - columnNames.append(quotedId); - columnNames.append(columnName); - columnNames.append(quotedId); + columnNames.append(qualifiedColumnName); - fieldValues.append(quotedId); - fieldValues.append(columnName); - fieldValues.append(quotedId); + fieldValues.append(qualifiedColumnName); fieldValues.append("=?"); //$NON-NLS-1$ } + this.qualifiedAndQuotedTableName = allTablesBuf.toString(); + this.updateSQL = "UPDATE " + this.qualifiedAndQuotedTableName + " " //$NON-NLS-1$ //$NON-NLS-2$ + fieldValues.toString() //$NON-NLS-1$ //$NON-NLS-2$ + " WHERE " + keyValues.toString(); //$NON-NLS-1$ @@ -716,6 +800,30 @@ + keyValues.toString(); } + private Map getColumnsToIndexMapForTableAndDB(String databaseName, String tableName) { + Map nameToIndex; + Map> tablesUsedToColumnsMap = this.databasesUsedToTablesUsed.get(databaseName); + + if (tablesUsedToColumnsMap == null) { + if (this.connection.lowerCaseTableNames()) { + tablesUsedToColumnsMap = new TreeMap>(String.CASE_INSENSITIVE_ORDER); + } else { + tablesUsedToColumnsMap = new TreeMap>(); + } + + this.databasesUsedToTablesUsed.put(databaseName, tablesUsedToColumnsMap); + } + + nameToIndex = tablesUsedToColumnsMap.get(tableName); + + if (nameToIndex == null) { + nameToIndex = new HashMap(); + tablesUsedToColumnsMap.put(tableName, nameToIndex); + } + + return nameToIndex; + } + private synchronized SingleByteCharsetConverter getCharConverter() throws SQLException { if (!this.initializedCharConverter) { @@ -734,9 +842,9 @@ /** * JDBC 2.0 Return the concurrency of this result set. The concurrency used * is determined by the statement that created the result set. - * + * * @return the concurrency type, CONCUR_READ_ONLY, etc. - * + * * @exception SQLException * if a database-access error occurs */ @@ -763,7 +871,7 @@ /** * JDBC 2.0 Insert the contents of the insert row into the result set and * the database. Must be on the insert row when this method is called. - * + * * @exception SQLException * if a database-access error occurs, if called when not on * the insert row, or if all non-nullable columns in the @@ -773,7 +881,7 @@ checkClosed(); if (!this.onInsertRow) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.7")); //$NON-NLS-1$ + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.7"), getExceptionInterceptor()); //$NON-NLS-1$ } this.inserter.executeUpdate(); @@ -794,28 +902,29 @@ // than one auto-increment key (which is the way it is _today_) // if (this.fields[i].isAutoIncrement() && autoIncrementId > 0) { - newRow[i] = String.valueOf(autoIncrementId).getBytes(); + newRow[i] = StringUtils.getBytes(String.valueOf(autoIncrementId)); this.inserter.setBytesNoEscapeNoQuotes(i + 1, newRow[i]); } } - - refreshRow(this.inserter, newRow); - - this.rowData.addRow(newRow); + + ResultSetRow resultSetRow = new ByteArrayRow(newRow, getExceptionInterceptor()); + + refreshRow(this.inserter, resultSetRow); + + this.rowData.addRow(resultSetRow); resetInserter(); } - /** * JDBC 2.0 - * + * *

    * Determine if the cursor is after the last row in the result set. *

    - * + * * @return true if after the last row, false otherwise. Returns false when * the result set contains no rows. - * + * * @exception SQLException * if a database-access error occurs. */ @@ -825,14 +934,14 @@ /** * JDBC 2.0 - * + * *

    * Determine if the cursor is before the first row in the result set. *

    - * + * * @return true if before the first row, false otherwise. Returns false when * the result set contains no rows. - * + * * @exception SQLException * if a database-access error occurs. */ @@ -842,13 +951,13 @@ /** * JDBC 2.0 - * + * *

    * Determine if the cursor is on the first row of the result set. *

    - * + * * @return true if on the first row, false otherwise. - * + * * @exception SQLException * if a database-access error occurs. */ @@ -858,16 +967,16 @@ /** * JDBC 2.0 - * + * *

    * Determine if the cursor is on the last row of the result set. Note: * Calling isLast() may be expensive since the JDBC driver might need to * fetch ahead one row in order to determine whether the current row is the * last row in the result set. *

    - * + * * @return true if on the last row, false otherwise. - * + * * @exception SQLException * if a database-access error occurs. */ @@ -881,13 +990,13 @@ /** * JDBC 2.0 - * + * *

    * Moves to the last row in the result set. *

    - * + * * @return true if on a valid row, false if no rows in the result set. - * + * * @exception SQLException * if a database-access error occurs, or result set type is * TYPE_FORWARD_ONLY. @@ -899,7 +1008,7 @@ /** * JDBC 2.0 Move the cursor to the remembered cursor position, usually the * current row. Has no effect unless the cursor is on the insert row. - * + * * @exception SQLException * if a database-access error occurs, or the result set is * not updatable @@ -929,7 +1038,7 @@ * cursor is on the insert row. All of the columns in a result set must be * given a value each time this method is called before calling insertRow(). * UpdateXXX()must be called before getXXX() on a column. - * + * * @exception SQLException * if a database-access error occurs, or the result set is * not updatable @@ -948,12 +1057,12 @@ generateStatements(); } - this.inserter = this.connection + this.inserter = (PreparedStatement) this.connection .clientPrepareStatement(this.insertSQL); if (this.populateInserterWithDefaultValues) { extractDefaultValues(); } - + resetInserter(); } else { resetInserter(); @@ -964,24 +1073,25 @@ this.onInsertRow = true; this.doingUpdates = false; this.savedCurrentRow = this.thisRow; - this.thisRow = new byte[numFields][]; + 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, - "DEFAULT".getBytes()); - this.thisRow[i] = null; + 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: - + if (this.defaultColumnValue[i].length > 7 && this.defaultColumnValue[i][0] == (byte) 'C' && this.defaultColumnValue[i][1] == (byte) 'U' @@ -993,40 +1103,44 @@ && this.defaultColumnValue[i][7] == (byte) '_') { this.inserter.setBytesNoEscapeNoQuotes(i + 1, this.defaultColumnValue[i]); - + 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(defaultColumnValue[i], 0, defaultValueCopy, 0, defaultValueCopy.length); - this.thisRow[i] = defaultValueCopy; + newRowData[i] = defaultValueCopy; } else { this.inserter.setNull(i + 1, java.sql.Types.NULL); - this.thisRow[i] = null; + newRowData[i] = null; } } } } - + + // --------------------------------------------------------------------- + // Updates + // --------------------------------------------------------------------- + /** * A ResultSet is initially positioned before its first row, the first call * to next makes the first row the current row; the second call makes the * second row the current row, etc. - * + * *

    * If an input stream from the previous row is open, it is implicitly * closed. The ResultSet's warning chain is cleared when a new row is read *

    - * + * * @return true if the new current is valid; false if there are no more rows - * + * * @exception SQLException * if a database access error occurs */ @@ -1038,14 +1152,14 @@ * The prev method is not part of JDBC, but because of the architecture of * this driver it is possible to move both forward and backward within the * result set. - * + * *

    * If an input stream from the previous row is open, it is implicitly * closed. The ResultSet's warning chain is cleared when a new row is read *

    - * + * * @return true if the new current is valid; false if there are no more rows - * + * * @exception SQLException * if a database access error occurs */ @@ -1055,18 +1169,18 @@ /** * JDBC 2.0 - * + * *

    * Moves to the previous row in the result set. *

    - * + * *

    * Note: previous() is not the same as relative(-1) since it makes sense to * call previous() when there is no current row. *

    - * + * * @return true if on a valid row, false if off the result set. - * + * * @exception SQLException * if a database-access error occurs, or result set type is * TYPE_FORWAR_DONLY. @@ -1076,25 +1190,26 @@ } /** - * Closes this ResultSet, releasing all resources. + * Closes this ResultSet and releases resources. * * @param calledExplicitly - * was this called from close()? + * was realClose called by the standard ResultSet.close() method, or was it closed internally by the + * driver? * * @throws SQLException * if an error occurs. */ - protected void realClose(boolean calledExplicitly) throws SQLException { + public synchronized void realClose(boolean calledExplicitly) throws SQLException { if (this.isClosed) { return; } - + SQLException sqlEx = null; if (this.useUsageAdvisor) { if ((this.deleter == null) && (this.inserter == null) && (this.refresher == null) && (this.updater == null)) { - this.eventSink = ProfileEventSink.getInstance(this.connection); + this.eventSink = ProfilerEventHandlerFactory.getInstance(this.connection); String message = Messages.getString("UpdatableResultSet.34"); //$NON-NLS-1$ @@ -1163,7 +1278,7 @@ * calling updateXXX(), but before calling updateRow() then the updates made * to the row are lost. Calling refreshRow() frequently will likely slow * performance. - * + * * @exception SQLException * if a database-access error occurs, or if called when on * the insert row. @@ -1178,26 +1293,26 @@ } if (this.onInsertRow) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.8")); //$NON-NLS-1$ + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.8"), getExceptionInterceptor()); //$NON-NLS-1$ } else if (this.rowData.size() == 0) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.9")); //$NON-NLS-1$ + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.9"), getExceptionInterceptor()); //$NON-NLS-1$ } else if (isBeforeFirst()) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.10")); //$NON-NLS-1$ + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.10"), getExceptionInterceptor()); //$NON-NLS-1$ } else if (isAfterLast()) { - throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.11")); //$NON-NLS-1$ + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.11"), getExceptionInterceptor()); //$NON-NLS-1$ } refreshRow(this.updater, this.thisRow); } - - private synchronized void refreshRow(PreparedStatement updateInsertStmt, - Object[] rowToRefresh) throws SQLException { + + private synchronized void refreshRow(PreparedStatement updateInsertStmt, + ResultSetRow rowToRefresh) throws SQLException { if (this.refresher == null) { if (this.refreshSQL == null) { generateStatements(); } - this.refresher = this.connection + this.refresher = (PreparedStatement) this.connection .clientPrepareStatement(this.refreshSQL); } @@ -1207,36 +1322,41 @@ if (numKeys == 1) { byte[] dataFrom = null; - int index = ((Integer) this.primaryKeyIndicies.get(0)).intValue(); + int index = this.primaryKeyIndicies.get(0).intValue(); if (!this.doingUpdates && !this.onInsertRow) { - dataFrom = (byte[]) rowToRefresh[index]; + dataFrom = rowToRefresh.getColumnValue(index); } else { dataFrom = updateInsertStmt.getBytesRepresentation(index); // Primary keys not set? if (updateInsertStmt.isNull(index) || (dataFrom.length == 0)) { - dataFrom = (byte[]) rowToRefresh[index]; + dataFrom = rowToRefresh.getColumnValue(index); } else { dataFrom = stripBinaryPrefix(dataFrom); } } - this.refresher.setBytesNoEscape(1, dataFrom); + if (this.fields[index].getvalueNeedsQuoting()) { + this.refresher.setBytesNoEscape(1, dataFrom); + } else { + this.refresher.setBytesNoEscapeNoQuotes(1, dataFrom); + } + } else { for (int i = 0; i < numKeys; i++) { byte[] dataFrom = null; - int index = ((Integer) this.primaryKeyIndicies.get(i)) + int index = this.primaryKeyIndicies.get(i) .intValue(); if (!this.doingUpdates && !this.onInsertRow) { - dataFrom = (byte[]) rowToRefresh[index]; + dataFrom = rowToRefresh.getColumnValue(index); } else { dataFrom = updateInsertStmt.getBytesRepresentation(index); // Primary keys not set? if (updateInsertStmt.isNull(index) || (dataFrom.length == 0)) { - dataFrom = (byte[]) this.thisRow[index]; + dataFrom = rowToRefresh.getColumnValue(index); } else { dataFrom = stripBinaryPrefix(dataFrom); } @@ -1258,15 +1378,15 @@ byte[] val = rs.getBytes(i + 1); if ((val == null) || rs.wasNull()) { - rowToRefresh[i] = null; + rowToRefresh.setColumnValue(i, null); } else { - rowToRefresh[i] = rs.getBytes(i + 1); + rowToRefresh.setColumnValue(i, rs.getBytes(i + 1)); } } } else { throw SQLError.createSQLException(Messages .getString("UpdatableResultSet.12"), //$NON-NLS-1$ - SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$ + SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor()); //$NON-NLS-1$ } } finally { if (rs != null) { @@ -1281,26 +1401,26 @@ /** * JDBC 2.0 - * + * *

    * Moves a relative number of rows, either positive or negative. Attempting * to move beyond the first/last row in the result set positions the cursor * before/after the the first/last row. Calling relative(0) is valid, but * does not change the cursor position. *

    - * + * *

    * Note: Calling relative(1) is different than calling next() since is makes * sense to call next() when there is no current row, for example, when the * cursor is positioned before the first row or after the last row of the * result set. *

    - * + * * @param rows * DOCUMENT ME! - * + * * @return true if on a row, false otherwise. - * + * * @exception SQLException * if a database-access error occurs, or there is no current * row, or result set type is TYPE_FORWARD_ONLY. @@ -1322,59 +1442,59 @@ * a visible "hole" in a result set. This method can be used to detect holes * in a result set. The value returned depends on whether or not the result * set can detect deletions. - * + * * @return true if deleted and deletes are detected - * + * * @exception SQLException * if a database-access error occurs * @throws NotImplemented * DOCUMENT ME! - * + * * @see DatabaseMetaData#deletesAreDetected */ public synchronized boolean rowDeleted() throws SQLException { - throw new NotImplemented(); + throw SQLError.notImplemented(); } /** * JDBC 2.0 Determine if the current row has been inserted. The value * returned depends on whether or not the result set can detect visible * inserts. - * + * * @return true if inserted and inserts are detected - * + * * @exception SQLException * if a database-access error occurs * @throws NotImplemented * DOCUMENT ME! - * + * * @see DatabaseMetaData#insertsAreDetected */ public synchronized boolean rowInserted() throws SQLException { - throw new NotImplemented(); + throw SQLError.notImplemented(); } /** * JDBC 2.0 Determine if the current row has been updated. The value * returned depends on whether or not the result set can detect updates. - * + * * @return true if the row has been visibly updated by the owner or another, * and updates are detected - * + * * @exception SQLException * if a database-access error occurs * @throws NotImplemented * DOCUMENT ME! - * + * * @see DatabaseMetaData#updatesAreDetected */ public synchronized boolean rowUpdated() throws SQLException { - throw new NotImplemented(); + throw SQLError.notImplemented(); } /** * Sets the concurrency type of this result set - * + * * @param concurrencyFlag * the type of concurrency that this ResultSet should support. */ @@ -1399,27 +1519,32 @@ /** * Reset UPDATE prepared statement to value in current row. This_Row MUST * point to current, valid row. - * + * * @throws SQLException * DOCUMENT ME! */ - synchronized void syncUpdate() throws SQLException { + protected synchronized void syncUpdate() throws SQLException { if (this.updater == null) { if (this.updateSQL == null) { generateStatements(); } - this.updater = this.connection + this.updater = (PreparedStatement) this.connection .clientPrepareStatement(this.updateSQL); } int numFields = this.fields.length; this.updater.clearParameters(); for (int i = 0; i < numFields; i++) { - if (this.thisRow[i] != null) { - this.updater.setBytes(i + 1, (byte[]) this.thisRow[i], - this.fields[i].isBinary(), false); + if (this.thisRow.getColumnValue(i) != null) { + + if (this.fields[i].getvalueNeedsQuoting()) { + this.updater.setBytes(i + 1, this.thisRow.getColumnValue(i), + this.fields[i].isBinary(), false); + } else { + this.updater.setBytesNoEscapeNoQuotes(i + 1, this.thisRow.getColumnValue(i)); + } } else { this.updater.setNull(i + 1, 0); } @@ -1428,20 +1553,14 @@ int numKeys = this.primaryKeyIndicies.size(); if (numKeys == 1) { - int index = ((Integer) this.primaryKeyIndicies.get(0)).intValue(); - byte[] keyData = (byte[]) this.thisRow[index]; - this.updater.setBytes(numFields + 1, keyData, false, false); + int index = this.primaryKeyIndicies.get(0).intValue(); + this.setParamValue(this.updater, numFields + 1, this.thisRow, index , + this.fields[index].getSQLType()); } else { for (int i = 0; i < numKeys; i++) { - byte[] currentVal = (byte[]) this.thisRow[((Integer) this.primaryKeyIndicies - .get(i)).intValue()]; - - if (currentVal != null) { - this.updater.setBytes(numFields + i + 1, currentVal, false, - false); - } else { - this.updater.setNull(numFields + i + 1, 0); - } + int idx = this.primaryKeyIndicies.get(i).intValue(); + this.setParamValue(this.updater, numFields + i + 1, this.thisRow, + idx , this.fields[idx].getSQLType()); } } } @@ -1452,14 +1571,14 @@ * insert row. The updateXXX() methods do not update the underlying * database, instead the updateRow() or insertRow() methods are called to * update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value * @param length * the length of the stream - * + * * @exception SQLException * if a database-access error occurs */ @@ -1474,7 +1593,7 @@ this.updater.setAsciiStream(columnIndex, x, length); } else { this.inserter.setAsciiStream(columnIndex, x, length); - this.thisRow[columnIndex - 1] = STREAM_DATA_MARKER; + this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); } } @@ -1484,14 +1603,14 @@ * insert row. The updateXXX() methods do not update the underlying * database, instead the updateRow() or insertRow() methods are called to * update the database. - * + * * @param columnName * the name of the column * @param x * the new column value * @param length * of the stream - * + * * @exception SQLException * if a database-access error occurs */ @@ -1505,12 +1624,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1527,9 +1646,9 @@ this.inserter.setBigDecimal(columnIndex, x); if (x == null) { - this.thisRow[columnIndex - 1] = null; + this.thisRow.setColumnValue(columnIndex - 1, null); } else { - this.thisRow[columnIndex - 1] = x.toString().getBytes(); + this.thisRow.setColumnValue(columnIndex - 1, StringUtils.getBytes(x.toString())); } } } @@ -1539,12 +1658,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1559,14 +1678,14 @@ * insert row. The updateXXX() methods do not update the underlying * database, instead the updateRow() or insertRow() methods are called to * update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value * @param length * the length of the stream - * + * * @exception SQLException * if a database-access error occurs */ @@ -1583,9 +1702,9 @@ this.inserter.setBinaryStream(columnIndex, x, length); if (x == null) { - this.thisRow[columnIndex - 1] = null; + this.thisRow.setColumnValue(columnIndex - 1, null); } else { - this.thisRow[columnIndex - 1] = STREAM_DATA_MARKER; + this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); } } } @@ -1596,14 +1715,14 @@ * insert row. The updateXXX() methods do not update the underlying * database, instead the updateRow() or insertRow() methods are called to * update the database. - * + * * @param columnName * the name of the column * @param x * the new column value * @param length * of the stream - * + * * @exception SQLException * if a database-access error occurs */ @@ -1613,7 +1732,7 @@ } /** - * @see ResultSet#updateBlob(int, Blob) + * @see ResultSetInternalMethods#updateBlob(int, Blob) */ public synchronized void updateBlob(int columnIndex, java.sql.Blob blob) throws SQLException { @@ -1628,15 +1747,15 @@ this.inserter.setBlob(columnIndex, blob); if (blob == null) { - this.thisRow[columnIndex - 1] = null; + this.thisRow.setColumnValue(columnIndex - 1, null); } else { - this.thisRow[columnIndex - 1] = STREAM_DATA_MARKER; + this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); } } } /** - * @see ResultSet#updateBlob(String, Blob) + * @see ResultSetInternalMethods#updateBlob(String, Blob) */ public synchronized void updateBlob(String columnName, java.sql.Blob blob) throws SQLException { @@ -1648,12 +1767,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1669,8 +1788,8 @@ } else { this.inserter.setBoolean(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -1679,12 +1798,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1698,12 +1817,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1719,8 +1838,8 @@ } else { this.inserter.setByte(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -1729,12 +1848,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1748,12 +1867,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1769,7 +1888,7 @@ } else { this.inserter.setBytes(columnIndex, x); - this.thisRow[columnIndex - 1] = x; + this.thisRow.setColumnValue(columnIndex - 1, x); } } @@ -1778,12 +1897,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1798,14 +1917,14 @@ * insert row. The updateXXX() methods do not update the underlying * database, instead the updateRow() or insertRow() methods are called to * update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value * @param length * the length of the stream - * + * * @exception SQLException * if a database-access error occurs */ @@ -1822,9 +1941,9 @@ this.inserter.setCharacterStream(columnIndex, x, length); if (x == null) { - this.thisRow[columnIndex - 1] = null; + this.thisRow.setColumnValue(columnIndex - 1, null); } else { - this.thisRow[columnIndex - 1] = STREAM_DATA_MARKER; + this.thisRow.setColumnValue(columnIndex - 1, STREAM_DATA_MARKER); } } } @@ -1835,14 +1954,14 @@ * insert row. The updateXXX() methods do not update the underlying * database, instead the updateRow() or insertRow() methods are called to * update the database. - * + * * @param columnName * the name of the column * @param reader * the new column value * @param length * of the stream - * + * * @exception SQLException * if a database-access error occurs */ @@ -1852,7 +1971,7 @@ } /** - * @see ResultSet#updateClob(int, Clob) + * @see ResultSetInternalMethods#updateClob(int, Clob) */ public void updateClob(int columnIndex, java.sql.Clob clob) throws SQLException { @@ -1869,12 +1988,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1890,8 +2009,8 @@ } else { this.inserter.setDate(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -1900,12 +2019,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1919,12 +2038,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1940,8 +2059,8 @@ } else { this.inserter.setDouble(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -1950,12 +2069,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1969,12 +2088,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -1990,8 +2109,8 @@ } else { this.inserter.setFloat(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -2000,12 +2119,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2019,12 +2138,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2040,8 +2159,8 @@ } else { this.inserter.setInt(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -2050,12 +2169,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2069,12 +2188,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2090,8 +2209,8 @@ } else { this.inserter.setLong(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -2100,12 +2219,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2119,10 +2238,10 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... - * + * * @exception SQLException * if a database-access error occurs */ @@ -2137,7 +2256,7 @@ } else { this.inserter.setNull(columnIndex, 0); - this.thisRow[columnIndex - 1] = null; + this.thisRow.setColumnValue(columnIndex - 1, null); } } @@ -2146,10 +2265,10 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column - * + * * @exception SQLException * if a database-access error occurs */ @@ -2162,12 +2281,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2183,8 +2302,8 @@ } else { this.inserter.setObject(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -2193,7 +2312,7 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x @@ -2202,7 +2321,7 @@ * For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types * this is the number of digits after the decimal. For all other * types this value will be ignored. - * + * * @exception SQLException * if a database-access error occurs */ @@ -2218,8 +2337,8 @@ } else { this.inserter.setObject(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -2228,12 +2347,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2247,7 +2366,7 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x @@ -2256,7 +2375,7 @@ * For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types * this is the number of digits after the decimal. For all other * types this value will be ignored. - * + * * @exception SQLException * if a database-access error occurs */ @@ -2268,7 +2387,7 @@ /** * JDBC 2.0 Update the underlying database with the new contents of the * current row. Cannot be called when on the insert row. - * + * * @exception SQLException * if a database-access error occurs, or if called when on * the insert row @@ -2284,6 +2403,8 @@ this.updater.executeUpdate(); refreshRow(); this.doingUpdates = false; + } else if (this.onInsertRow) { + throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.44"), getExceptionInterceptor()); //$NON-NLS-1$ } // @@ -2297,12 +2418,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2318,8 +2439,8 @@ } else { this.inserter.setShort(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -2328,12 +2449,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2347,19 +2468,19 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ public synchronized void updateString(int columnIndex, String x) throws SQLException { checkClosed(); - + if (!this.onInsertRow) { if (!this.doingUpdates) { this.doingUpdates = true; @@ -2371,15 +2492,15 @@ this.inserter.setString(columnIndex, x); if (x == null) { - this.thisRow[columnIndex - 1] = null; + this.thisRow.setColumnValue(columnIndex - 1, null); } else { if (getCharConverter() != null) { - this.thisRow[columnIndex - 1] = StringUtils.getBytes(x, + this.thisRow.setColumnValue(columnIndex - 1, StringUtils.getBytes(x, this.charConverter, this.charEncoding, this.connection.getServerCharacterEncoding(), - this.connection.parserKnowsUnicode()); + this.connection.parserKnowsUnicode(), getExceptionInterceptor())); } else { - this.thisRow[columnIndex - 1] = x.getBytes(); + this.thisRow.setColumnValue(columnIndex - 1, StringUtils.getBytes(x)); } } } @@ -2390,12 +2511,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2409,12 +2530,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2430,8 +2551,8 @@ } else { this.inserter.setTime(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -2440,12 +2561,12 @@ * used to update column values in the current row, or the insert row. The * updateXXX() methods do not update the underlying database, instead the * updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2459,12 +2580,12 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnIndex * the first column is 1, the second is 2, ... * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ @@ -2480,8 +2601,8 @@ } else { this.inserter.setTimestamp(columnIndex, x); - this.thisRow[columnIndex - 1] = this.inserter - .getBytesRepresentation(columnIndex - 1); + this.thisRow.setColumnValue(columnIndex - 1, this.inserter + .getBytesRepresentation(columnIndex - 1)); } } @@ -2490,17 +2611,17 @@ * are used to update column values in the current row, or the insert row. * The updateXXX() methods do not update the underlying database, instead * the updateRow() or insertRow() methods are called to update the database. - * + * * @param columnName * the name of the column * @param x * the new column value - * + * * @exception SQLException * if a database-access error occurs */ public synchronized void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException { updateTimestamp(findColumn(columnName), x); } -} \ No newline at end of file +} Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Util.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/Util.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Util.java 17 Aug 2012 14:57:08 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Util.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,34 +1,42 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.ObjectInputStream; import java.io.PrintWriter; import java.io.StringWriter; +import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; import java.util.TimeZone; /** @@ -37,20 +45,68 @@ * @author Mark Matthews */ public class Util { + protected final static Method systemNanoTimeMethod; - protected static Method systemNanoTimeMethod; - - private static boolean isColdFusion = false; - static { + Method aMethod; + try { - systemNanoTimeMethod = System.class.getMethod("nanoTime", null); + aMethod = System.class.getMethod("nanoTime", (Class[])null); } catch (SecurityException e) { - systemNanoTimeMethod = null; + aMethod = null; } catch (NoSuchMethodException e) { - systemNanoTimeMethod = null; + aMethod = null; } + systemNanoTimeMethod = aMethod; + } + + public static boolean nanoTimeAvailable() { + return systemNanoTimeMethod != null; + } + + private static Method CAST_METHOD; + + // cache this ourselves, as the method call is statically-synchronized in + // all but JDK6! + + private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getDefault(); + + static final TimeZone getDefaultTimeZone() { + return (TimeZone) DEFAULT_TIMEZONE.clone(); + } + + class RandStructcture { + long maxValue; + + double maxValueDbl; + + long seed1; + + long seed2; + } + + private static Util enclosingInstance = new Util(); + + private static boolean isJdbc4 = false; + + private static boolean isColdFusion = false; + + static { + try { + CAST_METHOD = Class.class.getMethod("cast", + new Class[] { Object.class }); + } catch (Throwable t) { + // ignore - not available in this VM + } + + try { + Class.forName("java.sql.NClob"); + isJdbc4 = true; + } catch (Throwable t) { + isJdbc4 = false; + } + // // Detect the ColdFusion MX environment // @@ -66,38 +122,20 @@ isColdFusion = false; } } + + // ~ Methods + // ---------------------------------------------------------------- + + public static boolean isJdbc4() { + return isJdbc4; + } public static boolean isColdFusion() { return isColdFusion; } - - protected static boolean nanoTimeAvailable() { - return systemNanoTimeMethod != null; - } - - // cache this ourselves, as the method call is statically-synchronized in all but JDK6! - - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getDefault(); - - static final TimeZone getDefaultTimeZone() { - return (TimeZone)DEFAULT_TIMEZONE.clone(); - } - - class RandStructcture { - long maxValue; - double maxValueDbl; - - long seed1; - - long seed2; - } - - - private static Util enclosingInstance = new Util(); - // Right from Monty's code - static String newCrypt(String password, String seed) { + public static String newCrypt(String password, String seed) { byte b; double d; @@ -156,7 +194,7 @@ return result; } - static String oldCrypt(String password, String seed) { + public static String oldCrypt(String password, String seed) { long hp; long hm; long s1; @@ -291,7 +329,7 @@ to[i] ^= extra; } - val = new String(to); + val = StringUtils.toString(to); } return val; @@ -337,27 +375,110 @@ return traceBuf.toString(); } - + + public static Object getInstance(String className, Class[] argTypes, + Object[] args, ExceptionInterceptor exceptionInterceptor) throws SQLException { + + try { + return handleNewInstance(Class.forName(className).getConstructor( + argTypes), args, exceptionInterceptor); + } catch (SecurityException e) { + throw SQLError.createSQLException( + "Can't instantiate required class", + SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); + } catch (NoSuchMethodException e) { + throw SQLError.createSQLException( + "Can't instantiate required class", + SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); + } catch (ClassNotFoundException e) { + throw SQLError.createSQLException( + "Can't instantiate required class", + SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); + } + } + /** + * Handles constructing new instance with the given constructor and wrapping + * (or not, as required) the exceptions that could possibly be generated + */ + public static final Object handleNewInstance(Constructor ctor, Object[] args, ExceptionInterceptor exceptionInterceptor) + throws SQLException { + try { + + return ctor.newInstance(args); + } catch (IllegalArgumentException e) { + throw SQLError.createSQLException( + "Can't instantiate required class", + SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); + } catch (InstantiationException e) { + throw SQLError.createSQLException( + "Can't instantiate required class", + SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); + } catch (IllegalAccessException e) { + throw SQLError.createSQLException( + "Can't instantiate required class", + SQLError.SQL_STATE_GENERAL_ERROR, e, exceptionInterceptor); + } catch (InvocationTargetException e) { + Throwable target = e.getTargetException(); + + if (target instanceof SQLException) { + throw (SQLException) target; + } + + if (target instanceof ExceptionInInitializerError) { + target = ((ExceptionInInitializerError) target).getException(); + } + + throw SQLError.createSQLException(target.toString(), + SQLError.SQL_STATE_GENERAL_ERROR, + target, exceptionInterceptor); + } + } + + /** * Does a network interface exist locally with the given hostname? * - * @param hostname the hostname (or IP address in string form) to check - * @return true if it exists, false if no, or unable to determine due to VM version support - * of java.net.NetworkInterface + * @param hostname + * the hostname (or IP address in string form) to check + * @return true if it exists, false if no, or unable to determine due to VM + * version support of java.net.NetworkInterface */ public static boolean interfaceExists(String hostname) { try { - Class networkInterfaceClass = Class.forName("java.net.NetworkInterface"); - return networkInterfaceClass.getMethod("getByName", null).invoke(networkInterfaceClass, new Object[] { hostname }) != null; + Class networkInterfaceClass = Class + .forName("java.net.NetworkInterface"); + return networkInterfaceClass.getMethod("getByName", (Class[])null).invoke( + networkInterfaceClass, new Object[] { hostname }) != null; } catch (Throwable t) { return false; } } + /** + * Reflexive access on JDK-1.5's Class.cast() method so we don't have to + * move that out into separate classes built for JDBC-4.0. + * + * @param invokeOn + * @param toCast + * @return + */ + public static Object cast(Object invokeOn, Object toCast) { + if (CAST_METHOD != null) { + try { + return CAST_METHOD.invoke(invokeOn, new Object[] { toCast }); + } catch (Throwable t) { + return null; + } + } + + return null; + } + public static long getCurrentTimeNanosOrMillis() { if (systemNanoTimeMethod != null) { try { - return ((Long)systemNanoTimeMethod.invoke(null, null)).longValue(); + return ((Long) systemNanoTimeMethod.invoke(null, (Object[])null)) + .longValue(); } catch (IllegalArgumentException e) { // ignore - fall through to currentTimeMillis() } catch (IllegalAccessException e) { @@ -366,7 +487,133 @@ // ignore - fall through to currentTimeMillis() } } - + return System.currentTimeMillis(); } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static void resultSetToMap(Map mappedValues, java.sql.ResultSet rs) + throws SQLException { + while (rs.next()) { + mappedValues.put(rs.getObject(1), rs.getObject(2)); + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static void resultSetToMap(Map mappedValues, java.sql.ResultSet rs, int key, int value) + throws SQLException { + while (rs.next()) { + mappedValues.put(rs.getObject(key), rs.getObject(value)); + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static void resultSetToMap(Map mappedValues, java.sql.ResultSet rs, String key, String value) + throws SQLException { + while (rs.next()) { + mappedValues.put(rs.getObject(key), rs.getObject(value)); + } + } + + public static Map calculateDifferences(Map map1, Map map2) { + Map diffMap = new HashMap(); + + for (Map.Entry entry : map1.entrySet()) { + Object key = entry.getKey(); + + Number value1 = null; + Number value2 = null; + + if (entry.getValue() instanceof Number) { + + value1 = (Number) entry.getValue(); + value2 = (Number) map2.get(key); + } else { + try { + value1 = new Double(entry.getValue().toString()); + value2 = new Double(map2.get(key).toString()); + } catch (NumberFormatException nfe) { + continue; + } + } + + if (value1.equals(value2)) { + continue; + } + + if (value1 instanceof Byte) { + diffMap.put(key, Byte.valueOf( + (byte) (((Byte) value2).byteValue() - ((Byte) value1) + .byteValue()))); + } else if (value1 instanceof Short) { + diffMap.put(key, Short.valueOf((short) (((Short) value2) + .shortValue() - ((Short) value1).shortValue()))); + } else if (value1 instanceof Integer) { + diffMap.put(key, Integer.valueOf( + (((Integer) value2).intValue() - ((Integer) value1) + .intValue()))); + } else if (value1 instanceof Long) { + diffMap.put(key, Long.valueOf( + (((Long) value2).longValue() - ((Long) value1) + .longValue()))); + } else if (value1 instanceof Float) { + diffMap.put(key, Float.valueOf(((Float) value2).floatValue() + - ((Float) value1).floatValue())); + } else if (value1 instanceof Double) { + diffMap.put(key, Double.valueOf( + (((Double) value2).shortValue() - ((Double) value1) + .shortValue()))); + } else if (value1 instanceof BigDecimal) { + diffMap.put(key, ((BigDecimal) value2) + .subtract((BigDecimal) value1)); + } else if (value1 instanceof BigInteger) { + diffMap.put(key, ((BigInteger) value2) + .subtract((BigInteger) value1)); + } + } + + return diffMap; + } + + /** + * Returns initialized instances of classes listed in extensionClassNames. + * There is no need to call Extension.init() method after that if you don't change connection or properties. + * + * @param conn + * @param props + * @param extensionClassNames + * @param errorMessageKey + * @param exceptionInterceptor + * @return + * @throws SQLException + */ + public static List loadExtensions(Connection conn, + Properties props, String extensionClassNames, + String errorMessageKey, ExceptionInterceptor exceptionInterceptor) throws SQLException { + List extensionList = new LinkedList(); + + List interceptorsToCreate = StringUtils.split(extensionClassNames, ",", true); + + String className = null; + + try { + for (int i = 0, s = interceptorsToCreate.size(); i < s; i++) { + className = interceptorsToCreate.get(i); + Extension extensionInstance = (Extension) Class.forName( + className).newInstance(); + extensionInstance.init(conn, props); + + extensionList.add(extensionInstance); + } + } catch (Throwable t) { + SQLException sqlEx = SQLError.createSQLException(Messages + .getString(errorMessageKey, new Object[] { className }), exceptionInterceptor); + sqlEx.initCause(t); + + throw sqlEx; + } + + return extensionList; + } + } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/V1toV2StatementInterceptorAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/WatchableOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/WatchableOutputStream.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/WatchableOutputStream.java 17 Aug 2012 14:57:10 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/WatchableOutputStream.java 30 Jul 2014 08:37:28 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.ByteArrayOutputStream; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/WatchableWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/WatchableWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/WatchableWriter.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/WatchableWriter.java 30 Jul 2014 08:37:26 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; import java.io.CharArrayWriter; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/WriterWatcher.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/WriterWatcher.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/WriterWatcher.java 17 Aug 2012 14:57:09 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/WriterWatcher.java 30 Jul 2014 08:37:27 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc; /** Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlClearPasswordPlugin.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlNativePasswordPlugin.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlOldPasswordPlugin.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/Sha256PasswordPlugin.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/3-0-Compat.properties =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/3-0-Compat.properties,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/3-0-Compat.properties 17 Aug 2012 14:57:13 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/3-0-Compat.properties 30 Jul 2014 08:37:23 -0000 1.1.2.1 @@ -15,4 +15,5 @@ autoClosePStmtStreams=true processEscapeCodesForPrepStmts=false useFastDateParsing=false -populateInsertRowWithDefaultValues=false \ No newline at end of file +populateInsertRowWithDefaultValues=false +useDirectRowUnpack=false \ No newline at end of file Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/5-0-Compat.properties'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/fullDebug.properties =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/fullDebug.properties,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/fullDebug.properties 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/fullDebug.properties 30 Jul 2014 08:37:23 -0000 1.1.2.1 @@ -1,6 +1,6 @@ # Settings for 'max-debug' style situations profileSQL=true -gatherPerMetrics=true +gatherPerfMetrics=true useUsageAdvisor=true logSlowQueries=true explainSlowQueries=true \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/maxPerformance.properties =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/maxPerformance.properties,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/maxPerformance.properties 17 Aug 2012 14:57:13 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/configs/maxPerformance.properties 30 Jul 2014 08:37:23 -0000 1.1.2.1 @@ -9,7 +9,7 @@ # restarting the application using this configuration bundle. cachePrepStmts=true -cacheCallableStatements=true +cacheCallableStmts=true cacheServerConfiguration=true @@ -26,4 +26,9 @@ # Can cause high-GC pressure if timeouts are used on every # query -enableQueryTimeouts=false \ No newline at end of file +enableQueryTimeouts=false + +# Bypass connection attribute handling during connection +# setup +connectionAttributes=none + Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/DeadlockTimeoutRollbackMarker.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLDataException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLDataException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLDataException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLDataException.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,30 +1,32 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.exceptions; public class MySQLDataException extends MySQLNonTransientException { + static final long serialVersionUID = 4317904269797988676L; + public MySQLDataException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLIntegrityConstraintViolationException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLIntegrityConstraintViolationException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLIntegrityConstraintViolationException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLIntegrityConstraintViolationException.java 30 Jul 2014 08:37:32 -0000 1.1.2.1 @@ -1,31 +1,33 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.exceptions; public class MySQLIntegrityConstraintViolationException extends MySQLNonTransientException { + static final long serialVersionUID = -5528363270635808904L; + public MySQLIntegrityConstraintViolationException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLInvalidAuthorizationSpecException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLInvalidAuthorizationSpecException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLInvalidAuthorizationSpecException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLInvalidAuthorizationSpecException.java 30 Jul 2014 08:37:32 -0000 1.1.2.1 @@ -1,31 +1,33 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.exceptions; public class MySQLInvalidAuthorizationSpecException extends MySQLNonTransientException { + static final long serialVersionUID = 6878889837492500030L; + public MySQLInvalidAuthorizationSpecException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLNonTransientConnectionException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLNonTransientConnectionException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLNonTransientConnectionException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLNonTransientConnectionException.java 30 Jul 2014 08:37:32 -0000 1.1.2.1 @@ -1,31 +1,33 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.exceptions; public class MySQLNonTransientConnectionException extends MySQLNonTransientException { + static final long serialVersionUID = -3050543822763367670L; + public MySQLNonTransientConnectionException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLNonTransientException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLNonTransientException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLNonTransientException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLNonTransientException.java 30 Jul 2014 08:37:32 -0000 1.1.2.1 @@ -1,32 +1,34 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.exceptions; import java.sql.SQLException; public class MySQLNonTransientException extends SQLException { + static final long serialVersionUID = -8714521137552613517L; + public MySQLNonTransientException() { super(); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLQueryInterruptedException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLStatementCancelledException.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLSyntaxErrorException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLSyntaxErrorException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLSyntaxErrorException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLSyntaxErrorException.java 30 Jul 2014 08:37:32 -0000 1.1.2.1 @@ -1,30 +1,32 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.exceptions; public class MySQLSyntaxErrorException extends MySQLNonTransientException { + static final long serialVersionUID = 6919059513432113764L; + public MySQLSyntaxErrorException() { super(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTimeoutException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTimeoutException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTimeoutException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTimeoutException.java 30 Jul 2014 08:37:32 -0000 1.1.2.1 @@ -1,30 +1,32 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.exceptions; public class MySQLTimeoutException extends MySQLTransientException { + static final long serialVersionUID = -789621240523230339L; + public MySQLTimeoutException(String reason, String SQLState, int vendorCode) { super(reason, SQLState, vendorCode); } @@ -40,9 +42,4 @@ public MySQLTimeoutException() { super("Statement cancelled due to timeout or client request"); } - - public int getErrorCode() { - // TODO Auto-generated method stub - return super.getErrorCode(); - } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTransactionRollbackException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTransactionRollbackException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTransactionRollbackException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTransactionRollbackException.java 30 Jul 2014 08:37:32 -0000 1.1.2.1 @@ -1,30 +1,32 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.exceptions; -public class MySQLTransactionRollbackException extends MySQLTransientException { +public class MySQLTransactionRollbackException extends MySQLTransientException 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/MySQLTransientConnectionException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTransientConnectionException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTransientConnectionException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTransientConnectionException.java 30 Jul 2014 08:37:32 -0000 1.1.2.1 @@ -1,30 +1,32 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.exceptions; public class MySQLTransientConnectionException extends MySQLTransientException { + 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/MySQLTransientException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTransientException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTransientException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/MySQLTransientException.java 30 Jul 2014 08:37:32 -0000 1.1.2.1 @@ -1,32 +1,34 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.exceptions; import java.sql.SQLException; public class MySQLTransientException extends SQLException { + static final long serialVersionUID = -1885878228558607563L; + public MySQLTransientException(String reason, String SQLState, int vendorCode) { super(reason, SQLState, vendorCode); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/CommunicationsException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLDataException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLIntegrityConstraintViolationException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLInvalidAuthorizationSpecException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLNonTransientConnectionException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLNonTransientException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLQueryInterruptedException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLSyntaxErrorException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTimeoutException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransactionRollbackException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransientConnectionException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/exceptions/jdbc4/MySQLTransientException.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/c3p0/MysqlConnectionTester.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/c3p0/MysqlConnectionTester.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/c3p0/MysqlConnectionTester.java 17 Aug 2012 14:57:13 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/c3p0/MysqlConnectionTester.java 30 Jul 2014 08:37:35 -0000 1.1.2.1 @@ -1,25 +1,26 @@ /* - Copyright (C) 2002-2005 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */ + package com.mysql.jdbc.integration.c3p0; import java.lang.reflect.Method; @@ -46,12 +47,12 @@ private static final Object[] NO_ARGS_ARRAY = new Object[0]; - private Method pingMethod; + private transient Method pingMethod; public MysqlConnectionTester() { try { pingMethod = com.mysql.jdbc.Connection.class - .getMethod("ping", null); + .getMethod("ping", (Class[])null); } catch (Exception ex) { // punt, we have no way to recover, other than we now use 'SELECT 1' // for @@ -103,7 +104,9 @@ * java.lang.Throwable) */ public int statusOnException(Connection arg0, Throwable throwable) { - if (throwable instanceof CommunicationsException) { + if (throwable instanceof CommunicationsException + || "com.mysql.jdbc.exceptions.jdbc4.CommunicationsException" + .equals(throwable.getClass().getName())) { return CONNECTION_IS_INVALID; } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/jboss/ExtendedMysqlExceptionSorter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/jboss/ExtendedMysqlExceptionSorter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/jboss/ExtendedMysqlExceptionSorter.java 17 Aug 2012 14:57:13 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/jboss/ExtendedMysqlExceptionSorter.java 30 Jul 2014 08:37:34 -0000 1.1.2.1 @@ -1,30 +1,30 @@ /* - Copyright (C) 2002-2005 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */ + package com.mysql.jdbc.integration.jboss; import java.sql.SQLException; -import org.jboss.resource.adapter.jdbc.ExceptionSorter; import org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter; /** @@ -36,6 +36,8 @@ */ public final class ExtendedMysqlExceptionSorter extends MySQLExceptionSorter { + static final long serialVersionUID = -2454582336945931069L; + /* * (non-Javadoc) * Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java 17 Aug 2012 14:57:13 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java 30 Jul 2014 08:37:34 -0000 1.1.2.1 @@ -1,37 +1,35 @@ /* - Copyright (C) 2002-2006 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + */ package com.mysql.jdbc.integration.jboss; import java.io.Serializable; -import java.lang.reflect.Method; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import org.jboss.resource.adapter.jdbc.ValidConnectionChecker; -import com.mysql.jdbc.SQLError; - /** * A more efficient connection checker for JBoss. * @@ -41,31 +39,9 @@ public final class MysqlValidConnectionChecker implements ValidConnectionChecker, Serializable { - private static final long serialVersionUID = 3258689922776119348L; + private static final long serialVersionUID = 8909421133577519177L; - private Method pingMethod; - - private Method pingMethodWrapped; - - private final static Object[] NO_ARGS_OBJECT_ARRAY = new Object[0]; - public MysqlValidConnectionChecker() { - try { - // Avoid classloader goofiness - Class mysqlConnection = Thread.currentThread() - .getContextClassLoader().loadClass( - "com.mysql.jdbc.Connection"); - - pingMethod = mysqlConnection.getMethod("ping", null); - - Class mysqlConnectionWrapper = Thread.currentThread() - .getContextClassLoader().loadClass( - "com.mysql.jdbc.jdbc2.optional.ConnectionWrapper"); - - pingMethodWrapped = mysqlConnectionWrapper.getMethod("ping", null); - } catch (Exception ex) { - // Punt, we'll use 'SELECT 1' to do the check - } } /* @@ -74,44 +50,17 @@ * @see org.jboss.resource.adapter.jdbc.ValidConnectionChecker#isValidConnection(java.sql.Connection) */ public SQLException isValidConnection(Connection conn) { - if (conn instanceof com.mysql.jdbc.Connection) { - if (pingMethod != null) { - try { - this.pingMethod.invoke(conn, null); - - return null; - } catch (Exception ex) { - if (ex instanceof SQLException) { - return (SQLException) ex; - } - - return SQLError.createSQLException("Ping failed: " + ex.toString()); - } - } - } else if (conn instanceof com.mysql.jdbc.jdbc2.optional.ConnectionWrapper) { - if (pingMethodWrapped != null) { - try { - this.pingMethodWrapped.invoke(conn, null); - - return null; - } catch (Exception ex) { - if (ex instanceof SQLException) { - return (SQLException) ex; - } - - return SQLError.createSQLException("Ping failed: " + ex.toString()); - } - } - } - // Punt and use 'SELECT 1' + // Use "/* ping */ SELECT 1" which will send + // pings across multi-connections too in case the connection + // was "wrapped" by Jboss in any way... Statement pingStatement = null; try { pingStatement = conn.createStatement(); - pingStatement.executeQuery("SELECT 1").close(); + pingStatement.executeQuery("/* ping */ SELECT 1").close(); return null; } catch (SQLException sqlEx) { Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/interceptors/ResultSetScannerInterceptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/interceptors/ServerStatusDiffInterceptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/interceptors/SessionAssociationInterceptor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,39 +1,38 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - */ package com.mysql.jdbc.jdbc2.optional; import java.io.InputStream; import java.io.Reader; +import java.lang.reflect.Constructor; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; import java.sql.Clob; import java.sql.Date; -import java.sql.PreparedStatement; import java.sql.Ref; import java.sql.SQLException; import java.sql.Time; @@ -42,6 +41,7 @@ import java.util.Map; import com.mysql.jdbc.SQLError; +import com.mysql.jdbc.Util; /** * Wraps callable statements created by pooled connections. @@ -52,6 +52,44 @@ public class CallableStatementWrapper extends PreparedStatementWrapper implements CallableStatement { + private static final Constructor JDBC_4_CALLABLE_STATEMENT_WRAPPER_CTOR; + + static { + if (Util.isJdbc4()) { + try { + JDBC_4_CALLABLE_STATEMENT_WRAPPER_CTOR = Class.forName( + "com.mysql.jdbc.jdbc2.optional.JDBC4CallableStatementWrapper").getConstructor( + new Class[] { ConnectionWrapper.class, + MysqlPooledConnection.class, + CallableStatement.class }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_CALLABLE_STATEMENT_WRAPPER_CTOR = null; + } + } + + protected static CallableStatementWrapper getInstance(ConnectionWrapper c, + MysqlPooledConnection conn, + CallableStatement toWrap) throws SQLException { + if (!Util.isJdbc4()) { + return new CallableStatementWrapper(c, + conn, toWrap); + } + + return (CallableStatementWrapper) Util.handleNewInstance( + JDBC_4_CALLABLE_STATEMENT_WRAPPER_CTOR, + new Object[] {c, + conn, toWrap }, conn.getExceptionInterceptor()); + } + + + /** * @param c * @param conn @@ -76,7 +114,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -97,7 +135,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -113,11 +151,11 @@ try { if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt).wasNull(); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -135,11 +173,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getString(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -156,11 +194,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getBoolean(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -178,11 +216,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getByte(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -200,11 +238,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getShort(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -222,11 +260,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getInt(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -244,11 +282,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getLong(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -266,11 +304,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getFloat(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -288,11 +326,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getDouble(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -311,11 +349,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt).getBigDecimal( parameterIndex, scale); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -333,11 +371,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getBytes(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -355,11 +393,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getDate(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -377,11 +415,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getTime(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -399,11 +437,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getTimestamp(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -421,11 +459,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getObject(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -443,11 +481,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getBigDecimal(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -460,17 +498,17 @@ * * @see java.sql.CallableStatement#getObject(int, java.util.Map) */ - public Object getObject(int parameterIndex, Map typeMap) + public Object getObject(int parameterIndex, Map> typeMap) throws SQLException { try { if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt).getObject( parameterIndex, typeMap); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -487,11 +525,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getRef(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -509,11 +547,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getBlob(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -531,11 +569,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getClob(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -552,11 +590,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getArray(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -573,11 +611,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt).getDate( parameterIndex, cal); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -594,11 +632,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt).getTime( parameterIndex, cal); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -616,11 +654,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt).getTimestamp( parameterIndex, cal); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -642,7 +680,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -664,7 +702,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -686,7 +724,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -708,7 +746,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -725,11 +763,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getURL(parameterIndex); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -750,7 +788,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -770,7 +808,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -790,7 +828,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -810,7 +848,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -830,7 +868,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -849,7 +887,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -869,7 +907,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -889,7 +927,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -909,7 +947,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -931,7 +969,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -952,7 +990,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -972,7 +1010,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -992,7 +1030,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1012,7 +1050,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1034,7 +1072,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1056,7 +1094,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1079,7 +1117,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1101,7 +1139,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1123,7 +1161,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1144,7 +1182,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1166,7 +1204,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1188,7 +1226,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1210,7 +1248,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1232,7 +1270,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1254,7 +1292,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -1271,11 +1309,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getString(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1292,11 +1330,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getBoolean(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1314,11 +1352,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getByte(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1336,11 +1374,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getShort(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1358,11 +1396,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getInt(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1380,11 +1418,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getLong(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1402,11 +1440,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getFloat(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1424,11 +1462,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getDouble(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1446,11 +1484,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getBytes(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1468,11 +1506,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getDate(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1490,11 +1528,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getTime(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1512,11 +1550,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getTimestamp(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1534,11 +1572,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getObject(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1556,11 +1594,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getBigDecimal(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1573,17 +1611,17 @@ * * @see java.sql.CallableStatement#getObject(int, java.util.Map) */ - public Object getObject(String parameterName, Map typeMap) + public Object getObject(String parameterName, Map> typeMap) throws SQLException { try { if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt).getObject( parameterName, typeMap); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1600,11 +1638,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getRef(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1622,11 +1660,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getBlob(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1644,11 +1682,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getClob(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1665,11 +1703,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getArray(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1686,11 +1724,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt).getDate( parameterName, cal); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1707,11 +1745,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt).getTime( parameterName, cal); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1729,11 +1767,11 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt).getTimestamp( parameterName, cal); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -1750,16 +1788,850 @@ if (this.wrappedStmt != null) { return ((CallableStatement) this.wrappedStmt) .getURL(parameterName); - } else { - throw SQLError.createSQLException( - "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); } + throw SQLError.createSQLException( + "No operations allowed after statement closed", + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); + } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } return null; } +// +// public Reader getCharacterStream(int parameterIndex) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getCharacterStream(parameterIndex); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public Reader getCharacterStream(String parameterName) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getCharacterStream(parameterName); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public Reader getNCharacterStream(int parameterIndex) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getCharacterStream(parameterIndex); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public Reader getNCharacterStream(String parameterName) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getNCharacterStream(parameterName); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public NClob getNClob(int parameterIndex) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getNClob(parameterIndex); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public NClob getNClob(String parameterName) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getNClob(parameterName); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public String getNString(int parameterIndex) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getNString(parameterIndex); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public String getNString(String parameterName) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getNString(parameterName); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public RowId getRowId(int parameterIndex) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getRowId(parameterIndex); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public RowId getRowId(String parameterName) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getRowId(parameterName); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public SQLXML getSQLXML(int parameterIndex) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getSQLXML(parameterIndex); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public SQLXML getSQLXML(String parameterName) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .getSQLXML(parameterName); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return null; +// } +// +// public void setAsciiStream(String parameterName, InputStream x) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setAsciiStream(parameterName, x) ; +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setAsciiStream(parameterName, x, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBinaryStream(String parameterName, InputStream x) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setBinaryStream(parameterName, x); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setBinaryStream(parameterName, x, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBlob(String parameterName, Blob x) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setBlob(parameterName, x); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBlob(String parameterName, InputStream inputStream) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setBlob(parameterName, inputStream); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setBlob(parameterName, inputStream, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setCharacterStream(String parameterName, Reader reader) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setCharacterStream(parameterName, reader); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setCharacterStream(parameterName, reader, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setClob(String parameterName, Clob x) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setClob(parameterName, x); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setClob(String parameterName, Reader reader) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setClob(parameterName, reader); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setClob(String parameterName, Reader reader, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setClob(parameterName, reader, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNCharacterStream(String parameterName, Reader value) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNCharacterStream(parameterName, value); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNCharacterStream(parameterName, value, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNClob(String parameterName, NClob value) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNClob(parameterName, value); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNClob(String parameterName, Reader reader) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNClob(parameterName, reader); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNClob(String parameterName, Reader reader, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNClob(parameterName, reader, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNString(String parameterName, String value) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNString(parameterName, value); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setRowId(String parameterName, RowId x) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setRowId(parameterName, x); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setSQLXML(parameterName, xmlObject); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setAsciiStream(parameterIndex, x); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setAsciiStream(parameterIndex, x, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setBinaryStream(parameterIndex, x) ; +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setBinaryStream(parameterIndex, x, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setBlob(parameterIndex, inputStream); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setBlob(parameterIndex, inputStream, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setCharacterStream(parameterIndex, reader); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .getCharacterStream(parameterIndex); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setClob(int parameterIndex, Reader reader) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setClob(parameterIndex, reader); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setClob(parameterIndex, reader, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNCharacterStream(parameterIndex, value); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// } +// +// public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNCharacterStream(parameterIndex, value, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNClob(int parameterIndex, NClob value) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNClob(parameterIndex, value); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNClob(int parameterIndex, Reader reader) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNClob(parameterIndex, reader); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNClob(parameterIndex, reader, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNString(int parameterIndex, String value) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setNString(parameterIndex, value); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setRowId(int parameterIndex, RowId x) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setRowId(parameterIndex, x); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setSQLXML(parameterIndex, xmlObject); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// } +// +// public boolean isClosed() throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// .isClosed(); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return true; +// } +// +// public boolean isPoolable() throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((CallableStatement) this.wrappedStmt) +// . isPoolable(); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return false; +// } +// +// public void setPoolable(boolean poolable) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((CallableStatement) this.wrappedStmt) +// .setPoolable(poolable); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// } +// +// public boolean isWrapperFor(Class arg0) throws SQLException { +// throw SQLError.notImplemented(); +// } +// +// public Object unwrap(Class arg0) throws SQLException { +// throw SQLError.notImplemented(); +// } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,36 +1,45 @@ /* - Copyright (C) 2002-2006 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.jdbc2.optional; -import java.sql.Connection; +import java.lang.reflect.Constructor; import java.sql.SQLException; import java.sql.Savepoint; import java.sql.Statement; +import java.util.Map; +import java.util.Properties; +import java.util.TimeZone; +import java.util.concurrent.Executor; +import com.mysql.jdbc.Connection; +import com.mysql.jdbc.ExceptionInterceptor; +import com.mysql.jdbc.Extension; +import com.mysql.jdbc.MySQLConnection; import com.mysql.jdbc.MysqlErrorNumbers; import com.mysql.jdbc.SQLError; +import com.mysql.jdbc.Util; +import com.mysql.jdbc.log.Log; /** * This class serves as a wrapper for the org.gjt.mm.mysql.jdbc2.Connection @@ -55,15 +64,50 @@ * @see org.gjt.mm.mysql.jdbc2.optional.MysqlPooledConnection */ public class ConnectionWrapper extends WrapperBase implements Connection { - private com.mysql.jdbc.Connection mc = null; + protected Connection mc = null; - private MysqlPooledConnection mpc = null; - private String invalidHandleStr = "Logical handle no longer valid"; private boolean closed; + private boolean isForXa; - + + private static final Constructor JDBC_4_CONNECTION_WRAPPER_CTOR; + + static { + if (Util.isJdbc4()) { + try { + JDBC_4_CONNECTION_WRAPPER_CTOR = Class.forName( + "com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper") + .getConstructor( + new Class[] { MysqlPooledConnection.class, + Connection.class, Boolean.TYPE }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_CONNECTION_WRAPPER_CTOR = null; + } + } + + protected static ConnectionWrapper getInstance( + MysqlPooledConnection mysqlPooledConnection, + Connection mysqlConnection, boolean forXa) throws SQLException { + if (!Util.isJdbc4()) { + return new ConnectionWrapper(mysqlPooledConnection, + mysqlConnection, forXa); + } + + return (ConnectionWrapper) Util.handleNewInstance( + JDBC_4_CONNECTION_WRAPPER_CTOR, new Object[] { + mysqlPooledConnection, mysqlConnection, + Boolean.valueOf(forXa) }, mysqlPooledConnection.getExceptionInterceptor()); + } + /** * Construct a new LogicalHandle and set instance variables * @@ -76,14 +120,13 @@ * if an error occurs. */ public ConnectionWrapper(MysqlPooledConnection mysqlPooledConnection, - com.mysql.jdbc.Connection mysqlConnection, - boolean forXa) throws SQLException { - this.mpc = mysqlPooledConnection; + Connection mysqlConnection, boolean forXa) throws SQLException { + super(mysqlPooledConnection); + this.mc = mysqlConnection; this.closed = false; - this.pooledConnection = this.mpc; this.isForXa = forXa; - + if (this.isForXa) { setInGlobalTx(false); } @@ -99,11 +142,12 @@ checkClosed(); if (autoCommit && isInGlobalTx()) { - throw SQLError.createSQLException("Can't set autocommit to 'true' on an XAConnection", - SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, - MysqlErrorNumbers.ER_XA_RMERR); + throw SQLError.createSQLException( + "Can't set autocommit to 'true' on an XAConnection", + SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, + MysqlErrorNumbers.ER_XA_RMERR, this.exceptionInterceptor); } - + try { this.mc.setAutoCommit(autoCommit); } catch (SQLException sqlException) { @@ -176,7 +220,7 @@ return (this.closed || this.mc.isClosed()); } - public boolean isMasterConnection() throws SQLException { + public boolean isMasterConnection() { return this.mc.isMasterConnection(); } @@ -206,7 +250,7 @@ } return Statement.CLOSE_CURRENT_RESULT; // we don't reach this code, - // compiler can't tell + // compiler can't tell } /** @@ -280,11 +324,12 @@ checkClosed(); if (isInGlobalTx()) { - throw SQLError.createSQLException("Can't set autocommit to 'true' on an XAConnection", - SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, - MysqlErrorNumbers.ER_XA_RMERR); + throw SQLError.createSQLException( + "Can't set autocommit to 'true' on an XAConnection", + SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, + MysqlErrorNumbers.ER_XA_RMERR, this.exceptionInterceptor); } - + try { return this.mc.setSavepoint(); } catch (SQLException sqlException) { @@ -301,11 +346,12 @@ checkClosed(); if (isInGlobalTx()) { - throw SQLError.createSQLException("Can't set autocommit to 'true' on an XAConnection", - SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, - MysqlErrorNumbers.ER_XA_RMERR); + throw SQLError.createSQLException( + "Can't set autocommit to 'true' on an XAConnection", + SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, + MysqlErrorNumbers.ER_XA_RMERR, this.exceptionInterceptor); } - + try { return this.mc.setSavepoint(arg0); } catch (SQLException sqlException) { @@ -347,32 +393,17 @@ } return TRANSACTION_REPEATABLE_READ; // we don't reach this code, - // compiler can't tell + // compiler can't tell } - /** - * Passes call to method on physical connection instance. Notifies listeners - * of any caught exceptions before re-throwing to client. - * - * @see java.sql.Connection#setTypeMap() - */ - public void setTypeMap(java.util.Map map) throws SQLException { - checkClosed(); - try { - this.mc.setTypeMap(map); - } catch (SQLException sqlException) { - checkAndFireConnectionError(sqlException); - } - } - /** * Passes call to method on physical connection instance. Notifies listeners * of any caught exceptions before re-throwing to client. * * @see java.sql.Connection#getTypeMap() */ - public java.util.Map getTypeMap() throws SQLException { + public java.util.Map> getTypeMap() throws SQLException { checkClosed(); try { @@ -442,12 +473,13 @@ */ public void commit() throws SQLException { checkClosed(); - + if (isInGlobalTx()) { - throw SQLError.createSQLException( - "Can't call commit() on an XAConnection associated with a global transaction", - SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, - MysqlErrorNumbers.ER_XA_RMERR); + throw SQLError + .createSQLException( + "Can't call commit() on an XAConnection associated with a global transaction", + SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, + MysqlErrorNumbers.ER_XA_RMERR, this.exceptionInterceptor); } try { @@ -467,7 +499,7 @@ checkClosed(); try { - return new StatementWrapper(this, this.mpc, this.mc + return StatementWrapper.getInstance(this, this.pooledConnection, this.mc .createStatement()); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -487,7 +519,7 @@ checkClosed(); try { - return new StatementWrapper(this, this.mpc, this.mc + return StatementWrapper.getInstance(this, this.pooledConnection, this.mc .createStatement(resultSetType, resultSetConcurrency)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -504,7 +536,7 @@ checkClosed(); try { - return new StatementWrapper(this, this.mpc, this.mc + return StatementWrapper.getInstance(this, this.pooledConnection, this.mc .createStatement(arg0, arg1, arg2)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -542,7 +574,7 @@ checkClosed(); try { - return new CallableStatementWrapper(this, this.mpc, this.mc + return CallableStatementWrapper.getInstance(this, this.pooledConnection, this.mc .prepareCall(sql)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -562,7 +594,7 @@ checkClosed(); try { - return new CallableStatementWrapper(this, this.mpc, this.mc + return CallableStatementWrapper.getInstance(this, this.pooledConnection, this.mc .prepareCall(sql, resultSetType, resultSetConcurrency)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -579,7 +611,7 @@ checkClosed(); try { - return new CallableStatementWrapper(this, this.mpc, this.mc + return CallableStatementWrapper.getInstance(this, this.pooledConnection, this.mc .prepareCall(arg0, arg1, arg2, arg3)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -588,36 +620,35 @@ return null; // we don't reach this code, compiler can't tell } - public java.sql.PreparedStatement clientPrepare(String sql) throws SQLException - { + public java.sql.PreparedStatement clientPrepare(String sql) + throws SQLException { checkClosed(); try { - return new PreparedStatementWrapper(this, this.mpc, - this.mc.clientPrepareStatement(sql)); + return new PreparedStatementWrapper(this, this.pooledConnection, this.mc + .clientPrepareStatement(sql)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); } - + return null; } - + public java.sql.PreparedStatement clientPrepare(String sql, - int resultSetType, int resultSetConcurrency) throws SQLException - { + int resultSetType, int resultSetConcurrency) throws SQLException { checkClosed(); try { - return new PreparedStatementWrapper(this, this.mpc, - this.mc.clientPrepareStatement(sql, - resultSetType, resultSetConcurrency)); + return new PreparedStatementWrapper(this, this.pooledConnection, this.mc + .clientPrepareStatement(sql, resultSetType, + resultSetConcurrency)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); } - + return null; } - + /** * Passes call to method on physical connection instance. Notifies listeners * of any caught exceptions before re-throwing to client. @@ -629,7 +660,7 @@ checkClosed(); try { - return new PreparedStatementWrapper(this, this.mpc, this.mc + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc .prepareStatement(sql)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -649,8 +680,9 @@ checkClosed(); try { - return new PreparedStatementWrapper(this, this.mpc, this.mc - .prepareStatement(sql, resultSetType, resultSetConcurrency)); + return PreparedStatementWrapper + .getInstance(this, this.pooledConnection, this.mc.prepareStatement(sql, + resultSetType, resultSetConcurrency)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); } @@ -666,7 +698,7 @@ checkClosed(); try { - return new PreparedStatementWrapper(this, this.mpc, this.mc + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc .prepareStatement(arg0, arg1, arg2, arg3)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -683,7 +715,7 @@ checkClosed(); try { - return new PreparedStatementWrapper(this, this.mpc, this.mc + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc .prepareStatement(arg0, arg1)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -700,7 +732,7 @@ checkClosed(); try { - return new PreparedStatementWrapper(this, this.mpc, this.mc + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc .prepareStatement(arg0, arg1)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -717,7 +749,7 @@ checkClosed(); try { - return new PreparedStatementWrapper(this, this.mpc, this.mc + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc .prepareStatement(arg0, arg1)); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); @@ -748,13 +780,14 @@ public void rollback() throws SQLException { checkClosed(); - if (isInGlobalTx()) { - throw SQLError.createSQLException("Can't call rollback() on an XAConnection associated with a global transaction", - SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, - MysqlErrorNumbers.ER_XA_RMERR); + throw SQLError + .createSQLException( + "Can't call rollback() on an XAConnection associated with a global transaction", + SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, + MysqlErrorNumbers.ER_XA_RMERR, this.exceptionInterceptor); } - + try { this.mc.rollback(); } catch (SQLException sqlException) { @@ -769,42 +802,40 @@ checkClosed(); if (isInGlobalTx()) { - throw SQLError.createSQLException("Can't call rollback() on an XAConnection associated with a global transaction", - SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, - MysqlErrorNumbers.ER_XA_RMERR); + throw SQLError + .createSQLException( + "Can't call rollback() on an XAConnection associated with a global transaction", + SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, + MysqlErrorNumbers.ER_XA_RMERR, this.exceptionInterceptor); } - + try { this.mc.rollback(arg0); } catch (SQLException sqlException) { checkAndFireConnectionError(sqlException); } } - public boolean isSameResource(Connection c) { + public boolean isSameResource(com.mysql.jdbc.Connection c) { if (c instanceof ConnectionWrapper) { - return this.mc.isSameResource(((ConnectionWrapper)c).mc); - } else if (c instanceof com.mysql.jdbc.Connection) { - return this.mc.isSameResource((com.mysql.jdbc.Connection)c); + return this.mc.isSameResource(((ConnectionWrapper) c).mc); } - - return false; + return this.mc.isSameResource(c); } - + protected void close(boolean fireClosedEvent) throws SQLException { - synchronized (this.mpc) { + synchronized (this.pooledConnection) { if (this.closed) { return; } - if (!isInGlobalTx() - && this.mc.getRollbackOnPooledClose() + if (!isInGlobalTx() && this.mc.getRollbackOnPooledClose() && !this.getAutoCommit()) { rollback(); } if (fireClosedEvent) { - this.mpc.callListener( + this.pooledConnection.callConnectionEventListeners( MysqlPooledConnection.CONNECTION_CLOSED_EVENT, null); } @@ -817,23 +848,2048 @@ } } - private void checkClosed() throws SQLException { + public void checkClosed() throws SQLException { if (this.closed) { - throw SQLError.createSQLException(this.invalidHandleStr); + throw SQLError.createSQLException(this.invalidHandleStr, this.exceptionInterceptor); } } - protected boolean isInGlobalTx() { + public boolean isInGlobalTx() { return this.mc.isInGlobalTx(); } - protected void setInGlobalTx(boolean flag) { + public void setInGlobalTx(boolean flag) { this.mc.setInGlobalTx(flag); } - + public void ping() throws SQLException { if (this.mc != null) { this.mc.ping(); } } -} + + public void changeUser(String userName, String newPassword) + throws SQLException { + checkClosed(); + + try { + this.mc.changeUser(userName, newPassword); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + } + + public void clearHasTriedMaster() { + this.mc.clearHasTriedMaster(); + } + + public java.sql.PreparedStatement clientPrepareStatement(String sql) + throws SQLException { + checkClosed(); + + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .clientPrepareStatement(sql)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public java.sql.PreparedStatement clientPrepareStatement(String sql, + int autoGenKeyIndex) throws SQLException { + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .clientPrepareStatement(sql, autoGenKeyIndex)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public java.sql.PreparedStatement clientPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency) throws SQLException { + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .clientPrepareStatement(sql, resultSetType, + resultSetConcurrency)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public java.sql.PreparedStatement clientPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException { + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .clientPrepareStatement(sql, resultSetType, + resultSetConcurrency, resultSetHoldability)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public java.sql.PreparedStatement clientPrepareStatement(String sql, + int[] autoGenKeyIndexes) throws SQLException { + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .clientPrepareStatement(sql, autoGenKeyIndexes)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public java.sql.PreparedStatement clientPrepareStatement(String sql, + String[] autoGenKeyColNames) throws SQLException { + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .clientPrepareStatement(sql, autoGenKeyColNames)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public int getActiveStatementCount() { + return this.mc.getActiveStatementCount(); + } + + public Log getLog() throws SQLException { + return this.mc.getLog(); + } + + public String getServerCharacterEncoding() { + return this.mc.getServerCharacterEncoding(); + } + + public TimeZone getServerTimezoneTZ() { + return this.mc.getServerTimezoneTZ(); + } + + public String getStatementComment() { + return this.mc.getStatementComment(); + } + + public boolean hasTriedMaster() { + return this.mc.hasTriedMaster(); + } + + public boolean isAbonormallyLongQuery(long millisOrNanos) { + return this.mc.isAbonormallyLongQuery(millisOrNanos); + } + + public boolean isNoBackslashEscapesSet() { + return this.mc.isNoBackslashEscapesSet(); + } + + public boolean lowerCaseTableNames() { + return this.mc.lowerCaseTableNames(); + } + + public boolean parserKnowsUnicode() { + return this.mc.parserKnowsUnicode(); + } + + public void reportQueryTime(long millisOrNanos) { + this.mc.reportQueryTime(millisOrNanos); + } + + public void resetServerState() throws SQLException { + checkClosed(); + + try { + this.mc.resetServerState(); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + } + + public java.sql.PreparedStatement serverPrepareStatement(String sql) + throws SQLException { + checkClosed(); + + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .serverPrepareStatement(sql)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public java.sql.PreparedStatement serverPrepareStatement(String sql, + int autoGenKeyIndex) throws SQLException { + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .serverPrepareStatement(sql, autoGenKeyIndex)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public java.sql.PreparedStatement serverPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency) throws SQLException { + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .serverPrepareStatement(sql, resultSetType, + resultSetConcurrency)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public java.sql.PreparedStatement serverPrepareStatement(String sql, + int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException { + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .serverPrepareStatement(sql, resultSetType, + resultSetConcurrency, resultSetHoldability)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public java.sql.PreparedStatement serverPrepareStatement(String sql, + int[] autoGenKeyIndexes) throws SQLException { + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .serverPrepareStatement(sql, autoGenKeyIndexes)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public java.sql.PreparedStatement serverPrepareStatement(String sql, + String[] autoGenKeyColNames) throws SQLException { + try { + return PreparedStatementWrapper.getInstance(this, this.pooledConnection, this.mc + .serverPrepareStatement(sql, autoGenKeyColNames)); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public void setFailedOver(boolean flag) { + this.mc.setFailedOver(flag); + + } + + public void setPreferSlaveDuringFailover(boolean flag) { + this.mc.setPreferSlaveDuringFailover(flag); + } + + public void setStatementComment(String comment) { + this.mc.setStatementComment(comment); + + } + + public void shutdownServer() throws SQLException { + checkClosed(); + + try { + this.mc.shutdownServer(); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + } + + public boolean supportsIsolationLevel() { + return this.mc.supportsIsolationLevel(); + } + + public boolean supportsQuotedIdentifiers() { + return this.mc.supportsQuotedIdentifiers(); + } + + public boolean supportsTransactions() { + return this.mc.supportsTransactions(); + } + + public boolean versionMeetsMinimum(int major, int minor, int subminor) + throws SQLException { + checkClosed(); + + try { + return this.mc.versionMeetsMinimum(major, minor, subminor); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return false; + } + + public String exposeAsXml() throws SQLException { + checkClosed(); + + try { + return this.mc.exposeAsXml(); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + + return null; + } + + public boolean getAllowLoadLocalInfile() { + return this.mc.getAllowLoadLocalInfile(); + } + + public boolean getAllowMultiQueries() { + return this.mc.getAllowMultiQueries(); + } + + public boolean getAllowNanAndInf() { + return this.mc.getAllowNanAndInf(); + } + + public boolean getAllowUrlInLocalInfile() { + return this.mc.getAllowUrlInLocalInfile(); + } + + public boolean getAlwaysSendSetIsolation() { + return this.mc.getAlwaysSendSetIsolation(); + } + + public boolean getAutoClosePStmtStreams() { + return this.mc.getAutoClosePStmtStreams(); + } + + public boolean getAutoDeserialize() { + return this.mc.getAutoDeserialize(); + } + + public boolean getAutoGenerateTestcaseScript() { + return this.mc.getAutoGenerateTestcaseScript(); + } + + public boolean getAutoReconnectForPools() { + return this.mc.getAutoReconnectForPools(); + } + + public boolean getAutoSlowLog() { + return this.mc.getAutoSlowLog(); + } + + public int getBlobSendChunkSize() { + return this.mc.getBlobSendChunkSize(); + } + + public boolean getBlobsAreStrings() { + return this.mc.getBlobsAreStrings(); + } + + public boolean getCacheCallableStatements() { + return this.mc.getCacheCallableStatements(); + } + + public boolean getCacheCallableStmts() { + return this.mc.getCacheCallableStmts(); + } + + public boolean getCachePrepStmts() { + return this.mc.getCachePrepStmts(); + } + + public boolean getCachePreparedStatements() { + return this.mc.getCachePreparedStatements(); + } + + public boolean getCacheResultSetMetadata() { + return this.mc.getCacheResultSetMetadata(); + } + + public boolean getCacheServerConfiguration() { + return this.mc.getCacheServerConfiguration(); + } + + public int getCallableStatementCacheSize() { + return this.mc.getCallableStatementCacheSize(); + } + + public int getCallableStmtCacheSize() { + return this.mc.getCallableStmtCacheSize(); + } + + public boolean getCapitalizeTypeNames() { + return this.mc.getCapitalizeTypeNames(); + } + + public String getCharacterSetResults() { + return this.mc.getCharacterSetResults(); + } + + public String getClientCertificateKeyStorePassword() { + return this.mc.getClientCertificateKeyStorePassword(); + } + + public String getClientCertificateKeyStoreType() { + return this.mc.getClientCertificateKeyStoreType(); + } + + public String getClientCertificateKeyStoreUrl() { + return this.mc.getClientCertificateKeyStoreUrl(); + } + + public String getClientInfoProvider() { + return this.mc.getClientInfoProvider(); + } + + public String getClobCharacterEncoding() { + return this.mc.getClobCharacterEncoding(); + } + + public boolean getClobberStreamingResults() { + return this.mc.getClobberStreamingResults(); + } + + public int getConnectTimeout() { + return this.mc.getConnectTimeout(); + } + + public String getConnectionCollation() { + return this.mc.getConnectionCollation(); + } + + public String getConnectionLifecycleInterceptors() { + return this.mc.getConnectionLifecycleInterceptors(); + } + + public boolean getContinueBatchOnError() { + return this.mc.getContinueBatchOnError(); + } + + public boolean getCreateDatabaseIfNotExist() { + return this.mc.getCreateDatabaseIfNotExist(); + } + + public int getDefaultFetchSize() { + return this.mc.getDefaultFetchSize(); + } + + public boolean getDontTrackOpenResources() { + return this.mc.getDontTrackOpenResources(); + } + + public boolean getDumpMetadataOnColumnNotFound() { + return this.mc.getDumpMetadataOnColumnNotFound(); + } + + public boolean getDumpQueriesOnException() { + return this.mc.getDumpQueriesOnException(); + } + + public boolean getDynamicCalendars() { + return this.mc.getDynamicCalendars(); + } + + public boolean getElideSetAutoCommits() { + return this.mc.getElideSetAutoCommits(); + } + + public boolean getEmptyStringsConvertToZero() { + return this.mc.getEmptyStringsConvertToZero(); + } + + public boolean getEmulateLocators() { + return this.mc.getEmulateLocators(); + } + + public boolean getEmulateUnsupportedPstmts() { + return this.mc.getEmulateUnsupportedPstmts(); + } + + public boolean getEnablePacketDebug() { + return this.mc.getEnablePacketDebug(); + } + + public boolean getEnableQueryTimeouts() { + return this.mc.getEnableQueryTimeouts(); + } + + public String getEncoding() { + return this.mc.getEncoding(); + } + + public boolean getExplainSlowQueries() { + return this.mc.getExplainSlowQueries(); + } + + public boolean getFailOverReadOnly() { + return this.mc.getFailOverReadOnly(); + } + + public boolean getFunctionsNeverReturnBlobs() { + return this.mc.getFunctionsNeverReturnBlobs(); + } + + public boolean getGatherPerfMetrics() { + return this.mc.getGatherPerfMetrics(); + } + + public boolean getGatherPerformanceMetrics() { + return this.mc.getGatherPerformanceMetrics(); + } + + public boolean getGenerateSimpleParameterMetadata() { + return this.mc.getGenerateSimpleParameterMetadata(); + } + + public boolean getHoldResultsOpenOverStatementClose() { + return this.mc.getHoldResultsOpenOverStatementClose(); + } + + public boolean getIgnoreNonTxTables() { + return this.mc.getIgnoreNonTxTables(); + } + + public boolean getIncludeInnodbStatusInDeadlockExceptions() { + return this.mc.getIncludeInnodbStatusInDeadlockExceptions(); + } + + public int getInitialTimeout() { + return this.mc.getInitialTimeout(); + } + + public boolean getInteractiveClient() { + return this.mc.getInteractiveClient(); + } + + public boolean getIsInteractiveClient() { + return this.mc.getIsInteractiveClient(); + } + + public boolean getJdbcCompliantTruncation() { + return this.mc.getJdbcCompliantTruncation(); + } + + public boolean getJdbcCompliantTruncationForReads() { + return this.mc.getJdbcCompliantTruncationForReads(); + } + + public String getLargeRowSizeThreshold() { + return this.mc.getLargeRowSizeThreshold(); + } + + public String getLoadBalanceStrategy() { + return this.mc.getLoadBalanceStrategy(); + } + + public String getLocalSocketAddress() { + return this.mc.getLocalSocketAddress(); + } + + public int getLocatorFetchBufferSize() { + return this.mc.getLocatorFetchBufferSize(); + } + + public boolean getLogSlowQueries() { + return this.mc.getLogSlowQueries(); + } + + public boolean getLogXaCommands() { + return this.mc.getLogXaCommands(); + } + + public String getLogger() { + return this.mc.getLogger(); + } + + public String getLoggerClassName() { + return this.mc.getLoggerClassName(); + } + + public boolean getMaintainTimeStats() { + return this.mc.getMaintainTimeStats(); + } + + public int getMaxQuerySizeToLog() { + return this.mc.getMaxQuerySizeToLog(); + } + + public int getMaxReconnects() { + return this.mc.getMaxReconnects(); + } + + public int getMaxRows() { + return this.mc.getMaxRows(); + } + + public int getMetadataCacheSize() { + return this.mc.getMetadataCacheSize(); + } + + public int getNetTimeoutForStreamingResults() { + return this.mc.getNetTimeoutForStreamingResults(); + } + + public boolean getNoAccessToProcedureBodies() { + return this.mc.getNoAccessToProcedureBodies(); + } + + public boolean getNoDatetimeStringSync() { + return this.mc.getNoDatetimeStringSync(); + } + + public boolean getNoTimezoneConversionForTimeType() { + return this.mc.getNoTimezoneConversionForTimeType(); + } + + public boolean getNullCatalogMeansCurrent() { + return this.mc.getNullCatalogMeansCurrent(); + } + + public boolean getNullNamePatternMatchesAll() { + return this.mc.getNullNamePatternMatchesAll(); + } + + public boolean getOverrideSupportsIntegrityEnhancementFacility() { + return this.mc.getOverrideSupportsIntegrityEnhancementFacility(); + } + + public int getPacketDebugBufferSize() { + return this.mc.getPacketDebugBufferSize(); + } + + public boolean getPadCharsWithSpace() { + return this.mc.getPadCharsWithSpace(); + } + + public boolean getParanoid() { + return this.mc.getParanoid(); + } + + public boolean getPedantic() { + return this.mc.getPedantic(); + } + + public boolean getPinGlobalTxToPhysicalConnection() { + return this.mc.getPinGlobalTxToPhysicalConnection(); + } + + public boolean getPopulateInsertRowWithDefaultValues() { + return this.mc.getPopulateInsertRowWithDefaultValues(); + } + + public int getPrepStmtCacheSize() { + return this.mc.getPrepStmtCacheSize(); + } + + public int getPrepStmtCacheSqlLimit() { + return this.mc.getPrepStmtCacheSqlLimit(); + } + + public int getPreparedStatementCacheSize() { + return this.mc.getPreparedStatementCacheSize(); + } + + public int getPreparedStatementCacheSqlLimit() { + return this.mc.getPreparedStatementCacheSqlLimit(); + } + + public boolean getProcessEscapeCodesForPrepStmts() { + return this.mc.getProcessEscapeCodesForPrepStmts(); + } + + public boolean getProfileSQL() { + return this.mc.getProfileSQL(); + } + + public boolean getProfileSql() { + return this.mc.getProfileSql(); + } + + public String getPropertiesTransform() { + return this.mc.getPropertiesTransform(); + } + + public int getQueriesBeforeRetryMaster() { + return this.mc.getQueriesBeforeRetryMaster(); + } + + public boolean getReconnectAtTxEnd() { + return this.mc.getReconnectAtTxEnd(); + } + + public boolean getRelaxAutoCommit() { + return this.mc.getRelaxAutoCommit(); + } + + public int getReportMetricsIntervalMillis() { + return this.mc.getReportMetricsIntervalMillis(); + } + + public boolean getRequireSSL() { + return this.mc.getRequireSSL(); + } + + public String getResourceId() { + return this.mc.getResourceId(); + } + + public int getResultSetSizeThreshold() { + return this.mc.getResultSetSizeThreshold(); + } + + public boolean getRewriteBatchedStatements() { + return this.mc.getRewriteBatchedStatements(); + } + + public boolean getRollbackOnPooledClose() { + return this.mc.getRollbackOnPooledClose(); + } + + public boolean getRoundRobinLoadBalance() { + return this.mc.getRoundRobinLoadBalance(); + } + + public boolean getRunningCTS13() { + return this.mc.getRunningCTS13(); + } + + public int getSecondsBeforeRetryMaster() { + return this.mc.getSecondsBeforeRetryMaster(); + } + + public String getServerTimezone() { + return this.mc.getServerTimezone(); + } + + public String getSessionVariables() { + return this.mc.getSessionVariables(); + } + + public int getSlowQueryThresholdMillis() { + return this.mc.getSlowQueryThresholdMillis(); + } + + public long getSlowQueryThresholdNanos() { + return this.mc.getSlowQueryThresholdNanos(); + } + + public String getSocketFactory() { + return this.mc.getSocketFactory(); + } + + public String getSocketFactoryClassName() { + return this.mc.getSocketFactoryClassName(); + } + + public int getSocketTimeout() { + return this.mc.getSocketTimeout(); + } + + public String getStatementInterceptors() { + return this.mc.getStatementInterceptors(); + } + + public boolean getStrictFloatingPoint() { + return this.mc.getStrictFloatingPoint(); + } + + public boolean getStrictUpdates() { + return this.mc.getStrictUpdates(); + } + + public boolean getTcpKeepAlive() { + return this.mc.getTcpKeepAlive(); + } + + public boolean getTcpNoDelay() { + return this.mc.getTcpNoDelay(); + } + + public int getTcpRcvBuf() { + return this.mc.getTcpRcvBuf(); + } + + public int getTcpSndBuf() { + return this.mc.getTcpSndBuf(); + } + + public int getTcpTrafficClass() { + return this.mc.getTcpTrafficClass(); + } + + public boolean getTinyInt1isBit() { + return this.mc.getTinyInt1isBit(); + } + + public boolean getTraceProtocol() { + return this.mc.getTraceProtocol(); + } + + public boolean getTransformedBitIsBoolean() { + return this.mc.getTransformedBitIsBoolean(); + } + + public boolean getTreatUtilDateAsTimestamp() { + return this.mc.getTreatUtilDateAsTimestamp(); + } + + public String getTrustCertificateKeyStorePassword() { + return this.mc.getTrustCertificateKeyStorePassword(); + } + + public String getTrustCertificateKeyStoreType() { + return this.mc.getTrustCertificateKeyStoreType(); + } + + public String getTrustCertificateKeyStoreUrl() { + return this.mc.getTrustCertificateKeyStoreUrl(); + } + + public boolean getUltraDevHack() { + return this.mc.getUltraDevHack(); + } + + public boolean getUseBlobToStoreUTF8OutsideBMP() { + return this.mc.getUseBlobToStoreUTF8OutsideBMP(); + } + + public boolean getUseCompression() { + return this.mc.getUseCompression(); + } + + public String getUseConfigs() { + return this.mc.getUseConfigs(); + } + + public boolean getUseCursorFetch() { + return this.mc.getUseCursorFetch(); + } + + public boolean getUseDirectRowUnpack() { + return this.mc.getUseDirectRowUnpack(); + } + + public boolean getUseDynamicCharsetInfo() { + return this.mc.getUseDynamicCharsetInfo(); + } + + public boolean getUseFastDateParsing() { + return this.mc.getUseFastDateParsing(); + } + + public boolean getUseFastIntParsing() { + return this.mc.getUseFastIntParsing(); + } + + public boolean getUseGmtMillisForDatetimes() { + return this.mc.getUseGmtMillisForDatetimes(); + } + + public boolean getUseHostsInPrivileges() { + return this.mc.getUseHostsInPrivileges(); + } + + public boolean getUseInformationSchema() { + return this.mc.getUseInformationSchema(); + } + + public boolean getUseJDBCCompliantTimezoneShift() { + return this.mc.getUseJDBCCompliantTimezoneShift(); + } + + public boolean getUseJvmCharsetConverters() { + return this.mc.getUseJvmCharsetConverters(); + } + + public boolean getUseLocalSessionState() { + return this.mc.getUseLocalSessionState(); + } + + public boolean getUseNanosForElapsedTime() { + return this.mc.getUseNanosForElapsedTime(); + } + + public boolean getUseOldAliasMetadataBehavior() { + return this.mc.getUseOldAliasMetadataBehavior(); + } + + public boolean getUseOldUTF8Behavior() { + return this.mc.getUseOldUTF8Behavior(); + } + + public boolean getUseOnlyServerErrorMessages() { + return this.mc.getUseOnlyServerErrorMessages(); + } + + public boolean getUseReadAheadInput() { + return this.mc.getUseReadAheadInput(); + } + + public boolean getUseSSL() { + return this.mc.getUseSSL(); + } + + public boolean getUseSSPSCompatibleTimezoneShift() { + return this.mc.getUseSSPSCompatibleTimezoneShift(); + } + + public boolean getUseServerPrepStmts() { + return this.mc.getUseServerPrepStmts(); + } + + public boolean getUseServerPreparedStmts() { + return this.mc.getUseServerPreparedStmts(); + } + + public boolean getUseSqlStateCodes() { + return this.mc.getUseSqlStateCodes(); + } + + public boolean getUseStreamLengthsInPrepStmts() { + return this.mc.getUseStreamLengthsInPrepStmts(); + } + + public boolean getUseTimezone() { + return this.mc.getUseTimezone(); + } + + public boolean getUseUltraDevWorkAround() { + return this.mc.getUseUltraDevWorkAround(); + } + + public boolean getUseUnbufferedInput() { + return this.mc.getUseUnbufferedInput(); + } + + public boolean getUseUnicode() { + return this.mc.getUseUnicode(); + } + + public boolean getUseUsageAdvisor() { + return this.mc.getUseUsageAdvisor(); + } + + public String getUtf8OutsideBmpExcludedColumnNamePattern() { + return this.mc.getUtf8OutsideBmpExcludedColumnNamePattern(); + } + + public String getUtf8OutsideBmpIncludedColumnNamePattern() { + return this.mc.getUtf8OutsideBmpIncludedColumnNamePattern(); + } + + public boolean getYearIsDateType() { + return this.mc.getYearIsDateType(); + } + + public String getZeroDateTimeBehavior() { + return this.mc.getZeroDateTimeBehavior(); + } + + public void setAllowLoadLocalInfile(boolean property) { + this.mc.setAllowLoadLocalInfile(property); + } + + public void setAllowMultiQueries(boolean property) { + this.mc.setAllowMultiQueries(property); + } + + public void setAllowNanAndInf(boolean flag) { + this.mc.setAllowNanAndInf(flag); + } + + public void setAllowUrlInLocalInfile(boolean flag) { + this.mc.setAllowUrlInLocalInfile(flag); + } + + public void setAlwaysSendSetIsolation(boolean flag) { + this.mc.setAlwaysSendSetIsolation(flag); + } + + public void setAutoClosePStmtStreams(boolean flag) { + this.mc.setAutoClosePStmtStreams(flag); + } + + public void setAutoDeserialize(boolean flag) { + this.mc.setAutoDeserialize(flag); + } + + public void setAutoGenerateTestcaseScript(boolean flag) { + this.mc.setAutoGenerateTestcaseScript(flag); + } + + public void setAutoReconnect(boolean flag) { + this.mc.setAutoReconnect(flag); + } + + public void setAutoReconnectForConnectionPools(boolean property) { + this.mc.setAutoReconnectForConnectionPools(property); + } + + public void setAutoReconnectForPools(boolean flag) { + this.mc.setAutoReconnectForPools(flag); + } + + public void setAutoSlowLog(boolean flag) { + this.mc.setAutoSlowLog(flag); + } + + public void setBlobSendChunkSize(String value) throws SQLException { + this.mc.setBlobSendChunkSize(value); + } + + public void setBlobsAreStrings(boolean flag) { + this.mc.setBlobsAreStrings(flag); + } + + public void setCacheCallableStatements(boolean flag) { + this.mc.setCacheCallableStatements(flag); + } + + public void setCacheCallableStmts(boolean flag) { + this.mc.setCacheCallableStmts(flag); + } + + public void setCachePrepStmts(boolean flag) { + this.mc.setCachePrepStmts(flag); + } + + public void setCachePreparedStatements(boolean flag) { + this.mc.setCachePreparedStatements(flag); + } + + public void setCacheResultSetMetadata(boolean property) { + this.mc.setCacheResultSetMetadata(property); + } + + public void setCacheServerConfiguration(boolean flag) { + this.mc.setCacheServerConfiguration(flag); + } + + public void setCallableStatementCacheSize(int size) throws SQLException { + this.mc.setCallableStatementCacheSize(size); + } + + public void setCallableStmtCacheSize(int cacheSize) throws SQLException { + this.mc.setCallableStmtCacheSize(cacheSize); + } + + public void setCapitalizeDBMDTypes(boolean property) { + this.mc.setCapitalizeDBMDTypes(property); + } + + public void setCapitalizeTypeNames(boolean flag) { + this.mc.setCapitalizeTypeNames(flag); + } + + public void setCharacterEncoding(String encoding) { + this.mc.setCharacterEncoding(encoding); + } + + public void setCharacterSetResults(String characterSet) { + this.mc.setCharacterSetResults(characterSet); + } + + public void setClientCertificateKeyStorePassword(String value) { + this.mc.setClientCertificateKeyStorePassword(value); + } + + public void setClientCertificateKeyStoreType(String value) { + this.mc.setClientCertificateKeyStoreType(value); + } + + public void setClientCertificateKeyStoreUrl(String value) { + this.mc.setClientCertificateKeyStoreUrl(value); + } + + public void setClientInfoProvider(String classname) { + this.mc.setClientInfoProvider(classname); + } + + public void setClobCharacterEncoding(String encoding) { + this.mc.setClobCharacterEncoding(encoding); + } + + public void setClobberStreamingResults(boolean flag) { + this.mc.setClobberStreamingResults(flag); + } + + public void setConnectTimeout(int timeoutMs) throws SQLException { + this.mc.setConnectTimeout(timeoutMs); + } + + public void setConnectionCollation(String collation) { + this.mc.setConnectionCollation(collation); + } + + public void setConnectionLifecycleInterceptors(String interceptors) { + this.mc.setConnectionLifecycleInterceptors(interceptors); + } + + public void setContinueBatchOnError(boolean property) { + this.mc.setContinueBatchOnError(property); + } + + public void setCreateDatabaseIfNotExist(boolean flag) { + this.mc.setCreateDatabaseIfNotExist(flag); + } + + public void setDefaultFetchSize(int n) throws SQLException { + this.mc.setDefaultFetchSize(n); + } + + public void setDetectServerPreparedStmts(boolean property) { + this.mc.setDetectServerPreparedStmts(property); + } + + public void setDontTrackOpenResources(boolean flag) { + this.mc.setDontTrackOpenResources(flag); + } + + public void setDumpMetadataOnColumnNotFound(boolean flag) { + this.mc.setDumpMetadataOnColumnNotFound(flag); + } + + public void setDumpQueriesOnException(boolean flag) { + this.mc.setDumpQueriesOnException(flag); + } + + public void setDynamicCalendars(boolean flag) { + this.mc.setDynamicCalendars(flag); + } + + public void setElideSetAutoCommits(boolean flag) { + this.mc.setElideSetAutoCommits(flag); + } + + public void setEmptyStringsConvertToZero(boolean flag) { + this.mc.setEmptyStringsConvertToZero(flag); + } + + public void setEmulateLocators(boolean property) { + this.mc.setEmulateLocators(property); + } + + public void setEmulateUnsupportedPstmts(boolean flag) { + this.mc.setEmulateUnsupportedPstmts(flag); + } + + public void setEnablePacketDebug(boolean flag) { + this.mc.setEnablePacketDebug(flag); + } + + public void setEnableQueryTimeouts(boolean flag) { + this.mc.setEnableQueryTimeouts(flag); + } + + public void setEncoding(String property) { + this.mc.setEncoding(property); + } + + public void setExplainSlowQueries(boolean flag) { + this.mc.setExplainSlowQueries(flag); + } + + public void setFailOverReadOnly(boolean flag) { + this.mc.setFailOverReadOnly(flag); + } + + public void setFunctionsNeverReturnBlobs(boolean flag) { + this.mc.setFunctionsNeverReturnBlobs(flag); + } + + public void setGatherPerfMetrics(boolean flag) { + this.mc.setGatherPerfMetrics(flag); + } + + public void setGatherPerformanceMetrics(boolean flag) { + this.mc.setGatherPerformanceMetrics(flag); + } + + public void setGenerateSimpleParameterMetadata(boolean flag) { + this.mc.setGenerateSimpleParameterMetadata(flag); + } + + public void setHoldResultsOpenOverStatementClose(boolean flag) { + this.mc.setHoldResultsOpenOverStatementClose(flag); + } + + public void setIgnoreNonTxTables(boolean property) { + this.mc.setIgnoreNonTxTables(property); + } + + public void setIncludeInnodbStatusInDeadlockExceptions(boolean flag) { + this.mc.setIncludeInnodbStatusInDeadlockExceptions(flag); + } + + public void setInitialTimeout(int property) throws SQLException { + this.mc.setInitialTimeout(property); + } + + public void setInteractiveClient(boolean property) { + this.mc.setInteractiveClient(property); + } + + public void setIsInteractiveClient(boolean property) { + this.mc.setIsInteractiveClient(property); + } + + public void setJdbcCompliantTruncation(boolean flag) { + this.mc.setJdbcCompliantTruncation(flag); + } + + public void setJdbcCompliantTruncationForReads( + boolean jdbcCompliantTruncationForReads) { + this.mc + .setJdbcCompliantTruncationForReads(jdbcCompliantTruncationForReads); + } + + public void setLargeRowSizeThreshold(String value) throws SQLException { + this.mc.setLargeRowSizeThreshold(value); + } + + public void setLoadBalanceStrategy(String strategy) { + this.mc.setLoadBalanceStrategy(strategy); + } + + public void setLocalSocketAddress(String address) { + this.mc.setLocalSocketAddress(address); + } + + public void setLocatorFetchBufferSize(String value) throws SQLException { + this.mc.setLocatorFetchBufferSize(value); + } + + public void setLogSlowQueries(boolean flag) { + this.mc.setLogSlowQueries(flag); + } + + public void setLogXaCommands(boolean flag) { + this.mc.setLogXaCommands(flag); + } + + public void setLogger(String property) { + this.mc.setLogger(property); + } + + public void setLoggerClassName(String className) { + this.mc.setLoggerClassName(className); + } + + public void setMaintainTimeStats(boolean flag) { + this.mc.setMaintainTimeStats(flag); + } + + public void setMaxQuerySizeToLog(int sizeInBytes) throws SQLException { + this.mc.setMaxQuerySizeToLog(sizeInBytes); + } + + public void setMaxReconnects(int property) throws SQLException { + this.mc.setMaxReconnects(property); + } + + public void setMaxRows(int property) throws SQLException { + this.mc.setMaxRows(property); + } + + public void setMetadataCacheSize(int value) throws SQLException { + this.mc.setMetadataCacheSize(value); + } + + public void setNetTimeoutForStreamingResults(int value) throws SQLException { + this.mc.setNetTimeoutForStreamingResults(value); + } + + public void setNoAccessToProcedureBodies(boolean flag) { + this.mc.setNoAccessToProcedureBodies(flag); + } + + public void setNoDatetimeStringSync(boolean flag) { + this.mc.setNoDatetimeStringSync(flag); + } + + public void setNoTimezoneConversionForTimeType(boolean flag) { + this.mc.setNoTimezoneConversionForTimeType(flag); + } + + public void setNullCatalogMeansCurrent(boolean value) { + this.mc.setNullCatalogMeansCurrent(value); + } + + public void setNullNamePatternMatchesAll(boolean value) { + this.mc.setNullNamePatternMatchesAll(value); + } + + public void setOverrideSupportsIntegrityEnhancementFacility(boolean flag) { + this.mc.setOverrideSupportsIntegrityEnhancementFacility(flag); + } + + public void setPacketDebugBufferSize(int size) throws SQLException { + this.mc.setPacketDebugBufferSize(size); + } + + public void setPadCharsWithSpace(boolean flag) { + this.mc.setPadCharsWithSpace(flag); + } + + public void setParanoid(boolean property) { + this.mc.setParanoid(property); + } + + public void setPedantic(boolean property) { + this.mc.setPedantic(property); + } + + public void setPinGlobalTxToPhysicalConnection(boolean flag) { + this.mc.setPinGlobalTxToPhysicalConnection(flag); + } + + public void setPopulateInsertRowWithDefaultValues(boolean flag) { + this.mc.setPopulateInsertRowWithDefaultValues(flag); + } + + public void setPrepStmtCacheSize(int cacheSize) throws SQLException { + this.mc.setPrepStmtCacheSize(cacheSize); + } + + public void setPrepStmtCacheSqlLimit(int sqlLimit) throws SQLException { + this.mc.setPrepStmtCacheSqlLimit(sqlLimit); + } + + public void setPreparedStatementCacheSize(int cacheSize) throws SQLException { + this.mc.setPreparedStatementCacheSize(cacheSize); + } + + public void setPreparedStatementCacheSqlLimit(int cacheSqlLimit) throws SQLException { + this.mc.setPreparedStatementCacheSqlLimit(cacheSqlLimit); + } + + public void setProcessEscapeCodesForPrepStmts(boolean flag) { + this.mc.setProcessEscapeCodesForPrepStmts(flag); + } + + public void setProfileSQL(boolean flag) { + this.mc.setProfileSQL(flag); + } + + public void setProfileSql(boolean property) { + this.mc.setProfileSql(property); + } + + public void setPropertiesTransform(String value) { + this.mc.setPropertiesTransform(value); + } + + public void setQueriesBeforeRetryMaster(int property) throws SQLException { + this.mc.setQueriesBeforeRetryMaster(property); + } + + public void setReconnectAtTxEnd(boolean property) { + this.mc.setReconnectAtTxEnd(property); + } + + public void setRelaxAutoCommit(boolean property) { + this.mc.setRelaxAutoCommit(property); + } + + public void setReportMetricsIntervalMillis(int millis) throws SQLException { + this.mc.setReportMetricsIntervalMillis(millis); + } + + public void setRequireSSL(boolean property) { + this.mc.setRequireSSL(property); + } + + public void setResourceId(String resourceId) { + this.mc.setResourceId(resourceId); + } + + public void setResultSetSizeThreshold(int threshold) throws SQLException { + this.mc.setResultSetSizeThreshold(threshold); + } + + public void setRetainStatementAfterResultSetClose(boolean flag) { + this.mc.setRetainStatementAfterResultSetClose(flag); + } + + public void setRewriteBatchedStatements(boolean flag) { + this.mc.setRewriteBatchedStatements(flag); + } + + public void setRollbackOnPooledClose(boolean flag) { + this.mc.setRollbackOnPooledClose(flag); + } + + public void setRoundRobinLoadBalance(boolean flag) { + this.mc.setRoundRobinLoadBalance(flag); + } + + public void setRunningCTS13(boolean flag) { + this.mc.setRunningCTS13(flag); + } + + public void setSecondsBeforeRetryMaster(int property) throws SQLException { + this.mc.setSecondsBeforeRetryMaster(property); + } + + public void setServerTimezone(String property) { + this.mc.setServerTimezone(property); + } + + public void setSessionVariables(String variables) { + this.mc.setSessionVariables(variables); + } + + public void setSlowQueryThresholdMillis(int millis) throws SQLException { + this.mc.setSlowQueryThresholdMillis(millis); + } + + public void setSlowQueryThresholdNanos(long nanos) throws SQLException { + this.mc.setSlowQueryThresholdNanos(nanos); + } + + public void setSocketFactory(String name) { + this.mc.setSocketFactory(name); + } + + public void setSocketFactoryClassName(String property) { + this.mc.setSocketFactoryClassName(property); + } + + public void setSocketTimeout(int property) throws SQLException { + this.mc.setSocketTimeout(property); + } + + public void setStatementInterceptors(String value) { + this.mc.setStatementInterceptors(value); + } + + public void setStrictFloatingPoint(boolean property) { + this.mc.setStrictFloatingPoint(property); + } + + public void setStrictUpdates(boolean property) { + this.mc.setStrictUpdates(property); + } + + public void setTcpKeepAlive(boolean flag) { + this.mc.setTcpKeepAlive(flag); + } + + public void setTcpNoDelay(boolean flag) { + this.mc.setTcpNoDelay(flag); + } + + public void setTcpRcvBuf(int bufSize) throws SQLException { + this.mc.setTcpRcvBuf(bufSize); + } + + public void setTcpSndBuf(int bufSize) throws SQLException { + this.mc.setTcpSndBuf(bufSize); + } + + public void setTcpTrafficClass(int classFlags) throws SQLException { + this.mc.setTcpTrafficClass(classFlags); + } + + public void setTinyInt1isBit(boolean flag) { + this.mc.setTinyInt1isBit(flag); + } + + public void setTraceProtocol(boolean flag) { + this.mc.setTraceProtocol(flag); + } + + public void setTransformedBitIsBoolean(boolean flag) { + this.mc.setTransformedBitIsBoolean(flag); + } + + public void setTreatUtilDateAsTimestamp(boolean flag) { + this.mc.setTreatUtilDateAsTimestamp(flag); + } + + public void setTrustCertificateKeyStorePassword(String value) { + this.mc.setTrustCertificateKeyStorePassword(value); + } + + public void setTrustCertificateKeyStoreType(String value) { + this.mc.setTrustCertificateKeyStoreType(value); + } + + public void setTrustCertificateKeyStoreUrl(String value) { + this.mc.setTrustCertificateKeyStoreUrl(value); + } + + public void setUltraDevHack(boolean flag) { + this.mc.setUltraDevHack(flag); + } + + public void setUseBlobToStoreUTF8OutsideBMP(boolean flag) { + this.mc.setUseBlobToStoreUTF8OutsideBMP(flag); + } + + public void setUseCompression(boolean property) { + this.mc.setUseCompression(property); + } + + public void setUseConfigs(String configs) { + this.mc.setUseConfigs(configs); + } + + public void setUseCursorFetch(boolean flag) { + this.mc.setUseCursorFetch(flag); + } + + public void setUseDirectRowUnpack(boolean flag) { + this.mc.setUseDirectRowUnpack(flag); + } + + public void setUseDynamicCharsetInfo(boolean flag) { + this.mc.setUseDynamicCharsetInfo(flag); + } + + public void setUseFastDateParsing(boolean flag) { + this.mc.setUseFastDateParsing(flag); + } + + public void setUseFastIntParsing(boolean flag) { + this.mc.setUseFastIntParsing(flag); + } + + public void setUseGmtMillisForDatetimes(boolean flag) { + this.mc.setUseGmtMillisForDatetimes(flag); + } + + public void setUseHostsInPrivileges(boolean property) { + this.mc.setUseHostsInPrivileges(property); + } + + public void setUseInformationSchema(boolean flag) { + this.mc.setUseInformationSchema(flag); + } + + public void setUseJDBCCompliantTimezoneShift(boolean flag) { + this.mc.setUseJDBCCompliantTimezoneShift(flag); + } + + public void setUseJvmCharsetConverters(boolean flag) { + this.mc.setUseJvmCharsetConverters(flag); + } + + public void setUseLocalSessionState(boolean flag) { + this.mc.setUseLocalSessionState(flag); + } + + public void setUseNanosForElapsedTime(boolean flag) { + this.mc.setUseNanosForElapsedTime(flag); + } + + public void setUseOldAliasMetadataBehavior(boolean flag) { + this.mc.setUseOldAliasMetadataBehavior(flag); + } + + public void setUseOldUTF8Behavior(boolean flag) { + this.mc.setUseOldUTF8Behavior(flag); + } + + public void setUseOnlyServerErrorMessages(boolean flag) { + this.mc.setUseOnlyServerErrorMessages(flag); + } + + public void setUseReadAheadInput(boolean flag) { + this.mc.setUseReadAheadInput(flag); + } + + public void setUseSSL(boolean property) { + this.mc.setUseSSL(property); + } + + public void setUseSSPSCompatibleTimezoneShift(boolean flag) { + this.mc.setUseSSPSCompatibleTimezoneShift(flag); + } + + public void setUseServerPrepStmts(boolean flag) { + this.mc.setUseServerPrepStmts(flag); + } + + public void setUseServerPreparedStmts(boolean flag) { + this.mc.setUseServerPreparedStmts(flag); + } + + public void setUseSqlStateCodes(boolean flag) { + this.mc.setUseSqlStateCodes(flag); + } + + public void setUseStreamLengthsInPrepStmts(boolean property) { + this.mc.setUseStreamLengthsInPrepStmts(property); + } + + public void setUseTimezone(boolean property) { + this.mc.setUseTimezone(property); + } + + public void setUseUltraDevWorkAround(boolean property) { + this.mc.setUseUltraDevWorkAround(property); + } + + public void setUseUnbufferedInput(boolean flag) { + this.mc.setUseUnbufferedInput(flag); + } + + public void setUseUnicode(boolean flag) { + this.mc.setUseUnicode(flag); + } + + public void setUseUsageAdvisor(boolean useUsageAdvisorFlag) { + this.mc.setUseUsageAdvisor(useUsageAdvisorFlag); + } + + public void setUtf8OutsideBmpExcludedColumnNamePattern(String regexPattern) { + this.mc.setUtf8OutsideBmpExcludedColumnNamePattern(regexPattern); + } + + public void setUtf8OutsideBmpIncludedColumnNamePattern(String regexPattern) { + this.mc.setUtf8OutsideBmpIncludedColumnNamePattern(regexPattern); + } + + public void setYearIsDateType(boolean flag) { + this.mc.setYearIsDateType(flag); + } + + public void setZeroDateTimeBehavior(String behavior) { + this.mc.setZeroDateTimeBehavior(behavior); + } + + public boolean useUnbufferedInput() { + return this.mc.useUnbufferedInput(); + } + + public void initializeExtension(Extension ex) throws SQLException { + this.mc.initializeExtension(ex); + } + + public String getProfilerEventHandler() { + return this.mc.getProfilerEventHandler(); + } + + public void setProfilerEventHandler(String handler) { + this.mc.setProfilerEventHandler(handler); + } + + public boolean getVerifyServerCertificate() { + return this.mc.getVerifyServerCertificate(); + } + + public void setVerifyServerCertificate(boolean flag) { + this.mc.setVerifyServerCertificate(flag); + } + + public boolean getUseLegacyDatetimeCode() { + return this.mc.getUseLegacyDatetimeCode(); + } + + public void setUseLegacyDatetimeCode(boolean flag) { + this.mc.setUseLegacyDatetimeCode(flag); + } + + public int getSelfDestructOnPingMaxOperations() { + return this.mc.getSelfDestructOnPingMaxOperations(); + } + + public int getSelfDestructOnPingSecondsLifetime() { + return this.mc.getSelfDestructOnPingSecondsLifetime(); + } + + public void setSelfDestructOnPingMaxOperations(int maxOperations) throws SQLException { + this.mc.setSelfDestructOnPingMaxOperations(maxOperations); + } + + public void setSelfDestructOnPingSecondsLifetime(int seconds) throws SQLException { + this.mc.setSelfDestructOnPingSecondsLifetime(seconds); + } + + public boolean getUseColumnNamesInFindColumn() { + return this.mc.getUseColumnNamesInFindColumn(); + } + + public void setUseColumnNamesInFindColumn(boolean flag) { + this.mc.setUseColumnNamesInFindColumn(flag); + } + + public boolean getUseLocalTransactionState() { + return this.mc.getUseLocalTransactionState(); + } + + public void setUseLocalTransactionState(boolean flag) { + this.mc.setUseLocalTransactionState(flag); + } + + public boolean getCompensateOnDuplicateKeyUpdateCounts() { + return this.mc.getCompensateOnDuplicateKeyUpdateCounts(); + } + + public void setCompensateOnDuplicateKeyUpdateCounts(boolean flag) { + this.mc.setCompensateOnDuplicateKeyUpdateCounts(flag); + } + + public boolean getUseAffectedRows() { + return this.mc.getUseAffectedRows(); + } + + public void setUseAffectedRows(boolean flag) { + this.mc.setUseAffectedRows(flag); + } + + public String getPasswordCharacterEncoding() { + return this.mc.getPasswordCharacterEncoding(); + } + + public void setPasswordCharacterEncoding(String characterSet) { + this.mc.setPasswordCharacterEncoding(characterSet); + } + + public int getAutoIncrementIncrement() { + return this.mc.getAutoIncrementIncrement(); + } + + public int getLoadBalanceBlacklistTimeout() { + return this.mc.getLoadBalanceBlacklistTimeout(); + } + + public void setLoadBalanceBlacklistTimeout(int loadBalanceBlacklistTimeout) throws SQLException { + this.mc.setLoadBalanceBlacklistTimeout(loadBalanceBlacklistTimeout); + } + public int getLoadBalancePingTimeout() { + return this.mc.getLoadBalancePingTimeout(); + } + + public void setLoadBalancePingTimeout(int loadBalancePingTimeout) throws SQLException { + this.mc.setLoadBalancePingTimeout(loadBalancePingTimeout); + } + + public boolean getLoadBalanceValidateConnectionOnSwapServer() { + return this.mc.getLoadBalanceValidateConnectionOnSwapServer(); + } + + public void setLoadBalanceValidateConnectionOnSwapServer( + boolean loadBalanceValidateConnectionOnSwapServer) { + this.mc.setLoadBalanceValidateConnectionOnSwapServer(loadBalanceValidateConnectionOnSwapServer); + } + + public void setRetriesAllDown(int retriesAllDown) throws SQLException { + this.mc.setRetriesAllDown(retriesAllDown); + } + + public int getRetriesAllDown() { + return this.mc.getRetriesAllDown(); + } + + public ExceptionInterceptor getExceptionInterceptor() { + return this.pooledConnection.getExceptionInterceptor(); + } + + public String getExceptionInterceptors() { + return this.mc.getExceptionInterceptors(); + } + + public void setExceptionInterceptors(String exceptionInterceptors) { + this.mc.setExceptionInterceptors(exceptionInterceptors); + } + + public boolean getQueryTimeoutKillsConnection() { + return this.mc.getQueryTimeoutKillsConnection(); + } + + public void setQueryTimeoutKillsConnection( + boolean queryTimeoutKillsConnection) { + this.mc.setQueryTimeoutKillsConnection(queryTimeoutKillsConnection); + } + + public boolean hasSameProperties(Connection c) { + return this.mc.hasSameProperties(c); + } + + public Properties getProperties() { + return this.mc.getProperties(); + } + + public String getHost() { + return this.mc.getHost(); + } + + public void setProxy(MySQLConnection conn) { + this.mc.setProxy(conn); + } + + public boolean getRetainStatementAfterResultSetClose() { + return this.mc.getRetainStatementAfterResultSetClose(); + } + + public int getMaxAllowedPacket() { + return this.mc.getMaxAllowedPacket(); + } + + public String getLoadBalanceConnectionGroup() { + return this.mc.getLoadBalanceConnectionGroup(); + } + + public boolean getLoadBalanceEnableJMX() { + return this.mc.getLoadBalanceEnableJMX(); + } + + public String getLoadBalanceExceptionChecker() { + return this.mc + .getLoadBalanceExceptionChecker(); + } + + public String getLoadBalanceSQLExceptionSubclassFailover() { + return this.mc + .getLoadBalanceSQLExceptionSubclassFailover(); + } + + public String getLoadBalanceSQLStateFailover() { + return this.mc + .getLoadBalanceSQLStateFailover(); + } + + public void setLoadBalanceConnectionGroup(String loadBalanceConnectionGroup) { + this.mc + .setLoadBalanceConnectionGroup(loadBalanceConnectionGroup); + + } + + public void setLoadBalanceEnableJMX(boolean loadBalanceEnableJMX) { + this.mc + .setLoadBalanceEnableJMX(loadBalanceEnableJMX); + + } + + public void setLoadBalanceExceptionChecker( + String loadBalanceExceptionChecker) { + this.mc + .setLoadBalanceExceptionChecker(loadBalanceExceptionChecker); + + } + + public void setLoadBalanceSQLExceptionSubclassFailover( + String loadBalanceSQLExceptionSubclassFailover) { + this.mc + .setLoadBalanceSQLExceptionSubclassFailover(loadBalanceSQLExceptionSubclassFailover); + + } + + public void setLoadBalanceSQLStateFailover( + String loadBalanceSQLStateFailover) { + this.mc + .setLoadBalanceSQLStateFailover(loadBalanceSQLStateFailover); + + } + + + public String getLoadBalanceAutoCommitStatementRegex() { + return this.mc.getLoadBalanceAutoCommitStatementRegex(); + } + + public int getLoadBalanceAutoCommitStatementThreshold() { + return this.mc.getLoadBalanceAutoCommitStatementThreshold(); + } + + public void setLoadBalanceAutoCommitStatementRegex( + String loadBalanceAutoCommitStatementRegex) { + this.mc.setLoadBalanceAutoCommitStatementRegex(loadBalanceAutoCommitStatementRegex); + + } + + public void setLoadBalanceAutoCommitStatementThreshold( + int loadBalanceAutoCommitStatementThreshold) throws SQLException { + this.mc.setLoadBalanceAutoCommitStatementThreshold(loadBalanceAutoCommitStatementThreshold); + + } + + public void setTypeMap(Map> map) throws SQLException { + checkClosed(); + + try { + this.mc.setTypeMap(map); + } catch (SQLException sqlException) { + checkAndFireConnectionError(sqlException); + } + } + + public boolean getIncludeThreadDumpInDeadlockExceptions() { + return this.mc.getIncludeThreadDumpInDeadlockExceptions(); + } + + public void setIncludeThreadDumpInDeadlockExceptions(boolean flag) { + this.mc.setIncludeThreadDumpInDeadlockExceptions(flag); + + } + + public boolean getIncludeThreadNamesAsStatementComment() { + return this.mc.getIncludeThreadNamesAsStatementComment(); + } + + public void setIncludeThreadNamesAsStatementComment(boolean flag) { + this.mc.setIncludeThreadNamesAsStatementComment(flag); + } + + public boolean isServerLocal() throws SQLException { + return this.mc.isServerLocal(); + } + + public void setAuthenticationPlugins(String authenticationPlugins) { + this.mc.setAuthenticationPlugins(authenticationPlugins); + } + + public String getAuthenticationPlugins() { + return this.mc.getAuthenticationPlugins(); + } + + public void setDisabledAuthenticationPlugins( + String disabledAuthenticationPlugins) { + this.mc.setDisabledAuthenticationPlugins(disabledAuthenticationPlugins); + } + + public String getDisabledAuthenticationPlugins() { + return this.mc.getDisabledAuthenticationPlugins(); + } + + public void setDefaultAuthenticationPlugin( + String defaultAuthenticationPlugin) { + this.mc.setDefaultAuthenticationPlugin(defaultAuthenticationPlugin); + + } + + public String getDefaultAuthenticationPlugin() { + return this.mc.getDefaultAuthenticationPlugin(); + } + + public void setParseInfoCacheFactory(String factoryClassname) { + this.mc.setParseInfoCacheFactory(factoryClassname); + } + + public String getParseInfoCacheFactory() { + return this.mc.getParseInfoCacheFactory(); + } + + public void setSchema(String schema) throws SQLException { + this.mc.setSchema(schema); + } + + public String getSchema() throws SQLException { + return this.mc.getSchema(); + } + + public void abort(Executor executor) throws SQLException { + this.mc.abort(executor); + } + + public void setNetworkTimeout(Executor executor, int milliseconds) + throws SQLException { + this.mc.setNetworkTimeout(executor, milliseconds); + } + + public int getNetworkTimeout() throws SQLException { + return this.mc.getNetworkTimeout(); + } + + public void setServerConfigCacheFactory(String factoryClassname) { + this.mc.setServerConfigCacheFactory(factoryClassname); + } + + public String getServerConfigCacheFactory() { + return this.mc.getServerConfigCacheFactory(); + } + + public void setDisconnectOnExpiredPasswords(boolean disconnectOnExpiredPasswords) { + this.mc.setDisconnectOnExpiredPasswords(disconnectOnExpiredPasswords); + } + + public boolean getDisconnectOnExpiredPasswords() { + return this.mc.getDisconnectOnExpiredPasswords(); + } + + public void setGetProceduresReturnsFunctions(boolean getProcedureReturnsFunctions) { + this.mc.setGetProceduresReturnsFunctions(getProcedureReturnsFunctions); + } + + public boolean getGetProceduresReturnsFunctions() { + return this.mc.getGetProceduresReturnsFunctions(); + } + + public void abortInternal() throws SQLException { + this.mc.abortInternal(); + } + + public Object getConnectionMutex() { + return this.mc.getConnectionMutex(); + } + + public boolean getAllowMasterDownConnections() { + return this.mc.getAllowMasterDownConnections(); + } + + public void setAllowMasterDownConnections(boolean connectIfMasterDown) { + this.mc.setAllowMasterDownConnections(connectIfMasterDown); + } + + public boolean getReplicationEnableJMX() { + return this.mc.getReplicationEnableJMX(); + } + + public void setReplicationEnableJMX(boolean replicationEnableJMX) { + this.mc.setReplicationEnableJMX(replicationEnableJMX); + + } + + public String getConnectionAttributes() throws SQLException { + return this.mc.getConnectionAttributes(); + } + + public void setDetectCustomCollations(boolean detectCustomCollations) { + this.mc.setDetectCustomCollations(detectCustomCollations); + } + + public boolean getDetectCustomCollations() { + return this.mc.getDetectCustomCollations(); + } + + public int getSessionMaxRows() { + return this.mc.getSessionMaxRows(); + } + + public void setSessionMaxRows(int max) throws SQLException { + this.mc.setSessionMaxRows(max); + } + + public String getServerRSAPublicKeyFile() { + return this.mc.getServerRSAPublicKeyFile(); + } + + public void setServerRSAPublicKeyFile(String serverRSAPublicKeyFile) throws SQLException { + this.mc.setServerRSAPublicKeyFile(serverRSAPublicKeyFile); + } + + public boolean getAllowPublicKeyRetrieval() { + return this.mc.getAllowPublicKeyRetrieval(); + } + + public void setAllowPublicKeyRetrieval(boolean allowPublicKeyRetrieval) throws SQLException { + this.mc.setAllowPublicKeyRetrieval(allowPublicKeyRetrieval); + } +} \ No newline at end of file Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4CallableStatementWrapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4ConnectionWrapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4MysqlPooledConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4MysqlXAConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4PreparedStatementWrapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4StatementWrapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/JDBC4SuspendableXAConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlConnectionPoolDataSource.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlConnectionPoolDataSource.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlConnectionPoolDataSource.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlConnectionPoolDataSource.java 30 Jul 2014 08:37:30 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.jdbc2.optional; import java.sql.Connection; @@ -43,6 +42,9 @@ */ public class MysqlConnectionPoolDataSource extends MysqlDataSource implements ConnectionPoolDataSource { + + static final long serialVersionUID = -7767325445592304961L; + // ~ Methods // ---------------------------------------------------------------- @@ -56,7 +58,7 @@ public synchronized PooledConnection getPooledConnection() throws SQLException { Connection connection = getConnection(); - MysqlPooledConnection mysqlPooledConnection = new MysqlPooledConnection( + MysqlPooledConnection mysqlPooledConnection = MysqlPooledConnection.getInstance( (com.mysql.jdbc.Connection)connection); return mysqlPooledConnection; @@ -77,7 +79,7 @@ public synchronized PooledConnection getPooledConnection(String s, String s1) throws SQLException { Connection connection = getConnection(s, s1); - MysqlPooledConnection mysqlPooledConnection = new MysqlPooledConnection( + MysqlPooledConnection mysqlPooledConnection = MysqlPooledConnection.getInstance( (com.mysql.jdbc.Connection)connection); return mysqlPooledConnection; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java 30 Jul 2014 08:37:30 -0000 1.1.2.1 @@ -1,68 +1,67 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.jdbc2.optional; -import com.mysql.jdbc.ConnectionProperties; -import com.mysql.jdbc.NonRegisteringDriver; - import java.io.PrintWriter; import java.io.Serializable; - import java.sql.SQLException; - +import java.util.Iterator; import java.util.Properties; import javax.naming.NamingException; import javax.naming.Reference; import javax.naming.Referenceable; import javax.naming.StringRefAddr; - import javax.sql.DataSource; +import com.mysql.jdbc.ConnectionPropertiesImpl; +import com.mysql.jdbc.NonRegisteringDriver; + /** * A JNDI DataSource for a Mysql JDBC connection * * @author Mark Matthews */ -public class MysqlDataSource extends ConnectionProperties implements - DataSource, Referenceable, Serializable { +public class MysqlDataSource extends ConnectionPropertiesImpl implements + DataSource, Referenceable, Serializable { + + static final long serialVersionUID = -5515846944416881264L; + /** The driver to create connections with */ - protected static com.mysql.jdbc.Driver mysqlDriver = null; + protected final static NonRegisteringDriver mysqlDriver; static { try { - mysqlDriver = (com.mysql.jdbc.Driver) Class.forName( - "com.mysql.jdbc.Driver").newInstance(); + mysqlDriver = new NonRegisteringDriver(); } catch (Exception E) { throw new RuntimeException( "Can not load Driver class com.mysql.jdbc.Driver"); } } /** Log stream */ - protected PrintWriter logWriter = null; + protected transient PrintWriter logWriter = null; /** Database Name */ protected String databaseName = null; @@ -422,6 +421,31 @@ jdbcUrlToUse = this.url; } + // + // URL should take precedence over properties + // + + Properties urlProps = mysqlDriver.parseURL(jdbcUrlToUse, null); + urlProps.remove(NonRegisteringDriver.DBNAME_PROPERTY_KEY); + urlProps.remove(NonRegisteringDriver.HOST_PROPERTY_KEY); + urlProps.remove(NonRegisteringDriver.PORT_PROPERTY_KEY); + + Iterator keys = urlProps.keySet().iterator(); + + while (keys.hasNext()) { + String key = (String)keys.next(); + + props.setProperty(key, urlProps.getProperty(key)); + } + return mysqlDriver.connect(jdbcUrlToUse, props); } +// +// public boolean isWrapperFor(Class iface) throws SQLException { +// throw SQLError.notImplemented(); +// } +// +// public T unwrap(Class iface) throws SQLException { +// throw SQLError.notImplemented(); +// } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSourceFactory.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSourceFactory.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSourceFactory.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSourceFactory.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.jdbc2.optional; import java.util.Hashtable; @@ -72,7 +71,7 @@ * DOCUMENT ME! */ public Object getObjectInstance(Object refObj, Name nm, Context ctx, - Hashtable env) throws Exception { + Hashtable env) throws Exception { Reference ref = (Reference) refObj; String className = ref.getClassName(); @@ -148,4 +147,4 @@ return asString; } -} +} \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlPooledConnection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlPooledConnection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlPooledConnection.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlPooledConnection.java 30 Jul 2014 08:37:30 -0000 1.1.2.1 @@ -1,40 +1,42 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.jdbc2.optional; +import java.lang.reflect.Constructor; import java.sql.Connection; import java.sql.SQLException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; -import java.util.Enumeration; -import java.util.Hashtable; - import javax.sql.ConnectionEvent; import javax.sql.ConnectionEventListener; import javax.sql.PooledConnection; +import com.mysql.jdbc.ExceptionInterceptor; import com.mysql.jdbc.SQLError; +import com.mysql.jdbc.Util; /** * This class is used to wrap and return a physical connection within a logical @@ -47,6 +49,37 @@ */ public class MysqlPooledConnection implements PooledConnection { + private static final Constructor JDBC_4_POOLED_CONNECTION_WRAPPER_CTOR; + + 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 }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_POOLED_CONNECTION_WRAPPER_CTOR = null; + } + } + + protected static MysqlPooledConnection getInstance(com.mysql.jdbc.Connection connection) throws SQLException { + if (!Util.isJdbc4()) { + return new MysqlPooledConnection(connection); + } + + return (MysqlPooledConnection) Util.handleNewInstance( + JDBC_4_POOLED_CONNECTION_WRAPPER_CTOR, new Object[] { + connection}, connection.getExceptionInterceptor()); + } + /** * The flag for an exception being thrown. */ @@ -59,11 +92,13 @@ // ~ Instance/static variables ............................................. - private Hashtable eventListeners; + private Map connectionEventListeners; private Connection logicalHandle; private com.mysql.jdbc.Connection physicalConn; + + private ExceptionInterceptor exceptionInterceptor; // ~ Constructors .......................................................... @@ -76,11 +111,10 @@ public MysqlPooledConnection(com.mysql.jdbc.Connection connection) { this.logicalHandle = null; this.physicalConn = connection; - this.eventListeners = new Hashtable(10); + this.connectionEventListeners = new HashMap(); + this.exceptionInterceptor = this.physicalConn.getExceptionInterceptor(); } - // ~ Methods ............................................................... - /** * Adds ConnectionEventListeners to a hash table to be used for notification * of ConnectionEvents @@ -91,8 +125,8 @@ public synchronized void addConnectionEventListener( ConnectionEventListener connectioneventlistener) { - if (this.eventListeners != null) { - this.eventListeners.put(connectioneventlistener, + if (this.connectionEventListeners != null) { + this.connectionEventListeners.put(connectioneventlistener, connectioneventlistener); } } @@ -107,8 +141,8 @@ public synchronized void removeConnectionEventListener( ConnectionEventListener connectioneventlistener) { - if (this.eventListeners != null) { - this.eventListeners.remove(connectioneventlistener); + if (this.connectionEventListeners != null) { + this.connectionEventListeners.remove(connectioneventlistener); } } @@ -129,8 +163,8 @@ if (this.physicalConn == null) { SQLException sqlException = SQLError.createSQLException( - "Physical Connection doesn't exist"); - callListener(CONNECTION_ERROR_EVENT, sqlException); + "Physical Connection doesn't exist", this.exceptionInterceptor); + callConnectionEventListeners(CONNECTION_ERROR_EVENT, sqlException); throw sqlException; } @@ -142,12 +176,14 @@ } if (resetServerState) { - ((com.mysql.jdbc.Connection) this.physicalConn).resetServerState(); + this.physicalConn.resetServerState(); } - this.logicalHandle = new ConnectionWrapper(this, this.physicalConn, forXa); + this.logicalHandle = ConnectionWrapper.getInstance(this, + this.physicalConn, + forXa); } catch (SQLException sqlException) { - callListener(CONNECTION_ERROR_EVENT, sqlException); + callConnectionEventListeners(CONNECTION_ERROR_EVENT, sqlException); throw sqlException; } @@ -165,9 +201,15 @@ public synchronized void close() throws SQLException { if (this.physicalConn != null) { this.physicalConn.close(); + + this.physicalConn = null; } - - this.physicalConn = null; + + if (this.connectionEventListeners != null) { + this.connectionEventListeners.clear(); + + this.connectionEventListeners = null; + } } /** @@ -182,31 +224,33 @@ * @param sqlException * the exception being thrown */ - protected synchronized void callListener(int eventType, + protected synchronized void callConnectionEventListeners(int eventType, SQLException sqlException) { - if (this.eventListeners == null) { + if (this.connectionEventListeners == null) { return; } - Enumeration enumeration = this.eventListeners.keys(); + Iterator> iterator = this.connectionEventListeners.entrySet().iterator(); + ConnectionEvent connectionevent = new ConnectionEvent(this, sqlException); - while (enumeration.hasMoreElements()) { + while (iterator.hasNext()) { - ConnectionEventListener connectioneventlistener = (ConnectionEventListener) enumeration - .nextElement(); - ConnectionEventListener connectioneventlistener1 = (ConnectionEventListener) this.eventListeners - .get(connectioneventlistener); + ConnectionEventListener connectioneventlistener = iterator.next().getValue(); if (eventType == CONNECTION_CLOSED_EVENT) { - connectioneventlistener1.connectionClosed(connectionevent); + connectioneventlistener.connectionClosed(connectionevent); } else if (eventType == CONNECTION_ERROR_EVENT) { - connectioneventlistener1 + connectioneventlistener .connectionErrorOccurred(connectionevent); } } } + + protected ExceptionInterceptor getExceptionInterceptor() { + return this.exceptionInterceptor; + } } \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAConnection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAConnection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAConnection.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAConnection.java 30 Jul 2014 08:37:30 -0000 1.1.2.1 @@ -1,27 +1,29 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */ + package com.mysql.jdbc.jdbc2.optional; +import java.lang.reflect.Constructor; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; @@ -37,6 +39,9 @@ import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; +import com.mysql.jdbc.ConnectionImpl; +import com.mysql.jdbc.StringUtils; +import com.mysql.jdbc.Util; import com.mysql.jdbc.log.Log; /* @@ -61,31 +66,67 @@ public class MysqlXAConnection extends MysqlPooledConnection implements XAConnection, XAResource { - private com.mysql.jdbc.Connection underlyingConnection; + private static final int MAX_COMMAND_LENGTH = 300; + + private com.mysql.jdbc.ConnectionImpl underlyingConnection; - private final static Map MYSQL_ERROR_CODES_TO_XA_ERROR_CODES; + private final static Map MYSQL_ERROR_CODES_TO_XA_ERROR_CODES; private Log log; protected boolean logXaCommands; static { - HashMap temp = new HashMap(); + HashMap temp = new HashMap(); - temp.put(new Integer(1397), new Integer(XAException.XAER_NOTA)); - temp.put(new Integer(1398), new Integer(XAException.XAER_INVAL)); - temp.put(new Integer(1399), new Integer(XAException.XAER_RMFAIL)); - temp.put(new Integer(1400), new Integer(XAException.XAER_OUTSIDE)); - temp.put(new Integer(1401), new Integer(XAException.XAER_RMERR)); - temp.put(new Integer(1402), new Integer(XAException.XA_RBROLLBACK)); + 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)); MYSQL_ERROR_CODES_TO_XA_ERROR_CODES = Collections.unmodifiableMap(temp); } + + private static final Constructor JDBC_4_XA_CONNECTION_WRAPPER_CTOR; + static { + if (Util.isJdbc4()) { + try { + JDBC_4_XA_CONNECTION_WRAPPER_CTOR = Class.forName( + "com.mysql.jdbc.jdbc2.optional.JDBC4MysqlXAConnection") + .getConstructor( + new Class[] { ConnectionImpl.class, Boolean.TYPE }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_XA_CONNECTION_WRAPPER_CTOR = null; + } + } + + protected static MysqlXAConnection getInstance(ConnectionImpl mysqlConnection, + boolean logXaCommands) throws SQLException { + if (!Util.isJdbc4()) { + return new MysqlXAConnection(mysqlConnection, logXaCommands); + } + + return (MysqlXAConnection) Util.handleNewInstance( + JDBC_4_XA_CONNECTION_WRAPPER_CTOR, new Object[] { + mysqlConnection, + Boolean.valueOf(logXaCommands) }, mysqlConnection.getExceptionInterceptor()); + } + /** * @param connection */ - public MysqlXAConnection(com.mysql.jdbc.Connection connection, boolean logXaCommands) + public MysqlXAConnection(ConnectionImpl connection, boolean logXaCommands) throws SQLException { super(connection); this.underlyingConnection = connection; @@ -120,7 +161,6 @@ * XAER_RMERR and XAER_RMFAIL. */ public int getTransactionTimeout() throws XAException { - // TODO Auto-generated method stub return 0; } @@ -146,7 +186,6 @@ * XAER_RMERR, XAER_RMFAIL, or XAER_INVAL. */ public boolean setTransactionTimeout(int arg0) throws XAException { - // TODO Auto-generated method stub return false; } @@ -261,7 +300,7 @@ ResultSet rs = null; Statement stmt = null; - List recoveredXidList = new ArrayList(); + List recoveredXidList = new ArrayList(); try { // TODO: Cache this for lifetime of XAConnection @@ -343,9 +382,9 @@ * XAER_PROTO. */ public int prepare(Xid xid) throws XAException { - StringBuffer commandBuf = new StringBuffer(); + StringBuilder commandBuf = new StringBuilder(MAX_COMMAND_LENGTH); commandBuf.append("XA PREPARE "); - commandBuf.append(xidToString(xid)); + appendXid(commandBuf, xid); dispatchCommand(commandBuf.toString()); @@ -364,7 +403,7 @@ * XAER_PROTO. */ public void forget(Xid xid) throws XAException { - // TODO Auto-generated method stub + // mysql doesn't support this } /** @@ -385,9 +424,9 @@ * has released all held resources. */ public void rollback(Xid xid) throws XAException { - StringBuffer commandBuf = new StringBuffer(); + StringBuilder commandBuf = new StringBuilder(MAX_COMMAND_LENGTH); commandBuf.append("XA ROLLBACK "); - commandBuf.append(xidToString(xid)); + appendXid(commandBuf, xid); try { dispatchCommand(commandBuf.toString()); @@ -424,20 +463,20 @@ * or XA_RB*. */ public void end(Xid xid, int flags) throws XAException { - StringBuffer commandBuf = new StringBuffer(); + StringBuilder commandBuf = new StringBuilder(MAX_COMMAND_LENGTH); commandBuf.append("XA END "); - commandBuf.append(xidToString(xid)); + appendXid(commandBuf, xid); switch (flags) { - case TMSUCCESS: - break; // no-op - case TMSUSPEND: - commandBuf.append(" SUSPEND"); - break; - case TMFAIL: - break; // no-op - default: - throw new XAException(XAException.XAER_INVAL); + case TMSUCCESS: + break; // no-op + case TMSUSPEND: + commandBuf.append(" SUSPEND"); + break; + case TMFAIL: + break; // no-op + default: + throw new XAException(XAException.XAER_INVAL); } dispatchCommand(commandBuf.toString()); @@ -467,26 +506,26 @@ * XAER_INVAL, or XAER_PROTO. */ public void start(Xid xid, int flags) throws XAException { - StringBuffer commandBuf = new StringBuffer(); + StringBuilder commandBuf = new StringBuilder(MAX_COMMAND_LENGTH); commandBuf.append("XA START "); - commandBuf.append(xidToString(xid)); + appendXid(commandBuf, xid); switch (flags) { - case TMJOIN: - commandBuf.append(" JOIN"); - break; - case TMRESUME: - commandBuf.append(" RESUME"); - break; - case TMNOFLAGS: - // no-op - break; - default: - throw new XAException(XAException.XAER_INVAL); + case TMJOIN: + commandBuf.append(" JOIN"); + break; + case TMRESUME: + commandBuf.append(" RESUME"); + break; + case TMNOFLAGS: + // no-op + break; + default: + throw new XAException(XAException.XAER_INVAL); } dispatchCommand(commandBuf.toString()); - + this.underlyingConnection.setInGlobalTx(true); } @@ -512,9 +551,9 @@ */ public void commit(Xid xid, boolean onePhase) throws XAException { - StringBuffer commandBuf = new StringBuffer(); + StringBuilder commandBuf = new StringBuilder(MAX_COMMAND_LENGTH); commandBuf.append("XA COMMIT "); - commandBuf.append(xidToString(xid)); + appendXid(commandBuf, xid); if (onePhase) { commandBuf.append(" ONE PHASE"); @@ -537,7 +576,8 @@ // TODO: Cache this for lifetime of XAConnection stmt = this.underlyingConnection.createStatement(); - + + stmt.execute(command); ResultSet rs = stmt.getResultSet(); @@ -557,8 +597,8 @@ protected static XAException mapXAExceptionFromSQLException(SQLException sqlEx) { - Integer xaCode = (Integer) MYSQL_ERROR_CODES_TO_XA_ERROR_CODES - .get(new Integer(sqlEx.getErrorCode())); + Integer xaCode = MYSQL_ERROR_CODES_TO_XA_ERROR_CODES + .get(Integer.valueOf(sqlEx.getErrorCode())); if (xaCode != null) { return new MysqlXAException(xaCode.intValue(), sqlEx.getMessage(), null); @@ -568,62 +608,21 @@ return new MysqlXAException(sqlEx.getMessage(), null); } - private static String xidToString(Xid xid) { + private static void appendXid(StringBuilder builder, Xid xid) { byte[] gtrid = xid.getGlobalTransactionId(); - byte[] btrid = xid.getBranchQualifier(); - int lengthAsString = 6; // for (0x and ,) * 2 - if (gtrid != null) { - lengthAsString += (2 * gtrid.length); + StringUtils.appendAsHex(builder, gtrid); } + builder.append(','); if (btrid != null) { - lengthAsString += (2 * btrid.length); + StringUtils.appendAsHex(builder, btrid); } - String formatIdInHex = Integer.toHexString(xid.getFormatId()); - - lengthAsString += formatIdInHex.length(); - lengthAsString += 3; // for the '.' after formatId - - StringBuffer asString = new StringBuffer(lengthAsString); - - asString.append("0x"); - - if (gtrid != null) { - for (int i = 0; i < gtrid.length; i++) { - String asHex = Integer.toHexString(gtrid[i] & 0xff); - - if (asHex.length() == 1) { - asString.append("0"); - } - - asString.append(asHex); - } - } - - asString.append(","); - - if (btrid != null) { - asString.append("0x"); - - for (int i = 0; i < btrid.length; i++) { - String asHex = Integer.toHexString(btrid[i] & 0xff); - - if (asHex.length() == 1) { - asString.append("0"); - } - - asString.append(asHex); - } - } - - asString.append(",0x"); - asString.append(formatIdInHex); - - return asString.toString(); + builder.append(','); + StringUtils.appendAsHex(builder, xid.getFormatId()); } /* Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXADataSource.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXADataSource.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXADataSource.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXADataSource.java 30 Jul 2014 08:37:30 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.jdbc2.optional; import java.sql.Connection; @@ -39,6 +38,8 @@ public class MysqlXADataSource extends MysqlDataSource implements javax.sql.XADataSource { + static final long serialVersionUID = 7911390333152247455L; + /** * @see javax.sql.XADataSource#getXAConnection() */ @@ -52,10 +53,10 @@ /** * @see javax.sql.XADataSource#getXAConnection(String, String) */ - public XAConnection getXAConnection(String user, String password) + public XAConnection getXAConnection(String u, String p) throws SQLException { - Connection conn = getConnection(user, password); + Connection conn = getConnection(u, p); return wrapConnection(conn); } @@ -67,9 +68,9 @@ private XAConnection wrapConnection(Connection conn) throws SQLException { if (getPinGlobalTxToPhysicalConnection() || ((com.mysql.jdbc.Connection)conn).getPinGlobalTxToPhysicalConnection()) { - return new SuspendableXAConnection((com.mysql.jdbc.Connection) conn); + return SuspendableXAConnection.getInstance((com.mysql.jdbc.ConnectionImpl) conn); } - return new MysqlXAConnection((com.mysql.jdbc.Connection) conn, getLogXaCommands()); + return MysqlXAConnection.getInstance((com.mysql.jdbc.ConnectionImpl) conn, getLogXaCommands()); } } \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAException.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXAException.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,23 +1,23 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */ @@ -33,7 +33,7 @@ private static final long serialVersionUID = -9075817535836563004L; private String message; - private String xidAsString; + protected String xidAsString; public MysqlXAException(int errorCode, String message, String xidAsString) { super(errorCode); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXid.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXid.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXid.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlXid.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,25 +1,25 @@ /* - Copyright (C) 2005 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 -*/ + */ package com.mysql.jdbc.jdbc2.optional; @@ -80,12 +80,10 @@ } return true; - } else { - return false; } - } else { - return false; } + + return false; } public byte[] getBranchQualifier() { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/PreparedStatementWrapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/PreparedStatementWrapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/PreparedStatementWrapper.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/PreparedStatementWrapper.java 30 Jul 2014 08:37:30 -0000 1.1.2.1 @@ -1,38 +1,33 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.jdbc2.optional; -import com.mysql.jdbc.SQLError; - import java.io.InputStream; import java.io.Reader; - +import java.lang.reflect.Constructor; import java.math.BigDecimal; - import java.net.URL; - import java.sql.Array; import java.sql.Blob; import java.sql.Clob; @@ -45,9 +40,11 @@ import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; - import java.util.Calendar; +import com.mysql.jdbc.SQLError; +import com.mysql.jdbc.Util; + /** * Wraps prepared statements so that errors can be reported correctly to * ConnectionEventListeners. @@ -59,6 +56,42 @@ */ public class PreparedStatementWrapper extends StatementWrapper implements PreparedStatement { + private static final Constructor JDBC_4_PREPARED_STATEMENT_WRAPPER_CTOR; + + static { + if (Util.isJdbc4()) { + try { + JDBC_4_PREPARED_STATEMENT_WRAPPER_CTOR = Class.forName( + "com.mysql.jdbc.jdbc2.optional.JDBC4PreparedStatementWrapper").getConstructor( + new Class[] { ConnectionWrapper.class, + MysqlPooledConnection.class, + PreparedStatement.class }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_PREPARED_STATEMENT_WRAPPER_CTOR = null; + } + } + + protected static PreparedStatementWrapper getInstance(ConnectionWrapper c, + MysqlPooledConnection conn, + PreparedStatement toWrap) throws SQLException { + if (!Util.isJdbc4()) { + return new PreparedStatementWrapper(c, + conn, toWrap); + } + + return (PreparedStatementWrapper) Util.handleNewInstance( + JDBC_4_PREPARED_STATEMENT_WRAPPER_CTOR, + new Object[] {c, + conn, toWrap }, conn.getExceptionInterceptor()); + } + PreparedStatementWrapper(ConnectionWrapper c, MysqlPooledConnection conn, PreparedStatement toWrap) { super(c, conn, toWrap); @@ -77,7 +110,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -99,7 +132,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -120,7 +153,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -142,7 +175,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -162,7 +195,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -182,7 +215,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -202,7 +235,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -222,7 +255,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -244,7 +277,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -264,7 +297,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -284,7 +317,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -306,7 +339,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -326,7 +359,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -346,7 +379,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -366,7 +399,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -386,7 +419,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -406,7 +439,7 @@ throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -427,7 +460,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -448,7 +481,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -468,7 +501,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -489,7 +522,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -511,7 +544,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -532,7 +565,7 @@ throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -553,7 +586,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -573,7 +606,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -593,7 +626,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -613,7 +646,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -635,7 +668,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -656,7 +689,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -678,7 +711,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -698,7 +731,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -731,7 +764,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -750,7 +783,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -769,7 +802,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -789,13 +822,13 @@ throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } return false; // we actually never get here, but the compiler can't - // figure + // figure // that out } @@ -811,20 +844,20 @@ ResultSet rs = ((PreparedStatement) this.wrappedStmt) .executeQuery(); - ((com.mysql.jdbc.ResultSet) rs).setWrapperStatement(this); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).setWrapperStatement(this); return rs; } throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + 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 + // figure // that out } @@ -842,7 +875,7 @@ throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -851,4 +884,358 @@ // that out } + + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append(super.toString()); + + if (this.wrappedStmt != null) { + buf.append(": "); //$NON-NLS-1$ + try { + buf.append(((com.mysql.jdbc.PreparedStatement) this.wrappedStmt).asSql()); + } catch(SQLException sqlEx) { + buf.append("EXCEPTION: " + sqlEx.toString()); + } + } + + return buf.toString(); + } +// +// public void setAsciiStream(int parameterIndex, InputStream x) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setAsciiStream( +// parameterIndex, x); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setAsciiStream(int parameterIndex, InputStream x, long length) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setAsciiStream( +// parameterIndex, x, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBinaryStream(int parameterIndex, InputStream x) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setBinaryStream( +// parameterIndex, x); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBinaryStream(int parameterIndex, InputStream x, long length) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setBinaryStream( +// parameterIndex, x, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBlob(int parameterIndex, InputStream inputStream) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setBlob(parameterIndex, +// inputStream); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setBlob(int parameterIndex, InputStream inputStream, long length) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setBlob(parameterIndex, +// inputStream, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setCharacterStream(int parameterIndex, Reader reader) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setCharacterStream( +// parameterIndex, reader); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setCharacterStream(int parameterIndex, Reader reader, +// long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setCharacterStream( +// parameterIndex, reader, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setClob(int parameterIndex, Reader reader) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setClob(parameterIndex, +// reader); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setClob(int parameterIndex, Reader reader, long length) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setClob(parameterIndex, +// reader, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNCharacterStream(int parameterIndex, Reader value) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setNCharacterStream( +// parameterIndex, value); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNCharacterStream(int parameterIndex, Reader value, +// long length) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setNCharacterStream( +// parameterIndex, value, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNClob(int parameterIndex, NClob value) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setNClob(parameterIndex, +// value); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNClob(int parameterIndex, Reader reader) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setNClob(parameterIndex, +// reader); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNClob(int parameterIndex, Reader reader, long length) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setNClob(parameterIndex, +// reader, length); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setNString(int parameterIndex, String value) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setNString( +// parameterIndex, value); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setRowId(int parameterIndex, RowId x) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setRowId(parameterIndex, +// x); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public void setSQLXML(int parameterIndex, SQLXML xmlObject) +// throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setSQLXML( +// parameterIndex, xmlObject); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public boolean isClosed() throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((PreparedStatement) this.wrappedStmt).isClosed(); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return true; +// } +// +// public boolean isPoolable() throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// return ((PreparedStatement) this.wrappedStmt).isPoolable(); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// +// return false; +// } +// +// public void setPoolable(boolean poolable) throws SQLException { +// try { +// if (this.wrappedStmt != null) { +// ((PreparedStatement) this.wrappedStmt).setPoolable(poolable); +// } else { +// throw SQLError.createSQLException( +// "No operations allowed after statement closed", +// SQLError.SQL_STATE_GENERAL_ERROR); +// } +// } catch (SQLException sqlEx) { +// checkAndFireConnectionError(sqlEx); +// } +// } +// +// public boolean isWrapperFor(Class arg0) throws SQLException { +// throw SQLError.notImplemented(); +// } +// +// public Object unwrap(Class arg0) throws SQLException { +// throw SQLError.notImplemented(); +// } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/StatementWrapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/StatementWrapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/StatementWrapper.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/StatementWrapper.java 30 Jul 2014 08:37:30 -0000 1.1.2.1 @@ -1,37 +1,38 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.jdbc2.optional; -import com.mysql.jdbc.SQLError; - +import java.lang.reflect.Constructor; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; +import com.mysql.jdbc.SQLError; +import com.mysql.jdbc.Util; + /** * Wraps statements so that errors can be reported correctly to * ConnectionEventListeners. @@ -42,13 +43,49 @@ * Exp $ */ public class StatementWrapper extends WrapperBase implements Statement { + private static final Constructor JDBC_4_STATEMENT_WRAPPER_CTOR; + + 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 }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_STATEMENT_WRAPPER_CTOR = null; + } + } + + protected static StatementWrapper getInstance(ConnectionWrapper c, + MysqlPooledConnection conn, + Statement toWrap) throws SQLException { + if (!Util.isJdbc4()) { + return new StatementWrapper(c, + conn, toWrap); + } + + return (StatementWrapper) Util.handleNewInstance( + JDBC_4_STATEMENT_WRAPPER_CTOR, + new Object[] {c, + conn, toWrap }, conn.getExceptionInterceptor()); + } + protected Statement wrappedStmt; protected ConnectionWrapper wrappedConn; - protected StatementWrapper(ConnectionWrapper c, MysqlPooledConnection conn, + public StatementWrapper(ConnectionWrapper c, MysqlPooledConnection conn, Statement toWrap) { - this.pooledConnection = conn; + super(conn); this.wrappedStmt = toWrap; this.wrappedConn = c; } @@ -65,7 +102,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -87,7 +124,7 @@ this.wrappedStmt.setCursorName(name); } else { throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -105,7 +142,7 @@ this.wrappedStmt.setEscapeProcessing(enable); } else { throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -123,7 +160,7 @@ this.wrappedStmt.setFetchDirection(direction); } else { throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -142,7 +179,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -164,7 +201,7 @@ this.wrappedStmt.setFetchSize(rows); } else { throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -183,7 +220,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -205,7 +242,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -227,7 +264,7 @@ this.wrappedStmt.setMaxFieldSize(max); } else { throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -246,7 +283,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -267,7 +304,7 @@ this.wrappedStmt.setMaxRows(max); } else { throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -286,7 +323,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -308,7 +345,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -328,7 +365,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -347,7 +384,7 @@ this.wrappedStmt.setQueryTimeout(seconds); } else { throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); @@ -366,7 +403,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -383,14 +420,15 @@ try { if (this.wrappedStmt != null) { ResultSet rs = this.wrappedStmt.getResultSet(); - - ((com.mysql.jdbc.ResultSet) rs).setWrapperStatement(this); - + + if (rs != null) { + ((com.mysql.jdbc.ResultSetInternalMethods) rs).setWrapperStatement(this); + } return rs; } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -410,7 +448,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -430,7 +468,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -450,7 +488,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -470,7 +508,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -490,7 +528,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -589,7 +627,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -612,7 +650,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -636,7 +674,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -659,7 +697,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -682,7 +720,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -703,13 +741,13 @@ if (this.wrappedStmt != null) { ResultSet rs = this.wrappedStmt.executeQuery(sql); - ((com.mysql.jdbc.ResultSet) rs).setWrapperStatement(this); + ((com.mysql.jdbc.ResultSetInternalMethods) rs).setWrapperStatement(this); return rs; } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -733,7 +771,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -756,7 +794,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -780,7 +818,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -802,7 +840,7 @@ } throw SQLError.createSQLException("Statement already closed", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); } @@ -820,7 +858,7 @@ } else { throw SQLError.createSQLException( "No operations allowed after statement closed", - SQLError.SQL_STATE_GENERAL_ERROR); + SQLError.SQL_STATE_GENERAL_ERROR, this.exceptionInterceptor); } } catch (SQLException sqlEx) { checkAndFireConnectionError(sqlEx); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/SuspendableXAConnection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/SuspendableXAConnection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/SuspendableXAConnection.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/SuspendableXAConnection.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,6 +1,30 @@ +/* + Copyright (c) 2002, 2014, 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 FLOSS 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.jdbc2.optional; +import java.lang.reflect.Constructor; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; @@ -10,38 +34,71 @@ import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; -import com.mysql.jdbc.Connection; +import com.mysql.jdbc.ConnectionImpl; +import com.mysql.jdbc.Util; public class SuspendableXAConnection extends MysqlPooledConnection implements XAConnection, XAResource { - public SuspendableXAConnection(Connection connection) { + private static final Constructor JDBC_4_XA_CONNECTION_WRAPPER_CTOR; + + static { + if (Util.isJdbc4()) { + try { + JDBC_4_XA_CONNECTION_WRAPPER_CTOR = Class.forName( + "com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection") + .getConstructor( + new Class[] { ConnectionImpl.class }); + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + JDBC_4_XA_CONNECTION_WRAPPER_CTOR = null; + } + } + + protected static SuspendableXAConnection getInstance(ConnectionImpl mysqlConnection) throws SQLException { + if (!Util.isJdbc4()) { + return new SuspendableXAConnection(mysqlConnection); + } + + return (SuspendableXAConnection) Util.handleNewInstance( + JDBC_4_XA_CONNECTION_WRAPPER_CTOR, new Object[] { + mysqlConnection}, mysqlConnection.getExceptionInterceptor()); + } + + public SuspendableXAConnection(ConnectionImpl connection) { super(connection); this.underlyingConnection = connection; } - private static final Map XIDS_TO_PHYSICAL_CONNECTIONS = - new HashMap(); + private static final Map XIDS_TO_PHYSICAL_CONNECTIONS = + new HashMap(); private Xid currentXid; private XAConnection currentXAConnection; private XAResource currentXAResource; - private Connection underlyingConnection; + private ConnectionImpl underlyingConnection; - private static synchronized XAConnection findConnectionForXid(Connection connectionToWrap, Xid xid) + private static synchronized XAConnection findConnectionForXid(ConnectionImpl connectionToWrap, Xid xid) throws SQLException { // TODO: check for same GTRID, but different BQUALs...MySQL doesn't allow this yet // Note, we don't need to check for XIDs here, because MySQL itself will complain // with a XAER_NOTA if need be. - XAConnection conn = (XAConnection)XIDS_TO_PHYSICAL_CONNECTIONS.get(xid); + XAConnection conn = XIDS_TO_PHYSICAL_CONNECTIONS.get(xid); if (conn == null) { - conn = new MysqlXAConnection(connectionToWrap, + conn = new MysqlXAConnection(connectionToWrap, connectionToWrap.getLogXaCommands()); + XIDS_TO_PHYSICAL_CONNECTIONS.put(xid, conn); } return conn; @@ -91,7 +148,6 @@ } public int getTransactionTimeout() throws XAException { - // TODO Auto-generated method stub return 0; } @@ -115,7 +171,6 @@ } public boolean setTransactionTimeout(int arg0) throws XAException { - // TODO Auto-generated method stub return false; } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/WrapperBase.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/WrapperBase.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/WrapperBase.java 17 Aug 2012 14:57:11 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/WrapperBase.java 30 Jul 2014 08:37:30 -0000 1.1.2.1 @@ -1,31 +1,36 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.jdbc2.optional; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; import java.sql.SQLException; +import java.util.Map; +import com.mysql.jdbc.ExceptionInterceptor; import com.mysql.jdbc.SQLError; /** @@ -51,11 +56,77 @@ if (this.pooledConnection != null) { if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE.equals(sqlEx .getSQLState())) { - this.pooledConnection.callListener( + this.pooledConnection.callConnectionEventListeners( MysqlPooledConnection.CONNECTION_ERROR_EVENT, sqlEx); } } throw sqlEx; } + + protected Map unwrappedInterfaces = null; + protected ExceptionInterceptor exceptionInterceptor; + + protected WrapperBase(MysqlPooledConnection pooledConnection) { + this.pooledConnection = pooledConnection; + this.exceptionInterceptor = this.pooledConnection.getExceptionInterceptor(); + } + + protected class ConnectionErrorFiringInvocationHandler implements InvocationHandler { + Object invokeOn = null; + + public ConnectionErrorFiringInvocationHandler(Object toInvokeOn) { + invokeOn = toInvokeOn; + } + + public Object invoke(Object proxy, Method method, + Object[] args) throws Throwable { + Object result = null; + + try { + result = method.invoke(invokeOn, args); + + if (result != null) { + result = proxyIfInterfaceIsJdbc(result, + result.getClass()); + } + } catch (InvocationTargetException e) { + if (e.getTargetException() instanceof SQLException) { + checkAndFireConnectionError((SQLException) e + .getTargetException()); + } else { + throw e; + } + } + + return result; + } + + /** + * Recursively checks for interfaces on the given object to determine + * if it implements a java.sql interface, and if so, proxies the + * instance so that we can catch and fire SQL errors. + * @param toProxy + * @param clazz + * @return + */ + private Object proxyIfInterfaceIsJdbc(Object toProxy, Class clazz) { + Class[] interfaces = clazz.getInterfaces(); + + for (Class iclass : interfaces) { + String packageName = iclass.getPackage().getName(); + + if ("java.sql".equals(packageName) || + "javax.sql".equals(packageName)) { + return Proxy.newProxyInstance(toProxy.getClass() + .getClassLoader(), interfaces, + new ConnectionErrorFiringInvocationHandler(toProxy)); + } + + return proxyIfInterfaceIsJdbc(toProxy, iclass); + } + + return toProxy; + } + } } \ No newline at end of file Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jmx/LoadBalanceConnectionGroupManager.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jmx/LoadBalanceConnectionGroupManagerMBean.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jmx/ReplicationGroupManager.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/jmx/ReplicationGroupManagerMBean.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/Jdk14Logger.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/log/Jdk14Logger.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/Jdk14Logger.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/Jdk14Logger.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,34 +1,33 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.log; -import com.mysql.jdbc.profiler.ProfilerEvent; - import java.util.logging.Level; import java.util.logging.Logger; +import com.mysql.jdbc.profiler.ProfilerEvent; + /** * Logging functionality for JDK1.4 * @@ -263,8 +262,8 @@ String messageAsString = null; String callerMethodName = "N/A"; String callerClassName = "N/A"; - int lineNumber = 0; - String fileName = "N/A"; + //int lineNumber = 0; + //String fileName = "N/A"; if (msg instanceof ProfilerEvent) { messageAsString = LogUtils.expandProfilerEventIfNecessary(msg) @@ -279,8 +278,8 @@ if (frameIdx != 0) { callerClassName = locations[frameIdx].getClassName(); callerMethodName = locations[frameIdx].getMethodName(); - lineNumber = locations[frameIdx].getLineNumber(); - fileName = locations[frameIdx].getFileName(); + //lineNumber = locations[frameIdx].getLineNumber(); + //fileName = locations[frameIdx].getFileName(); } messageAsString = String.valueOf(msg); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/Log.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/log/Log.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/Log.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/Log.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.log; /** Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogFactory.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogFactory.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogFactory.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogFactory.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,33 +1,33 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.log; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.sql.SQLException; +import com.mysql.jdbc.ExceptionInterceptor; import com.mysql.jdbc.SQLError; /** @@ -51,55 +51,81 @@ * @throws SQLException * if unable to create a logger instance */ - public static Log getLogger(String className, String instanceName) + public static Log getLogger(String className, String instanceName, ExceptionInterceptor exceptionInterceptor) throws SQLException { if (className == null) { throw SQLError.createSQLException("Logger class can not be NULL", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } if (instanceName == null) { - throw SQLError.createSQLException("Logger instance name can not be NULL", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + throw SQLError.createSQLException( + "Logger instance name can not be NULL", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); } try { - Class loggerClass = null; - + Class loggerClass = null; + try { loggerClass = Class.forName(className); } catch (ClassNotFoundException nfe) { - loggerClass = Class.forName(Log.class.getPackage().getName() + "." + className); + loggerClass = Class.forName(Log.class.getPackage().getName() + + "." + className); } - - Constructor constructor = loggerClass + + Constructor constructor = loggerClass .getConstructor(new Class[] { String.class }); return (Log) constructor.newInstance(new Object[] { instanceName }); } catch (ClassNotFoundException cnfe) { - throw SQLError.createSQLException("Unable to load class for logger '" - + className + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLException sqlEx = SQLError.createSQLException( + "Unable to load class for logger '" + className + "'", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + sqlEx.initCause(cnfe); + + throw sqlEx; } catch (NoSuchMethodException nsme) { - throw SQLError.createSQLException( - "Logger class does not have a single-arg constructor that takes an instance name", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLException sqlEx = SQLError + .createSQLException( + "Logger class does not have a single-arg constructor that takes an instance name", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + sqlEx.initCause(nsme); + + throw sqlEx; } catch (InstantiationException inse) { - throw SQLError.createSQLException("Unable to instantiate logger class '" - + className + "', exception in constructor?", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLException sqlEx = SQLError.createSQLException( + "Unable to instantiate logger class '" + className + + "', exception in constructor?", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + sqlEx.initCause(inse); + + throw sqlEx; } catch (InvocationTargetException ite) { - throw SQLError.createSQLException("Unable to instantiate logger class '" - + className + "', exception in constructor?", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLException sqlEx = SQLError.createSQLException( + "Unable to instantiate logger class '" + className + + "', exception in constructor?", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + sqlEx.initCause(ite); + + throw sqlEx; } catch (IllegalAccessException iae) { - throw SQLError.createSQLException("Unable to instantiate logger class '" - + className + "', constructor not public", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLException sqlEx = SQLError.createSQLException( + "Unable to instantiate logger class '" + className + + "', constructor not public", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + sqlEx.initCause(iae); + + throw sqlEx; } catch (ClassCastException cce) { - throw SQLError.createSQLException("Logger class '" + className - + "' does not implement the '" + Log.class.getName() - + "' interface", SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + SQLException sqlEx = SQLError.createSQLException("Logger class '" + + className + "' does not implement the '" + + Log.class.getName() + "' interface", + SQLError.SQL_STATE_ILLEGAL_ARGUMENT, exceptionInterceptor); + sqlEx.initCause(cce); + + throw sqlEx; } } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogUtils.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogUtils.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogUtils.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/LogUtils.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,23 +1,24 @@ /* - Copyright (C) 2005-2007 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + */ package com.mysql.jdbc.log; @@ -42,16 +43,14 @@ ProfilerEvent evt = (ProfilerEvent) possibleProfilerEvent; - Throwable locationException = evt.getEventCreationPoint(); + String locationInformation = evt.getEventCreationPointAsString(); - if (locationException == null) { - locationException = new Throwable(); + if (locationInformation == null) { + locationInformation = Util.stackTraceToString(new Throwable()); } msgBuf.append("Profiler Event: ["); - boolean appendLocationInfo = false; - switch (evt.getEventType()) { case ProfilerEvent.TYPE_EXECUTE: msgBuf.append("EXECUTE"); @@ -80,22 +79,20 @@ case ProfilerEvent.TYPE_WARN: msgBuf.append("WARN"); - appendLocationInfo = true; - + break; case ProfilerEvent.TYPE_SLOW_QUERY: msgBuf.append("SLOW QUERY"); - appendLocationInfo = false; - + break; default: msgBuf.append("UNKNOWN"); } msgBuf.append("] "); - msgBuf.append(findCallingClassAndMethod(locationException)); + msgBuf.append(locationInformation); msgBuf.append(" duration: "); msgBuf.append(evt.getEventDuration()); msgBuf.append(" "); @@ -114,19 +111,12 @@ msgBuf.append(evtMessage); } - if (appendLocationInfo) { - msgBuf - .append("\n\nFull stack trace of location where event occurred:\n\n"); - msgBuf.append(Util.stackTraceToString(locationException)); - msgBuf.append("\n"); - } - return msgBuf; } return possibleProfilerEvent; } - + public static String findCallingClassAndMethod(Throwable t) { String stackTraceAsString = Util.stackTraceToString(t); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/NullLogger.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/log/NullLogger.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/NullLogger.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/NullLogger.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.log; /** Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/log/Slf4JLogger.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/StandardLogger.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/log/StandardLogger.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/StandardLogger.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/log/StandardLogger.java 30 Jul 2014 08:37:31 -0000 1.1.2.1 @@ -1,34 +1,33 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.log; +import java.util.Date; + import com.mysql.jdbc.Util; import com.mysql.jdbc.profiler.ProfilerEvent; -import java.util.Date; - /** * Provides logging facilities for those platforms that don't have built-in * facilities. Simply logs messages to STDERR. @@ -64,6 +63,11 @@ this(name, false); } + /** + * + * @param name + * @param logLocationInfo + */ public StandardLogger(String name, boolean logLocationInfo) { this.logLocationInfo = logLocationInfo; } @@ -248,7 +252,7 @@ logInternal(WARN, message, exception); } - private void logInternal(int level, Object msg, Throwable exception) { + protected void logInternal(int level, Object msg, Throwable exception) { StringBuffer msgBuf = new StringBuffer(); msgBuf.append(new Date().toString()); msgBuf.append(" "); Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/profiler/LoggingProfilerEventHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/profiler/ProfilerEvent.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/profiler/ProfilerEvent.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/profiler/ProfilerEvent.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/profiler/ProfilerEvent.java 30 Jul 2014 08:37:29 -0000 1.1.2.1 @@ -1,31 +1,31 @@ /* - Copyright (C) 2002-2007 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */ package com.mysql.jdbc.profiler; import java.util.Date; -import com.mysql.jdbc.Util; +import com.mysql.jdbc.StringUtils; /** * @author mmatthew @@ -131,11 +131,6 @@ protected int eventCreationPointIndex; /** - * Where was the event created (as a Throwable)? - */ - protected Throwable eventCreationPoint; - - /** * Where was the event created (as a string description of the * eventCreationPoint)? */ @@ -175,7 +170,7 @@ public ProfilerEvent(byte eventType, String hostName, String catalog, long connectionId, int statementId, int resultSetId, long eventCreationTime, long eventDuration, String durationUnits, - String eventCreationPointDesc, Throwable eventCreationPoint, + String eventCreationPointDesc, String eventCreationPoint, String message) { this.eventType = eventType; this.connectionId = connectionId; @@ -184,7 +179,6 @@ this.eventCreationTime = eventCreationTime; this.eventDuration = eventDuration; this.durationUnits = durationUnits; - this.eventCreationPoint = eventCreationPoint; this.eventCreationPointDesc = eventCreationPointDesc; this.message = message; } @@ -195,11 +189,6 @@ * @return a description of when this event was created. */ public String getEventCreationPointAsString() { - if (this.eventCreationPointDesc == null) { - this.eventCreationPointDesc = Util - .stackTraceToString(this.eventCreationPoint); - } - return this.eventCreationPointDesc; } @@ -298,7 +287,7 @@ pos += eventDurationUnits.length; } - int eventCreationPointIndex = readInt(buf, pos); + readInt(buf, pos); pos += 4; byte[] eventCreationAsBytes = readBytes(buf, pos); pos += 4; @@ -316,9 +305,9 @@ return new ProfilerEvent(eventType, "", "", connectionId, statementId, resultSetId, eventCreationTime, eventDuration, - new String(eventDurationUnits, "ISO8859_1"), - new String(eventCreationAsBytes, "ISO8859_1"), null, - new String(message, "ISO8859_1")); + StringUtils.toString(eventDurationUnits, "ISO8859_1"), + StringUtils.toString(eventCreationAsBytes, "ISO8859_1"), null, + StringUtils.toString(message, "ISO8859_1")); } /** @@ -337,29 +326,30 @@ getEventCreationPointAsString(); if (this.eventCreationPointDesc != null) { - eventCreationAsBytes = this.eventCreationPointDesc - .getBytes("ISO8859_1"); + eventCreationAsBytes = StringUtils.getBytes( + this.eventCreationPointDesc, "ISO8859_1"); len += (4 + eventCreationAsBytes.length); } else { len += 4; } byte[] messageAsBytes = null; - if (messageAsBytes != null) { - messageAsBytes = this.message.getBytes("ISO8859_1"); + if (this.message != null) { + messageAsBytes = StringUtils.getBytes(this.message, "ISO8859_1"); len += (4 + messageAsBytes.length); } else { len += 4; } byte[] durationUnitsAsBytes = null; - if (durationUnits != null) { - durationUnitsAsBytes = this.durationUnits.getBytes("ISO8859_1"); + if (this.durationUnits != null) { + durationUnitsAsBytes = StringUtils.getBytes(this.durationUnits, "ISO8859_1"); len += (4 + durationUnitsAsBytes.length); } else { len += 4; + durationUnitsAsBytes = StringUtils.getBytes("", "ISO8859_1"); } byte[] buf = new byte[len]; @@ -428,7 +418,7 @@ } private static long readLong(byte[] buf, int pos) { - return (long) (buf[pos++] & 0xff) | ((long) (buf[pos++] & 0xff) << 8) + return (buf[pos++] & 0xff) | ((long) (buf[pos++] & 0xff) << 8) | ((long) (buf[pos++] & 0xff) << 16) | ((long) (buf[pos++] & 0xff) << 24) | ((long) (buf[pos++] & 0xff) << 32) @@ -467,16 +457,6 @@ } /** - * Returns the point (as a Throwable stacktrace) where this event was - * created. - * - * @return the point where this event was created - */ - public Throwable getEventCreationPoint() { - return this.eventCreationPoint; - } - - /** * Returns the time (in System.currentTimeMillis() form) when this event was * created * @@ -537,4 +517,4 @@ public String getMessage() { return this.message; } -} +} \ No newline at end of file Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/profiler/ProfilerEventHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/mysql-connector/com/mysql/jdbc/util/Base64Decoder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/BaseBugReport.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/util/BaseBugReport.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/BaseBugReport.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/BaseBugReport.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.util; import java.sql.Connection; @@ -34,7 +33,8 @@ * Base class to help file bug reports for Connector/J. * *

    - * MySQL AB + * MySQL AB, 2008 Sun Microsystems, 2009 Oracle Corporation + *

      * really *
    Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ErrorMappingsDocGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ErrorMappingsDocGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ErrorMappingsDocGenerator.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ErrorMappingsDocGenerator.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.util; import com.mysql.jdbc.SQLError; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/LRUCache.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/util/LRUCache.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/LRUCache.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/LRUCache.java 30 Jul 2014 08:37:23 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.util; import java.util.LinkedHashMap; @@ -31,12 +30,12 @@ * @author Mark Matthews * @version $Id$ */ -public class LRUCache extends LinkedHashMap { +public class LRUCache extends LinkedHashMap { private static final long serialVersionUID = 1L; protected int maxElements; public LRUCache(int maxSize) { - super(maxSize); + super(maxSize, 0.75F, true); this.maxElements = maxSize; } @@ -45,7 +44,8 @@ * * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) */ - protected boolean removeEldestEntry(Entry eldest) { + @Override + protected boolean removeEldestEntry(Entry eldest) { return (size() > this.maxElements); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/PropertiesDocGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/util/PropertiesDocGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/PropertiesDocGenerator.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/PropertiesDocGenerator.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,39 +1,40 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.util; import java.sql.SQLException; -import com.mysql.jdbc.ConnectionProperties; +import com.mysql.jdbc.ConnectionPropertiesImpl; /** * Creates docbook table of connection properties from ConnectionProperties * class. */ -public class PropertiesDocGenerator extends ConnectionProperties { +public class PropertiesDocGenerator extends ConnectionPropertiesImpl { + static final long serialVersionUID = -4869689139143855383L; + public static void main(String[] args) throws SQLException { System.out.println(new PropertiesDocGenerator().exposeAsXml()); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ReadAheadInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ReadAheadInputStream.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ReadAheadInputStream.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ReadAheadInputStream.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,25 +1,24 @@ /* - Copyright (C) 2002-2005 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - */ package com.mysql.jdbc.util; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ResultSetUtil.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ResultSetUtil.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ResultSetUtil.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ResultSetUtil.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.util; import java.sql.ResultSet; Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ServerController.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ServerController.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ServerController.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/ServerController.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,34 +1,31 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.util; import java.io.File; import java.io.IOException; - import java.util.Iterator; -import java.util.Locale; import java.util.Properties; import com.mysql.jdbc.StringUtils; @@ -145,11 +142,10 @@ public Process start() throws IOException { if (this.serverProcess != null) { throw new IllegalArgumentException("Server already started"); - } else { - this.serverProcess = Runtime.getRuntime().exec(getCommandLine()); - - return this.serverProcess; } + this.serverProcess = Runtime.getRuntime().exec(getCommandLine()); + + return this.serverProcess; } /** @@ -172,8 +168,7 @@ pathBuf.append(File.separator); } - String defaultsFilePath = getServerProps().getProperty( - DEFAULTS_FILE_KEY); + //String defaultsFilePath = getServerProps().getProperty(DEFAULTS_FILE_KEY); pathBuf.append("bin"); pathBuf.append(File.separator); @@ -292,7 +287,7 @@ if (this.serverProps != null) { - for (Iterator iter = this.serverProps.keySet().iterator(); iter + for (Iterator iter = this.serverProps.keySet().iterator(); iter .hasNext();) { String key = (String) iter.next(); String value = this.serverProps.getProperty(key); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/TimezoneDump.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/util/TimezoneDump.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/TimezoneDump.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/TimezoneDump.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,34 +1,33 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package com.mysql.jdbc.util; -import com.mysql.jdbc.TimeUtil; - import java.sql.DriverManager; import java.sql.ResultSet; +import com.mysql.jdbc.TimeUtil; + /** * Dumps the timezone of the MySQL server represented by the JDBC url given on * the commandline (or localhost/test if none provided). @@ -71,16 +70,23 @@ Class.forName("com.mysql.jdbc.Driver").newInstance(); - ResultSet rs = DriverManager.getConnection(jdbcUrl).createStatement() - .executeQuery("SHOW VARIABLES LIKE 'timezone'"); + ResultSet rs = null; + + try { + rs = DriverManager.getConnection(jdbcUrl).createStatement().executeQuery("SHOW VARIABLES LIKE 'timezone'"); - while (rs.next()) { - String timezoneFromServer = rs.getString(2); - System.out.println("MySQL timezone name: " + timezoneFromServer); - - String canonicalTimezone = TimeUtil - .getCanoncialTimezone(timezoneFromServer); - System.out.println("Java timezone name: " + canonicalTimezone); + while (rs.next()) { + String timezoneFromServer = rs.getString(2); + System.out.println("MySQL timezone name: " + timezoneFromServer); + + String canonicalTimezone = TimeUtil + .getCanoncialTimezone(timezoneFromServer, null); + System.out.println("Java timezone name: " + canonicalTimezone); + } + } finally { + if (rs != null) { + rs.close(); + } } } -} +} \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/VersionFSHierarchyMaker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/com/mysql/jdbc/util/VersionFSHierarchyMaker.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/VersionFSHierarchyMaker.java 17 Aug 2012 14:57:12 -0000 1.1 +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/VersionFSHierarchyMaker.java 30 Jul 2014 08:37:24 -0000 1.1.2.1 @@ -1,32 +1,32 @@ /* - Copyright (C) 2005-2006 MySQL AB + Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + */ + package com.mysql.jdbc.util; import java.io.File; import java.io.FileOutputStream; import java.sql.Connection; import java.sql.ResultSet; -import java.util.Properties; import com.mysql.jdbc.NonRegisteringDriver; Index: 3rdParty_sources/mysql-connector/org/gjt/mm/mysql/Driver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/mysql-connector/org/gjt/mm/mysql/Driver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/mysql-connector/org/gjt/mm/mysql/Driver.java 17 Aug 2012 14:57:13 -0000 1.1 +++ 3rdParty_sources/mysql-connector/org/gjt/mm/mysql/Driver.java 30 Jul 2014 08:37:33 -0000 1.1.2.1 @@ -1,27 +1,26 @@ /* - Copyright (C) 2002-2004 MySQL AB + Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. + 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 FLOSS License Exception + . - There are special exceptions to the terms and conditions of the GPL - as it is applied to this software. View the full text of the - exception in file EXCEPTIONS-CONNECTOR-J in the directory of this - software distribution. + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - */ + package org.gjt.mm.mysql; import java.sql.SQLException; Index: lams_build/3rdParty.userlibraries =================================================================== RCS file: /usr/local/cvsroot/lams_build/3rdParty.userlibraries,v diff -u -r1.71 -r1.71.2.1 --- lams_build/3rdParty.userlibraries 26 Jun 2014 14:56:29 -0000 1.71 +++ lams_build/3rdParty.userlibraries 30 Jul 2014 08:37:13 -0000 1.71.2.1 @@ -1,6 +1,6 @@ - + @@ -22,7 +22,6 @@ - @@ -46,5 +45,6 @@ + Index: lams_build/liblist.txt =================================================================== RCS file: /usr/local/cvsroot/lams_build/liblist.txt,v diff -u -r1.25 -r1.25.2.1 --- lams_build/liblist.txt 26 Jun 2014 14:56:29 -0000 1.25 +++ lams_build/liblist.txt 30 Jul 2014 08:37:13 -0000 1.25.2.1 @@ -54,7 +54,7 @@ lucene lucene-core-2.4.0.jar 2.4.0 Apache License 2.0 Apache text search engine library lucene-snowball-2.4.0.jar 2.4.0 -mysql mysql-connector-java-5.0.8-bin.jar 5.0.8 GPL Oracle Java connector for MySQL +mysql mysql-connector-java-5.1.31-bin.jar 5.1.31 GPL Oracle Java connector for MySQL odmg odmg-3.0.jar 3.0 Fisheye: Tag 1.1 refers to a dead (removed) revision in file `lams_build/conf/standalone.xml'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `lams_build/lib/mysql/module.xml'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_build/lib/mysql/mysql-connector-java-5.1.31-bin.jar =================================================================== RCS file: /usr/local/cvsroot/lams_build/lib/mysql/Attic/mysql-connector-java-5.1.31-bin.jar,v diff -u -r1.1 -r1.1.2.1 Binary files differ Index: lams_tool_deploy/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_deploy/.classpath,v diff -u -r1.12 -r1.12.2.1 --- lams_tool_deploy/.classpath 21 Mar 2013 06:53:56 -0000 1.12 +++ lams_tool_deploy/.classpath 30 Jul 2014 08:37:09 -0000 1.12.2.1 @@ -5,12 +5,12 @@ - +