Bug #34762 RowDataStatic does't always set the metadata in ResultSetRow
Submitted: 22 Feb 2008 18:02 Modified: 1 Mar 2008 12:32
Reporter: Marco Roduit Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S2 (Serious)
Version:5.1.5 OS:Any
Assigned to: CPU Architecture:Any

[22 Feb 2008 18:02] Marco Roduit
Description:
While searching for the cause of a strange exception (Cannot convert value '2008-02-22 14:19:27' from column 8 to TIMESTAMP) I started analysing the source of the JDBC driver and soon discovered that in some cases the "metadata" member of the ResultSetRow object was null; the result was the throwing of a NullPointerException while parsing a java.sql.Timestamp value and the conversion of that exception into the cited SQLException.

The cause of this bug resides in the RowDataStatic class. When using the ResultSet's "previous()" method, the driver convert's it into a call to RowDataStatic's "getAt(int)"; on the contrary, a call to ResultSet's "next()" method is converted into RowDataStatic's "next()" method.
While the latter correctly set the ResultSetRow's metadata member, through a call to the "setMetadata(Field[])" method, the former does not.
Furthermore, RowDataStatic's "getAt(int)" method doesn't set the current result set index (something the "next()" method does)

How to repeat:
- create a table with a DateTime column and fill it with some rows;
- now open a connection and  create a result set on that table
- navigate the result set with the next() and previous() methods,
  printing the value of timestamp column.
  While navigating forward works as expected, navigating backwards or asking 
  for a specific row (via the absolute(int) method) does not.

Suggested fix:
Replace RowDataStatic's "getAt(int)" in:
----
public ResultSetRow getAt(int atIndex) throws SQLException {
    if (atIndex >= 0 && atIndex < this.rows.size()) {
        this.index = atIndex;
        ResultSetRow row = (ResultSetRow) this.rows.get(this.index);
        row.setMetadata(this.metadata);
        return row; 
    }

    return null;
}
----

and refactor RowDataStatic's "next()" in:
----
public ResultSetRow next() throws SQLException {
    return getAt(this.index + 1);
}
----

I know that this is a quick'n dirty fix, but it works for me.
[27 Feb 2008 4:30] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/43029
[27 Feb 2008 7:38] Tonci Grgin
Hi Marco and thanks for your great report.
[27 Feb 2008 17:12] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/43086
[1 Mar 2008 12:32] MC Brown
A note has been added to the 5.1.6 changelog: 

RowDataStatic does't always set the metadata in ResultSetRow, which can lead to failures when unpacking DATE, TIME, DATETIME and TIMESTAMP types when using absolute, relative, and previous result set navigation methods.