List:Commits« Previous MessageNext Message »
From:mmatthews Date:January 4 2008 11:06pm
Subject:Connector/J commit: r6707 - in trunk: . src/com/mysql/jdbc src/com/mysql/jdbc/exceptions/jdbc4 src/com/mysql/jdbc/integration/jboss src/com/mysql/jdbc...
View as plain text  
Modified:
   trunk/
   trunk/CHANGES
   trunk/src/com/mysql/jdbc/Blob.java
   trunk/src/com/mysql/jdbc/Buffer.java
   trunk/src/com/mysql/jdbc/BufferRow.java
   trunk/src/com/mysql/jdbc/CallableStatement.java
   trunk/src/com/mysql/jdbc/Clob.java
   trunk/src/com/mysql/jdbc/CommunicationsException.java
   trunk/src/com/mysql/jdbc/CompressedInputStream.java
   trunk/src/com/mysql/jdbc/ConnectionImpl.java
   trunk/src/com/mysql/jdbc/ConnectionProperties.java
   trunk/src/com/mysql/jdbc/ConnectionPropertiesImpl.java
   trunk/src/com/mysql/jdbc/DatabaseMetaData.java
   trunk/src/com/mysql/jdbc/EscapeProcessor.java
   trunk/src/com/mysql/jdbc/ExportControlled.java
   trunk/src/com/mysql/jdbc/LicenseConfiguration.java
   trunk/src/com/mysql/jdbc/LocalizedErrorMessages.properties
   trunk/src/com/mysql/jdbc/Messages.java
   trunk/src/com/mysql/jdbc/MiniAdmin.java
   trunk/src/com/mysql/jdbc/MysqlIO.java
   trunk/src/com/mysql/jdbc/MysqlParameterMetadata.java
   trunk/src/com/mysql/jdbc/NamedPipeSocketFactory.java
   trunk/src/com/mysql/jdbc/NonRegisteringDriver.java
   trunk/src/com/mysql/jdbc/ParameterBindings.java
   trunk/src/com/mysql/jdbc/PreparedStatement.java
   trunk/src/com/mysql/jdbc/ReplicationConnection.java
   trunk/src/com/mysql/jdbc/ResultSetImpl.java
   trunk/src/com/mysql/jdbc/ResultSetInternalMethods.java
   trunk/src/com/mysql/jdbc/ResultSetMetaData.java
   trunk/src/com/mysql/jdbc/ResultSetRow.java
   trunk/src/com/mysql/jdbc/RowDataDynamic.java
   trunk/src/com/mysql/jdbc/RowDataStatic.java
   trunk/src/com/mysql/jdbc/SQLError.java
   trunk/src/com/mysql/jdbc/ServerPreparedStatement.java
   trunk/src/com/mysql/jdbc/SingleByteCharsetConverter.java
   trunk/src/com/mysql/jdbc/SocketFactory.java
   trunk/src/com/mysql/jdbc/StandardSocketFactory.java
   trunk/src/com/mysql/jdbc/StatementImpl.java
   trunk/src/com/mysql/jdbc/StringUtils.java
   trunk/src/com/mysql/jdbc/TimeUtil.java
   trunk/src/com/mysql/jdbc/UpdatableResultSet.java
   trunk/src/com/mysql/jdbc/exceptions/jdbc4/CommunicationsException.java
   trunk/src/com/mysql/jdbc/integration/jboss/ExtendedMysqlExceptionSorter.java
   trunk/src/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java
   trunk/src/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java
   trunk/src/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java
   trunk/src/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java
   trunk/src/com/mysql/jdbc/jdbc2/optional/MysqlPooledConnection.java
   trunk/src/com/mysql/jdbc/jdbc2/optional/MysqlXADataSource.java
   trunk/src/com/mysql/jdbc/jdbc2/optional/PreparedStatementWrapper.java
   trunk/src/com/mysql/jdbc/jdbc2/optional/StatementWrapper.java
   trunk/src/com/mysql/jdbc/jdbc2/optional/SuspendableXAConnection.java
   trunk/src/com/mysql/jdbc/log/Jdk14Logger.java
   trunk/src/com/mysql/jdbc/log/StandardLogger.java
   trunk/src/com/mysql/jdbc/profiler/ProfilerEventHandlerFactory.java
   trunk/src/com/mysql/jdbc/util/ServerController.java
   trunk/src/com/mysql/jdbc/util/TimezoneDump.java
   trunk/src/com/mysql/jdbc/util/VersionFSHierarchyMaker.java
   trunk/src/testsuite/BaseTestCase.java
   trunk/src/testsuite/perf/BasePerfTest.java
   trunk/src/testsuite/perf/LoadStorePerfTest.java
   trunk/src/testsuite/regression/BlobRegressionTest.java
   trunk/src/testsuite/regression/CallableStatementRegressionTest.java
   trunk/src/testsuite/regression/ConnectionRegressionTest.java
   trunk/src/testsuite/regression/MetaDataRegressionTest.java
   trunk/src/testsuite/regression/MicroPerformanceRegressionTest.java
   trunk/src/testsuite/regression/ResultSetRegressionTest.java
   trunk/src/testsuite/simple/BlobTest.java
   trunk/src/testsuite/simple/CallableStatementTest.java
   trunk/src/testsuite/simple/ConnectionTest.java
   trunk/src/testsuite/simple/DataSourceTest.java
   trunk/src/testsuite/simple/DateTest.java
   trunk/src/testsuite/simple/MetadataTest.java
   trunk/src/testsuite/simple/MiniAdminTest.java
   trunk/src/testsuite/simple/NumbersTest.java
   trunk/src/testsuite/simple/ResultSetTest.java
   trunk/src/testsuite/simple/ServerControllerTest.java
   trunk/src/testsuite/simple/StatementsTest.java
   trunk/src/testsuite/simple/TransactionTest.java
   trunk/src/testsuite/simple/UpdatabilityTest.java
   trunk/src/testsuite/simple/XATest.java
Log:
Merged revisions
6585-6586,6593-6597,6599-6602,6605,6607-6609,6612,6614-6617,6619-6620,6623-6627,6632,6636-6638,6641,6649,6658-6659,6663,6665-6673,6676,6681-6682,6684,6686,6688,6690-6691,6693,6698-6706
via svnmerge from 
svn+ssh://mmatthews@stripped/connectors-svnroot/connector-j/branches/branch_5_1

.......
  r6699 | mmatthews | 2007-12-18 09:39:28 -0600 (Tue, 18 Dec 2007) | 12 lines
  
  Added two new connection properties, "selfDestructOnPingSecondsLifetime" and 
        "selfDestructOnPingMaxOperations" designed to control overall connection lifetime
        (useful to reclaim resources on the server side) for connection pools that don't
have such a 
        facility. 
        
        The driver will consult the values of these properties when a ping is sent, either
through 
        calling Connection.ping(), issuing the "ping marker" query (any query that starts
with 
        "/* ping */"), or when using JDBC-4.0, calling Connection.isValid(). 
        
        If the connection has issued too many operations, or is too old, the driver will
        throw a SQLException with the SQLState of "08S01" at the time of the ping, which
        will cause the connection to be invalidated with most pools in use today.
.......
  r6700 | mmatthews | 2007-12-18 10:30:42 -0600 (Tue, 18 Dec 2007) | 11 lines
  
  Fixed issue where driver could send invalid server-side prepared statement 
        IDs to the server when the driver was setup to do auto-reconnect as the
        connection could get set up enough to start sending queries on one thread,
        while the thread that "noticed" the connection was down hasn't completed
        re-preparing all of the server-side prepared statements that were open when
        the connection died.
        
        Potentially fixes cause for bug 28934. Potentially fixes other possible race
        conditions where one thread that has created a connection "shares" it with other
        threads if the connection is reconnected due to auto-reconnect functionality.
.......
  r6701 | mmatthews | 2007-12-19 08:48:27 -0600 (Wed, 19 Dec 2007) | 1 line
  
  Small cleanups.
.......
  r6702 | mmatthews | 2007-12-19 08:54:25 -0600 (Wed, 19 Dec 2007) | 1 line
  
  Cleaned up imports.
