I ran the derbyall test suite without any failures.
~ Shreyas
Shreyas Kaushik (JIRA) wrote:
[ http://issues.apache.org/jira/browse/DERBY-186?page=comments#action_61704 ]
Shreyas Kaushik commented on DERBY-186:
---------------------------------------
I guess the problem is not whether you make a call to isFirst() first or next. The way a call to relative() is behaving when the param passed to it is more than the number of rows, is what is causing the problem.
I have small fix going for this which I am still testing. Will update when I get some results.
~ Shreyas
isFirst() returns true when relative(x) goes beyond result set --------------------------------------------------------------
Key: DERBY-186
URL: http://issues.apache.org/jira/browse/DERBY-186
Project: Derby
Type: Bug
Components: JDBC
Versions: 10.0.2.0
Environment: Windows XP SP1 Professional
Reporter: George Baklarz
Bizarre error. Not sure if this is a JDBC, Derby, or Java issue.
An opened result set has 4 records. A call to relative(3) while on row 3 should result in isAfterLast=true, and isFirst, isBeforeFirst, and IsLast set to false. However, the result is isAfterLast=True and isFirst=True.
ij connect 'IsAfter;create=true';
create table x (a char(1)); insert into x values '1','2','3','4';
quit;
import java.sql.*; public class ErrIsFirst {
public static void main(String argv[]) throws SQLException {
Connection conn = null;
Statement s = null;
ResultSet rs = null;
String DerbyDriver = "org.apache.derby.jdbc.EmbeddedDriver";
String returnValue;
try {
Class.forName(DerbyDriver).newInstance();
}
catch (Exception NoDriver) {
System.out.println("Derby driver not found: " + DerbyDriver);
NoDriver.printStackTrace();
System.exit(1);
}
try {
conn = DriverManager.getConnection("jdbc:derby:IsAfter"); s = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); rs = s.executeQuery( "SELECT A FROM X");
rs.next(); // First Record
returnValue = rs.getString("A"); System.out.println("Value="+returnValue); rs.relative(2);
System.out.println("isFirst=" + rs.isFirst() + " isLast=" + rs.isLast() + " isAfterLast=" + rs.isAfterLast());
returnValue = rs.getString("A"); System.out.println("Value="+returnValue); rs.relative(-2);
returnValue = rs.getString("A"); System.out.println("Value="+returnValue);
rs.relative(10);
System.out.println("isFirst=" + rs.isFirst() + " isLast=" + rs.isLast() + " isAfterLast=" + rs.isAfterLast());
returnValue = rs.getString("A"); System.out.println("Value="+returnValue); rs.close(); s.close();
}
catch (SQLException se) {
String SQLState = se.getSQLState(); String SQLMessage = se.getMessage();
System.out.println("Error = "+SQLState);
System.out.println(SQLMessage);
}
}
}
The results on my system are:
Value=1
isFirst=false isLast=false isAfterLast=false
Value=3
Value=1
isFirst=true isLast=false isAfterLast=true
Error = 24000
Invalid cursor state - no current row.
If you eliminate the first println call to isFirst() you get the following (correct) results.
Value=1
Value=3
Value=1
isFirst=false isLast=false isAfterLast=true
Error = 24000
Invalid cursor state - no current row.
Okay, so where did we go wrong?
Index:
java/engine/org/apache/derby/impl/sql/execute/ScrollInsensitiveResultSet.java
===================================================================
---
java/engine/org/apache/derby/impl/sql/execute/ScrollInsensitiveResultSet.java
(revision 159352)
+++
java/engine/org/apache/derby/impl/sql/execute/ScrollInsensitiveResultSet.java
(working copy)
@@ -750,6 +750,7 @@
else
{
afterLast = true;
+ currentPosition = positionInSource + 1;
}
}
Index:
java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/testRelative.java
===================================================================
---
java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/testRelative.java
(revision 0)
+++
java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/testRelative.java
(revision 0)
@@ -0,0 +1,98 @@
+package org.apache.derbyTesting.functionTests.tests.jdbcapi;
+
+
+import java.sql.*;
+
+import org.apache.derby.tools.ij;
+import org.apache.derby.tools.JDBCDisplayUtil;
+
+public class testRelative {
+ public static void main(String[] args) {
+ test1(args);
+ }
+
+ public static void test1(String []args) {
+ Connection con;
+ ResultSet rs;
+ PreparedStatement stmt = null;
+ PreparedStatement pStmt = null;
+ Statement stmt1 = null;
+ String returnValue = null;
+
+ System.out.println("Test testRelative starting");
+
+ try
+ {
+ // use the ij utility to read the property file and
+ // make the initial connection.
+ ij.getPropertyArg(args);
+ con = ij.startJBMS();
+
+ con.setAutoCommit(false);
+
+ stmt = con.prepareStatement("create table
testRelative(name varchar(10), i int)");
+ stmt.executeUpdate();
+ con.commit();
+
+ pStmt = con.prepareStatement("insert into testRelative
values (?,?)");
+
+ pStmt.setString(1,"work1");
+ pStmt.setNull(2,1);
+ pStmt.addBatch();
+
+ pStmt.setString(1,"work2");
+ pStmt.setNull(2,2);
+ pStmt.addBatch();
+
+ pStmt.setString(1,"work3");
+ pStmt.setNull(2,3);
+ pStmt.addBatch();
+
+ pStmt.setString(1,"work4");
+ pStmt.setNull(2,4);
+ pStmt.addBatch();
+
+
+ pStmt.executeBatch();
+ con.commit();
+
+ stmt1 =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
+ rs = stmt1.executeQuery("select * from testRelative");
+
+ rs.next(); // First Record
+ returnValue = rs.getString("name");
+ System.out.println("Value="+returnValue);
+
+ rs.relative(2);
+ System.out.println("isFirst=" + rs.isFirst() + "
isLast=" + rs.isLast() + " isAfterLast=" + rs.isAfterLast());
+ returnValue = rs.getString("name");
+ System.out.println("Value="+returnValue);
+
+ rs.relative(-2);
+ returnValue = rs.getString("name");
+ System.out.println("Value="+returnValue);
+
+ rs.relative(10);
+ System.out.println("isFirst=" + rs.isFirst() + "
isLast=" + rs.isLast() + " isAfterLast=" + rs.isAfterLast());
+
+ returnValue = rs.getString("name");
+ System.out.println("Value="+returnValue);
+
+ } catch(SQLException sqle) {
+ dumpSQLExceptions(sqle);
+ sqle.printStackTrace();
+ } catch(Throwable e) {
+ System.out.println("FAIL -- unexpected exception: "+e);
+ e.printStackTrace();
+
+ }
+ }
+
+ static private void dumpSQLExceptions (SQLException se) {
+ System.out.println("FAIL -- unexpected exception");
+ while (se != null) {
+ System.out.println("SQLSTATE("+se.getSQLState()+"):
"+se);
+ se = se.getNextException();
+ }
+ }
+}
\ No newline at end of file
Index:
java/testing/org/apache/derbyTesting/functionTests/master/testRelative.out
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/master/testRelative.out
(revision 0)
+++ java/testing/org/apache/derbyTesting/functionTests/master/testRelative.out
(revision 0)
@@ -0,0 +1,9 @@
+Test testRelative starting
+Value=work1
+isFirst=false isLast=false isAfterLast=false
+Value=work3
+Value=work1
+isFirst=false isLast=false isAfterLast=true
+FAIL -- unexpected exception
+SQLSTATE(24000): SQL Exception: Invalid cursor state - no current row.
+SQL Exception: Invalid cursor state - no current row.
