Could anybody review this?
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