.......
  r6703 | mmatthews | 2007-12-20 19:46:30 -0600 (Thu, 20 Dec 2007) | 3 lines
  
  For any SQLException caused by another Throwable, besides dumping the message or stack
  
        trace as a string into the message, set the underlying Throwable as the cause for
  
        the SQLException, making it accessible via getCause().
.......
  r6704 | mcbrown | 2008-01-03 03:40:44 -0600 (Thu, 03 Jan 2008) | 3 lines
  
  Adding a note to the description for the change of default value in
useOldAliasMetadataBehavior
.......
  r6705 | mmatthews | 2008-01-03 09:30:42 -0600 (Thu, 03 Jan 2008) | 12 lines
  
  Fixed Bug#33594 - When cursor fetch is enabled, wrong metadata is returned from 
  
        DatabaseMetaData calls. 
  
  
  
        The fix is two parts. 
  
        
  
        First, when asking for the first column value
  
        twice from a cursor-fetched row, the driver didn't re-position,
  
        and thus the "next" column was returned.
  
  
  
        Second, metadata statements and internal statements the driver
  
        uses shouldn't use cursor-based fetching at all, so we've
  
        ensured that internal statements have their fetch size set to "0".
.......
  r6706 | mmatthews | 2008-01-03 20:40:19 -0600 (Thu, 03 Jan 2008) | 5 lines
  
  Fixed Bug#33678 - Multiple result sets not supported in
  
         "streaming" mode. This fix covers both normal statements, and stored
  
         procedures, with the exception of stored procedures with registered 
  
         OUTPUT parameters, which can't be used at all with "streaming" result 
  
         sets.
.......



Property changes on: trunk
___________________________________________________________________
Name: svnmerge-integrated
   - /branches/branch_5_0:1-6636,6638-6670 /branches/branch_5_1:1-6582,6584-6678,6680-6697
   + /branches/branch_5_0:1-6636,6638-6670 /branches/branch_5_1:1-6582,6584-6678,6680-6706

Modified: trunk/CHANGES
===================================================================
--- trunk/CHANGES	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/CHANGES	2008-01-04 22:06:31 UTC (rev 6707)
@@ -84,6 +84,53 @@
     - Fixed BUG#30508 - ResultSet returned by Statement.getGeneratedKeys() is not closed 
       automatically when statement that created it is closed.
       
+    - Added two new connection properties, "selfDestructOnPingSecondsLifetime" and 
+      "selfDestructOnPingMaxOperations" designed to control overall connection lifetime
+      (useful to reclaim resources on the server side) for connection pools that don't
have such a 
+      facility. 
+      
+      The driver will consult the values of these properties when a ping is sent, either
through 
+      calling Connection.ping(), issuing the "ping marker" query (any query that starts
with 
+      "/* ping */"), or when using JDBC-4.0, calling Connection.isValid(). 
+      
+      If the connection has issued too many operations, or is too old, the driver will
+      throw a SQLException with the SQLState of "08S01" at the time of the ping, which
+      will cause the connection to be invalidated with most pools in use today.
+      
+    - Fixed issue where driver could send invalid server-side prepared statement 
+      IDs to the server when the driver was setup to do auto-reconnect as the
+      connection could get set up enough to start sending queries on one thread,
+      while the thread that "noticed" the connection was down hasn't completed
+      re-preparing all of the server-side prepared statements that were open when
+      the connection died.
+      
+      Potentially fixes cause for bug 28934. Potentially fixes other possible race
+      conditions where one thread that has created a connection "shares" it with other
+      threads if the connection is reconnected due to auto-reconnect functionality.
+      
+    - For any SQLException caused by another Throwable, besides dumping the message or
stack
+      trace as a string into the message, set the underlying Throwable as the cause for
+      the SQLException, making it accessible via getCause().
+      
+    - Fixed Bug#33594 - When cursor fetch is enabled, wrong metadata is returned from 
+      DatabaseMetaData calls. 
+
+      The fix is two parts. 
+      
+      First, when asking for the first column value
+      twice from a cursor-fetched row, the driver didn't re-position,
+      and thus the "next" column was returned.
+
+      Second, metadata statements and internal statements the driver
+      uses shouldn't use cursor-based fetching at all, so we've
+      ensured that internal statements have their fetch size set to "0".
+
+    -  Fixed Bug#33678 - Multiple result sets not supported in
+       "streaming" mode. This fix covers both normal statements, and stored
+       procedures, with the exception of stored procedures with registered 
+       OUTPUT parameters, which can't be used at all with "streaming" result 
+       sets.
+       
 10-09-07 - Version 5.1.5
 
     - Released instead of 5.1.4 to pickup patch for BUG#31053

Modified: trunk/src/com/mysql/jdbc/Blob.java
===================================================================
--- trunk/src/com/mysql/jdbc/Blob.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/Blob.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -28,7 +28,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-
 import java.sql.SQLException;
 
 /**
@@ -239,8 +238,11 @@
 		try {
 			bytesOut.write(bytes, offset, length);
 		} catch (IOException ioEx) {
-			throw SQLError.createSQLException(Messages.getString("Blob.1"), //$NON-NLS-1$
+			SQLException sqlEx = SQLError.createSQLException(Messages.getString("Blob.1"),
//$NON-NLS-1$
 					SQLError.SQL_STATE_GENERAL_ERROR);
+			sqlEx.initCause(ioEx);
+			
+			throw sqlEx;
 		} finally {
 			try {
 				bytesOut.close();

Modified: trunk/src/com/mysql/jdbc/Buffer.java
===================================================================
--- trunk/src/com/mysql/jdbc/Buffer.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/Buffer.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -25,9 +25,7 @@
 package com.mysql.jdbc;
 
 import java.io.UnsupportedEncodingException;
-
 import java.nio.ByteBuffer;
-
 import java.sql.SQLException;
 
 /**

Modified: trunk/src/com/mysql/jdbc/BufferRow.java
===================================================================
--- trunk/src/com/mysql/jdbc/BufferRow.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/BufferRow.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -180,7 +180,8 @@
 		if (index == 0) {
 			this.lastRequestedIndex = 0;
 			this.lastRequestedPos = this.homePosition;
-
+			this.rowFromServer.setPosition(this.homePosition);
+			
 			return 0;
 		}
 

Modified: trunk/src/com/mysql/jdbc/CallableStatement.java
===================================================================
--- trunk/src/com/mysql/jdbc/CallableStatement.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/CallableStatement.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -25,13 +25,9 @@
 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;
@@ -42,17 +38,13 @@
 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.Map;
-import java.util.Properties;
 
-import com.mysql.jdbc.exceptions.NotYetImplementedException;
-
 /**
  * Representation of stored procedures for JDBC
  * 

Modified: trunk/src/com/mysql/jdbc/Clob.java
===================================================================
--- trunk/src/com/mysql/jdbc/Clob.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/Clob.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -30,7 +30,6 @@
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.Writer;
-
 import java.sql.SQLException;
 
 import com.mysql.jdbc.exceptions.NotYetImplementedException;

Modified: trunk/src/com/mysql/jdbc/CommunicationsException.java
===================================================================
--- trunk/src/com/mysql/jdbc/CommunicationsException.java	2008-01-04 02:40:19 UTC (rev
6706)
+++ trunk/src/com/mysql/jdbc/CommunicationsException.java	2008-01-04 22:06:31 UTC (rev
6707)
@@ -24,8 +24,6 @@
  */
 package com.mysql.jdbc;
 
