List:Commits« Previous MessageNext Message »
From:mmatthews Date:November 9 2007 10:53pm
Subject:Connector/J commit: r6663 - in trunk: . src/com/mysql/jdbc src/com/mysql/jdbc/integration/jboss src/testsuite/regression
View as plain text  
Modified:
   trunk/
   trunk/CHANGES
   trunk/src/com/mysql/jdbc/ConnectionImpl.java
   trunk/src/com/mysql/jdbc/MysqlIO.java
   trunk/src/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java
   trunk/src/testsuite/regression/CallableStatementRegressionTest.java
   trunk/src/testsuite/regression/ConnectionRegressionTest.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-6662
via svnmerge from 
svn+ssh://mmatthews@stripped/connectors-svnroot/connector-j/branches/branch_5_1

.......
  r6660 | mmatthews | 2007-11-08 08:46:54 -0600 (Thu, 08 Nov 2007) | 2 lines
  
  Simplified the JBoss connection validator by piggy-backing on the
  
        special "ping" syntax rather than trying to do a bunch of reflection.
.......
  r6661 | mmatthews | 2007-11-08 08:51:52 -0600 (Thu, 08 Nov 2007) | 4 lines
  
   Driver now displays the version in a comment when issuing 
  
        "SHOW VARIABLES" when connecting (for debugging purposes, it shows
  
        up in the query log on the server). This information is not shown
  
        if the connection property "paranoid" has been set to "true".
.......
  r6662 | mmatthews | 2007-11-09 15:48:42 -0600 (Fri, 09 Nov 2007) | 6 lines
  
  Fixed BUG#32246 - When unpacking rows directly, we don't hand off error 
  
        message packets to the internal method which decodes them correctly, so 
  
        no exception is raised, and the driver than hangs trying to read rows 
  
        that aren't there. This tends to happen when calling stored procedures, as
  
        normal SELECTs won't have an error in this spot in the protocol unless an 
  
        I/O error occurs.
.......



Property changes on: trunk
___________________________________________________________________
Name: svnmerge-integrated
   - /branches/branch_5_0:1-6625 /branches/branch_5_1:1-6582,6584-6657
   + /branches/branch_5_0:1-6625 /branches/branch_5_1:1-6582,6584-6662

Modified: trunk/CHANGES
===================================================================
--- trunk/CHANGES	2007-11-09 21:48:42 UTC (rev 6662)
+++ trunk/CHANGES	2007-11-09 21:53:31 UTC (rev 6663)
@@ -48,6 +48,21 @@
       Statement.getGeneratedKeys() - it was returning null instead of
       "GENERATED_KEY" as in 5.0.x.
       
+    - Simplified the JBoss connection validator by piggy-backing on the
+      special "ping" syntax rather than trying to do a bunch of reflection.
+      
+    - Driver now displays the version in a comment when issuing 
+      "SHOW VARIABLES" when connecting (for debugging purposes, it shows
+      up in the query log on the server). This information is not shown
+      if the connection property "paranoid" has been set to "true".
+      
+    - Fixed BUG#32246 - When unpacking rows directly, we don't hand off error 
+      message packets to the internal method which decodes them correctly, so 
+      no exception is raised, and the driver than hangs trying to read rows 
+      that aren't there. This tends to happen when calling stored procedures, as
+      normal SELECTs won't have an error in this spot in the protocol unless an 
+      I/O error occurs.
+     
 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/ConnectionImpl.java
