Index: java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
===================================================================
--- java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java	(revision 406138)
+++ java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java	(working copy)
@@ -2132,6 +2132,9 @@
 	 */
 	public boolean rowUpdated() throws SQLException {
 		checkIfClosed("rowUpdated");
+		checkNotOnInsertRow();
+		checkOnRow();
+
         boolean rvalue = false;
 
 		try {
@@ -2159,6 +2162,9 @@
 	 */
 	public boolean rowInserted() throws SQLException {
 		checkIfClosed("rowInserted");
+		checkNotOnInsertRow();
+		checkOnRow();
+
 		return false;
 	}
 
@@ -2178,6 +2184,9 @@
 	 */
 	public boolean rowDeleted() throws SQLException {
 		checkIfClosed("rowUpdated");
+		checkNotOnInsertRow();
+		checkOnRow();
+
         boolean rvalue = false;
 
 		try {
Index: java/testing/org/apache/derbyTesting/functionTests/tests/lang/updatableResultSet.java
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/tests/lang/updatableResultSet.java	(revision 406138)
+++ java/testing/org/apache/derbyTesting/functionTests/tests/lang/updatableResultSet.java	(working copy)
@@ -971,7 +971,6 @@
       System.out.println("Since Derby returns false for detlesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowDeleted() for FORWARD_ONLY updatable resultsets");
       System.out.println("Have this call to rs.rowDeleted() just to make sure the method does always return false? " + rs.rowDeleted());
 			rs.deleteRow();
-      System.out.println("Have this call to rs.rowDeleted() just to make sure the method does always return false? " + rs.rowDeleted());
 			rs.close();
 
 			System.out.println("Positive Test6b - For Forward Only resultsets, DatabaseMetaData will return false for ownUpdatesAreVisible and updatesAreDetected");
@@ -989,7 +988,6 @@
 			System.out.println("Have this call to rs.rowUpdated() just to make sure the method does always return false? " + rs.rowUpdated());
 			rs.updateLong(1,123);
 			rs.updateRow();
-			System.out.println("Have this call to rs.rowUpdated() just to make sure the method does always return false? " + rs.rowUpdated());
 			rs.close();
 
 			System.out.println("Positive Test7a - delete using updatable resultset api from a temporary table");
Index: java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURTest.java
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURTest.java	(revision 406138)
+++ java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURTest.java	(working copy)
@@ -27,6 +27,9 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import java.util.Iterator;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
 /**
  * Tests for variants of scrollable updatable resultsets.
  *
@@ -849,6 +852,117 @@
     }
     
     /**
+     * Check that detectability methods throw the correct exception
+     * when called in an illegal row state, that is, somehow not
+     * positioned on a row. Minion of testDetectabilityExceptions.
+     *
+     * @param rs An open updatable result set.
+     * @param state A string describing the illegal state.
+     * @return No return value.
+     */
+    private void checkDetectabilityCallsOutsideRow(ResultSet rs, 
+                                                   String state)
+    {
+        try {
+            // Use reflection just for fun ;)
+            Method[] methods =
+                {ResultSet.class.getMethod("rowUpdated", null),
+                 ResultSet.class.getMethod("rowInserted", null),
+                 ResultSet.class.getMethod("rowDeleted", null)};
+
+            for (int i=0; i < methods.length; i++) {
+                try {
+                    try {
+                        methods[i].invoke(rs, null);
+                    } catch (InvocationTargetException e) {
+                        Throwable ex = e.getTargetException();
+                        throw ex;
+                    }
+                    fail(methods[i].getName() + " while " + state + 
+                         " did not throw exception");
+                } catch (SQLException e) {
+                    assertEquals(e.getSQLState(),
+                                 INVALID_CURSOR_STATE_NO_CURRENT_ROW);
+                }
+            }
+        } catch (Throwable e) {
+            fail("test error: " + e);
+        }
+    }
+
+
+    /**
+     * 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.
+     */
+    public void testDetectabilityExceptions() throws SQLException 
+    {
+        Statement s = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 
+                                          ResultSet.CONCUR_UPDATABLE);
+        ResultSet rs = s.executeQuery("select * from t1");
+        
+        checkDetectabilityCallsOutsideRow(rs, "before positioning");
+
+        rs.moveToInsertRow();
+        checkDetectabilityCallsOutsideRow(rs, 
+                                          "on insertRow before positioning");
+
+        rs.next();
+        rs.moveToInsertRow();
+        checkDetectabilityCallsOutsideRow(rs, "on insertRow");
+        rs.moveToCurrentRow(); // needed until to DERBY-1322 is fixed
+
+        rs.beforeFirst();
+        checkDetectabilityCallsOutsideRow(rs, "on beforeFirst row");
+
+        rs.afterLast();
+        checkDetectabilityCallsOutsideRow(rs, "on afterLast row");
+
+        rs.first();
+        rs.deleteRow();
+        checkDetectabilityCallsOutsideRow(rs, "after deleteRow");
+
+        rs.last();
+        rs.deleteRow();
+        checkDetectabilityCallsOutsideRow(rs, "after deleteRow of last row");
+
+        rs.close();
+        s.close();
+
+        // Not strictly SUR, but fixed in same patch, so we test it here.
+        s = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                                ResultSet.CONCUR_UPDATABLE);
+        rs = s.executeQuery("select * from t1");
+
+        checkDetectabilityCallsOutsideRow(rs, "before FO positioning");
+
+        rs.moveToInsertRow();
+        checkDetectabilityCallsOutsideRow(rs, 
+                                          "on insertRow before FO positioning");
+
+        rs.next();
+        rs.moveToInsertRow();
+        checkDetectabilityCallsOutsideRow(rs, "on FO insertRow");
+
+        rs.next();
+        rs.updateInt(2, 666);
+        rs.updateRow();
+        checkDetectabilityCallsOutsideRow(rs, "after FO updateRow");
+
+        rs.next();
+        rs.deleteRow();
+        checkDetectabilityCallsOutsideRow(rs, "after FO deleteRow");
+
+        while (rs.next()) {};
+        checkDetectabilityCallsOutsideRow(rs, "after FO emptied out");
+
+        rs.close();
+        s.close();
+    }
+
+
+    /**
      * Get a cursor name. We use the same cursor name for all cursors.
      */
     private final String getNextCursorName() {
Index: java/testing/org/apache/derbyTesting/functionTests/master/jdk14/updatableResultSet.out
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/master/jdk14/updatableResultSet.out	(revision 406138)
+++ java/testing/org/apache/derbyTesting/functionTests/master/jdk14/updatableResultSet.out	(working copy)
@@ -221,7 +221,6 @@
 The JDBC program should look at rowDeleted only if deletesAreDetected returns true
 Since Derby returns false for detlesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowDeleted() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowDeleted() just to make sure the method does always return false? false
-Have this call to rs.rowDeleted() just to make sure the method does always return false? false
 Positive Test6b - For Forward Only resultsets, DatabaseMetaData will return false for ownUpdatesAreVisible and updatesAreDetected
 This is because, after updateRow, we position the ResultSet before the next row
 ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)? false
@@ -230,7 +229,6 @@
 The JDBC program should look at rowUpdated only if updatesAreDetected returns true
 Since Derby returns false for updatesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowUpdated() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowUpdated() just to make sure the method does always return false? false
-Have this call to rs.rowUpdated() just to make sure the method does always return false? false
 Positive Test7a - delete using updatable resultset api from a temporary table
 following rows in temp table before deleteRow
 	 C21,C22
Index: java/testing/org/apache/derbyTesting/functionTests/master/j9_13/updatableResultSet.out
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/master/j9_13/updatableResultSet.out	(revision 406138)
+++ java/testing/org/apache/derbyTesting/functionTests/master/j9_13/updatableResultSet.out	(working copy)
@@ -216,7 +216,6 @@
 The JDBC program should look at rowDeleted only if deletesAreDetected returns true
 Since Derby returns false for detlesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowDeleted() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowDeleted() just to make sure the method does always return false? false
-Have this call to rs.rowDeleted() just to make sure the method does always return false? false
 Positive Test6b - For Forward Only resultsets, DatabaseMetaData will return false for ownUpdatesAreVisible and updatesAreDetected
 This is because, after updateRow, we position the ResultSet before the next row
 ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)? false
@@ -225,7 +224,6 @@
 The JDBC program should look at rowUpdated only if updatesAreDetected returns true
 Since Derby returns false for updatesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowUpdated() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowUpdated() just to make sure the method does always return false? false
-Have this call to rs.rowUpdated() just to make sure the method does always return false? false
 Positive Test7a - delete using updatable resultset api from a temporary table
 following rows in temp table before deleteRow
 	 C21,C22
Index: java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/updatableResultSet.out
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/updatableResultSet.out	(revision 406138)
+++ java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/updatableResultSet.out	(working copy)
@@ -222,7 +222,6 @@
 The JDBC program should look at rowDeleted only if deletesAreDetected returns true
 Since Derby returns false for detlesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowDeleted() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowDeleted() just to make sure the method does always return false? false
-Have this call to rs.rowDeleted() just to make sure the method does always return false? false
 Positive Test6b - For Forward Only resultsets, DatabaseMetaData will return false for ownUpdatesAreVisible and updatesAreDetected
 This is because, after updateRow, we position the ResultSet before the next row
 ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)? false