-import java.net.BindException;
-
 import java.sql.SQLException;
 
 /**
@@ -52,6 +50,10 @@
 
 		this.exceptionMessage = SQLError.createLinkFailureMessageBasedOnHeuristics(conn,
 				lastPacketSentTimeMs, underlyingException, this.streamingResultSetInPlay);
+		
+		if (underlyingException != null) {
+			initCause(underlyingException);
+		}
 	}
 
 	

Modified: trunk/src/com/mysql/jdbc/CompressedInputStream.java
===================================================================
--- trunk/src/com/mysql/jdbc/CompressedInputStream.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/CompressedInputStream.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -27,9 +27,7 @@
 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;
 

Modified: trunk/src/com/mysql/jdbc/ConnectionImpl.java
===================================================================
--- trunk/src/com/mysql/jdbc/ConnectionImpl.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/ConnectionImpl.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -39,7 +39,6 @@
 import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -53,9 +52,9 @@
 import com.mysql.jdbc.log.Log;
 import com.mysql.jdbc.log.LogFactory;
 import com.mysql.jdbc.log.NullLogger;
+import com.mysql.jdbc.profiler.ProfilerEvent;
 import com.mysql.jdbc.profiler.ProfilerEventHandler;
 import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
-import com.mysql.jdbc.profiler.ProfilerEvent;
 import com.mysql.jdbc.util.LRUCache;
 
 /**
@@ -775,13 +774,13 @@
 		if (histogramCounts == null) {
 			createInitialHistogram(histogramBreakpoints,
 					currentLowerBound, currentUpperBound);
-		}
-
-		for (int i = 0; i < HISTOGRAM_BUCKETS; i++) {
-			if (histogramBreakpoints[i] >= value) {
-				histogramCounts[i] += numberOfTimes;
-
-				break;
+		} else {
+			for (int i = 0; i < HISTOGRAM_BUCKETS; i++) {
+				if (histogramBreakpoints[i] >= value) {
+					histogramCounts[i] += numberOfTimes;
+	
+					break;
+				}
 			}
 		}
 	}
@@ -831,12 +830,8 @@
 				if (sortedCollationMap == null) {
 					sortedCollationMap = new TreeMap();
 
-					stmt = createStatement();
+					stmt = getMetadataSafeStatement();
 
-					if (stmt.getMaxRows() != 0) {
-						stmt.setMaxRows(0);
-					}
-
 					results = stmt
 							.executeQuery("SHOW COLLATION");
 
@@ -1967,198 +1962,56 @@
 	 */
 	protected void createNewIO(boolean isForReconnect)
 			throws SQLException {
-		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;
-					}
+		// Synchronization Not needed for *new* connections, but defintely for
+		// connections going through fail-over, since we might get the
+		// new connection up and running *enough* to start sending
+		// cached or still-open server-side prepared statements over
+		// to the backend before we get a chance to re-prepare them...
+		
+		synchronized (this.mutex) {
+			Properties mergedProps  = exposeAsProperties(this.props);
+	
+			long queriesIssuedFailedOverCopy = this.queriesIssuedFailedOver;
+			this.queriesIssuedFailedOver = 0;
+			
+			try {
+				if (!getHighAvailability() && !this.failedOver) {
+					boolean connectionGood = false;
+					Exception connectionNotEstablishedBecause = null;
 					
-					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 || StringUtils.isEmptyOrWhitespaceOnly(newHost)) {
-							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.largeRowSizeThreshold.getValueAsInt());
+					int hostIndex = 0;
 	
-						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);
+					//
+					// 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;
 						}
-
-						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 SQLError.createCommunicationsException(this,
-									(this.io != null) ? this.io
-											.getLastPacketSentTimeMs() : 0,
-											EEE);
-						}
-					}
-				}
-				
-				if (!connectionGood) {
-					// We've really failed!
-					SQLException chainedEx = SQLError.createSQLException(
-							Messages.getString("Connection.UnableToConnect"),
-							SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE);
-					chainedEx.initCause(connectionNotEstablishedBecause);
-					
-					throw chainedEx;
-				}
-			} 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 || StringUtils.isEmptyOrWhitespaceOnly(newHost)) {
 								newHost = "localhost";
 							}
-
+	
 							if (hostPortPair[NonRegisteringDriver.PORT_NUMBER_INDEX] != null) {
 								try {
 									newPort = Integer
@@ -2171,143 +2024,293 @@
 											SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE);
 								}
 							}
-
-							this.io = new MysqlIO(newHost, newPort,
-									mergedProps, getSocketFactoryClassName(),
-									this, getSocketTimeout(),
+	
+							this.io = new MysqlIO(newHost, newPort, mergedProps,
+									getSocketFactoryClassName(), this,
+									getSocketTimeout(), 
 									this.largeRowSizeThreshold.getValueAsInt());
+		
 							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;
+	
+							connectionGood = true;
+							
+							break; // low-level connection succeeded
 						} catch (Exception EEE) {
-							connectionException = 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 SQLError.createCommunicationsException(this,
+										(this.io != null) ? this.io
+												.getLastPacketSentTimeMs() : 0,
+												EEE);
 							}
 						}
-
-						if (connectionGood) {
-							break;
+					}
+					
+					if (!connectionGood) {
+						// We've really failed!
+						SQLException chainedEx = SQLError.createSQLException(
+								Messages.getString("Connection.UnableToConnect"),
+								SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE);
+						chainedEx.initCause(connectionNotEstablishedBecause);
+						
+						throw chainedEx;
+					}
+				} 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 (attemptCount > 0) {
+						
+						if (this.preferSlaveDuringFailover && hostIndex == 0) {
+							hostIndex++;
+						}
+	
+						for (int attemptCount = 0; (attemptCount < getMaxReconnects())
+								&& !connectionGood; attemptCount++) {
 							try {
-								Thread.sleep((long) timeout * 1000);
-							} catch (InterruptedException IE) {
-								// ignore
+								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 || StringUtils.isEmptyOrWhitespaceOnly(newHost)) {
+									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.largeRowSizeThreshold.getValueAsInt());
+								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 */;
+								}
 							}
-						}
-					} // end attempts for a single host
-				} // end iterator for list of hosts
-
-				if (!connectionGood) {
-					// We've really failed!
-					SQLException chainedEx = SQLError.createSQLException(
-							Messages.getString("Connection.UnableToConnectWithRetries",
-									new Object[] {new Integer(getMaxReconnects())}),
-							SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE);
-					chainedEx.initCause(connectionException);
-					
-					throw chainedEx;
+	
+							if (connectionGood) {
+								break;
+							}
+	
+							if (attemptCount > 0) {
+								try {
+									Thread.sleep((long) timeout * 1000);
+								} catch (InterruptedException IE) {
+									// ignore
+								}
+							}
+						} // end attempts for a single host
+					} // end iterator for list of hosts
+	
+					if (!connectionGood) {
+						// We've really failed!
+						SQLException chainedEx = SQLError.createSQLException(
+								Messages.getString("Connection.UnableToConnectWithRetries",
+										new Object[] {new Integer(getMaxReconnects())}),
+								SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE);
+						chainedEx.initCause(connectionException);
+						
+						throw chainedEx;
+					}
 				}
-			}
-
-			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();
+	
+				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);
 						}
-
-						serverPreparedStatements.add(statementObj);
 					}
-				}
-
-				if (serverPreparedStatements != null) {
-					while (!serverPreparedStatements.isEmpty()) {
-						((ServerPreparedStatement) serverPreparedStatements
-								.pop()).rePrepare();
+	
+					if (serverPreparedStatements != null) {
+						while (!serverPreparedStatements.isEmpty()) {
+							((ServerPreparedStatement) serverPreparedStatements
+									.pop()).rePrepare();
+						}
 					}
 				}
+			} finally {
+				this.queriesIssuedFailedOver = queriesIssuedFailedOverCopy;
+				
+				if (this.io != null && getStatementInterceptors() != null) {
+					this.io.initializeStatementInterceptors(
+							getStatementInterceptors(), mergedProps);
+				}
 			}
-		} finally {
-			this.queriesIssuedFailedOver = queriesIssuedFailedOverCopy;
-			
-			if (this.io != null && getStatementInterceptors() != null) {
-				this.io.initializeStatementInterceptors(
-						getStatementInterceptors(), mergedProps);
-			}
 		}
 	}
 
@@ -2316,32 +2319,34 @@
 		
 		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);
