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 be...@apache.org on 2006/06/02 16:25:49 UTC

svn commit: r411167 - in /db/derby/code/trunk/java: client/org/apache/derby/client/net/ drda/org/apache/derby/impl/drda/ testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/

Author: bernt
Date: Fri Jun  2 07:25:48 2006
New Revision: 411167

URL: http://svn.apache.org/viewvc?rev=411167&view=rev
Log:
DERBY-1313: SUR: Use DRDA's extended diagnostic to send ROW_UPDATED and ROW_DELETED warnings. Submitted by Fernanda Pizzorno

Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/net/CodePoint.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/CodePoint.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURQueryMixTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURTest.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/CodePoint.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/CodePoint.java?rev=411167&r1=411166&r2=411167&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/CodePoint.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/CodePoint.java Fri Jun  2 07:25:48 2006
@@ -153,6 +153,15 @@
     // upon SQLSTATE 02000.
     static final int QRYCLSIMP_NO = 0x02;
 
+    // SQL Error Diagnostic Level
+    // DIAGLVL0 A null SQLDIAGGRP is returned. This is the default.
+    // DIAGLVL1 A non-null SQLDIAGGRP should be returned.
+    // DIAGLVL2 A non-null SQLDIAGGRP should be returned, and both SQLDCMSG
+    // message text fields should be returned as null strings.
+    static final byte DIAGLVL0 = (byte)0xF0;
+    static final byte DIAGLVL1 = (byte)0xF1;
+    static final byte DIAGLVL2 = (byte)0xF2;
+
     // ----------------------ddm code points--------------------------------------
 
     // Exchange Server Attributes.
@@ -484,6 +493,9 @@
 
     // XA Manager
     static final int XAMGR = 0x1C01;
+
+    // SQL Error Diagnostic Level
+    static final int DIAGLVL = 0x2160;
 
     //-----------------------DDM reply codepoints---------------------------------
 

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java?rev=411167&r1=411166&r2=411167&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java Fri Jun  2 07:25:48 2006
@@ -395,6 +395,9 @@
                 typdef.isCcsidMbcSet(),
                 typdef.getCcsidMbc());
 
+        // This specifies the SQL Error Diagnostic Level
+        buildDIAGLVL();
+
         // RDB allow update is an optional parameter which indicates
         // whether the RDB allows the requester to perform update operations
         // in the RDB.  If update operations are not allowed, this connection
@@ -562,6 +565,13 @@
 
         updateLengthBytes();
 