@@ -231,7 +230,6 @@
 The JDBC program should look at rowUpdated only if updatesAreDetected returns true
 Since Derby returns false for updatesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowUpdated() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowUpdated() just to make sure the method does always return false? false
-Have this call to rs.rowUpdated() just to make sure the method does always return false? false
 Positive Test7a - delete using updatable resultset api from a temporary table
 following rows in temp table before deleteRow
 	 C21,C22
Index: java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/updatableResultSet.out
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/updatableResultSet.out	(revision 406138)
+++ java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/updatableResultSet.out	(working copy)
@@ -222,7 +222,6 @@
 The JDBC program should look at rowDeleted only if deletesAreDetected returns true
 Since Derby returns false for detlesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowDeleted() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowDeleted() just to make sure the method does always return false? false
-Have this call to rs.rowDeleted() just to make sure the method does always return false? false
 Positive Test6b - For Forward Only resultsets, DatabaseMetaData will return false for ownUpdatesAreVisible and updatesAreDetected
 This is because, after updateRow, we position the ResultSet before the next row
 ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)? false
@@ -231,7 +230,6 @@
 The JDBC program should look at rowUpdated only if updatesAreDetected returns true
 Since Derby returns false for updatesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowUpdated() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowUpdated() just to make sure the method does always return false? false
-Have this call to rs.rowUpdated() just to make sure the method does always return false? false
 Positive Test7a - delete using updatable resultset api from a temporary table
 following rows in temp table before deleteRow
 	 C21,C22
