You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by km...@apache.org on 2007/10/02 01:13:39 UTC

svn commit: r581109 - in /db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda: DRDAConnThread.java DRDAStatement.java

Author: kmarsden
Date: Mon Oct  1 16:13:38 2007
New Revision: 581109

URL: http://svn.apache.org/viewvc?rev=581109&view=rev
Log:
DERBY-3085   Derby
Fails to handle BLOB fields with a PreparedStatement with size >32750 bytes

port from trunk


Modified:
    db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
    db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAStatement.java

Modified: db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?rev=581109&r1=581108&r2=581109&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (original)
+++ db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java Mon Oct  1 16:13:38 2007
@@ -4527,6 +4527,7 @@
 							if (stream==null) {
 								ps.setBytes(i+1, null);
 							} else {
+								stmt.setStreamedParameter(stream);
 								ps.setBinaryStream(i+1, stream, (int) stream.getLength());
 							}
 							

Modified: db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAStatement.java?rev=581109&r1=581108&r2=581109&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAStatement.java (original)
+++ db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAStatement.java Mon Oct  1 16:13:38 2007
@@ -21,6 +21,7 @@
 
 package org.apache.derby.impl.drda;
 
+import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -106,6 +107,12 @@
 	 * of Integer/Byte in order to re-use the same storage each time
 	 * the statement is executed. */
 	private static class DrdaParamState {
+		// The last parameter may be streamed. 
+		// We need to keep a record of it so we can drain it if it is not 
+		// used.
+		// Only the last parameter with an EXTDTA will be streamed. 
+		//(See DRDAConnThread.readAndSetAllExtParams()). 
+		private EXTDTAReaderInputStream streamedParameter = null;
 		private int typeLstEnd_ = 0;
 		private byte[] typeLst_ = new byte[10];
 		private int[]  lenLst_ = new int[10];
@@ -130,6 +137,7 @@
 		 * @param trim - if true; release excess storage
 		 */
 		protected void clear(boolean trim) {
+			streamedParameter = null;
 			typeLstEnd_ = 0;
 			extLstEnd_ = 0;
 			if (trim && typeLst_.length > 10) {
@@ -221,6 +229,33 @@
 		 * of the ith external parameter (zero-based)
 		 */
 		protected int getExtPos(int i) { return extLst_[i]; }
+        
+		/**
+		 * Read the rest of the streamed parameter if not consumed
+		 * by the executing statement.  DERBY-3085
+		 * @throws IOException
+		 */
+		protected void drainStreamedParameter() throws IOException
+		{
+			if (streamedParameter != null)
+			{   
+				// we drain the buffer 1000 bytes at a time.
+				// 1000 is just a random selection that doesn't take
+				// too much memory. Perhaps something else would be 
+				// more efficient?
+				byte[] buffer = new byte[1000];
+				int i;
+				do {
+					i= streamedParameter.read(buffer,0,1000);
+				}  while (i != -1);
+			}
+		}
+            
+
+		public void setStreamedParameter(EXTDTAReaderInputStream eis) {
+			streamedParameter = eis;    
+		}
+		
 	}
 	private DrdaParamState drdaParamState_ = new DrdaParamState();
 
@@ -676,7 +711,16 @@
 	protected boolean execute() throws SQLException
 	{
 		boolean hasResultSet = ps.execute();
-
+		// DERBY-3085 - We need to make sure we drain the streamed parameter
+		// if not used by the server, for example if an update statement does not 
+		// update any rows, the parameter won't be used.  Network Server will
+		// stream only the last parameter with an EXTDTA. This is stored when the
+		// parameter is set and drained now after statement execution if needed.
+		try {
+			drdaParamState_.drainStreamedParameter();
+		} catch (IOException e) { 
+			Util.javaException(e);
+		}
 		// java.sql.Statement says any result sets that are opened
 		// when the statement is re-executed must be closed; this
 		// is handled by the call to "ps.execute()" above--but we
@@ -1270,6 +1314,11 @@
 		drdaParamState_.addDrdaParam(t, l);
 	}
 
+    protected void setStreamedParameter(EXTDTAReaderInputStream eis)
+    {
+        drdaParamState_.setStreamedParameter(eis);
+    }
+    
 	/**
 	 * get parameter DRDAType
 	 *