JdbcStatement.getUpdateCount() bug?

181 views
Skip to first unread message

Igal

unread,
May 1, 2012, 11:08:19 PM5/1/12
to h2-da...@googlegroups.com
I think that getUpdateCount() in org.h2.jdbc.JdbcStatement.getUpdateCount() is not working according to standards.

-----

int getUpdateCount() throws SQLException :

Retrieves the current result as an update count; if the result is a ResultSet object or there are no more results, -1 is returned. This method should be called only once per result.

Returns: the current result as an update count; -1 if the current result is a ResultSet object or there are no more results 
-----

it seems to me that the first time this method is called it should return the Update Count, but if it is called a second time it should return -1, i.e. line 222 should be changed to something like this:

  int result = updateCount;
  updateCount = -1;         // for subsequent calls
  return result;

I'm trying to use H2 from Railo (https://groups.google.com/forum/#!forum/railo) and am experiencing a problem reported at https://issues.jboss.org/browse/RAILO-1638

thank you for your consideration,


Igal


cowwoc

unread,
May 1, 2012, 11:26:30 PM5/1/12
to h2-da...@googlegroups.com

    I don't think that's what they mean. According to http://onjava.com/onjava/excerpt/javaentnut_2/index2.html section "Multiple Result Sets":

It is possible to write a SQL statement that returns more than one ResultSet or update count (exact methods of doing so vary depending on the database). [...] To be sure you've processed all the results for a Statement, you need to check that getMoreResults( ) returns false and that getUpdateCount( ) returns -1.

    And actually if you look at the Javadoc for getMoreResults() it seems to back up their claim. It provides example code that shows them doing exactly what is mentioned above (waiting for getUpdateCount() to become -1). Notice that they imply invoking getUpdateCount() multiple times (once per result).

Gili
--
You received this message because you are subscribed to the Google Groups "H2 Database" group.
To view this discussion on the web visit https://groups.google.com/d/msg/h2-database/-/hY30Mzoc3LEJ.
To post to this group, send email to h2-da...@googlegroups.com.
To unsubscribe from this group, send email to h2-database...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/h2-database?hl=en.

Igal

unread,
May 2, 2012, 2:40:21 AM5/2/12
to h2-da...@googlegroups.com
Gili -- thank you for your input.  it pushed me to run some more tests.  here's what I found:

the Railo code calls Statement.getMoreResult() with an argument Statement.CLOSE_CURRENT_RESULT;  when that method is called with the argument it for some reason changes the UpdateCount and the loop never reaches the break statement so it becomes an infinite loop.

when I commented out the arg to getMoreResults() the code was running properly:

if( ( stat.getMoreResults( /* Statement.CLOSE_CURRENT_RESULT */ ) == false ) && ( uc == -1 ) )
    break;

this code is running with many other DBMSs and the only issue that I'm aware of is with H2;  perhaps there's a bug in JdbcStatement.getMoreResults( Statement.CLOSE_CURRENT_RESULT ) ?


Igal
To unsubscribe from this group, send email to h2-database+unsubscribe@googlegroups.com.

Igal

unread,
May 2, 2012, 5:02:14 AM5/2/12
to h2-da...@googlegroups.com
JdbcStatement.getMoreResults(int flag) behaves differently from the parameter-less JdbcStatement.getMoreResults() even when they both close the resultSet and return false.

the behavior of JdbcStatement.getMoreResults(int flag) is causing a major problem with the Railo application server (as documented at https://issues.jboss.org/browse/RAILO-1638) and makes H2 impossible unusable in Railo.

since both methods always return false, perhaps a good solution would be to call the parameter-less method from within the parameterized version when the flag is set to Close?  i.e.


    /**
     * Move to the next result set.
     * This method always returns false.
     *
     * @param current Statement.CLOSE_CURRENT_RESULT,
     *          Statement.KEEP_CURRENT_RESULT,
     *          or Statement.CLOSE_ALL_RESULTS
     * @return false
     */
    public boolean getMoreResults(int current) throws SQLException {
        try {
            debugCodeCall("getMoreResults", current);
            switch (current) {
            case Statement.CLOSE_CURRENT_RESULT:
            case Statement.CLOSE_ALL_RESULTS:
    //          if (resultSet != null) {
    //              resultSet.close();
    //          }
                getMoreResults();
                break;
            case Statement.KEEP_CURRENT_RESULT:
                // nothing to do
                break;
            default:
                throw DbException.getInvalidValueException("current", current);
            }
            return false;
        } catch (Exception e) {
            throw logAndConvert(e);
        }
    }

//-------- code below shows current code --------//

    /**
     * Moves to the next result set - however there is always only one result
     * set. This call also closes the current result set (if there is one).
     * Returns true if there is a next result set (that means - it always
     * returns false).
     *
     * @return false
     * @throws SQLException if this object is closed.
     */
    public boolean getMoreResults() throws SQLException {
        try {
            debugCodeCall("getMoreResults");
            checkClosed();
            closeOldResultSet();
            return false;
        } catch (Exception e) {
            throw logAndConvert(e);
        }
    }


    /**
     * Move to the next result set.
     * This method always returns false.
     *
     * @param current Statement.CLOSE_CURRENT_RESULT,
     *          Statement.KEEP_CURRENT_RESULT,
     *          or Statement.CLOSE_ALL_RESULTS
     * @return false
     */
    public boolean getMoreResults(int current) throws SQLException {
        try {
            debugCodeCall("getMoreResults", current);
            switch (current) {
            case Statement.CLOSE_CURRENT_RESULT:
            case Statement.CLOSE_ALL_RESULTS:
                if (resultSet != null) {
                    resultSet.close();
                }
                break;
            case Statement.KEEP_CURRENT_RESULT:
                // nothing to do
                break;
            default:
                throw DbException.getInvalidValueException("current", current);
            }
            return false;
        } catch (Exception e) {
            throw logAndConvert(e);
        }
    }

Noel Grandin

unread,
May 2, 2012, 5:30:28 AM5/2/12
to h2-da...@googlegroups.com, Igal
Thanks for your investigation.

This will be fixed in the next version of H2.

Igal

unread,
May 2, 2012, 5:34:00 AM5/2/12
to h2-da...@googlegroups.com, Igal
thanks Noel :)

Igal

unread,
May 20, 2012, 3:42:22 PM5/20/12
to h2-da...@googlegroups.com, Igal
Is there a scheduled release date for the next update? I'd love to be able to start using H2...

On Wednesday, May 2, 2012 2:30:28 AM UTC-7, Noel Grandin wrote:

Igal

unread,
May 23, 2012, 3:32:42 PM5/23/12
to h2-da...@googlegroups.com, Igal
thanks guys.  version 1.3.167 resolved this issue.

thanks again,


Igal


On Wednesday, May 2, 2012 2:30:28 AM UTC-7, Noel Grandin wrote:
Reply all
Reply to author
Forward
0 new messages