Index: java/testing/org/apache/derbyTesting/functionTests/master/j9_foundation/updatableResultSet.out
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/master/j9_foundation/updatableResultSet.out	(revision 406138)
+++ java/testing/org/apache/derbyTesting/functionTests/master/j9_foundation/updatableResultSet.out	(working copy)
@@ -238,7 +238,6 @@
 The JDBC program should look at rowDeleted only if deletesAreDetected returns true
 Since Derby returns false for detlesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowDeleted() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowDeleted() just to make sure the method does always return false? false
-Have this call to rs.rowDeleted() just to make sure the method does always return false? false
 Positive Test6b - For Forward Only resultsets, DatabaseMetaData will return false for ownUpdatesAreVisible and updatesAreDetected
 This is because, after updateRow, we position the ResultSet before the next row
 ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)? false
@@ -247,7 +246,6 @@
 The JDBC program should look at rowUpdated only if updatesAreDetected returns true
 Since Derby returns false for updatesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowUpdated() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowUpdated() just to make sure the method does always return false? false
-Have this call to rs.rowUpdated() just to make sure the method does always return false? false
 Positive Test7a - delete using updatable resultset api from a temporary table
 following rows in temp table before deleteRow
 	 C21,C22
Index: java/testing/org/apache/derbyTesting/functionTests/master/updatableResultSet.out
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/master/updatableResultSet.out	(revision 406138)
+++ java/testing/org/apache/derbyTesting/functionTests/master/updatableResultSet.out	(working copy)
@@ -221,7 +221,6 @@
 The JDBC program should look at rowDeleted only if deletesAreDetected returns true
 Since Derby returns false for detlesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowDeleted() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowDeleted() just to make sure the method does always return false? false
-Have this call to rs.rowDeleted() just to make sure the method does always return false? false
 Positive Test6b - For Forward Only resultsets, DatabaseMetaData will return false for ownUpdatesAreVisible and updatesAreDetected
 This is because, after updateRow, we position the ResultSet before the next row
 ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)? false
@@ -230,7 +229,6 @@
 The JDBC program should look at rowUpdated only if updatesAreDetected returns true
 Since Derby returns false for updatesAreDetected for FORWARD_ONLY updatable resultset,the program should not rely on rs.rowUpdated() for FORWARD_ONLY updatable resultsets
 Have this call to rs.rowUpdated() just to make sure the method does always return false? false
-Have this call to rs.rowUpdated() just to make sure the method does always return false? false
 Positive Test7a - delete using updatable resultset api from a temporary table
 following rows in temp table before deleteRow
 	 C21,C22
Index: java/client/org/apache/derby/client/am/ResultSet.java
===================================================================
--- java/client/org/apache/derby/client/am/ResultSet.java	(revision 406138)
+++ java/client/org/apache/derby/client/am/ResultSet.java	(working copy)
@@ -2728,6 +2728,12 @@
         {
             checkForClosedResultSet();
 
+            if (isOnInsertRow_ || !isValidCursorPosition_) {
+                throw new SqlException
+                    (agent_.logWriter_, 
+                     new ClientMessageId(SQLState.NO_CURRENT_ROW));
+            }
+
             boolean rowUpdated = cursor_.getIsRowUpdated();
 
             if (agent_.loggingEnabled()) {
@@ -2746,6 +2752,13 @@
         {
             boolean rowInserted = false;
             checkForClosedResultSet();
+
+            if (isOnInsertRow_ || !isValidCursorPosition_) {
+                throw new SqlException
+                    (agent_.logWriter_, 
+                     new ClientMessageId(SQLState.NO_CURRENT_ROW));
+            }
+
             if (agent_.loggingEnabled()) {
                 agent_.logWriter_.traceExit(this, "rowInserted", rowInserted);
             }
@@ -2762,6 +2775,12 @@
         {
             checkForClosedResultSet();
 
+            if (isOnInsertRow_ || !isValidCursorPosition_) {
+                throw new SqlException
+                    (agent_.logWriter_, 
+                     new ClientMessageId(SQLState.NO_CURRENT_ROW));
+            }
+
             boolean rowDeleted = (resultSetType_ == ResultSet.TYPE_SCROLL_INSENSITIVE) ?
 		cursor_.getIsUpdateDeleteHole() :
 		false;