===================================================================
--- trunk/src/com/mysql/jdbc/ConnectionImpl.java	2007-11-09 21:48:42 UTC (rev 6662)
+++ trunk/src/com/mysql/jdbc/ConnectionImpl.java	2007-11-09 21:53:31 UTC (rev 6663)
@@ -727,8 +727,8 @@
 		initializeDriverProperties(info);
 
 		try {
+			this.dbmd = getMetaData(false);
 			createNewIO(false);
-			this.dbmd = getMetaData();
 		} catch (SQLException ex) {
 			cleanup(ex);
 
@@ -2988,7 +2988,14 @@
 	 *                if a database access error occurs
 	 */
 	public java.sql.DatabaseMetaData getMetaData() throws SQLException {
-		checkClosed();	
+		return getMetaData(true);
+	}
+	
+	private java.sql.DatabaseMetaData getMetaData(boolean checkClosed) throws SQLException {
+		if (checkClosed) {
+			checkClosed();	
+		}
+		
 		return com.mysql.jdbc.DatabaseMetaData.getInstance(this, this.database);
 	}
 
@@ -3725,11 +3732,32 @@
 		try {
 			stmt = createStatement();
 			stmt.setEscapeProcessing(false);
+			
+			String version = this.dbmd.getDriverVersion();
+			
+			if (version != null && version.indexOf('*') != -1) {
+				StringBuffer buf = new StringBuffer(version.length() + 10);
 
-			String query = "SHOW VARIABLES";
+				for (int i = 0; i < version.length(); i++) {
+					char c = version.charAt(i);
+
+					if (c == '*') {
+						buf.append("[star]");
+					} else {
+						buf.append(c);
+					}
+				}
+
+				version = buf.toString();
+			}
+
+			String versionComment = (this.getParanoid() || version == null) ? ""
+					: "/* " + version + " */";
 			
+			String query = versionComment + "SHOW VARIABLES";
+			
 			if (versionMeetsMinimum(5, 0, 3)) {
-				query = "SHOW VARIABLES WHERE Variable_name ='language'"
+				query = versionComment + "SHOW VARIABLES WHERE Variable_name ='language'"
 					+ " OR Variable_name = 'net_write_timeout'"
 					+ " OR Variable_name = 'interactive_timeout'"
 					+ " OR Variable_name = 'wait_timeout'"

Modified: trunk/src/com/mysql/jdbc/MysqlIO.java
===================================================================
--- trunk/src/com/mysql/jdbc/MysqlIO.java	2007-11-09 21:48:42 UTC (rev 6662)
+++ trunk/src/com/mysql/jdbc/MysqlIO.java	2007-11-09 21:53:31 UTC (rev 6663)
@@ -406,7 +406,7 @@
         }
 
         packet = reuseAndReadPacket(this.reusablePacket);
-
+        
         readServerStatusForResultSets(packet);
 
 		//
@@ -1510,11 +1510,19 @@
 
 				if (firstTime) {
 					if (sw == 255) {
-						// error packet
-						Buffer errorPacket = new Buffer(packetLength);
+						// error packet - we assemble it whole for "fidelity"
+						// in case we ever need an entire packet in checkErrorPacket()
+						// but we could've gotten away with just writing the error code
+						// and message in it (for now).
+						Buffer errorPacket = new Buffer(packetLength + HEADER_LENGTH);
+						errorPacket.setPosition(0);
+						errorPacket.writeByte(this.packetHeaderBuf[0]);
+						errorPacket.writeByte(this.packetHeaderBuf[1]);
+						errorPacket.writeByte(this.packetHeaderBuf[2]);
+						errorPacket.writeByte((byte) 1);
 						errorPacket.writeByte((byte)sw);
-						readFully(this.mysqlInput, errorPacket.getByteBuffer(), 1, packetLength - 1);
-
+						readFully(this.mysqlInput, errorPacket.getByteBuffer(), 5, packetLength - 1);
+						errorPacket.setPosition(4);
 						checkErrorPacket(errorPacket);
 					}
 

Modified: trunk/src/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java
===================================================================
--- trunk/src/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java	2007-11-09
21:48:42 UTC (rev 6662)
+++ trunk/src/com/mysql/jdbc/integration/jboss/MysqlValidConnectionChecker.java	2007-11-09
21:53:31 UTC (rev 6663)
@@ -42,31 +42,9 @@
 public final class MysqlValidConnectionChecker implements
 		ValidConnectionChecker, Serializable {
 
-	private static final long serialVersionUID = 3258689922776119348L;
+	private static final long serialVersionUID = 8909421133577519177L;
 
-	private Method pingMethod;
-	
-	private Method pingMethodWrapped;
-
-	private final static Object[] NO_ARGS_OBJECT_ARRAY = new Object[0];
-
 	public MysqlValidConnectionChecker() {
-		try {
-			// Avoid classloader goofiness
-			Class mysqlConnection = Thread.currentThread()
-					.getContextClassLoader().loadClass(
-							"com.mysql.jdbc.Connection");
-
-			pingMethod = mysqlConnection.getMethod("ping", null);
-			
-			Class mysqlConnectionWrapper = Thread.currentThread()
-			.getContextClassLoader().loadClass(
-					"com.mysql.jdbc.jdbc2.optional.ConnectionWrapper");
-			
-			pingMethodWrapped = mysqlConnectionWrapper.getMethod("ping", null);
-		} catch (Exception ex) {
-			// Punt, we'll use 'SELECT 1' to do the check
-		}
 	}
 
 	/*
@@ -75,47 +53,8 @@
 	 * @see
org.jboss.resource.adapter.jdbc.ValidConnectionChecker#isValidConnection(java.sql.Connection)
 	 */
 	public SQLException isValidConnection(Connection conn) {
-		if (conn instanceof PingTarget) {
-			try {
-				((PingTarget)conn).doPing();
-			} catch (Exception ex) {
-				if (ex instanceof SQLException) {
-					return (SQLException) ex;
-				}
 
-				return SQLError.createSQLException("Ping failed: " + ex.toString());
-			}
-		} else if (conn instanceof com.mysql.jdbc.Connection) {
-			if (pingMethod != null) {
-				try {
-					this.pingMethod.invoke(conn, null);
-	
-					return null;
-				} catch (Exception ex) {
-					if (ex instanceof SQLException) {
-						return (SQLException) ex;
-					}
-	
-					return SQLError.createSQLException("Ping failed: " + ex.toString());
-				}
-			}
-		} else if (conn instanceof com.mysql.jdbc.jdbc2.optional.ConnectionWrapper) {
-			if (pingMethodWrapped != null) {
-				try {
-					this.pingMethodWrapped.invoke(conn, null);
-	
-					return null;
-				} catch (Exception ex) {
-					if (ex instanceof SQLException) {
-						return (SQLException) ex;
-					}
-	
-					return SQLError.createSQLException("Ping failed: " + ex.toString());
-				}
-			}
-		}
-
-		// Punt and use "/* ping */ SELECT 1" which will send
+		// Use "/* ping */ SELECT 1" which will send
 		// pings across multi-connections too in case the connection
 		// was "wrapped" by Jboss in any way...
 

Modified: trunk/src/testsuite/regression/CallableStatementRegressionTest.java
===================================================================
--- trunk/src/testsuite/regression/CallableStatementRegressionTest.java	2007-11-09
21:48:42 UTC (rev 6662)
+++ trunk/src/testsuite/regression/CallableStatementRegressionTest.java	2007-11-09
21:53:31 UTC (rev 6663)
@@ -1400,4 +1400,77 @@
 			}
 		}
 	}
+	
+	/**
+	 * Tests fix for Bug#32246 - When unpacking rows directly, we don't
+	 * hand off error message packets to the internal method which decodes
+	 * them correctly, so no exception is rasied, and the driver than hangs
+	 * trying to read rows that aren't there...
+	 * 
+	 * @throws Exception if the test fails
+	 */
+	public void testBug32246() throws Exception {
+		if (!versionMeetsMinimum(5, 0)) {
+			return;
+		}
+		
+		doBug32246(this.conn);
+		dropTable("test_table_2");
+		dropTable("test_table_1");
+		doBug32246(getConnectionWithProps("useDirectRowUnpack=false"));
+	}
+
+	private void doBug32246(Connection aConn) throws SQLException {
+		createTable("test_table_1", "(value_1 BIGINT PRIMARY KEY) ENGINE=InnoDB");
+		this.stmt.executeUpdate("INSERT INTO test_table_1 VALUES (1)");
+		createTable("test_table_2", "(value_2 BIGINT PRIMARY KEY) ENGINE=InnoDB");
+		this.stmt.executeUpdate("DROP FUNCTION IF EXISTS test_function");
+		createFunction("test_function", "() RETURNS BIGINT " +
+				"DETERMINISTIC MODIFIES SQL DATA BEGIN " +
+				"DECLARE max_value BIGINT; " +
+				"SELECT MAX(value_1) INTO max_value FROM test_table_2; " +
+				"RETURN max_value; END;");
+
+		CallableStatement callable = null;
+		
+		try {
+			callable = aConn.prepareCall("{? = call test_function()}");
+
+			callable.registerOutParameter(1,Types.BIGINT);
+	
+			try {
+				callable.executeUpdate();
+				fail("impossible; we should never get here.");
+			} catch (SQLException sqlEx) {
+				assertEquals("42S22", sqlEx.getSQLState());
+			}
+			
+			createTable("test_table_1", "(value_1 BIGINT PRIMARY KEY) ENGINE=InnoDB");
+			this.stmt.executeUpdate("INSERT INTO test_table_1 VALUES (1)");
+			createTable("test_table_2", "(value_2 BIGINT PRIMARY KEY, " +
+					" FOREIGN KEY (value_2) REFERENCES test_table_1 (value_1) ON DELETE CASCADE)
ENGINE=InnoDB");
+			createFunction("test_function", "(value BIGINT) RETURNS BIGINT " +
+					"DETERMINISTIC MODIFIES SQL DATA BEGIN " +
+					"INSERT INTO test_table_2 VALUES (value); RETURN value; END;"); 
+	
+			callable = aConn.prepareCall("{? = call test_function(?)}");
+			callable.registerOutParameter(1,Types.BIGINT);
+	
+			callable.setLong(2,1);
+			callable.executeUpdate();
+	
+			callable.setLong(2,2);
+			
+			try {
+				callable.executeUpdate();
+				fail("impossible; we should never get here.");
+			} catch (SQLException sqlEx) {
+				assertEquals("23000", sqlEx.getSQLState());
+			}
+		} finally {
+			if (callable != null) {
+				callable.close();
+			}
+		}
+	}
 }
\ No newline at end of file

Modified: trunk/src/testsuite/regression/ConnectionRegressionTest.java
===================================================================
--- trunk/src/testsuite/regression/ConnectionRegressionTest.java	2007-11-09 21:48:42 UTC
(rev 6662)
+++ trunk/src/testsuite/regression/ConnectionRegressionTest.java	2007-11-09 21:53:31 UTC
(rev 6663)
@@ -50,6 +50,7 @@
 import com.mysql.jdbc.NonRegisteringDriver;
 import com.mysql.jdbc.ReplicationConnection;
 import com.mysql.jdbc.ReplicationDriver;
+import com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker;
 import com.mysql.jdbc.log.StandardLogger;
 
 /**
@@ -2161,6 +2162,12 @@
 		}
 	}
 	
+	public void testBug29106() throws Exception {
+		ClassLoader cl = Thread.currentThread().getContextClassLoader(); 
+		Class checkerClass =
cl.loadClass("com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker");
+		((MysqlValidConnectionChecker)checkerClass.newInstance()).isValidConnection(this.conn);
+	}
+	
 	public void testBug29852() throws Exception {
     	Connection lbConn = getLoadBalancedConnection();
     	assertTrue(!lbConn.getClass().getName().startsWith("com.mysql.jdbc"));

Thread
Connector/J commit: r6663 - in trunk: . src/com/mysql/jdbc src/com/mysql/jdbc/integration/jboss src/testsuite/regressionmmatthews9 Nov