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 2004/11/01 08:13:22 UTC

svn commit: rev 56215 - incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda

Author: kmarsden
Date: Sun Oct 31 23:13:21 2004
New Revision: 56215

Modified:
   incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java
   incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
Log:
Fix for derby-5. Instead of clearing buffer, just clear back to appropriate point if query fails. Sumbitting for Army Brown (army@golux.com)



Modified: incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java
==============================================================================
--- incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java	(original)
+++ incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java	Sun Oct 31 23:13:21 2004
@@ -90,7 +90,13 @@
 
 	// Whether or not the current DSS is a continuation DSS.
 	private boolean isContinuationDss;
-	
+
+	// In situations where we want to "mark" a buffer location so that
+	// we can "back-out" of a write to handle errors, this holds the
+	// location within the "bytes" array of the start of the header
+	// that immediately precedes the mark.
+	private int lastDSSBeforeMark;
+
 	// Constructors
 	DDMWriter (int minSize, CcsidManager ccsidManager, DRDAConnThread agent, DssTrace dssTrace)
 	{
@@ -101,6 +107,7 @@
 		this.previousCorrId = DssConstants.CORRELATION_ID_UNKNOWN;
 		this.previousChainByte = DssConstants.DSS_NOCHAIN;
 		this.isContinuationDss = false;
+		this.lastDSSBeforeMark = -1;
 		reset(dssTrace);
 	}
 
@@ -113,6 +120,7 @@
 		this.previousCorrId = DssConstants.CORRELATION_ID_UNKNOWN;
 		this.previousChainByte = DssConstants.DSS_NOCHAIN;
 		this.isContinuationDss = false;
+		this.lastDSSBeforeMark = -1;
 		reset(dssTrace);
 	}
 
@@ -1808,6 +1816,59 @@
 					"OutputStream.flush()",
 					e.getMessage(),"*");
 			}
+		}
+
+	}
+
+	/**
+	 * Takes note of the location of the most recently completed
+	 * DSS in the buffer, and then returns the current offset.
+	 * This method is used in conjunction with "clearDSSesBackToMark"
+	 * to allow for DRDAConnThread to "back-out" DSSes in the
+	 * event of errors.
+	 */
+	protected int markDSSClearPoint()
+	{
+
+		lastDSSBeforeMark = prevHdrLocation;
+		return getOffset();
+
+	}
+
+	/**
+	 * Does a logical "clear" of everything written to the buffer after
+	 * the received mark.  It's assumed that this method will be used
+	 * in error cases when we've started writing one or more DSSes,
+	 * but then hit an error and need to back out.  After backing out,
+	 * we'll always need to write _something_ back to the client to
+	 * indicate an error (typically, we just write an SQLCARD) but what
+	 * exactly gets written is handled in DRDAConnThread.  Here, we
+	 * just do the necessary prep so that whatever comes next will
+	 * succeed.
+	 */
+	protected void clearDSSesBackToMark(int mark)
+	{
+
+		// Logical clear.
+		setOffset(mark);
+
+		// Because we've just cleared out the most recently-
+		// written DSSes, we have to make sure the next thing
+		// we write will have the correct correlation id.  We
+		// do this by setting the value of 'nextCorrelationID'
+		// based on the chaining byte from the last remaining
+		// DSS (where "remaining" means that it still exists
+		// in the buffer after the clear).
+		if (lastDSSBeforeMark == -1)
+		// we cleared out the entire buffer; reset corr id.
+			nextCorrelationID = 1;
+		else {
+		// last remaining DSS had chaining, so we set "nextCorrelationID"
+		// to be 1 greater than whatever the last remaining DSS had as
+		// its correlation id.
+ 			nextCorrelationID = 1 + (int)
+				(((bytes[lastDSSBeforeMark + 4] & 0xff) << 8) +
+				(bytes[lastDSSBeforeMark + 5] & 0xff));
 		}
 
 	}

Modified: incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
==============================================================================
--- incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java	(original)
+++ incubator/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java	Sun Oct 31 23:13:21 2004
@@ -558,6 +558,7 @@
 		{
 			correlationID = reader.readDssHeader();
 			int codePoint = reader.readLengthAndCodePoint();
+			int writerMark = writer.markDSSClearPoint();
 			switch(codePoint)
 			{
 				case CodePoint.CNTQRY:
@@ -581,7 +582,7 @@
  						{
 							// if we got a SQLException we need to clean up and
  							// close the statement Beetle 4758
-							writer.clearBuffer();
+							writer.clearDSSesBackToMark(writerMark);
  							if (! stmt.rsIsClosed())
  							{
  								try {
@@ -626,6 +627,7 @@
 							null, updateCount, true, true);
 					} catch (SQLException e)
 					{
+						writer.clearDSSesBackToMark(writerMark);
 						writeSQLCARDs(e, 0);
 						errorInChain(e);
 					}
@@ -643,6 +645,7 @@
 					}
 					catch (SQLException e)
 					{
+						writer.clearDSSesBackToMark(writerMark);
 						writeSQLCARDs(e, 0);
 						errorInChain(e);
 					}
@@ -663,6 +666,7 @@
 
 					} catch (SQLException e)
 					{
+						writer.clearDSSesBackToMark(writerMark);
 						writeSQLCARDs(e, 0, true);
 						PRPSQLSTTfailed = true;
 						errorInChain(e);
@@ -702,13 +706,9 @@
 					}
 					catch (SQLException e)
 					{
+						writer.clearDSSesBackToMark(writerMark);
 						try {
 							// Try to cleanup if we hit an error.
-							// We me have written all or part of
-							// OPNQRYRM and/or QRYDSC before hitting
-							// the error, so we have to clear the write
-							// buffer and ONLY write the OPNQLFRM.
-							writer.clearBuffer();
 							if (ps != null)
 								ps.close();
 							writeOPNQFLRM(e);
@@ -735,6 +735,7 @@
 					}
 					catch (SQLException e)
 					{
+						writer.clearDSSesBackToMark(writerMark);
 						// Even in case of error, we have to write the ENDUOWRM.
 						writeENDUOWRM(COMMIT);
 						writeSQLCARDs(e, 0);
@@ -756,6 +757,7 @@
 					}
 					catch (SQLException e)
 					{
+						writer.clearDSSesBackToMark(writerMark);
 						// Even in case of error, we have to write the ENDUOWRM.
 						writeENDUOWRM(ROLLBACK);
 						writeSQLCARDs(e, 0);
@@ -770,6 +772,7 @@
 					}
 					catch (SQLException e)
 					{
+						writer.clearDSSesBackToMark(writerMark);
 						writeSQLCARDs(e, 0);
 						errorInChain(e);
 					}
@@ -811,6 +814,7 @@
 						
 					} catch (SQLException e)
 					{
+						writer.clearDSSesBackToMark(writerMark);
 						server.consoleExceptionPrint(e);
 						try {
 							writeSQLDARD(database.getCurrentStatement(), true, e);
@@ -835,6 +839,7 @@
 							curStmt.rsSuspend();
 					} catch (SQLException e)
 					{
+						writer.clearDSSesBackToMark(writerMark);
 						if (SanityManager.DEBUG) 
 						{
 							server.consoleExceptionPrint(e);