>>>>>>>>>>>> Bernt M. Johnsen wrote (2005-05-27 14:31:39):
> Could anybody review this?
Well?
> This patch will make relative() allowed when the cursor is before
> first or after last. It will also let absolute(0) be equivalent to
> beforeFirst().
>
> This should be in accordance with JDBC 3.0 (although the tutorial and
> javadoc as a bit inconsistent on relative()).
>
> The patch will also cause the Network clinet to deviate from the
> behaviour of DB2JCC.
>
> derbyall is run with one fail which should not be related to this patch:
> derbyall/derbynetclientmats/derbynetmats.fail:lang/updatableResultSet.java
>
> derbyall run on:
> Java Version: 1.5.0_03
> Java Vendor: Sun Microsystems Inc.
> OS name: Linux
> OS architecture: i386
> OS version: 2.4.20-31.9
>
> Attached are the patch and the stat.
> --
> Bernt Marius Johnsen, Database Technology Group,
> Sun Microsystems, Trondheim, Norway
> Index: java/tools/org/apache/derby/impl/tools/ij/utilMain.java
> ===================================================================
> --- java/tools/org/apache/derby/impl/tools/ij/utilMain.java (revision
> 178761)
> +++ java/tools/org/apache/derby/impl/tools/ij/utilMain.java (working copy)
> @@ -693,12 +693,7 @@
> throw ijException.forwardOnlyCursor("ABSOLUTE");
> }
>
> - // 0 is an invalid value for row
> - if (row == 0)
> - {
> - throw ijException.zeroInvalidForAbsolute();
> - }
> -
> + // 0 is an *VALID* value for row
> return new ijRowResult(rs, rs.absolute(row));
> }
>
> Index:
> java/engine/org/apache/derby/impl/sql/execute/ScrollInsensitiveResultSet.java
> ===================================================================
> ---
> java/engine/org/apache/derby/impl/sql/execute/ScrollInsensitiveResultSet.java
> (revision 178761)
> +++
> java/engine/org/apache/derby/impl/sql/execute/ScrollInsensitiveResultSet.java
> (working copy)
> @@ -232,10 +232,11 @@
> }
> }
>
> - // 0 is an invalid parameter
> + // Absolute 0 is defined to be before first!
> if (row == 0)
> {
> - throw
> StandardException.newException(SQLState.LANG_ZERO_INVALID_FOR_R_S_ABSOLUTE);
> + setBeforeFirstRow();
> + return null;
> }
>
> if (row > 0)
> @@ -330,16 +331,14 @@
> }
> }
>
> - /* Throw exception if before first or after last */
> - if (beforeFirst || afterLast)
> - {
> - throw
> StandardException.newException(SQLState.LANG_NO_CURRENT_ROW_FOR_RELATIVE);
> - }
> -
> // Return the current row for 0
> if (row == 0)
> {
> + if (beforeFirst || afterLast) {
> + return null;
> + } else {
> return getRowFromHashTable(currentPosition);
> + }
> }
> else if (row > 0)
> {
> Index:
> java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors2.java
> ===================================================================
> ---
> java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors2.java
> (revision 178761)
> +++
> java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors2.java
> (working copy)
> @@ -613,6 +613,16 @@
> System.out.println("expected to be before the 1st row");
> passed = false;
> }
> + if (rs.absolute(0))
> + {
> + System.out.println("absolute(0) expected to return
> false");
> + passed = false;
> + }
> + if (! rs.isBeforeFirst())
> + {
> + System.out.println("still expected to be before the 1st
> row");
> + passed = false;
> + }
> // go to first row
> if (! rs.first())
> {
> @@ -1002,19 +1012,6 @@
> passed = passed && checkException(sqle, "XJ062");
> }
>
> - // absolute(0)
> - try
> - {
> - rs.absolute(0);
> - System.out.println("absolute(0) expected to fail");
> - passed = false;
> - }
> - catch (SQLException sqle)
> - {
> - /* Check to be sure the exception is the one we expect
> */
> - passed = passed && checkException(sqle, "X0X86");
> - }
> -
> s_i_r.close();
>
> return passed;
> Index:
> java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors1.sql
> ===================================================================
> ---
> java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors1.sql
> (revision 178761)
> +++
> java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors1.sql
> (working copy)
> @@ -25,19 +25,15 @@
> close c1;
>
> get scroll insensitive cursor c1 as 'select * from t1';
> --- 0 is invalid value for absolute
> absolute 0 c1;
> close c1;
> get scroll insensitive cursor c1 as 'select * from t1';
> --- relative is invalid when not positioned on a row
> relative 0 c1;
> close c1;
> get scroll insensitive cursor c1 as 'select * from t1';
> --- relative is invalid when not positioned on a row
> relative 2 c1;
> close c1;
>
> -
> -- positive
>
> -- test positioning
> Index:
> java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/scrollCursors1.out
> ===================================================================
> ---
> java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/scrollCursors1.out
> (revision 178761)
> +++
> java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/scrollCursors1.out
> (working copy)
> @@ -34,18 +34,15 @@
> IJ ERROR: RELATIVE is not allowed on a forward only cursor.
> ij> close c1;
> ij> get scroll insensitive cursor c1 as 'select * from t1';
> -ij> -- 0 is invalid value for absolute
> -absolute 0 c1;
> -IJ ERROR: 0 is an invalid value for ABSOLUTE <integer> <cursorname>
> +ij> absolute 0 c1;
> +No current row
> ij> close c1;
> ij> get scroll insensitive cursor c1 as 'select * from t1';
> -ij> -- relative is invalid when not positioned on a row
> -relative 0 c1;
> +ij> relative 0 c1;
> ERROR (no SQLState): Cursor is Not on a Valid Row
> ij> close c1;
> ij> get scroll insensitive cursor c1 as 'select * from t1';
> -ij> -- relative is invalid when not positioned on a row
> -relative 2 c1;
> +ij> relative 2 c1;
> ERROR (no SQLState): Cursor is Not on a Valid Row
> ij> close c1;
> ij> -- positive
> Index:
> java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/scrollCursors1.out
> ===================================================================
> ---
> java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/scrollCursors1.out
> (revision 178761)
> +++
> java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/scrollCursors1.out
> (working copy)
> @@ -34,19 +34,18 @@
> IJ ERROR: RELATIVE is not allowed on a forward only cursor.
> ij> close c1;
> ij> get scroll insensitive cursor c1 as 'select * from t1';
> -ij> -- 0 is invalid value for absolute
> -absolute 0 c1;
> -IJ ERROR: 0 is an invalid value for ABSOLUTE <integer> <cursorname>
> +ij> absolute 0 c1;
> +No current row
> ij> close c1;
> ij> get scroll insensitive cursor c1 as 'select * from t1';
> -ij> -- relative is invalid when not positioned on a row
> -relative 0 c1;
> -ERROR (no SQLState): Cursor is Not on a Valid Row
> +ij> relative 0 c1;
> +No current row
> ij> close c1;
> ij> get scroll insensitive cursor c1 as 'select * from t1';
> -ij> -- relative is invalid when not positioned on a row
> -relative 2 c1;
> -ERROR (no SQLState): Cursor is Not on a Valid Row
> +ij> relative 2 c1;
> +C50 |I
> +-----
> +c |3
> ij> close c1;
> ij> -- positive
> ----- test positioning
> Index:
> java/testing/org/apache/derbyTesting/functionTests/master/scrollCursors1.out
> ===================================================================
> ---
> java/testing/org/apache/derbyTesting/functionTests/master/scrollCursors1.out
> (revision 178761)
> +++
> java/testing/org/apache/derbyTesting/functionTests/master/scrollCursors1.out
> (working copy)
> @@ -34,19 +34,18 @@
> IJ ERROR: RELATIVE is not allowed on a forward only cursor.
> ij> close c1;
> ij> get scroll insensitive cursor c1 as 'select * from t1';
> -ij> -- 0 is invalid value for absolute
> -absolute 0 c1;
> -IJ ERROR: 0 is an invalid value for ABSOLUTE <integer> <cursorname>
> +ij> absolute 0 c1;
> +No current row
> ij> close c1;
> ij> get scroll insensitive cursor c1 as 'select * from t1';
> -ij> -- relative is invalid when not positioned on a row
> -relative 0 c1;
> -ERROR X0X87: ResultSet.relative(int row) cannot be called when the cursor is
> not positioned on a row.
> +ij> relative 0 c1;
> +No current row
> ij> close c1;
> ij> get scroll insensitive cursor c1 as 'select * from t1';
> -ij> -- relative is invalid when not positioned on a row
> -relative 2 c1;
> -ERROR X0X87: ResultSet.relative(int row) cannot be called when the cursor is
> not positioned on a row.
> +ij> relative 2 c1;
> +C50 |I
> +--------------------------------------------------------------
> +c |3
> ij> close c1;
> ij> -- positive
> -- test positioning
> Index: java/client/org/apache/derby/client/am/ResultSet.java
> ===================================================================
> --- java/client/org/apache/derby/client/am/ResultSet.java (revision
> 178761)
> +++ java/client/org/apache/derby/client/am/ResultSet.java (working copy)
> @@ -1804,18 +1804,51 @@
> // discard all previous updates when moving the cursor.
> resetUpdatedColumns();
>
> - // this method may only be called when the cursor on a valid row,
> - // not after the last row, before the first row, or on the insert
> row.
> - // throw exception if result set contains no rows, because there is
> no current row.
> - if (isBeforeFirstX() || isAfterLastX() || isOnInsertRow_ ||
> resultSetContainsNoRows()) {
> + // this method may not be called when the cursor on the insert row
> + if (isOnInsertRow_) {
> throw new SqlException(agent_.logWriter_, "Cursor is Not on a
> Valid Row");
> }
>
> + // If the resultset is empty, relative(n) is a null operation
> + if (resultSetContainsNoRows()) {
> + isValidCursorPosition_ = false;
> + return isValidCursorPosition_;
> + }
> +
> + // relative(0) is a null-operation, but the retruned result is
> + // dependent on wether the cursorposition is on a row or not.
> if (rows == 0) {
> - isValidCursorPosition_ = true;
> + if (isBeforeFirstX() || isAfterLastX()) {
> + isValidCursorPosition_ = false;
> + } else {
> + isValidCursorPosition_ = true;
> + }
> return isValidCursorPosition_;
> }
>
> + // Handle special cases when the cursor is before first or
> + // after last, since the following code assumes we ar on a
> + // valid cursor
> + if (isBeforeFirstX()) {
> + if (rows > 0) {
> + nextX();
> + return relativeX(rows-1);
> + } else {
> + isValidCursorPosition_ = false;
> + return isValidCursorPosition_;
> + }
> + }
> + if (isAfterLastX()) {
> + if (rows < 0) {
> + previousX();
> + return relativeX(rows+1);
> + } else {
> + isValidCursorPosition_ = false;
> + return isValidCursorPosition_;
> + }
> + }
> + // Ok, now we are on a row and ready to do some real positioning.....
> +
> resetRowsetFlags();
>
> // currentAbsoluteRowNumber is used for static cursors only.
> M java/tools/org/apache/derby/impl/tools/ij/utilMain.java
> M
> java/engine/org/apache/derby/impl/sql/execute/ScrollInsensitiveResultSet.java
> M
> java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors2.java
> M
> java/testing/org/apache/derbyTesting/functionTests/tests/lang/scrollCursors1.sql
> M
> java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/scrollCursors1.out
> M
> java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/scrollCursors1.out
> M
> java/testing/org/apache/derbyTesting/functionTests/master/scrollCursors1.out
> M java/client/org/apache/derby/client/am/ResultSet.java
--
Bernt Marius Johnsen, Database Technology Group,
Sun Microsystems, Trondheim, Norway