+		if (getUseServerPreparedStmts()) {
+			this.serverSideStatementCheckCache = new LRUCache(cacheSize);
+			
+			this.serverSideStatementCache = new LRUCache(cacheSize) {
+				protected boolean removeEldestEntry(java.util.Map.Entry eldest) {
+					if (this.maxElements <= 1) {
+						return false;
+					}
 					
-					try {
-						ps.close();
-					} catch (SQLException sqlEx) {
-						// punt
+					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;
 				}
-				
-				return removeIt;
-			}
-		};
+			};
+		}
 	}
 
 	/**
@@ -2993,6 +2998,10 @@
 		}
 
 		stmt.setEscapeProcessing(false);
+		
+		if (stmt.getFetchSize() != 0) {
+			stmt.setFetchSize(0);
+		}
 
 		return stmt;
 	}
@@ -3689,7 +3698,7 @@
 	}
 
 	private boolean usingCachedConfig = false;
-	
+
 	/**
 	 * Loads the result of 'SHOW VARIABLES' into the serverVariables field so
 	 * that the driver can configure itself.
@@ -3716,8 +3725,7 @@
 		java.sql.ResultSet results = null;
 
 		try {
-			stmt = createStatement();
-			stmt.setEscapeProcessing(false);
+			stmt = getMetadataSafeStatement();
 			
 			String version = this.dbmd.getDriverVersion();
 			
@@ -3899,6 +3907,19 @@
 			checkClosed();
 		}
 
+		long pingMillisLifetime = getSelfDestructOnPingSecondsLifetime();
+		int pingMaxOperations = getSelfDestructOnPingMaxOperations();
+
+		if ((pingMillisLifetime > 0 && (System.currentTimeMillis() -
this.connectionCreationTimeMillis) > pingMillisLifetime)
+				|| (pingMaxOperations > 0 && pingMaxOperations <= this.io
+						.getCommandCount())) {
+
+			close();
+
+			throw SQLError.createSQLException(Messages
+					.getString("Connection.exceededConnectionLifetime"),
+					SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE);
+		}
 		// Need MySQL-3.22.1, but who uses anything older!?
 		this.io.sendCommand(MysqlDefs.PING, null, null, false, null);
 	}
@@ -4627,7 +4648,7 @@
 					java.sql.Statement stmt = null;
 	
 					try {
-						stmt = createStatement();
+						stmt = getMetadataSafeStatement();
 	
 						stmt.executeUpdate(rollbackQuery.toString());
 					} catch (SQLException sqlEx) {
@@ -5046,7 +5067,7 @@
 				java.sql.Statement stmt = null;
 	
 				try {
-					stmt = createStatement();
+					stmt = getMetadataSafeStatement();
 	
 					stmt.executeUpdate(savePointQuery.toString());
 				} finally {

Modified: trunk/src/com/mysql/jdbc/ConnectionProperties.java
===================================================================
--- trunk/src/com/mysql/jdbc/ConnectionProperties.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/ConnectionProperties.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -1586,4 +1586,12 @@
 	public abstract boolean getUseLegacyDatetimeCode();
 
 	public abstract void setUseLegacyDatetimeCode(boolean flag);
+	
+	public int getSelfDestructOnPingSecondsLifetime();
+
+	public void setSelfDestructOnPingSecondsLifetime(int seconds);
+
+	public int getSelfDestructOnPingMaxOperations();
+
+	public void setSelfDestructOnPingMaxOperations(int maxOperations);
 }

Modified: trunk/src/com/mysql/jdbc/ConnectionPropertiesImpl.java
===================================================================
--- trunk/src/com/mysql/jdbc/ConnectionPropertiesImpl.java	2008-01-04 02:40:19 UTC (rev
6706)
+++ trunk/src/com/mysql/jdbc/ConnectionPropertiesImpl.java	2008-01-04 22:06:31 UTC (rev
6707)
@@ -23,15 +23,10 @@
 
 package com.mysql.jdbc;
 
-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;
@@ -43,6 +38,9 @@
 import javax.naming.Reference;
 import javax.naming.StringRefAddr;
 
+import com.mysql.jdbc.log.Log;
+import com.mysql.jdbc.log.StandardLogger;
+
 /**
  * Represents configurable properties for Connections and DataSources. Can also
  * expose properties as JDBC DriverPropertyInfo if required as well.
@@ -658,7 +656,10 @@
 				}
 			}
 		} catch (Exception ex) {
-			throw new RuntimeException(ex.toString());
+			RuntimeException rtEx = new RuntimeException();
+			rtEx.initCause(ex);
+			
+			throw rtEx;
 		}
 	}
 
@@ -1277,6 +1278,22 @@
 			Messages.getString("ConnectionProperties.secondsBeforeRetryMaster"), //$NON-NLS-1$
 			"3.0.2", HA_CATEGORY, 8); //$NON-NLS-1$
 
+	private IntegerConnectionProperty selfDestructOnPingSecondsLifetime = new
IntegerConnectionProperty(
+			"selfDestructOnPingSecondsLifetime",
+			0,
+			0,
+			Integer.MAX_VALUE,
+			Messages.getString("ConnectionProperties.selfDestructOnPingSecondsLifetime"),
+			"5.1.6", HA_CATEGORY, Integer.MAX_VALUE);
+	
+	private IntegerConnectionProperty selfDestructOnPingMaxOperations = new
IntegerConnectionProperty(
+			"selfDestructOnPingMaxOperations",
+			0,
+			0,
+			Integer.MAX_VALUE,
+			Messages.getString("ConnectionProperties.selfDestructOnPingMaxOperations"),
+			"5.1.6", HA_CATEGORY, Integer.MAX_VALUE);
+			
 	private StringConnectionProperty serverTimezone = new StringConnectionProperty(
 			"serverTimezone", //$NON-NLS-1$
 			null,
@@ -4325,4 +4342,20 @@
 	public void setUseLegacyDatetimeCode(boolean flag) {
 		this.useLegacyDatetimeCode.setValue(flag);
 	}
+
+	public int getSelfDestructOnPingSecondsLifetime() {
+		return this.selfDestructOnPingSecondsLifetime.getValueAsInt();
+	}
+
+	public void setSelfDestructOnPingSecondsLifetime(int seconds) {
+		this.selfDestructOnPingSecondsLifetime.setValue(seconds);
+	}
+
+	public int getSelfDestructOnPingMaxOperations() {
+		return this.selfDestructOnPingMaxOperations.getValueAsInt();
+	}
+
+	public void setSelfDestructOnPingMaxOperations(int maxOperations) {
+		this.selfDestructOnPingMaxOperations.setValue(maxOperations);
+	}
 }

Modified: trunk/src/com/mysql/jdbc/DatabaseMetaData.java
===================================================================
--- trunk/src/com/mysql/jdbc/DatabaseMetaData.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/DatabaseMetaData.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -26,13 +26,10 @@
 
 import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -40,7 +37,6 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Properties;
 import java.util.StringTokenizer;
 import java.util.TreeMap;
 
@@ -1090,7 +1086,7 @@
 				int lastParenIndex = line.lastIndexOf(")");
 	
 				if (lastParenIndex != (line.length() - 1)) {
-					String cascadeOptions = cascadeOptions = line
+					String cascadeOptions = line
 							.substring(lastParenIndex + 1);
 					commentBuf.append(" ");
 					commentBuf.append(cascadeOptions);

Modified: trunk/src/com/mysql/jdbc/EscapeProcessor.java
===================================================================
--- trunk/src/com/mysql/jdbc/EscapeProcessor.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/EscapeProcessor.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -33,7 +33,6 @@
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.text.SimpleDateFormat;
-
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.GregorianCalendar;

Modified: trunk/src/com/mysql/jdbc/ExportControlled.java
===================================================================
--- trunk/src/com/mysql/jdbc/ExportControlled.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/ExportControlled.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -33,7 +33,6 @@
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
 import java.security.UnrecoverableKeyException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
@@ -43,7 +42,6 @@
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.TrustManagerFactorySpi;
 import javax.net.ssl.X509TrustManager;
 
 /**
@@ -182,9 +180,12 @@
 						+ " does not appear to be a valid URL.", SQL_STATE_BAD_SSL_PARAMS, 0,
 						false);
 			} catch (IOException ioe) {
-				throw SQLError.createSQLException("Cannot open "
+				SQLException sqlEx = SQLError.createSQLException("Cannot open "
 						+ clientCertificateKeyStoreUrl + " ["
 						+ ioe.getMessage() + "]", SQL_STATE_BAD_SSL_PARAMS, 0, false);
+				sqlEx.initCause(ioe);
+				
+				throw sqlEx;
 			}
 		}
 
@@ -218,9 +219,13 @@
 						+ " does not appear to be a valid URL.", SQL_STATE_BAD_SSL_PARAMS, 0,
 						false);
 			} catch (IOException ioe) {
-				throw SQLError.createSQLException("Cannot open "
+				SQLException sqlEx = SQLError.createSQLException("Cannot open "
 						+ trustCertificateKeyStoreUrl + " [" + ioe.getMessage()
 						+ "]", SQL_STATE_BAD_SSL_PARAMS, 0, false);
+				
+				sqlEx.initCause(ioe);
+				
+				throw sqlEx;
 			}
 		}
 

Modified: trunk/src/com/mysql/jdbc/LicenseConfiguration.java
===================================================================
--- trunk/src/com/mysql/jdbc/LicenseConfiguration.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/LicenseConfiguration.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -25,7 +25,6 @@
 package com.mysql.jdbc;
 
 import java.sql.SQLException;
-
 import java.util.Map;
 
 /**

Modified: trunk/src/com/mysql/jdbc/LocalizedErrorMessages.properties
===================================================================
--- trunk/src/com/mysql/jdbc/LocalizedErrorMessages.properties	2008-01-04 02:40:19 UTC
(rev 6706)
+++ trunk/src/com/mysql/jdbc/LocalizedErrorMessages.properties	2008-01-04 22:06:31 UTC
(rev 6707)
@@ -542,6 +542,8 @@
 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 connnection'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 connnection'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'?
@@ -572,7 +574,7 @@
 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.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?
+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?
@@ -615,4 +617,6 @@
 
 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}.
\ No newline at end of file
+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.
\ No newline at end of file

Modified: trunk/src/com/mysql/jdbc/Messages.java
===================================================================
--- trunk/src/com/mysql/jdbc/Messages.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/Messages.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -57,9 +57,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;

Modified: trunk/src/com/mysql/jdbc/MiniAdmin.java
===================================================================
--- trunk/src/com/mysql/jdbc/MiniAdmin.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/MiniAdmin.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -25,7 +25,6 @@
 package com.mysql.jdbc;
 
 import java.sql.SQLException;
-
 import java.util.Properties;
 
 /**

Modified: trunk/src/com/mysql/jdbc/MysqlIO.java
===================================================================
--- trunk/src/com/mysql/jdbc/MysqlIO.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/MysqlIO.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -49,9 +49,9 @@
 import java.util.Properties;
 import java.util.zip.Deflater;
 
+import com.mysql.jdbc.profiler.ProfilerEvent;
 import com.mysql.jdbc.profiler.ProfilerEventHandler;
 import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
-import com.mysql.jdbc.profiler.ProfilerEvent;
 import com.mysql.jdbc.util.ReadAheadInputStream;
 import com.mysql.jdbc.util.ResultSetUtil;
 
@@ -95,7 +95,7 @@
     private static final int CLIENT_MULTI_RESULTS = 131072; // Enable/disable
multi-results
     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_STATUS_CURSOR_EXISTS = 64;
@@ -234,6 +234,7 @@
 	private List statementInterceptors;
 	private boolean useDirectRowUnpack = true;
 	private int useBufferRowSizeThreshold;
+	private int commandCount = 0;
 
     /**
      * Constructor:  Connect to the MySQL server and setup a stream connection.
@@ -591,6 +592,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();
@@ -1667,6 +1672,55 @@
         this.streamingData = null;
     }
 
+    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,
@@ -1691,10 +1745,17 @@
         // 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;
@@ -1754,6 +1815,8 @@
     final Buffer sendCommand(int command, String extraData, Buffer queryPacket,
         boolean skipCheck, String extraDataCharEncoding)
         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
@@ -2400,7 +2463,7 @@
      *
      * @throws SQLException if an error occurs while reading the rows
      */
