List:Commits« Previous MessageNext Message »
From:mmatthews Date:March 7 2006 9:01pm
Subject:Connector/J commit: r5024 - in branches: branch_3_1/connector-j branch_3_1/connector-j/src/com/mysql/jdbc branch_3_1/connector-j/src/testsuite/regress...
View as plain text  
Modified:
   branches/branch_3_1/connector-j/CHANGES
   branches/branch_3_1/connector-j/src/com/mysql/jdbc/MysqlIO.java
   branches/branch_3_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java
   branches/branch_3_1/connector-j/src/testsuite/regression/StatementRegressionTest.java
   branches/branch_5_0/connector-j/CHANGES
   branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java
   branches/branch_5_0/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java
   branches/branch_5_0/connector-j/src/testsuite/regression/StatementRegressionTest.java
   branches/branch_5_1/connector-j/CHANGES
   branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java
   branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java
   branches/branch_5_1/connector-j/src/testsuite/regression/StatementRegressionTest.java
Log:
Fixed BUG#18041 - Server-side prepared statements don't cause 
 truncation exceptions to be thrown when truncation happens.

Modified: branches/branch_3_1/connector-j/CHANGES
===================================================================
--- branches/branch_3_1/connector-j/CHANGES	2006-03-07 01:02:10 UTC (rev 5023)
+++ branches/branch_3_1/connector-j/CHANGES	2006-03-07 20:01:06 UTC (rev 5024)
@@ -57,6 +57,9 @@
     - Fixed BUG#15570 - ReplicationConnection incorrectly copies state,
 	  doesn't transfer connection context correctly when transitioning between 
 	  the same read-only states.
+	  
+	- Fixed BUG#18041 - Server-side prepared statements don't cause 
+	  truncation exceptions to be thrown when truncation happens.
     
 11-30-05 - Version 3.1.12
 

Modified: branches/branch_3_1/connector-j/src/com/mysql/jdbc/MysqlIO.java
===================================================================
--- branches/branch_3_1/connector-j/src/com/mysql/jdbc/MysqlIO.java	2006-03-07 01:02:10
UTC (rev 5023)
+++ branches/branch_3_1/connector-j/src/com/mysql/jdbc/MysqlIO.java	2006-03-07 20:01:06
UTC (rev 5024)
@@ -1408,7 +1408,8 @@
         boolean moreRowSetsExist = checkForMoreResults & serverHasMoreResults;
 
         while (moreRowSetsExist) {
-            Buffer fieldPacket = readPacket();
+            Buffer fieldPacket = checkErrorPacket();
+            fieldPacket.setPosition(0);
 
             if ((fieldPacket.readByte(0) == 0) &&
                     (fieldPacket.readByte(1) == 0) &&
@@ -2627,6 +2628,24 @@
             reclaimLargeSharedSendPacket();
         }
     }
+    
+    void enableMultiQueries() throws SQLException {
+    	Buffer buf = getSharedSendPacket();
+    	
+    	buf.clear();
+    	buf.writeByte((byte)MysqlDefs.COM_SET_OPTION);
+    	buf.writeInt(0);
+    	sendCommand(MysqlDefs.COM_SET_OPTION, null, buf, false, null);
+    }
+    
+    void disableMultiQueries() throws SQLException {
+    	Buffer buf = getSharedSendPacket();
+    	
+    	buf.clear();
+    	buf.writeByte((byte)MysqlDefs.COM_SET_OPTION);
+    	buf.writeInt(1);
+    	sendCommand(MysqlDefs.COM_SET_OPTION, null, buf, false, null);
+    }
 
     private final void send(Buffer packet, int packetLen)
         throws SQLException {
@@ -3404,7 +3423,11 @@
         }
     }
 
-    private void scanForAndThrowDataTruncation() throws SQLException {
+    boolean hadWarnings() {
+    	return this.hadWarnings;
+    }
+    
+    void scanForAndThrowDataTruncation() throws SQLException {
         if ((this.streamingData == null) && versionMeetsMinimum(4, 1, 0)
&&
                 this.connection.getJdbcCompliantTruncation()) {
             SQLError.convertShowWarningsToSQLWarnings(this.connection,

Modified: branches/branch_3_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java
===================================================================
---
branches/branch_3_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java	2006-03-07
01:02:10 UTC (rev 5023)
+++
branches/branch_3_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java	2006-03-07
20:01:06 UTC (rev 5024)
@@ -1193,6 +1193,10 @@
 				}
 			}
 			
+			if (mysql.hadWarnings()) {
+	            mysql.scanForAndThrowDataTruncation();
+	        }
+			
 			return rs;
 		}
 	}

