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.