-    private final ResultSetImpl readResultsForQueryOrUpdate(
+    protected final ResultSetImpl readResultsForQueryOrUpdate(
         StatementImpl callingStatement, int maxRows, int resultSetType,
         int resultSetConcurrency, boolean streamResults, String catalog,
         Buffer resultPacket, boolean isBinaryEncoded, long preSentColumnCount,
@@ -2515,9 +2578,11 @@
                 info = resultPacket.readString();
             }
         } 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);
+            sqlEx.initCause(ex);
+            
+            throw sqlEx;
         }
 
         ResultSetInternalMethods updateRs =
com.mysql.jdbc.ResultSetImpl.getInstance(updateCount,
@@ -2631,12 +2696,14 @@
             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)),
+                Messages.getString("MysqlIO.77"),
                 SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE);
+            
+            sqlEx.initCause(ex);
+            
+            throw sqlEx;
         }
     }
 
@@ -3273,8 +3340,11 @@
                 try {
                     fileIn.close();
                 } catch (Exception ex) {
-                    throw SQLError.createSQLException(Messages.getString("MysqlIO.65"),
//$NON-NLS-1$
+                    SQLException sqlEx =
SQLError.createSQLException(Messages.getString("MysqlIO.65"), //$NON-NLS-1$
                         SQLError.SQL_STATE_GENERAL_ERROR);
+                    sqlEx.initCause(ex);
+                    
+                    throw sqlEx;
                 }
 
                 fileIn = null;
@@ -4458,4 +4528,8 @@
 	protected String getQueryTimingUnits() {
 		return this.queryTimingUnits;
 	}
-}
+	
+	protected int getCommandCount() {
+		return this.commandCount;
+	}
+}
\ No newline at end of file

Modified: trunk/src/com/mysql/jdbc/MysqlParameterMetadata.java
===================================================================
--- trunk/src/com/mysql/jdbc/MysqlParameterMetadata.java	2008-01-04 02:40:19 UTC (rev
6706)
+++ trunk/src/com/mysql/jdbc/MysqlParameterMetadata.java	2008-01-04 22:06:31 UTC (rev
6707)
@@ -27,8 +27,6 @@
 import java.sql.SQLException;
 import java.sql.Types;
 