Modified:
branches/branch_3_1/connector-j/src/testsuite/regression/StatementRegressionTest.java
===================================================================
---
branches/branch_3_1/connector-j/src/testsuite/regression/StatementRegressionTest.java	2006-03-07
01:02:10 UTC (rev 5023)
+++
branches/branch_3_1/connector-j/src/testsuite/regression/StatementRegressionTest.java	2006-03-07
20:01:06 UTC (rev 5024)
@@ -791,6 +791,47 @@
 		}
 	}
 	
+	/**
+	 * Tests fix for BUG#18041 - Server-side prepared statements
+	 * don't cause truncation exceptions to be thrown.
+	 * 
+	 * @throws Exception if the test fails
+	 */
+	public void testBug18041() throws Exception {
+		if (versionMeetsMinimum(4, 1)) {
+			createTable("testBug18041", "(`a` tinyint(4) NOT NULL,"
+					+ "`b` char(4) default NULL)");
+	
+			Properties props = new Properties();
+			props.setProperty("jdbcCompliantTruncation", "true");
+			props.setProperty("useServerPrepStmts", "true");
+	
+			Connection truncConn = null;
+			PreparedStatement stm = null;
+			
+			try {
+				truncConn = getConnectionWithProps(props);
+
+				stm = truncConn
+					.prepareStatement("insert into testBug18041 values (?,?)");
+				stm.setInt(1, 1000);
+				stm.setString(2, "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn");
+				stm.executeUpdate();
+				fail("Truncation exception should have been thrown");
+			} catch (DataTruncation truncEx) {
+				// we expect this
+			} finally {
+				if (stmt != null) {
+					stmt.close();
+				}
+				
+				if (truncConn != null) {
+					truncConn.close();
+				}
+			}
+		}	
+	}
+	
 	private void testStreamsForBug15024(boolean shouldBeClosedStream, 
 			boolean shouldBeClosedReader) throws SQLException {
 		IsClosedInputStream bIn = new IsClosedInputStream(new byte[4]);

Modified: branches/branch_5_0/connector-j/CHANGES
===================================================================
--- branches/branch_5_0/connector-j/CHANGES	2006-03-07 01:02:10 UTC (rev 5023)
+++ branches/branch_5_0/connector-j/CHANGES	2006-03-07 20:01:06 UTC (rev 5024)
@@ -160,6 +160,9 @@
     - Fixed BUG#15570 - ReplicationConnection incorrectly copies state,
 	  doesn't transfer connection context correctly when transitioning between 
 	  the same read-only states.
+	  	  
+	- Fixed BUG#18041 - Server-side prepared statements don't cause 
+	  truncation exceptions to be thrown when truncation happens.
     
 11-30-05 - Version 3.1.12
 

Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java
===================================================================
--- branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java	2006-03-07 01:02:10
UTC (rev 5023)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java	2006-03-07 20:01:06
UTC (rev 5024)
@@ -2981,7 +2981,11 @@
         }
     }
 