+    }
+
+    private void buildDIAGLVL() throws SqlException {
+        markLengthBytes(CodePoint.DIAGLVL);
+        
+        writeByte(CodePoint.DIAGLVL2);
+        updateLengthBytes();
     }
 
     private void buildMGRLVLLS(int agent,

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java?rev=411167&r1=411166&r2=411167&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java Fri Jun  2 07:25:48 2006
@@ -33,8 +33,6 @@
 import org.apache.derby.shared.common.reference.SQLState;
 import org.apache.derby.shared.common.sanity.SanityManager;
 
-import org.apache.derby.shared.common.reference.SQLState;
-
 public class NetCursor extends org.apache.derby.client.am.Cursor {
 
     NetResultSet netResultSet_;
@@ -138,49 +136,51 @@
         int[] columnDataComputedLength = null;
         boolean[] columnDataIsNull = null;
         boolean receivedDeleteHoleWarning = false;
+        boolean receivedRowUpdatedWarning = false;
 
         if ((position_ == lastValidBytePosition_) &&
                 (netResultSet_ != null) && (netResultSet_.scrollable_)) {
             return false;
         }
 
-        NetSqlca netSqlca = this.parseSQLCARD(qrydscTypdef_);
-
-        if (netResultSet_ != null && netResultSet_.scrollable_) {
-            if (netSqlca != null && 
-                    netSqlca.getSqlState().equals(SQLState.ROW_DELETED)) {
-                receivedDeleteHoleWarning = true;
-                netSqlca = null;
-            } else {
-                setIsUpdataDeleteHole(rowIndex, false);
-            }
-            if (netSqlca != null && 
-                    netSqlca.getSqlState().equals(SQLState.ROW_UPDATED)) {
-                setIsRowUpdated(true);
-                netSqlca = null;
-            } else {
-                setIsRowUpdated(false);
-            }
-        }
+        NetSqlca[] netSqlca = this.parseSQLCARD(qrydscTypdef_);
 
         if (netSqlca != null) {
-            int sqlcode = netSqlca.getSqlCode();
-            if (sqlcode < 0) {
-                throw new SqlException(netAgent_.logWriter_, netSqlca);
-            } else {
-                if (sqlcode > 0) {
+            for (int i=0;i<netSqlca.length; i++) {
+                int sqlcode = netSqlca[i].getSqlCode();
+                if (sqlcode < 0) {
+                    throw new SqlException(netAgent_.logWriter_, 
+                            netSqlca[i]);
+                } else {
                     if (sqlcode == SqlCode.END_OF_DATA.getCode()) {
                         setAllRowsReceivedFromServer(true);
-                        if (netResultSet_ != null && netSqlca.containsSqlcax()) {
-                            netResultSet_.setRowCountEvent(netSqlca.getRowCount(qrydscTypdef_));
+                        if (netResultSet_ != null && 
+                                netSqlca[i].containsSqlcax()) {
+                            netResultSet_.setRowCountEvent(
+                                    netSqlca[i].getRowCount(
+                                        qrydscTypdef_));
+                        }
+                    } else if (netResultSet_ != null && sqlcode > 0) {
+                        String sqlState = netSqlca[i].getSqlState();
+                        if (!sqlState.equals(SQLState.ROW_DELETED) && 
+                                !sqlState.equals(SQLState.ROW_UPDATED)) {
+                            netResultSet_.accumulateWarning(
+                                    new SqlWarning(agent_.logWriter_, 
+                                        netSqlca[i]));
+                        } else {
+                            receivedDeleteHoleWarning 
+                                    |= sqlState.equals(SQLState.ROW_DELETED);
+                            receivedRowUpdatedWarning 
+                                    |= sqlState.equals(SQLState.ROW_UPDATED);
                         }
-                    } else if (netResultSet_ != null) {
-                        netResultSet_.accumulateWarning(new SqlWarning(agent_.logWriter_, netSqlca));
                     }
                 }
             }
         }
 
+        setIsUpdataDeleteHole(rowIndex, receivedDeleteHoleWarning);
+        setIsRowUpdated(receivedRowUpdatedWarning);
+        
         // If we don't have at least one byte in the buffer for the DA null indicator,
         // then we need to send a CNTQRY request to fetch the next block of data.
         // Read the DA null indicator.
@@ -426,6 +426,28 @@
         return i;
     }
 
+    // Reads 8-bytes from the dataBuffer from the current position.
+    // If position is already at the end of the buffer, send CNTQRY to get more 
+    // data.
+    private long readFdocaLong() throws 
+            org.apache.derby.client.am.DisconnectException, SqlException {
+        if ((position_ + 8) > lastValidBytePosition_) {
+            // Check for ENDQRYRM, throw SqlException if already received one.
+            checkAndThrowReceivedEndqryrm();
+
+            // Send CNTQRY to complete the row/rowset.
+            int lastValidByteBeforeFetch = completeSplitRow();
+
+            // if lastValidBytePosition_ has not changed, and an ENDQRYRM was 
+            // received, throw a SqlException for the ENDQRYRM.
+            checkAndThrowReceivedEndqryrm(lastValidByteBeforeFetch);
+        }
+
+        long i = SignedBinary.getLong(dataBuffer_, position_);
+        position_ += 8;
+        return i;
+    }
+        
     // Reads 1-byte from the dataBuffer from the current position.
     // If position is already at the end of the buffer, send CNTQRY to get more data.
     private int readFdocaOneByte() throws org.apache.derby.client.am.DisconnectException, SqlException {
@@ -672,7 +694,7 @@
     //
     // FORMAT FOR ALL SQLAM LEVELS
     //   SQLCAGRP; GROUP LID 0x54; ELEMENT TAKEN 0(all); REP FACTOR 1
-    NetSqlca parseSQLCARD(Typdef typdef) throws org.apache.derby.client.am.DisconnectException, SqlException {
+    NetSqlca[] parseSQLCARD(Typdef typdef) throws org.apache.derby.client.am.DisconnectException, SqlException {
         return parseSQLCAGRP(typdef);
     }
 
@@ -691,7 +713,7 @@
     //   SQLERRPROC; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 8
     //   SQLCAXGRP; PROTOCOL TYPE N-GDA; ENVLID 0x52; Length Override 0
     //   SQLDIAGGRP; PROTOCOL TYPE N-GDA; ENVLID 0x56; Length Override 0
-    private NetSqlca parseSQLCAGRP(Typdef typdef) throws org.apache.derby.client.am.DisconnectException, SqlException {
+    private NetSqlca[] parseSQLCAGRP(Typdef typdef) throws org.apache.derby.client.am.DisconnectException, SqlException {
         if (readFdocaOneByte() == CodePoint.NULLDATA) {
             return null;
         }
@@ -702,9 +724,18 @@
 
         parseSQLCAXGRP(typdef, netSqlca);
 
-        parseSQLDIAGGRP();
+        NetSqlca[] sqlCa = parseSQLDIAGGRP();
 
-        return netSqlca;
+        NetSqlca[] ret_val;
+        if (sqlCa != null) {
+            ret_val = new NetSqlca[sqlCa.length + 1];
+            System.arraycopy(sqlCa, 0, ret_val, 1, sqlCa.length);
+        } else {
+            ret_val = new NetSqlca[1];
+        }
+        ret_val[0] = netSqlca;
+        
+        return ret_val;
     }
 
     // SQLCAXGRP : EARLY FDOCA GROUP
@@ -794,14 +825,154 @@
     }
 
     // SQLDIAGGRP : FDOCA EARLY GROUP
-    private void parseSQLDIAGGRP() throws DisconnectException, SqlException {
+    private NetSqlca[] parseSQLDIAGGRP() throws DisconnectException, SqlException {
+        if (readFdocaOneByte() == CodePoint.NULLDATA) {
+            return null;
+        }
+
+        parseSQLDIAGSTT();
+        NetSqlca[] sqlca = parseSQLDIAGCI();
+        parseSQLDIAGCN();
+
+        return sqlca;
+    }
+
+    // SQL Diagnostics Statement Group Description - Identity 0xD3
+    // NULLDATA will be received for now
+    private void parseSQLDIAGSTT() throws DisconnectException, SqlException {
+        if (readFdocaOneByte() == CodePoint.NULLDATA) {
+            return;
+        }
+
+        // The server should send NULLDATA
+        netAgent_.accumulateChainBreakingReadExceptionAndThrow(
+                new DisconnectException(netAgent_, 
+                    new ClientMessageId(SQLState.DRDA_COMMAND_NOT_IMPLEMENTED),
+                    "parseSQLDIAGSTT"));
+    }
+
+    // SQL Diagnostics Condition Information Array - Identity 0xF5
+    // SQLNUMROW; ROW LID 0x68; ELEMENT TAKEN 0(all); REP FACTOR 1
+    // SQLDCIROW; ROW LID 0xE5; ELEMENT TAKEN 0(all); REP FACTOR 0(all)
+    private NetSqlca[] parseSQLDIAGCI() 
+            throws DisconnectException, SqlException {
+        int num = readFdocaTwoByteLength(); // SQLNUMGRP - SQLNUMROW
+        NetSqlca[] ret_val = null;
+        if (num != 0) {
+            ret_val = new NetSqlca[num];
+        } 
+
+        for (int i = 0; i < num; i++) {
+            ret_val[i] = parseSQLDCROW();
+        }
+        return ret_val;
+    }
+
+    // SQL Diagnostics Connection Array - Identity 0xF6
+    // NULLDATA will be received for now
+    private void parseSQLDIAGCN() throws DisconnectException, SqlException {
+        if (readFdocaOneByte() == CodePoint.NULLDATA) {
+            return;
+        }
+        
+        // The server should send NULLDATA
+        netAgent_.accumulateChainBreakingReadExceptionAndThrow(
+                new DisconnectException(netAgent_, 
+                    new ClientMessageId(SQLState.DRDA_COMMAND_NOT_IMPLEMENTED),
+                    "parseSQLDIAGCN"));
+    }
+
+    // SQL Diagnostics Condition Group Description
+    //
+    // SQLDCCODE; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+    // SQLDCSTATE; PROTOCOL TYPE FCS; ENVLID Ox30; Lengeh Override 5
+    // SQLDCREASON; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+    // SQLDCLINEN; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+    // SQLDCROWN; PROTOCOL TYPE I8; ENVLID 0x16; Lengeh Override 8
+    // SQLDCER01; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+    // SQLDCER02; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+    // SQLDCER03; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+    // SQLDCER04; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+    // SQLDCPART; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+    // SQLDCPPOP; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+    // SQLDCMSGID; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 10
+    // SQLDCMDE; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 8
+    // SQLDCPMOD; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 5
+    // SQLDCRDB; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255
+    // SQLDCTOKS; PROTOCOL TYPE N-RLO; ENVLID 0xF7; Length Override 0
+    // SQLDCMSG_m; PROTOCOL TYPE NVMC; ENVLID 0x3F; Length Override 32672
+    // SQLDCMSG_S; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 32672
+    // SQLDCCOLN_m; PROTOCOL TYPE NVCM ; ENVLID 0x3F; Length Override 255
+    // SQLDCCOLN_s; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
+    // SQLDCCURN_m; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
+    // SQLDCCURN_s; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
+    // SQLDCPNAM_m; PROTOCOL TYPE NVCM; ENVLID 0x3F; Length Override 255
+    // SQLDCPNAM_s; PROTOCOL TYPE NVCS; ENVLID 0x33; Length Override 255
+    // SQLDCXGRP; PROTOCOL TYPE N-GDA; ENVLID 0xD3; Length Override 1
+    private NetSqlca parseSQLDCGRP() 
+            throws DisconnectException, SqlException {
+        
+        int sqldcCode = readFdocaInt(); // SQLCODE
+        String sqldcState = readFdocaString(5, 
+                netAgent_.targetTypdef_.getCcsidSbcEncoding()); // SQLSTATE
+        int sqldcReason = readFdocaInt();  // REASON_CODE
+
+        skipFdocaBytes(12); // LINE_NUMBER + ROW_NUMBER
+
+        NetSqlca sqlca = new NetSqlca(netAgent_.netConnection_,
+                    sqldcCode,
+                    sqldcState,
+                    (byte[]) null);
+
+        skipFdocaBytes(49); // SQLDCER01-04 + SQLDCPART + SQLDCPPOP + SQLDCMSGID
+                            // SQLDCMDE + SQLDCPMOD + RDBNAME
+        parseSQLDCTOKS(); // MESSAGE_TOKENS
+
+        String sqldcMsg = parseVCS(qrydscTypdef_); // MESSAGE_TEXT
+
+        if (sqldcMsg != null) {
+            sqlca.setSqlerrmcBytes(sqldcMsg.getBytes(), 
+                    netAgent_.targetTypdef_.getByteOrder());
+        }
+
+        skipFdocaBytes(12);  // COLUMN_NAME + PARAMETER_NAME + EXTENDED_NAMES
+
+        parseSQLDCXGRP(); // SQLDCXGRP
+        return sqlca;
+    }
+
+    // SQL Diagnostics Condition Row - Identity 0xE5
+    // SQLDCGRP; GROUP LID 0xD5; ELEMENT TAKEN 0(all); REP FACTOR 1
+    private NetSqlca parseSQLDCROW() throws DisconnectException, SqlException {
+        return parseSQLDCGRP();
+    }
+    
+    // SQL Diagnostics Condition Token Array - Identity 0xF7
+    // NULLDATA will be received for now
+    void parseSQLDCTOKS() throws DisconnectException, SqlException {
+        if (readFdocaOneByte() == CodePoint.NULLDATA) {
+            return;
+        }
+
+        // The server should send NULLDATA
+        netAgent_.accumulateChainBreakingReadExceptionAndThrow(
+                new DisconnectException(netAgent_, 
+                    new ClientMessageId(SQLState.DRDA_COMMAND_NOT_IMPLEMENTED),
+                    "parseSQLDCTOKS"));
+    }
+
+    // SQL Diagnostics Extended Names Group Description - Identity 0xD5
+    // NULLDATA will be received for now
+    private void parseSQLDCXGRP() throws DisconnectException, SqlException {
         if (readFdocaOneByte() == CodePoint.NULLDATA) {
             return;
         }
 
-        netAgent_.accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(netAgent_,
-                new ClientMessageId(SQLState.DRDA_COMMAND_NOT_IMPLEMENTED),
-                "parseSQLDIAGGRP"));
+        // The server should send NULLDATA
+        netAgent_.accumulateChainBreakingReadExceptionAndThrow(
+                new DisconnectException(netAgent_, 
+                    new ClientMessageId(SQLState.DRDA_COMMAND_NOT_IMPLEMENTED),
+                    "parseSQLDCXGRP"));
     }
 
     private String parseVCS(Typdef typdefInEffect) throws DisconnectException, SqlException {

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/CodePoint.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/CodePoint.java?rev=411167&r1=411166&r2=411167&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/CodePoint.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/CodePoint.java Fri Jun  2 07:25:48 2006
@@ -490,6 +490,9 @@
 	// Number codepoint constant.
 	static final int PKGNAMCSN = 0x2113;
 
+	// SQL Error Diagnostic Level
+	static final int DIAGLVL = 0x2160;
+
 	//-----------------------DDM reply codepoints---------------------------------
 
 	// Invalid description
@@ -646,6 +649,15 @@
 	// in the QRYBLKSZ parameter, except for possibly the last
 	// query block which may be shorter.
 	static final int QRYBLKFLX = 0x01;
+
+	// SQL Error Diagnostic Level
+	// DIAGLVL0 A null SQLDIAGGRP is returned. This is the default.
+	// DIAGLVL1 A non-null SQLDIAGGRP should be returned.
+	// DIAGLVL2 A non-null SQLDIAGGRP should be returned, and both SQLDCMSG
+	// message text fields should be returned as null strings.
+	static final byte DIAGLVL0 = (byte)0xF0;
+	static final byte DIAGLVL1 = (byte)0xF1;
+	static final byte DIAGLVL2 = (byte)0xF2;
 	
 	//----------------------------fdoca code points-------------------------------
 

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?rev=411167&r1=411166&r2=411167&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java Fri Jun  2 07:25:48 2006
@@ -124,6 +124,9 @@
 	private Database database; 	// pointer to the current database
 	private int sqlamLevel;		// SQLAM Level - determines protocol
 
+	// DRDA diagnostic level, DIAGLVL0 by default 
+	private byte diagnosticLevel = (byte)0xF0; 
+
 	// manager processing
 	private Vector unknownManagers;
 	private Vector knownManagers;
@@ -2934,6 +2937,10 @@
 				case CodePoint.STTSTRDEL:
 					codePointNotSupported(codePoint);
 					break;
+				// optional
+				case CodePoint.DIAGLVL:
+					diagnosticLevel = reader.readByte();
+					break;
 				default:
 					invalidCodePoint(codePoint);
 			}
@@ -5554,24 +5561,27 @@
 	private void writeSQLDIAGGRP(SQLException nextException) 
 		throws DRDAProtocolException
 	{
-		writer.writeByte(CodePoint.NULLDATA);
-		return;
+		// for now we only want to send ROW_DELETED and ROW_UPDATED warnings
+		// as extended diagnostics
+		// move to first ROW_DELETED or ROW_UPDATED exception. These have been
+		// added to the end of the warning chain.
+		while (
+				nextException != null && 
+				nextException.getSQLState() != SQLState.ROW_UPDATED &&
+				nextException.getSQLState() != SQLState.ROW_DELETED) {
+			nextException = nextException.getNextException();
+		}
 
-		/**
-		 * TODO: Enable the following code when JCC can support SQLDIAGGRP
-		 * for all SQLCARD accesses. Commented out for now.
-		 */
-		/*
-		if (nextException == null)
-		{
+		if ((nextException == null) || 
+				(diagnosticLevel == CodePoint.DIAGLVL0)) {
 			writer.writeByte(CodePoint.NULLDATA);
 			return;
 		}
+		writer.writeByte(0); // SQLDIAGGRP indicator
 
 		writeSQLDIAGSTT();
 		writeSQLDIAGCI(nextException);
 		writeSQLDIAGCN();
-		*/
 	}
 
 	/*
@@ -5601,13 +5611,32 @@
 		while (se != null)
 		{
 			String sqlState = se.getSQLState();
-			int sqlCode = getSqlCode(getExceptionSeverity(se));
+
+			// SQLCode > 0 -> Warning
+			// SQLCode = 0 -> Info
+			// SQLCode < 0 -> Error
+			int severity = getExceptionSeverity(se);
+			int sqlCode = -1;
+			if (severity == CodePoint.SVRCOD_WARNING)
+				sqlCode = 1;
+			else if (severity == CodePoint.SVRCOD_INFO)
+				sqlCode = 0;
+
 			String sqlerrmc = "";
-				
+			if (diagnosticLevel == CodePoint.DIAGLVL1) {
+				sqlerrmc = se.getLocalizedMessage();
+			}
+
 			// arguments are variable part of a message
-			Object[] args = ((EmbedSQLException)se).getArguments();
-			for (int i = 0; args != null &&  i < args.length; i++)
-				sqlerrmc += args[i].toString() + SQLERRMC_TOKEN_DELIMITER;
+			// only send arguments for diagnostic level 0
+			if (diagnosticLevel == CodePoint.DIAGLVL0) {
+				// we are only able to get arguments of EmbedSQLException
+				if (se instanceof EmbedSQLException) {
+					Object[] args = ((EmbedSQLException)se).getArguments();
+					for (int i = 0; args != null &&  i < args.length; i++)
+						sqlerrmc += args[i].toString() + SQLERRMC_TOKEN_DELIMITER;
+				}
+			}
 
 			String dbname = null;
 			if (database != null)
@@ -5618,7 +5647,6 @@
 			se = se.getNextException();
 		}
 			
-		writer.writeByte(CodePoint.NULLDATA);
 		return;
 	}
 
@@ -5648,7 +5676,7 @@
 
 		/* Count the number of chained exceptions to be sent */
 		for (se = nextException; se != null; se = se.getNextException()) i++;
-		writer.writeInt(i);
+		writer.writeShort(i);
 	}
 
 	/**
@@ -6211,26 +6239,29 @@
 			SQLWarning sqlw = (rs != null)? rs.getWarnings(): null;
 
 			// for updatable, insensitive result sets we signal the
-			// row updated condition to the client via a warning which
-			// is pushed on top of any other warnings on the result
-			// set, to be popped by client onto its rowUpdated state,
-			// i.e.  this warning should not reach API level.
+			// row updated condition to the client via a warning to be 
+			// popped by client onto its rowUpdated state, i.e. this 
+			// warning should not reach API level.
 			if (rs != null && rs.rowUpdated()) {
-				SQLWarning w = new SQLWarning(null, SQLState.ROW_UPDATED);
+				SQLWarning w = new SQLWarning(null, SQLState.ROW_UPDATED,
+						ExceptionSeverity.WARNING_SEVERITY);
 				if (sqlw != null) {
-					w.setNextWarning(sqlw);
-				} 
-				sqlw = w;
+					sqlw.setNextWarning(w);
+				} else {
+					sqlw = w;
+				}
 			}
 			// Delete holes are manifest as a row consisting of a non-null
 			// SQLCARD and a null data group. The SQLCARD has a warning
 			// SQLSTATE of 02502
 			if (rs != null && rs.rowDeleted()) {
-				SQLWarning w = new SQLWarning(null, SQLState.ROW_DELETED);
+				SQLWarning w = new SQLWarning(null, SQLState.ROW_DELETED,
+						ExceptionSeverity.WARNING_SEVERITY);
 				if (sqlw != null) {
-					w.setNextWarning(sqlw);
-				} 
-				sqlw = w;
+					sqlw.setNextWarning(w);
+				} else {
+					sqlw = w;
+				}
 			}
 
 			if (sqlw == null)

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURQueryMixTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURQueryMixTest.java?rev=411167&r1=411166&r2=411167&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURQueryMixTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURQueryMixTest.java Fri Jun  2 07:25:48 2006
@@ -364,8 +364,7 @@
                              "forward.", rows.get(new Integer(i)), rowString);
                 
                 
-                if (checkRowUpdated && updatedRows.contains(new Integer(i)) &&
-                        !deletedRows.contains(new Integer(i))) {
+                if (checkRowUpdated && updatedRows.contains(new Integer(i))) {
                     assertTrue("Expected rs.rowUpdated() to return true on " + 
                                "updated row " + rowString, rs.rowUpdated());
                 } 
@@ -385,8 +384,7 @@
                          " when navigating forward.", 
                          rows.get(new Integer(i)),
                          rowString);
-            if (checkRowUpdated && updatedRows.contains(new Integer(i)) &&
-                    !deletedRows.contains(new Integer(i))) {
+            if (checkRowUpdated && updatedRows.contains(new Integer(i))) {
                 assertTrue("Expected rs.rowUpdated() to return true on " +
                            "updated row " + rowString, rs.rowUpdated());
             }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURTest.java?rev=411167&r1=411166&r2=411167&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURTest.java Fri Jun  2 07:25:48 2006
@@ -1258,6 +1258,36 @@
 
 
     /**
+     * Test that rowUpdated() and rowDeleted() methods both return true when
+     * the row has first been updated and then deleted using the updateRow()
+     * and deleteRow() methods.
+     */
+    public void testRowUpdatedAndRowDeleted() throws SQLException {
+        Statement s = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 
+                                           ResultSet.CONCUR_UPDATABLE);
+        s.setCursorName(getNextCursorName());
+        ResultSet rs = s.executeQuery("select a,b from t1");
+        rs.next();
+        rs.updateInt(1, rs.getInt(1) + 2 * recordCount);
+        rs.updateRow();
+        assertTrue("Expected rowUpdated() to return true", rs.rowUpdated());
+        rs.deleteRow();
+        rs.next();
+        rs.previous();
+        assertTrue("Expected rowUpdated() to return true", rs.rowUpdated());
+        assertTrue("Expected rowDeleted() to return true", rs.rowDeleted());
+        rs.next();
+        assertFalse("Expected rowUpdated() to return false", rs.rowUpdated());
+        assertFalse("Expected rowDeleted() to return false", rs.rowDeleted());
+        rs.previous();
+        assertTrue("Expected rowUpdated() to return true", rs.rowUpdated());
+        assertTrue("Expected rowDeleted() to return true", rs.rowDeleted());
+        rs.close();
+        s.close();
+    }
+
+
+    /**
      * Test that the JDBC detectability calls throw correct exceptions when
      * called in in wrong row states. 
      * This is done for both supported updatable result set types.