-import com.mysql.jdbc.exceptions.NotYetImplementedException;
-
 public class MysqlParameterMetadata implements ParameterMetaData {
 	boolean returnSimpleMetadata = false;
 

Modified: trunk/src/com/mysql/jdbc/NamedPipeSocketFactory.java
===================================================================
--- trunk/src/com/mysql/jdbc/NamedPipeSocketFactory.java	2008-01-04 02:40:19 UTC (rev
6706)
+++ trunk/src/com/mysql/jdbc/NamedPipeSocketFactory.java	2008-01-04 22:06:31 UTC (rev
6707)
@@ -28,10 +28,8 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.RandomAccessFile;
-
 import java.net.Socket;
 import java.net.SocketException;
-
 import java.util.Properties;
 
 /**

Modified: trunk/src/com/mysql/jdbc/NonRegisteringDriver.java
===================================================================
--- trunk/src/com/mysql/jdbc/NonRegisteringDriver.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/NonRegisteringDriver.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -30,7 +30,6 @@
 import java.net.URLDecoder;
 import java.sql.DriverPropertyInfo;
 import java.sql.SQLException;
-
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -289,11 +288,15 @@
 			// 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);
+			
+			sqlEx.initCause(ex);
+			
+			throw sqlEx;
 		}
 	}
 
@@ -719,12 +722,15 @@
 					}
 					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);
+					sqlEx.initCause(ioEx);
+					
+					throw sqlEx;
 				}
 			}
 

Modified: trunk/src/com/mysql/jdbc/ParameterBindings.java
===================================================================
--- trunk/src/com/mysql/jdbc/ParameterBindings.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/ParameterBindings.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -27,7 +27,6 @@
 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.Ref;

Modified: trunk/src/com/mysql/jdbc/PreparedStatement.java
===================================================================
--- trunk/src/com/mysql/jdbc/PreparedStatement.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/PreparedStatement.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -33,12 +33,10 @@
 import java.io.StringReader;
 import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.net.URL;
 import java.sql.Array;
-import java.sql.BatchUpdateException;
 import java.sql.Clob;
 import java.sql.Date;
 import java.sql.ParameterMetaData;
@@ -54,12 +52,9 @@
 import java.util.Calendar;
 import java.util.List;
 import java.util.Locale;
-import java.util.Properties;
 import java.util.TimeZone;
 
-import com.mysql.jdbc.StatementImpl.CancelTask;
 import com.mysql.jdbc.exceptions.MySQLStatementCancelledException;
-import com.mysql.jdbc.exceptions.NotYetImplementedException;
 import com.mysql.jdbc.exceptions.MySQLTimeoutException;
 import com.mysql.jdbc.profiler.ProfilerEvent;
 
@@ -2600,9 +2595,12 @@
 	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);
+			sqlEx.initCause(ex);
+			
+			throw sqlEx;
 		}
 	}
 
@@ -2616,9 +2614,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);
+			sqlEx.initCause(ex);
+			
+			throw sqlEx;
 		}
 	}
 
@@ -3798,13 +3799,17 @@
 					throw (SQLException) ex;
 				}
 
-				throw SQLError.createSQLException(
+				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);
+				
+				sqlEx.initCause(ex);
+				
+				throw sqlEx;
 			}
 		}
 	}
@@ -3912,9 +3917,12 @@
 			setBinaryStream(parameterIndex, bytesIn, buf.length);
 			this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] =
Types.JAVA_OBJECT;
 		} 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);
+			sqlEx.initCause(ex);
+			
+			throw sqlEx;
 		}
 	}
 

Modified: trunk/src/com/mysql/jdbc/ReplicationConnection.java
===================================================================
--- trunk/src/com/mysql/jdbc/ReplicationConnection.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/ReplicationConnection.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -21,17 +21,13 @@
  */
 package com.mysql.jdbc;
 
-import java.sql.Array;
-import java.sql.Blob;
 import java.sql.CallableStatement;
-import java.sql.Clob;
 import java.sql.DatabaseMetaData;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.sql.SQLWarning;
 import java.sql.Savepoint;
 import java.sql.Statement;
-import java.sql.Struct;
 import java.util.Map;
 import java.util.Properties;
 

Modified: trunk/src/com/mysql/jdbc/ResultSetImpl.java
===================================================================
--- trunk/src/com/mysql/jdbc/ResultSetImpl.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/ResultSetImpl.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -24,29 +24,18 @@
  */
 package com.mysql.jdbc;
 
-import com.mysql.jdbc.PreparedStatement.ParseInfo;
-import com.mysql.jdbc.exceptions.NotYetImplementedException;
-import com.mysql.jdbc.profiler.ProfilerEventHandler;
-import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
-import com.mysql.jdbc.profiler.ProfilerEvent;
-
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectInputStream;
-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.MalformedURLException;
 import java.net.URL;
-
 import java.sql.Array;
-import java.sql.DataTruncation;
 import java.sql.Date;
 import java.sql.Ref;
 import java.sql.SQLException;
@@ -54,7 +43,6 @@
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
-
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
@@ -64,6 +52,10 @@
 import java.util.TimeZone;
 import java.util.TreeMap;
 
+import com.mysql.jdbc.profiler.ProfilerEvent;
+import com.mysql.jdbc.profiler.ProfilerEventHandler;
+import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
+
 /**
  * A ResultSet provides access to a table of data generated by executing a
  * Statement. The table rows are retrieved in sequence. Within a row its column
@@ -3449,6 +3441,13 @@
 		case MysqlDefs.FIELD_TYPE_BIT:
 			return (byte[]) value;
 
+		case MysqlDefs.FIELD_TYPE_STRING:
+		case MysqlDefs.FIELD_TYPE_VARCHAR:
+		case MysqlDefs.FIELD_TYPE_VAR_STRING:
+			if (value instanceof byte[]) {
+				return (byte[]) value;
+			}
+			// fallthrough
 		default:
 			int sqlType = field.getSQLType();
 		
@@ -5890,8 +5889,11 @@
 						tz, rollForward);
 			}
 		} catch (Exception ex) {
-			throw SQLError.createSQLException(ex.toString(),
+			SQLException sqlEx = SQLError.createSQLException(ex.toString(),
 					SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+			sqlEx.initCause(ex);
+			
+			throw sqlEx;
 		}
 	}
 	
@@ -5952,8 +5954,6 @@
 	 *                if a database access error occurs
 	 */
 	public Timestamp getTimestamp(int columnIndex) throws java.sql.SQLException {
-		checkColumnBounds(columnIndex);
-		
 		return getTimestampInternal(columnIndex, null, this.getDefaultTimeZone(),
 				false);
 	}
@@ -6302,9 +6302,12 @@
 				}
 			}
 		} catch (Exception e) {
-			throw new java.sql.SQLException("Cannot convert value '"
+			SQLException sqlEx = SQLError.createSQLException("Cannot convert value '"
 					+ timestampValue + "' from column " + columnIndex
 					+ " to TIMESTAMP.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+			sqlEx.initCause(e);
+			
+			throw sqlEx;
 		}
 		
 	}
@@ -6582,9 +6585,12 @@
 				}
 			}
 		} catch (Exception e) {
-			throw new java.sql.SQLException("Cannot convert value '"
+			SQLException sqlEx = SQLError.createSQLException("Cannot convert value '"
 					+ new String(timestampAsBytes) + "' from column " + columnIndex
 					+ " to TIMESTAMP.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+			sqlEx.initCause(e);
+			
+			throw sqlEx;
 		}	
 	}
 	
@@ -6618,6 +6624,9 @@
 					timestampValue, tz,
 					rollForward);
 		} else {
+			checkClosed();
+			checkColumnBounds(columnIndex);
+			
 			tsVal = this.thisRow.getTimestampFast(columnIndex - 1, 
 					targetCalendar, tz, rollForward, this.connection, this);
 		}

Modified: trunk/src/com/mysql/jdbc/ResultSetInternalMethods.java
===================================================================
--- trunk/src/com/mysql/jdbc/ResultSetInternalMethods.java	2008-01-04 02:40:19 UTC (rev
6706)
+++ trunk/src/com/mysql/jdbc/ResultSetInternalMethods.java	2008-01-04 22:06:31 UTC (rev
6707)
@@ -24,13 +24,7 @@
 package com.mysql.jdbc;
 
 import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
 
-import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
-import com.mysql.jdbc.profiler.ProfilerEvent;
-
 /**
  * This interface is intended to be used by implementors of statement
  * interceptors so that implementors can create static or dynamic (via 

Modified: trunk/src/com/mysql/jdbc/ResultSetMetaData.java
===================================================================
--- trunk/src/com/mysql/jdbc/ResultSetMetaData.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/ResultSetMetaData.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -25,8 +25,6 @@
 import java.sql.SQLException;
 import java.sql.Types;
 
-import com.mysql.jdbc.exceptions.NotYetImplementedException;
-
 /**
  * A ResultSetMetaData object can be used to find out about the types and
  * properties of the columns in a ResultSet

Modified: trunk/src/com/mysql/jdbc/ResultSetRow.java
===================================================================
--- trunk/src/com/mysql/jdbc/ResultSetRow.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/ResultSetRow.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -967,8 +967,11 @@
 						rollForward);
 			}
 		} catch (Exception ex) {
-			throw SQLError.createSQLException(ex.toString(),
+			SQLException sqlEx = SQLError.createSQLException(ex.toString(),
 					SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+			sqlEx.initCause(ex);
+			
+			throw sqlEx;
 		}
 	}
 
@@ -1315,10 +1318,13 @@
 				}
 			}
 		} catch (Exception e) {
-			throw new java.sql.SQLException("Cannot convert value '"
+			SQLException sqlEx = SQLError.createSQLException("Cannot convert value '"
 					+ getString(columnIndex, "ISO8859_1", conn)
 					+ "' from column " + (columnIndex + 1) + " to TIMESTAMP.",
 					SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+			sqlEx.initCause(e);
+			
+			throw sqlEx;
 		}
 	}
 

Modified: trunk/src/com/mysql/jdbc/RowDataDynamic.java
===================================================================
--- trunk/src/com/mysql/jdbc/RowDataDynamic.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/RowDataDynamic.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -25,10 +25,11 @@
 package com.mysql.jdbc;
 
 import java.sql.SQLException;
+import java.sql.Statement;
 
+import com.mysql.jdbc.profiler.ProfilerEvent;
 import com.mysql.jdbc.profiler.ProfilerEventHandler;
 import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
-import com.mysql.jdbc.profiler.ProfilerEvent;
 
 /**
  * Allows streaming of MySQL data.
@@ -69,6 +70,8 @@
 
 	private boolean useBufferRowExplicit;
 
+	private boolean moreResultsExisted;
+
 	/**
 	 * Creates a new RowDataDynamic object.
 	 * 
@@ -388,7 +391,7 @@
 
 		nextRecord();
 
-		if (this.nextRow == null && !this.streamerClosed) {
+		if (this.nextRow == null && !this.streamerClosed &&
!this.moreResultsExisted) {
 			this.io.closeStreamer(this);
 			this.streamerClosed = true;
 		}
@@ -414,7 +417,8 @@
 
 				if (this.nextRow == null) {
 					this.isAtEnd = true;
-					
+					this.moreResultsExisted = this.io.tackOnMoreStreamingResults(this.owner);
+
 					if (this.index == -1) {
 						this.wasEmpty = true;
 					}
@@ -436,10 +440,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$
+			sqlEx.initCause(ex);
+			
+			throw sqlEx;
 		}
 	}
 

Modified: trunk/src/com/mysql/jdbc/RowDataStatic.java
===================================================================
--- trunk/src/com/mysql/jdbc/RowDataStatic.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/RowDataStatic.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -25,7 +25,6 @@
 package com.mysql.jdbc;
 
 import java.sql.SQLException;
-import java.util.ArrayList;
 import java.util.List;
 
 /**

Modified: trunk/src/com/mysql/jdbc/SQLError.java
===================================================================
--- trunk/src/com/mysql/jdbc/SQLError.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/SQLError.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -30,7 +30,6 @@
 import java.sql.DataTruncation;
 import java.sql.SQLException;
 import java.sql.SQLWarning;
-
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Iterator;

Modified: trunk/src/com/mysql/jdbc/ServerPreparedStatement.java
===================================================================
--- trunk/src/com/mysql/jdbc/ServerPreparedStatement.java	2008-01-04 02:40:19 UTC (rev
6706)
+++ trunk/src/com/mysql/jdbc/ServerPreparedStatement.java	2008-01-04 22:06:31 UTC (rev
6707)
@@ -24,23 +24,14 @@
  */
 package com.mysql.jdbc;
 