-    private void scanForAndThrowDataTruncation() throws SQLException {
+    boolean hadWarnings() {
+    	return this.hadWarnings;
+    }
+    
+    void scanForAndThrowDataTruncation() throws SQLException {
         if ((this.streamingData == null) && versionMeetsMinimum(4, 1, 0)
&&
                 this.connection.getJdbcCompliantTruncation()) {
             SQLError.convertShowWarningsToSQLWarnings(this.connection,

Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java
===================================================================
---
branches/branch_5_0/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java	2006-03-07
01:02:10 UTC (rev 5023)
+++
branches/branch_5_0/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java	2006-03-07
20:01:06 UTC (rev 5024)
@@ -1011,7 +1011,7 @@
 					if (this.parameterBindings[i].isLongData) {
 						if (firstFound && boundTimeToCheck != 
 							this.parameterBindings[i].boundBeforeExecutionNum) { 					
-							throw SQLError.createSQLException(Messages
+							throw new SQLException(Messages
 									.getString("ServerPreparedStatement.11") //$NON-NLS-1$
 									+ Messages.getString("ServerPreparedStatement.12"), //$NON-NLS-1$
 									SQLError.SQL_STATE_DRIVER_NOT_CAPABLE);
@@ -1028,11 +1028,10 @@
 				serverResetStatement();
 			}
 
-
 			// Check bindings
 			for (int i = 0; i < this.parameterCount; i++) {
 				if (!this.parameterBindings[i].isSet) {
-					throw SQLError.createSQLException(Messages
+					throw new SQLException(Messages
 							.getString("ServerPreparedStatement.13") + (i + 1) //$NON-NLS-1$
 							+ Messages.getString("ServerPreparedStatement.14"),
 							SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
@@ -1063,28 +1062,9 @@
 			packet.writeByte((byte) MysqlDefs.COM_EXECUTE);
 			packet.writeLong(this.serverStatementId);
 
-			boolean usingCursor = false;
-
 			if (this.connection.versionMeetsMinimum(4, 1, 2)) {
-				// we only create cursor-backed result sets if
-				// a) The query is a SELECT
-				// b) The server supports it
-				// c) We know it is forward-only (note this doesn't
-				// preclude updatable result sets)
-				// d) The user has set a fetch size
-				if (this.resultFields != null &&
-						this.connection.isCursorFetchEnabled()
-						&& getResultSetType() == ResultSet.TYPE_FORWARD_ONLY
-						&& getResultSetConcurrency() == ResultSet.CONCUR_READ_ONLY
-						&& getFetchSize() > 0) {
-					packet.writeByte(MysqlDefs.OPEN_CURSOR_FLAG);
-					usingCursor = true;
-				} else {
-					packet.writeByte((byte) 0); // placeholder for flags
-				}
-
-				packet.writeLong(1); // placeholder for parameter
-				                     // iterations
+				packet.writeByte((byte) 0); // placeholder for flags
+				packet.writeLong(1); // placeholder for parameter iterations
 			}
 
 			/* Reserve place for null-marker bytes */
@@ -1144,104 +1124,83 @@
 				begin = System.currentTimeMillis();
 			}
 
-			this.wasCancelled = false;
+			Buffer resultPacket = mysql.sendCommand(MysqlDefs.COM_EXECUTE,
+					null, packet, false, null);
+
 			
-			CancelThread timeoutThread = null;
 
-			try {
-				if (this.timeout != 0
-						&& this.connection.versionMeetsMinimum(5, 0, 0)
-						&& usingCursor /* FIXME: Not supported currently */) {
-					timeoutThread = new CancelThread(this.timeout);
-					new Thread(timeoutThread).start();
-				}
-				
-				Buffer resultPacket = mysql.sendCommand(MysqlDefs.COM_EXECUTE,
-					null, packet, false, null);
-				
-				if (timeoutThread != null) {
-					timeoutThread.dontCancel();
-					timeoutThread = null;
-				}
-				
-				if (this.wasCancelled) {
-					this.wasCancelled = false;
-					throw new MySQLTimeoutException();
-				}
+			this.connection.incrementNumberOfPreparedExecutes();
+
+			if (this.connection.getProfileSql()) {
+				this.eventSink = ProfileEventSink.getInstance(this.connection);
+
+				this.eventSink.consumeEvent(new ProfilerEvent(
+						ProfilerEvent.TYPE_EXECUTE, "", this.currentCatalog, //$NON-NLS-1$
+						this.connection.getId(), this.statementId, -1, System
+								.currentTimeMillis(), (int) (System
+								.currentTimeMillis() - begin), null,
+						new Throwable(), truncateQueryToLog(asSql(true))));
+			}
+
+			com.mysql.jdbc.ResultSet rs = mysql.readAllResults(this,
+					maxRowsToRetrieve, this.resultSetType,
+					this.resultSetConcurrency, createStreamingResultSet,
+					this.currentCatalog, resultPacket, true, this.fieldCount,
+					true);
+
 			
-				this.connection.incrementNumberOfPreparedExecutes();
-	
-				if (this.connection.getProfileSql()) {
-					this.eventSink = ProfileEventSink.getInstance(this.connection);
-	
-					this.eventSink.consumeEvent(new ProfilerEvent(
-							ProfilerEvent.TYPE_EXECUTE, "", this.currentCatalog, //$NON-NLS-1$
-							this.connectionId, this.statementId, -1, System
-									.currentTimeMillis(), (int) (System
-									.currentTimeMillis() - begin), null,
-							new Throwable(), truncateQueryToLog(asSql(true))));
-				}
-	
-				com.mysql.jdbc.ResultSet rs = mysql.readAllResults(this,
-						maxRowsToRetrieve, this.resultSetType,
-						this.resultSetConcurrency, createStreamingResultSet,
-						this.currentCatalog, resultPacket, true, this.fieldCount,
-						true);
-	
-				
-				if (!createStreamingResultSet && 
-						this.serverNeedsResetBeforeEachExecution) {
-					serverResetStatement(); // clear any long data...
-				}
-	
-				this.sendTypesToServer = false;
-				this.results = rs;
-	
+			if (!createStreamingResultSet && 
+					this.serverNeedsResetBeforeEachExecution) {
+				serverResetStatement(); // clear any long data...
+			}
+
+			this.sendTypesToServer = false;
+			this.results = rs;
+
+			if (this.connection.getLogSlowQueries()
+					|| this.connection.getGatherPerformanceMetrics()) {
+				long elapsedTime = System.currentTimeMillis() - begin;
+
 				if (this.connection.getLogSlowQueries()
-						|| this.connection.getGatherPerformanceMetrics()) {
-					long elapsedTime = System.currentTimeMillis() - begin;
-	
-					if (this.connection.getLogSlowQueries()
-							&& (elapsedTime >= this.connection
-									.getSlowQueryThresholdMillis())) {
-						StringBuffer mesgBuf = new StringBuffer(
-								48 + this.originalSql.length());
-						mesgBuf.append(Messages
-								.getString("ServerPreparedStatement.15")); //$NON-NLS-1$
-						mesgBuf.append(this.connection
-								.getSlowQueryThresholdMillis());
-						mesgBuf.append(Messages
-								.getString("ServerPreparedStatement.15a")); //$NON-NLS-1$
-						mesgBuf.append(elapsedTime);
-						mesgBuf.append(Messages
-								.getString("ServerPreparedStatement.16")); //$NON-NLS-1$
-						
-						mesgBuf.append("as prepared: ");
-						mesgBuf.append(this.originalSql);
-						mesgBuf.append("\n\n with parameters bound:\n\n");
-						mesgBuf.append(asSql(true));
-	
-						this.connection.getLog().logWarn(mesgBuf.toString());
-	
-						if (this.connection.getExplainSlowQueries()) {
-							String queryAsString = asSql(true);
-	
-							mysql.explainSlowQuery(queryAsString.getBytes(),
-									queryAsString);
-						}
+						&& (elapsedTime >= this.connection
+								.getSlowQueryThresholdMillis())) {
+					StringBuffer mesgBuf = new StringBuffer(
+							48 + this.originalSql.length());
+					mesgBuf.append(Messages
+							.getString("ServerPreparedStatement.15")); //$NON-NLS-1$
+					mesgBuf.append(this.connection
+							.getSlowQueryThresholdMillis());
+					mesgBuf.append(Messages
+							.getString("ServerPreparedStatement.15a")); //$NON-NLS-1$
+					mesgBuf.append(elapsedTime);
+					mesgBuf.append(Messages
+							.getString("ServerPreparedStatement.16")); //$NON-NLS-1$
+					
+					mesgBuf.append("as prepared: ");
+					mesgBuf.append(this.originalSql);
+					mesgBuf.append("\n\n with parameters bound:\n\n");
+					mesgBuf.append(asSql(true));
+
+					this.connection.getLog().logWarn(mesgBuf.toString());
+
+					if (this.connection.getExplainSlowQueries()) {
+						String queryAsString = asSql(true);
+
+						mysql.explainSlowQuery(queryAsString.getBytes(),
+								queryAsString);
 					}
-	
-					if (this.connection.getGatherPerformanceMetrics()) {
-						this.connection.registerQueryExecutionTime(elapsedTime);
-					}
 				}
-				
-				return rs;
-			} finally {
-				if (timeoutThread != null) {
-					timeoutThread.dontCancel();
+
+				if (this.connection.getGatherPerformanceMetrics()) {
+					this.connection.registerQueryExecutionTime(elapsedTime);
 				}
 			}
+			
+			if (mysql.hadWarnings()) {
+	            mysql.scanForAndThrowDataTruncation();
+	        }
+			
+			return rs;
 		}
 	}
 

Modified:
branches/branch_5_0/connector-j/src/testsuite/regression/StatementRegressionTest.java
===================================================================
---
branches/branch_5_0/connector-j/src/testsuite/regression/StatementRegressionTest.java	2006-03-07
01:02:10 UTC (rev 5023)
+++
branches/branch_5_0/connector-j/src/testsuite/regression/StatementRegressionTest.java	2006-03-07
20:01:06 UTC (rev 5024)
@@ -3038,4 +3038,45 @@
 		}
 	}
 
+	/**
+	 * Tests fix for BUG#18041 - Server-side prepared statements
+	 * don't cause truncation exceptions to be thrown.
+	 * 
+	 * @throws Exception if the test fails
+	 */
+	public void testBug18041() throws Exception {
+		if (versionMeetsMinimum(4, 1)) {
+			createTable("testBug18041", "(`a` tinyint(4) NOT NULL,"
+					+ "`b` char(4) default NULL)");
+	
+			Properties props = new Properties();
+			props.setProperty("jdbcCompliantTruncation", "true");
+			props.setProperty("useServerPrepStmts", "true");
+	
+			Connection truncConn = null;
+			PreparedStatement stm = null;
+			
+			try {
+				truncConn = getConnectionWithProps(props);
+	
+				stm = truncConn
+					.prepareStatement("insert into testBug18041 values (?,?)");
+				stm.setInt(1, 1000);
+				stm.setString(2, "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn");
+				stm.executeUpdate();
+				fail("Truncation exception should have been thrown");
+			} catch (DataTruncation truncEx) {
+				// we expect this
+			} finally {
+				if (stmt != null) {
+					stmt.close();
+				}
+				
+				if (truncConn != null) {
+					truncConn.close();
+				}
+			}
+		}	
+	}
+
 }

Modified: branches/branch_5_1/connector-j/CHANGES
===================================================================
--- branches/branch_5_1/connector-j/CHANGES	2006-03-07 01:02:10 UTC (rev 5023)
+++ branches/branch_5_1/connector-j/CHANGES	2006-03-07 20:01:06 UTC (rev 5024)
@@ -162,6 +162,9 @@
     - Fixed BUG#15570 - ReplicationConnection incorrectly copies state,
 	  doesn't transfer connection context correctly when transitioning between 
 	  the same read-only states.
+		  
+	- Fixed BUG#18041 - Server-side prepared statements don't cause 
+	  truncation exceptions to be thrown when truncation happens.
     
 11-30-05 - Version 3.1.12
 

Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java	2006-03-07 01:02:10
UTC (rev 5023)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java	2006-03-07 20:01:06
UTC (rev 5024)
@@ -2336,7 +2336,11 @@
     	
     }
 
-    private void scanForAndThrowDataTruncation() throws SQLException {
+    boolean hadWarnings() {
+    	return this.hadWarnings;
+    }
+    
+    void scanForAndThrowDataTruncation() throws SQLException {
         if ((this.streamingData == null) && versionMeetsMinimum(4, 1, 0)
&&
                 this.connection.getJdbcCompliantTruncation()) {
             SQLError.convertShowWarningsToSQLWarnings(this.connection,

Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java
===================================================================
---
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java	2006-03-07
01:02:10 UTC (rev 5023)
+++
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java	2006-03-07
20:01:06 UTC (rev 5024)
@@ -1213,6 +1213,10 @@
 					}
 				}
 				
+				if (mysql.hadWarnings()) {
+		            mysql.scanForAndThrowDataTruncation();
+		        }
+				
 				return rs;
 			} finally {
 				if (timeoutThread != null) {

Modified:
branches/branch_5_1/connector-j/src/testsuite/regression/StatementRegressionTest.java
===================================================================
---
branches/branch_5_1/connector-j/src/testsuite/regression/StatementRegressionTest.java	2006-03-07
01:02:10 UTC (rev 5023)
+++
branches/branch_5_1/connector-j/src/testsuite/regression/StatementRegressionTest.java	2006-03-07
20:01:06 UTC (rev 5024)
@@ -3038,4 +3038,45 @@
 		}
 	}
 
+	/**
+	 * Tests fix for BUG#18041 - Server-side prepared statements
+	 * don't cause truncation exceptions to be thrown.
+	 * 
+	 * @throws Exception if the test fails
+	 */
+	public void testBug18041() throws Exception {
+		if (versionMeetsMinimum(4, 1)) {
+			createTable("testBug18041", "(`a` tinyint(4) NOT NULL,"
+					+ "`b` char(4) default NULL)");
+	
+			Properties props = new Properties();
+			props.setProperty("jdbcCompliantTruncation", "true");
+			props.setProperty("useServerPrepStmts", "true");
+	
+			Connection truncConn = null;
+			PreparedStatement stm = null;
+			
+			try {
+				truncConn = getConnectionWithProps(props);
+	
+				stm = truncConn
+					.prepareStatement("insert into testBug18041 values (?,?)");
+				stm.setInt(1, 1000);
+				stm.setString(2, "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn");
+				stm.executeUpdate();
+				fail("Truncation exception should have been thrown");
+			} catch (DataTruncation truncEx) {
+				// we expect this
+			} finally {
+				if (stmt != null) {
+					stmt.close();
+				}
+				
+				if (truncConn != null) {
+					truncConn.close();
+				}
+			}
+		}	
+	}
+
 }

Thread
Connector/J commit: r5024 - in branches: branch_3_1/connector-j branch_3_1/connector-j/src/com/mysql/jdbc branch_3_1/connector-j/src/testsuite/regress...mmatthews7 Mar