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 2005/11/22 17:31:57 UTC

svn commit: r348192 - in /db/derby/code/trunk/java: client/org/apache/derby/client/am/ drda/org/apache/derby/impl/drda/ testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/ testing/org/apache/derbyTesting/functionTests/suites/ testing/o...

Author: bernt
Date: Tue Nov 22 08:31:22 2005
New Revision: 348192

URL: http://svn.apache.org/viewcvs?rev=348192&view=rev
Log:
DERBY-517 ResultSet - relative(int rows) behaves different in embedded and client/server mode when the positioning before the first row or after the last row.
Submitted by Fernanda.Pizzorno@Sun.COM

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/scrollCursors2.out
Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors2.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java?rev=348192&r1=348191&r2=348192&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java Tue Nov 22 08:31:22 2005
@@ -184,6 +184,10 @@
     // reposition the cursor before updating/deleting again.  This flag will be set to true
     // whenever a commit happens, and reset to false again after we repositoin the cursor.
     public boolean cursorUnpositionedOnServer_ = false;
+    
+    // Keep maxRows in the ResultSet, so that changes to maxRow in the statement
+    // do not affect the resultSet after it has been created
+    private int maxRows_;
 
     //---------------------constructors/finalizer---------------------------------
 
@@ -206,6 +210,8 @@
         fetchDirection_ = statement_.fetchDirection_;
         fetchSize_ = statement_.fetchSize_;
 
+        maxRows_ = statement_.maxRows_;
+        
         // Only set the warning if actual resultSetType returned by the server is less
         // than the application requested resultSetType.
         // TYPE_FORWARD_ONLY = 1003
@@ -289,7 +295,7 @@
 //    if (!isValidCursorPosition_ && // We've gone past the end (+100)
 //        cursor_ != null) {
             if ((!isValidCursorPosition_ && cursor_ != null) ||
-                    (statement_.maxRows_ > 0 && cursor_.rowsRead_ > statement_.maxRows_)) {
+                    (maxRows_ > 0 && cursor_.rowsRead_ > maxRows_)) {
                 isValidCursorPosition_ = false;
 
                 // if not on a valid row and the query is closed at the server.
@@ -359,8 +365,8 @@
         // maxRows_ will be ignored by sensitive dynamic cursors since we don't know the rowCount
         if (!openOnClient_) {
             isValidCursorPosition_ = false;
-        } else if (sensitivity_ != sensitivity_sensitive_dynamic__ && statement_.maxRows_ > 0 &&
-                (firstRowInRowset_ + currentRowInRowset_ > statement_.maxRows_)) {
+        } else if (sensitivity_ != sensitivity_sensitive_dynamic__ && maxRows_ > 0 &&
+                (firstRowInRowset_ + currentRowInRowset_ > maxRows_)) {
             isValidCursorPosition_ = false;
         }
         return isValidCursorPosition_;
@@ -1503,7 +1509,7 @@
                     (firstRowInRowset_ == currentRowInRowset_ &&
                     currentRowInRowset_ == lastRowInRowset_ &&
                     lastRowInRowset_ == 0 &&
-                    absolutePosition_ == rowCount_ + 1));
+                    absolutePosition_ == (maxRows_ == 0 ? rowCount_ + 1 : maxRows_ + 1)));
         }
     }
 
@@ -1687,9 +1693,9 @@
             getRowCount();
         }
         long row = rowCount_;