-import com.mysql.jdbc.StatementImpl.CancelTask;
-import com.mysql.jdbc.exceptions.MySQLStatementCancelledException;
-import com.mysql.jdbc.exceptions.MySQLTimeoutException;
-import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
-import com.mysql.jdbc.profiler.ProfilerEvent;
-
 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;
@@ -52,13 +43,16 @@
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
-
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
-import java.util.Properties;
 import java.util.TimeZone;
 
+import com.mysql.jdbc.exceptions.MySQLStatementCancelledException;
+import com.mysql.jdbc.exceptions.MySQLTimeoutException;
+import com.mysql.jdbc.profiler.ProfilerEvent;
+import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
+
 /**
  * JDBC Interface for MySQL-4.1 and newer server-side PreparedStatements.
  * 
@@ -434,8 +428,11 @@
 		} catch (Exception ex) {
 			realClose(false, true);
 
-			throw SQLError.createSQLException(ex.toString(),
+			SQLException sqlEx = SQLError.createSQLException(ex.toString(),
 					SQLError.SQL_STATE_GENERAL_ERROR);
+			sqlEx.initCause(ex);
+			
+			throw sqlEx;
 		}
 		
 		setResultSetType(resultSetType);
@@ -583,12 +580,16 @@
 	protected void setClosed(boolean flag) {
 		this.isClosed = flag;
 	}
+	
 	/**
 	 * @see java.sql.Statement#close()
 	 */
-	public void close() throws SQLException {
+	public synchronized void close() throws SQLException {
 		if (this.isCached) {
+			clearParameters();
+			
 			this.isClosed = true;
+			
 			this.connection.recachePreparedStatement(this);
 			return;
 		}
@@ -875,6 +876,8 @@
 						.toString());
 			}
 
+			sqlEx.initCause(ex);
+			
 			throw sqlEx;
 		}
 	}
