[CONJ-119] ResultSet cursor query methods does not behave as specified by the Java JDBC API Created: 2014-10-27 Updated: 2014-11-06 Resolved: 2014-11-06 |
|
| Status: | Closed |
| Project: | MariaDB Connector/J |
| Component/s: | None |
| Affects Version/s: | 1.1.7 |
| Fix Version/s: | 1.1.8 |
| Type: | Bug | Priority: | Minor |
| Reporter: | Lennart Schedin | Assignee: | Massimo Siani (Inactive) |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Description |
|
Background:
When this pattern is used everything works as expected. However if for some reason the SQL code is to be adapted to the java.util.Iterator pattern thing gets a bit complicated. The iterator pattern looks like this:
It would be possible to create an abstraction class that exposes the ResultSet as an Iterator (and this has happened in the code I’m working out now). In the code I’m working on the iterator.next() is implemented directly as resultSet.next(). But the iterator.hasNext() is implemented by some weird combination of the “is”-methods in ResultSet: isBeforeFirst(), isFirst(), isLast(),isAfterLast() and isClosed(). These “is”-methods doesn’t work as expected in MariaDB, hence this ticket. How to reproduce:
I have both used a 1.1.7-ish version of and also version 534 (http://bazaar.launchpad.net/~maria-captains/mariadb-java-client/trunk/revision/534) to test this. Actual:
Expected: The documentation of ResultSet can be found here: http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html. I will try to break down each method as best I can. isClosed(): From what I can see in the code the MariaDB JDBC closes the ResultSet very soon after the server has responded. I guess it could be debatable what in the API documentation qualifies as “automatically closed”. It is clear however that MariaDB JDBC behaves differently than Mysql and H2. isBeforeFirst(): Since my test code called the close() method I guess to make it conformant to the API the isBeforeFirst() method should throw an SQLException. isFirst(): This is one case where MariaDB behaves differently if there are zero rows returned. For a zero row SELECT this method should probably never return true? Since the cursor never is on a row? In the multiple row SELECT I think MariaDB JDBC behaves more or less correct, with the exception of not throwing an SQLException after the ResultSet is closed. isLast(): With a zero row SELECT the cursor could never be on the last row, because there is no row? This is basically the same argument as the problem for isFirst(). In the multiple row SELECT I think MariaDB JDBC behaves more or less correct, with the exception of not throwing an SQLException after the ResultSet is closed. isAfterLast(): With a zero row SELECT this method should always return false, since it is explicitly stated in the API. In the multiple row SELECT I think MariaDB JDBC behaves more or less correct, with the exception of not throwing an SQLException after the ResultSet is closed. Backwards compatibility problems: From my perspective (the switching from Mysql JDBC to MariaDB JDBC-perspective) I think they should behave the same. |
| Comments |
| Comment by Massimo Siani (Inactive) [ 2014-10-30 ] |
|
Hi Lennart, thanks for this one, that's quite tricky. |
| Comment by Lennart Schedin [ 2014-11-04 ] |
|
I checked the code in the branch briefly. I cannot find any obvious errors. However I did not write any test cases for previous(), and I see that the MySQLResultSet.previous() uses isBeforeFirst(). So just make sure the changes does not trigger an error in the previous() method. |