-        if (sensitivity_ != sensitivity_sensitive_dynamic__ && statement_.maxRows_ > 0) {
-            if (rowCount_ > statement_.maxRows_) {
-                row = statement_.maxRows_;
+        if (sensitivity_ != sensitivity_sensitive_dynamic__ && maxRows_ > 0) {
+            if (rowCount_ > maxRows_) {
+                row = maxRows_;
             }
         }
 
@@ -1780,14 +1786,14 @@
 
         resetRowsetFlags();
 
-        if (statement_.maxRows_ > 0) {
+        if (maxRows_ > 0) {
             // if "row" is positive and > maxRows, fetch afterLast
             // else if "row" is negative, and abs(row) > maxRows, fetch beforeFirst
-            if (row > 0 && row > statement_.maxRows_) {
+            if (row > 0 && row > maxRows_) {
                 afterLastX();
                 isValidCursorPosition_ = false;
                 return isValidCursorPosition_;
-            } else if (row <= 0 && java.lang.Math.abs(row) > statement_.maxRows_) {
+            } else if (row <= 0 && java.lang.Math.abs(row) > maxRows_) {
                 beforeFirstX();
                 isValidCursorPosition_ = false;
                 return isValidCursorPosition_;
@@ -1907,7 +1913,7 @@
         // the currentrow number, will fetch beforeFirst anyways.  do not need to check
         // for maxRows.
         if (sensitivity_ != sensitivity_sensitive_dynamic__ &&
-                statement_.maxRows_ > 0 && rows > 0 && currentAbsoluteRowNumber + rows > statement_.maxRows_) {
+                maxRows_ > 0 && rows > 0 && currentAbsoluteRowNumber + rows > maxRows_) {
             afterLastX();
             isValidCursorPosition_ = false;
             return isValidCursorPosition_;
@@ -1921,6 +1927,15 @@
             long rowNumber =
                     (sensitivity_ == sensitivity_sensitive_dynamic__) ? currentRowInRowset_ + rows :
                     currentAbsoluteRowNumber + rows - absolutePosition_;
+            if (maxRows_ < Math.abs(rowNumber) && maxRows_ != 0) {
+                if (rowNumber > 0) {
+                    afterLastX();
+                } else {
+                    beforeFirstX();
+                }
+                isValidCursorPosition_ = false;
+                return isValidCursorPosition_;
+            }
             isValidCursorPosition_ = getRelativeRowset(rowNumber);
         }
 
@@ -1979,8 +1994,8 @@
             return isValidCursorPosition_;
         }
 
-        if (sensitivity_ != sensitivity_sensitive_dynamic__ && statement_.maxRows_ > 0 &&
-                (firstRowInRowset_ + currentRowInRowset_ > statement_.maxRows_)) {
+        if (sensitivity_ != sensitivity_sensitive_dynamic__ && maxRows_ > 0 &&
+                (firstRowInRowset_ + currentRowInRowset_ > maxRows_)) {
             isValidCursorPosition_ = false;
         }
         // auto-close result set if this is the last row from server and return false
@@ -2021,7 +2036,7 @@
                 agent_.logWriter_.traceEntry(this, "setFetchSize", rows);
             }
             checkForClosedResultSet();
-            if (rows < 0 || (statement_.maxRows_ != 0 && rows > statement_.maxRows_)) {
+            if (rows < 0 || (maxRows_ != 0 && rows > maxRows_)) {
                 throw new SqlException(agent_.logWriter_, "Invalid fetch size " + rows);
             }
             setFetchSize_(rows);
@@ -2925,7 +2940,7 @@
     public void setRowsetAfterLastEvent() throws SqlException {
         firstRowInRowset_ = 0;
         lastRowInRowset_ = 0;
-        absolutePosition_ = rowCount_ + 1;
+        absolutePosition_ = (maxRows_ == 0) ? rowCount_ + 1 : maxRows_ + 1;
         currentRowInRowset_ = 0;
         rowsReceivedInCurrentRowset_ = 0;
     }
@@ -3533,14 +3548,14 @@
         if (isRowsetCursor_ && sensitivity_ != sensitivity_sensitive_dynamic__ && firstRowInRowset_ != 0) {
             absolutePosition_ = firstRowInRowset_;
         } else {
-            absolutePosition_ = rowCount_ + 1;
+            absolutePosition_ = (maxRows_ == 0) ? rowCount_ + 1 : maxRows_ + 1;
         }
     }
 
     private void flowGetRowset(int orientation, long rowNumber) throws SqlException {
         cursor_.resetDataBuffer();
         agent_.beginWriteChain(statement_);
-
+        
         writeScrollableFetch_((generatedSection_ == null) ? statement_.section_ : generatedSection_,
                 fetchSize_,
                 orientation,
@@ -3667,6 +3682,14 @@
                 rowNumber = 1;
                 orientation = scrollOrientation_absolute__;
             }
+            
+            // If afterLast and maxRows > 0, go backward from maxRows and not 
+            // from last row in the resultSet
+            if (maxRows_ > 0 && orientation == scrollOrientation_relative__ && isAfterLast) {
+                rowNumber += maxRows_ + 1;
+                orientation = scrollOrientation_absolute__;
+            }
+            
             flowGetRowset(orientation, rowNumber);
         }
 
@@ -3699,7 +3722,10 @@
             lastRowInRowset_ = rowsReceivedInCurrentRowset_;
             absolutePosition_ = (isAfterLastRow) ? lastRowInRowset_ + 1 : lastRowInRowset_;
         } else {
-            lastRowInRowset_ = (isAfterLastRow) ? rowCount_ : firstRowInRowset_ - 1;
+            if (maxRows_ == 0)
+                lastRowInRowset_ = (isAfterLastRow) ? rowCount_ : firstRowInRowset_ - 1;
+            else
+                lastRowInRowset_ = (isAfterLastRow) ? maxRows_ : firstRowInRowset_ - 1;
             firstRowInRowset_ = lastRowInRowset_ - rowsReceivedInCurrentRowset_ + 1;
             absolutePosition_ = lastRowInRowset_;
             currentRowInRowset_ = lastRowInRowset_ - firstRowInRowset_;
@@ -3822,7 +3848,12 @@
             // If fetchSize_ is smaller than the total number of rows in the ResultSet,
             // then fetch one rowset of fetchSize_ number of rows.  Otherwise, we will
             // fetch all rows in the ResultSet, so start fetching from row 1.
-            long rowNumber = (fetchSize_ < row) ? (-1) * fetchSize_ : 1;
+            long rowNumber;
+            if (maxRows_ == 0) {
+                rowNumber = (fetchSize_ < row) ? ((-1) * fetchSize_) : 1;
+            } else {
+                rowNumber = (fetchSize_ < row) ? (maxRows_ - fetchSize_) + 1 : 1;
+            }
             flowGetRowset(scrollOrientation_absolute__, rowNumber);
         }
         parseRowset_();
@@ -3845,6 +3876,9 @@
     private void adjustLastRowset(long row) {
         lastRowInRowset_ = row;
         firstRowInRowset_ = lastRowInRowset_ - rowsReceivedInCurrentRowset_ + 1;
+        if (firstRowInRowset_ <= 0) {
+            firstRowInRowset_ = 1;
+        }
         setAbsolutePositionBasedOnAllRowsReceived();
         currentRowInRowset_ = lastRowInRowset_ - firstRowInRowset_;
     }

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?rev=348192&r1=348191&r2=348192&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 Tue Nov 22 08:31:22 2005
@@ -6179,12 +6179,23 @@
 		{
 			if (stmt.isScrollable())
 			{
+                                //keep isAfterLast and isBeforeFirst to be able 
+                                //to reposition after counting rows
+                                boolean isAfterLast = rs.isAfterLast();
+                                boolean isBeforeFirst = rs.isBeforeFirst();
+                                
 				// for scrollable cursors - calculate the row count
 				// since we may not have gone through each row
 				rs.last();
 				stmt.rowCount  = rs.getRow();
-				//reposition after last
-				rs.afterLast();
+
+                                // reposition after last or before first
+                                if (isAfterLast) {
+                                    rs.afterLast();
+                                }
+                                if (isBeforeFirst) {
+                                    rs.beforeFirst();
+                                } 
 			}
 			else  // non-scrollable cursor
 			{
@@ -6227,15 +6238,13 @@
 		switch (stmt.getQryscrorn())
 		{
 			case CodePoint.QRYSCRREL:
-				//we aren't on a row - go to first row
-				//JCC seems to use relative 1 to get to the first row
-				//JDBC doesn't allow you to use relative unless you are on
-				//a valid row so we cheat here.
-				if (rs.isBeforeFirst() || rs.isAfterLast())
-					retval = rs.first();
-				else
-					retval = rs.relative((int)stmt.getQryrownbr());
-				break;
+                                int rows = (int)stmt.getQryrownbr();
+                                if ((rs.isAfterLast() && rows > 0) || (rs.isBeforeFirst() && rows < 0)) {
+                                    retval = false;
+                                } else {
+                                    retval = rs.relative(rows);
+                                }
+                                break;
 			case CodePoint.QRYSCRABS:
 				// JCC uses an absolute value of 0 which is not allowed in JDBC
 				// We translate it into beforeFirst which seems to work.

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/scrollCursors2.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/scrollCursors2.out?rev=348192&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/scrollCursors2.out (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/scrollCursors2.out Tue Nov 22 08:31:22 2005
@@ -0,0 +1,25 @@
+Test scrollCurors2 starting
+Invalid maxRows value: -1
+This method should only be called on ResultSet objects that are scrollable(type TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE)
+This method should only be called on ResultSet objects that are scrollable(type TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE)
+This method should only be called on ResultSet objects that are scrollable(type TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE)
+This method should only be called on ResultSet objects that are scrollable(type TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE)
+This method should only be called on ResultSet objects that are scrollable(type TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE)
+This method should only be called on ResultSet objects that are scrollable(type TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE)
+This method should only be called on ResultSet objects that are scrollable(type TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE)
+This method should only be called on ResultSet objects that are scrollable(type TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE)
+This method should only be called on ResultSet objects that are scrollable(type TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE)
+This method should only be called on ResultSet objects that are scrollable(type TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE)
+warning = org.apache.derby.client.am.SqlWarning: Scroll sensitive result sets are not supported by server; remapping to forward-only cursor
+warning = org.apache.derby.client.am.SqlWarning: Scroll sensitive result sets are not supported by server; remapping to forward-only cursor
+warning = org.apache.derby.client.am.SqlWarning: Insensitive updatable result sets are not supported by server; remapping to insensitive read-only cursor
+warning = org.apache.derby.client.am.SqlWarning: Insensitive updatable result sets are not supported by server; remapping to insensitive read-only cursor
+warning = org.apache.derby.client.am.SqlWarning: Insensitive updatable result sets are not supported by server; remapping to insensitive read-only cursor
+Invalid maxRows value: -1
+Invalid fetch size -5
+warning = org.apache.derby.client.am.SqlWarning: Scroll sensitive result sets are not supported by server; remapping to forward-only cursor
+warning = org.apache.derby.client.am.SqlWarning: Scroll sensitive result sets are not supported by server; remapping to forward-only cursor
+warning = org.apache.derby.client.am.SqlWarning: Insensitive updatable result sets are not supported by server; remapping to insensitive read-only cursor
+warning = org.apache.derby.client.am.SqlWarning: Insensitive updatable result sets are not supported by server; remapping to insensitive read-only cursor
+PASS
+Test scrollCursors2 finished

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude?rev=348192&r1=348191&r2=348192&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude Tue Nov 22 08:31:22 2005
@@ -7,7 +7,7 @@
 # excluding jdbcapi/checkDataSource30.java - Client behaves differently. Need to look into this
 # excluding jdbcapi/statementJdbc30.java - Client behaves differently. Need to look into this
 lang/errorStream.java
-lang/scrollCursors2.java
+# lang/scrollCursors2.java
 jdbcapi/batchUpdate.java
 jdbcapi/statementJdbc20.java
 jdbcapi/testRelative.java

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors2.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors2.java?rev=348192&r1=348191&r2=348192&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors2.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors2.java Tue Nov 22 08:31:22 2005
@@ -38,6 +38,7 @@
 
 import org.apache.derby.tools.ij;
 import org.apache.derby.tools.JDBCDisplayUtil;
+import org.apache.derbyTesting.functionTests.util.TestUtil;
 
 /**
  * Test of scroll cursors.
@@ -47,6 +48,8 @@
 
 public class scrollCursors2 { 
 
+        private static boolean isDerbyNetClient = false;
+    
 	public static void main(String[] args) {
 		boolean		passed = true;
 		Connection	conn = null;
@@ -56,6 +59,7 @@
 		try {
 			System.out.println("Test scrollCurors2 starting");
 
+                        isDerbyNetClient = TestUtil.isDerbyNetClientFramework();
 			// use the ij utility to read the property file and
 			// make the initial connection.
 			ij.getPropertyArg(args);
@@ -85,8 +89,16 @@
 
 			// tests for PreparedStatement.getMetaData()
 			passed = passed && getMetaDataTests(conn);
-			
-
+                        
+                        // test scrollable with different maxRows and fetchSize
+                        passed = passed && scrollVerifyMaxRowWithFetchSize(conn, 10, 10);
+                        passed = passed && scrollVerifyMaxRowWithFetchSize(conn, 10, 5);
+                        passed = passed && scrollVerifyMaxRowWithFetchSize(conn, 10, 0);
+                        passed = passed && scrollVerifyMaxRowWithFetchSize(conn, 0, 0);
+                        passed = passed && scrollVerifyMaxRowWithFetchSize(conn, 0, 5);
+                        passed = passed && scrollVerifyMaxRowWithFetchSize(conn, 0, 10);
+                        passed = passed && scrollVerifyMaxRowWithFetchSize(conn, 0, 15);
+                        
 		} 
 		catch (SQLException se) 
 		{
@@ -199,7 +211,11 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ063");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ063");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
 		}
 		// Verify maxRows still 0
 		if (s_f_r.getMaxRows() != 0)
@@ -233,7 +249,12 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ061");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ061");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
+
 		}
 		try
 		{
@@ -245,7 +266,12 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ061");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ061");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
+
 		}
 		try
 		{
@@ -257,7 +283,12 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ061");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ061");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
+
 		}
 		try
 		{
@@ -269,7 +300,12 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ061");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ061");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
+
 		}
 		try
 		{
@@ -281,7 +317,11 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ061");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ061");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
 		}
 		try
 		{
@@ -293,7 +333,11 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ061");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ061");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
 		}
 		try
 		{
@@ -305,7 +349,11 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ061");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ061");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
 		}
 		try
 		{
@@ -317,7 +365,11 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ061");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ061");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
 		}
 
 		// setFetchDirection should fail
@@ -331,16 +383,24 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ061");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ061");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
 		}
 
 		/* Book says that getFetchDirection(), getFetchSize() and
 		 * setFetchSize() are all okay.
 		 */
-		if (rs.getFetchSize() != 1)
+		if ((rs.getFetchSize() != 1 && !isDerbyNetClient) || (rs.getFetchSize() != 0 && isDerbyNetClient))
 	 	{
-			System.out.println("getFetchSize() expected to return 1");
-			passed = false;
+                        if (!isDerbyNetClient) {
+                            System.out.println("getFetchSize() expected to return 1");
+                        } else {
+                            System.out.println("getFetchSize() expected to return 0");
+                        }
+                        passed = false;
 		}
 		rs.setFetchSize(5);
 		if (rs.getFetchSize() != 5)
@@ -398,7 +458,12 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ061");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ061");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
+
 		}
 		rs.close();
 		ps_f_r.close();
@@ -716,10 +781,17 @@
 		}
 
 		// get/setFetchSize()
-		if (rs.getFetchSize() != 1)
-		{
-			System.out.println(
-				"getFetchSize() expected to return 1, not " + rs.getFetchSize());
+		if (
+                        (rs.getFetchSize() != 1 && !isDerbyNetClient) || 
+                        (rs.getFetchSize() != 64 && isDerbyNetClient))
+		{
+                        if (!isDerbyNetClient) {
+                            System.out.println(
+                                    "getFetchSize() expected to return 1, not " + rs.getFetchSize());
+                        } else {
+                            System.out.println(
+                                    "getFetchSize() expected to return 64, not " + rs.getFetchSize());
+                        }
 			passed = false;
 		}
 		rs.setFetchSize(5);
@@ -730,14 +802,22 @@
 			passed = false;
 		}
 		// setFetchSize() to 0 should have no effect.
+                // for client server, fetchSize should have to 64
 		rs.setFetchSize(0);
-		if (rs.getFetchSize() != 5)
+		if (
+                        (rs.getFetchSize() != 5 && !isDerbyNetClient) || 
+                        (rs.getFetchSize() != 64 && isDerbyNetClient))
 		{
-			System.out.println(
+                        if (!isDerbyNetClient) {
+                            System.out.println(
 				"getFetchSize() expected to return 5, not " + rs.getFetchSize());
+                        } else {
+                            System.out.println(
+				"getFetchSize() expected to return 64, not " + rs.getFetchSize());
+                        }
+
 			passed = false;
 		}
-
 		// done
 		rs.close();
 
@@ -841,7 +921,7 @@
 		{
 			System.out.println("rs.last() failed.");
 			passed = false;
-		}
+		} 
 		// Iterate backwards thru RS, expect only 4 more (5 total) rows.
 		for (int index = 1; index < 5; index++)
 		{
@@ -851,7 +931,7 @@
 				passed = false;
 				break;
 			}
-		}
+		} 
 		// We should not see another row (only 5, not 6)
 		if (rs.previous())
 		{
@@ -954,7 +1034,12 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ063");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ063");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
+
 		}
 		// Verify maxRows still 0
 		if (s_i_r.getMaxRows() != 0)
@@ -1049,7 +1134,12 @@
 		catch (SQLException sqle)
 		{
 			/* Check to be sure the exception is the one we expect */
-			passed = passed && checkException(sqle, "XJ062");
+                        if (!isDerbyNetClient) {
+                            passed = passed && checkException(sqle, "XJ062");
+                        } else {
+                            System.out.println(sqle.getMessage());
+                        }
+
 		}
 
 		s_i_r.close();
@@ -1269,6 +1359,214 @@
 		return passed;
 	}
 
+        
+	/**
+ 	 * Tests for maxRow and fetchSize with scrollable cursors
+	 *
+	 * @param conn	The connection to use.
+         * @param maxRows The maxRows value to use
+         * @param fetchSize The fetchSize value to use
+	 *
+	 * @return	Whether or not we were successful.
+	 *
+	 * @exception SQLException	Thrown if some unexpected error happens
+	 */
+        private static boolean scrollVerifyMaxRowWithFetchSize(Connection conn, int maxRows, int fetchSize) {
+            ResultSet rs;
+            boolean passed = true;
+            Statement	s_i_r = null;
+
+            try {
+                s_i_r = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
+                        ResultSet.CONCUR_READ_ONLY);
+                s_i_r.setMaxRows(maxRows);
+
+                // Execute query
+                rs = s_i_r.executeQuery("values 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15");
+                rs.setFetchSize(fetchSize);
+
+                // this should not affect the ResultSet because
+                s_i_r.setMaxRows(2);
+                if (maxRows == 0)
+                    maxRows = 15;
+
+                if (rs == null)
+                {
+                        System.out.println("rs expected to be non-null.");
+                        passed = false;
+                }
+                // Start from before first
+                // Iterate straight thru RS, expect only maxRows rows.
+                for (int index = 1; index < maxRows + 1; index++)
+                {
+                        if (! rs.next())
+                        {
+                                System.out.println("rs.next() failed, index = " + index);
+                                passed = false;
+                                break;
+                        } else {
+                                if (index != rs.getInt(1)) {
+                                    System.out.println("Expected: " + index + 
+                                            " not: " + rs.getInt(1));
+                                }
+                        }
+                }
+                // We should not see another row (only maxRows, not total)
+                if (rs.next())
+                {
+                        System.out.println("Error with maxRows = " + maxRows + 
+                                " and fetchSize = " + fetchSize + "\n" + 
+                                "rs.next() failed, should not have seen " + 
+                                (maxRows + 1) + "th row.");
+                        passed = false;
+                }
+
+                // Start from first and verify maxRows
+                if (!rs.first())
+                {
+                        System.out.println("rs.first() failed.");
+                        passed = false;
+                } 
+                // Iterate forward thru RS, expect only (maxRows - 1) more rows.
+                for (int index = 1; index < maxRows; index++)
+                {
+                        if (! rs.next())
+                        {
+                                System.out.println("rs.previous() failed, index = " + 
+                                        index);
+                                passed = false;
+                                break;
+                        } else {
+                                if ((index + 1) != rs.getInt(1))
+                                    System.out.println("Error with maxRows = " + 
+                                            maxRows + " and fetchSize = " + 
+                                            fetchSize + "\n" + "Error with maxRows = " + 
+                                            maxRows + " and fetchSize = " + fetchSize + 
+                                            "\n" + "Expected: " + (index + 1) + 
+                                            " not: " + rs.getInt(1));
+                        }
+                } 
+                // We should not see another row (only maxRows, not total)
+                if (rs.next())
+                {
+                        System.out.println("Error with maxRows = " + maxRows + 
+                                " and fetchSize = " + fetchSize + "\n" + 
+                                "rs.next() failed, should not have seen " + 
+                                (maxRows + 1) + "th row.");
+                        passed = false;
+                }
+
+                // Start from afterLast and verify maxRows
+                rs.afterLast();
+                // Iterate backwards thru RS, expect only (maxRows - 1) rows.
+                for (int index = 1; index < maxRows + 1; index++)
+                {
+                        if (! rs.previous())
+                        {
+                                System.out.println("rs.previous() failed, index = " + 
+                                        index);
+                                passed = false;
+                                break;
+                        } else {
+                                if (((maxRows - index) + 1) != rs.getInt(1)) {
+                                    System.out.println("Error with maxRows = " + maxRows + 
+                                            " and fetchSize = " + fetchSize + "\n" + 
+                                            "Expected: " + ((maxRows - index) + 1) + 
+                                            " not: " + rs.getInt(1));
+                                }
+                        }
+                }
+                // We should not see another row (only maxRows, not total)
+                if (rs.previous())
+                {
+                        System.out.println("Error with maxRows = " + maxRows + 
+                                " and fetchSize = " + fetchSize + "\n" + 
+                                "rs.previous() failed, should not have seen " + 
+                                (maxRows + 1) + "th row.");
+                        passed = false;
+                }
+
+                // Start from last and verify maxRows
+                if (!rs.last())
+                {
+                        System.out.println("rs.last() failed.");
+                        passed = false;
+                } 
+                // Iterate backwards thru RS, expect only (maxRows - 1) more rows.
+                for (int index = 1; index < maxRows; index++)
+                {
+                        if (! rs.previous())
+                        {
+                                System.out.println("rs.previous() failed, index = " + 
+                                        index);
+                                passed = false;
+                                break;
+                        } else {
+                                if ((maxRows - index) != rs.getInt(1)) {
+                                    System.out.println("Error with maxRows = " + maxRows + 
+                                            " and fetchSize = " + fetchSize + "\n" + 
+                                            "Expected: " + (maxRows - index) + " not: " + 
+                                            rs.getInt(1));
+                                }
+                        }
+                } 
+                // We should not see another row (only 5, not 6)
+                if (rs.previous())
+                {
+                        System.out.println("Error with maxRows = " + maxRows + 
+                                " and fetchSize = " + fetchSize + "\n" + 
+                                "rs.previous() failed, should not have seen " + 
+                                (maxRows + 1) + "th row.");
+                        passed = false;
+                }
+
+                rs.last();
+                int rows = rs.getRow();
+                
+                rs.absolute(rows/2);
+                if (rs.relative(-1 * (rows))) {
+                    System.out.println("relative(" + -1 * (rows) + ") should return false, position outside of the resultSet");
+                    
+                }
+                if (!rs.isBeforeFirst()) {
+                    System.out.println("isBeforeFirst should be true");
+                }
+
+                rs.absolute(rows/2);
+                if (rs.relative(rows)) {
+                    System.out.println("relative(" + (rows) + ") should return false, position outside of the resultSet");
+                }
+                if (!rs.isAfterLast()) {
+                    System.out.println("isAfterLast should be true");
+                }
+                rs.absolute(rows/2);
+                if (rs.absolute(rows + 1)) {
+                    System.out.println("absolute(" + (rows + 1) + ") should return false, position outside of the resultSet");
+                    System.out.println("Current row: " + rs.getInt(1));
+                }
+                if (!rs.isAfterLast()) {
+                    System.out.println("isAfterLast should be true");
+                }
+                rs.absolute(rows/2);
+                if (rs.absolute((-1) * (rows + 1))) {
+                    System.out.println("absolute(" + (((-1) * (rows + 1))) + ") should return false, position outside of the resultSet");
+                    System.out.println("Current row: " + rs.getInt(1));
+                }
+                if (!rs.isBeforeFirst()) {
+                    System.out.println("isBeforeFirst should be true");
+                }
+
+                rs.close();        
+            
+            } catch (SQLException e) {
+                System.out.println(e.getMessage());
+            }
+
+            return passed;
+        }
+
+
+        
 	/**
 	 * Check to make sure that the given SQLException is an exception
 	 * with the expected sqlstate.