@@ -1097,6 +1100,7 @@
 		} catch (Exception ex) {
 			this.invalidationException = SQLError.createSQLException(ex.toString(),
 					SQLError.SQL_STATE_GENERAL_ERROR);
+			this.invalidationException.initCause(ex);
 		}
 
 		if (this.invalidationException != null) {
@@ -1685,8 +1689,11 @@
 			} catch (SQLException sqlEx) {
 				throw sqlEx;
 			} catch (Exception ex) {
-				throw SQLError.createSQLException(ex.toString(),
+				SQLException sqlEx = SQLError.createSQLException(ex.toString(),
 						SQLError.SQL_STATE_GENERAL_ERROR);
+				sqlEx.initCause(ex);
+				
+				throw sqlEx;
 			} finally {
 				mysql.clearInputStream();
 			}
@@ -2592,9 +2599,12 @@
 						null);
 			}
 		} catch (IOException ioEx) {
-			throw SQLError.createSQLException(Messages
+			SQLException sqlEx = SQLError.createSQLException(Messages
 					.getString("ServerPreparedStatement.24") //$NON-NLS-1$
 					+ ioEx.toString(), SQLError.SQL_STATE_GENERAL_ERROR);
+			sqlEx.initCause(ioEx);
+			
+			throw sqlEx;
 		} finally {
 			if (this.connection.getAutoClosePStmtStreams()) {
 				if (inStream != null) {
@@ -2659,9 +2669,12 @@
 						null);
 			}
 		} catch (IOException ioEx) {
-			throw SQLError.createSQLException(Messages
+			SQLException sqlEx = SQLError.createSQLException(Messages
 					.getString("ServerPreparedStatement.25") //$NON-NLS-1$
 					+ ioEx.toString(), SQLError.SQL_STATE_GENERAL_ERROR);
+			sqlEx.initCause(ioEx);
+			
+			throw sqlEx;
 		} finally {
 			if (this.connection.getAutoClosePStmtStreams()) {
 				if (inStream != null) {

Modified: trunk/src/com/mysql/jdbc/SingleByteCharsetConverter.java
===================================================================
--- trunk/src/com/mysql/jdbc/SingleByteCharsetConverter.java	2008-01-04 02:40:19 UTC (rev
6706)
+++ trunk/src/com/mysql/jdbc/SingleByteCharsetConverter.java	2008-01-04 22:06:31 UTC (rev
6707)
@@ -25,7 +25,6 @@
 package com.mysql.jdbc;
 
 import java.io.UnsupportedEncodingException;
-
 import java.sql.SQLException;
 import java.util.HashMap;
 import java.util.Map;

Modified: trunk/src/com/mysql/jdbc/SocketFactory.java
===================================================================
--- trunk/src/com/mysql/jdbc/SocketFactory.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/SocketFactory.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -25,10 +25,8 @@
 package com.mysql.jdbc;
 
 import java.io.IOException;
-
 import java.net.Socket;
 import java.net.SocketException;
-
 import java.util.Properties;
 
 /**

Modified: trunk/src/com/mysql/jdbc/StandardSocketFactory.java
===================================================================
--- trunk/src/com/mysql/jdbc/StandardSocketFactory.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/StandardSocketFactory.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -25,15 +25,12 @@
 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.Socket;
 import java.net.SocketException;
-
 import java.util.Properties;
 
 /**

Modified: trunk/src/com/mysql/jdbc/StatementImpl.java
===================================================================
--- trunk/src/com/mysql/jdbc/StatementImpl.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/StatementImpl.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -24,29 +24,25 @@
  */
 package com.mysql.jdbc;
 
-import com.mysql.jdbc.exceptions.MySQLStatementCancelledException;
-import com.mysql.jdbc.exceptions.NotYetImplementedException;
-import com.mysql.jdbc.exceptions.MySQLTimeoutException;
-import com.mysql.jdbc.profiler.ProfilerEventHandler;
-import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
-import com.mysql.jdbc.profiler.ProfilerEvent;
-import com.mysql.jdbc.util.LRUCache;
-
 import java.io.InputStream;
 import java.sql.BatchUpdateException;
 import java.sql.ResultSet;
 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.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.TimerTask;
 
+import com.mysql.jdbc.exceptions.MySQLStatementCancelledException;
+import com.mysql.jdbc.exceptions.MySQLTimeoutException;
+import com.mysql.jdbc.profiler.ProfilerEvent;
+import com.mysql.jdbc.profiler.ProfilerEventHandler;
+import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
+
 /**
  * A Statement object is used for executing a static SQL statement and obtaining
  * the results produced by it.
@@ -1936,13 +1932,25 @@
 			return false;
 		}
 
+		boolean streamingMode = createStreamingResultSet();
+		
+		if (streamingMode) {
+			if (this.results.reallyResult()) {
+				while (this.results.next()); // need to drain remaining rows to get to server status 
+										 // which tells us whether more results actually exist or not
+			}
+		}
+		
 		ResultSetInternalMethods nextResultSet = this.results.getNextResultSet();
 
 		switch (current) {
 		case java.sql.Statement.CLOSE_CURRENT_RESULT:
 
 			if (this.results != null) {
-				this.results.close();
+				if (!streamingMode) { 
+					this.results.close();
+				}
+				
 				this.results.clearNextResult();
 			}
 
@@ -1951,7 +1959,10 @@
 		case java.sql.Statement.CLOSE_ALL_RESULTS:
 
 			if (this.results != null) {
-				this.results.close();
+				if (!streamingMode) { 
+					this.results.close();
+				}
+				
 				this.results.clearNextResult();
 			}
 

Modified: trunk/src/com/mysql/jdbc/StringUtils.java
===================================================================
--- trunk/src/com/mysql/jdbc/StringUtils.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/StringUtils.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -31,9 +31,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
-
 import java.sql.SQLException;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.StringTokenizer;

Modified: trunk/src/com/mysql/jdbc/TimeUtil.java
===================================================================
--- trunk/src/com/mysql/jdbc/TimeUtil.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/TimeUtil.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -28,7 +28,6 @@
 import java.sql.SQLException;
 import java.sql.Time;
 import java.sql.Timestamp;
-
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.GregorianCalendar;

Modified: trunk/src/com/mysql/jdbc/UpdatableResultSet.java
===================================================================
--- trunk/src/com/mysql/jdbc/UpdatableResultSet.java	2008-01-04 02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/UpdatableResultSet.java	2008-01-04 22:06:31 UTC (rev 6707)
@@ -24,15 +24,8 @@
  */
 package com.mysql.jdbc;
 
-import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
-import com.mysql.jdbc.profiler.ProfilerEvent;
-
-import java.io.InputStream;
-import java.io.Reader;
 import java.math.BigDecimal;
-
 import java.sql.SQLException;
-
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -40,6 +33,9 @@
 import java.util.Map;
 import java.util.TreeMap;
 
+import com.mysql.jdbc.profiler.ProfilerEvent;
+import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
+
 /**
  * A result set that is updatable.
  *
@@ -617,7 +613,7 @@
 
 		for (int i = 0; i < this.fields.length; i++) {
 		    StringBuffer tableNameBuffer = new StringBuffer();
-		    Map columnNameToIndex = null;
+		    Map updColumnNameToIndex = null;
 
 		    // FIXME: What about no table?
 		    if (this.fields[i].getOriginalTableName() != null) {
@@ -650,7 +646,7 @@
 
 	            columnIndicesToTable.put(new Integer(i), fqTableName);
 
-	            columnNameToIndex = getColumnsToIndexMapForTableAndDB(databaseName,
tableOnlyName);
+	            updColumnNameToIndex = getColumnsToIndexMapForTableAndDB(databaseName,
tableOnlyName);
 	        } else {
 	            String tableOnlyName = this.fields[i].getTableName();
 
@@ -672,7 +668,7 @@
 
                     columnIndicesToTable.put(new Integer(i), fqTableName);
 
-                    columnNameToIndex = getColumnsToIndexMapForTableAndDB(this.catalog,
tableOnlyName);
+                    updColumnNameToIndex =
getColumnsToIndexMapForTableAndDB(this.catalog, tableOnlyName);
 	            }
 	        }
 
@@ -687,8 +683,8 @@
 				columnName = this.fields[i].getName();
 			}
 
-			if (columnNameToIndex != null && columnName != null) {
-			    columnNameToIndex.put(columnName, new Integer(i));
+			if (updColumnNameToIndex != null && columnName != null) {
+			    updColumnNameToIndex.put(columnName, new Integer(i));
 			}
 
 			String originalTableName = this.fields[i].getOriginalTableName();

Modified: trunk/src/com/mysql/jdbc/exceptions/jdbc4/CommunicationsException.java
===================================================================
--- trunk/src/com/mysql/jdbc/exceptions/jdbc4/CommunicationsException.java	2008-01-04
02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/exceptions/jdbc4/CommunicationsException.java	2008-01-04
22:06:31 UTC (rev 6707)
@@ -55,6 +55,10 @@
 
 		this.exceptionMessage = SQLError.createLinkFailureMessageBasedOnHeuristics(conn,
 				lastPacketSentTimeMs, underlyingException, this.streamingResultSetInPlay);
+		
+		if (underlyingException != null) {
+			initCause(underlyingException);
+		}
 	}
 
 	/*

Modified: trunk/src/com/mysql/jdbc/integration/jboss/ExtendedMysqlExceptionSorter.java
===================================================================
---
trunk/src/com/mysql/jdbc/integration/jboss/ExtendedMysqlExceptionSorter.java	2008-01-04
02:40:19 UTC (rev 6706)
+++
trunk/src/com/mysql/jdbc/integration/jboss/ExtendedMysqlExceptionSorter.java	2008-01-04
22:06:31 UTC (rev 6707)
@@ -24,7 +24,6 @@
 
 import java.sql.SQLException;
 
-import org.jboss.resource.adapter.jdbc.ExceptionSorter;
 import org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter;
 
 /**

Modified: trunk/src/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java
===================================================================
--- trunk/src/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java	2008-01-04
02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java	2008-01-04
22:06:31 UTC (rev 6707)
@@ -23,16 +23,12 @@
 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.PingTarget;
-import com.mysql.jdbc.SQLError;
-
 /**
  * A more efficient connection checker for JBoss.
  * 

Modified: trunk/src/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java
===================================================================
--- trunk/src/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java	2008-01-04
02:40:19 UTC (rev 6706)
+++ trunk/src/com/mysql/jdbc/jdbc2/optional/CallableStatementWrapper.java	2008-01-04
22:06:31 UTC (rev 6707)
@@ -34,12 +34,8 @@
 import java.sql.CallableStatement;
 import java.sql.Clob;
 import java.sql.Date;
-import java.sql.PreparedStatement;
-//import java.sql.NClob;
 import java.sql.Ref;
-//import java.sql.RowId;
 import java.sql.SQLException;
-//import java.sql.SQLXML;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Calendar;
@@ -47,7 +43,6 @@
 
 import com.mysql.jdbc.SQLError;
 import com.mysql.jdbc.Util;
-import com.mysql.jdbc.exceptions.NotYetImplementedException;
 
 /**
  * Wraps callable statements created by pooled connections.

Modified: trunk/src/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java
===================================================================
--- trunk/src/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java	2008-01-04 02:40:19 UTC
(rev 6706)
+++ trunk/src/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java	2008-01-04 22:06:31 UTC
(rev 6707)
@@ -2524,4 +2524,20 @@
 	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) {
+		this.mc.setSelfDestructOnPingMaxOperations(maxOperations);
+	}
+
+	public void setSelfDestructOnPingSecondsLifetime(int seconds) {
+		this.mc.setSelfDestructOnPingSecondsLifetime(seconds);
+	}
 }

Modified: trunk/src/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java
===================================================================
--- trunk/src/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java	2008-01-04 02:40:19 UTC
(rev 6706)
+++ trunk/src/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java	2008-01-04 22:06:31 UTC
(rev 6707)
@@ -24,24 +24,20 @@
  */
 package com.mysql.jdbc.jdbc2.optional;
 
-import com.mysql.jdbc.ConnectionPropertiesImpl;
-import com.mysql.jdbc.NonRegisteringDriver;
-import com.mysql.jdbc.exceptions.NotYetImplementedException;
-
 import java.io.PrintWriter;
 import java.io.Serializable;
-
 import java.sql.SQLException;
-
 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.NonRe