Re: Boolean column stick to "false" after calling updateRow() on updateable ResultSet

From: Clemens Eisserer <linuxhippy(at)gmail(dot)com>
To: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: Boolean column stick to "false" after calling updateRow() on updateable ResultSet
Date: 2020-01-25 19:07:53
Message-ID: CAFvQSYQDsF21Ypptew8vRf9oBHhm-uE0P15yM5ft683Z6s3xjQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

Hi again,

I debugged a bit into the driver and it seems I've found the cause for
the behaviour (quite sure it is a bug).
I've filed id #1623 regarding this issue.

In PgResultSet.getBoolean() there is manual type conversion from
byte[] to boolean going on:

int col = columnIndex - 1;
if (Oid.BOOL == fields[col].getOID()) {
final byte[] v = thisRow[col];
return (1 == v.length) && (116 == v[0]); // 116 = 't'
}

... so in case the value of thisRow[col] is a single character with
the letter 't' the check succeeds.
This is the case when the value was sent from the server (right after
the select or after calling refreshRow()).

However after updateRow(), fields[col]. contains the string "true",
because of length != 1, the check fails.

A quick&dirty hack would be to extent the condition to also check for
"true" - however I lack the in-depth-knowledge wether it would be
cleaner to avoid the "true" lurking around in the first place.

Best regards, Clemens

Am Sa., 25. Jan. 2020 um 17:43 Uhr schrieb Clemens Eisserer
<linuxhippy(at)gmail(dot)com>:
>
> Hi,
>
> I've observed something unexpected when migrating an application from
> PostgreSQL-8.4.21 & postgresql-8.4-701.jdbc3.jar to PostgreSQL-12 &
> postgresql-42.2.9.
>
> With the updated software-stack boolean columns always seem to stick
> to "false" after updateRow() is called on updateable ResultSets.
> The value stored however is correct, and calling refreshRow() right
> after updateRow() seems to restore the "old" behaviour and restores
> the value set a few lines aboce.
>
> I could fix the issue simply by forcing the additional roundtrip
> caused by refreshRow - however I still wonder - is the observed
> behaviour conformat to the spec / to be spected?
>
> Thank you in advance & best regards, Clemens
>
>
> //DDL
> CREATE TABLE sometable (id integer NOT NULL, someprop boolean DEFAULT false);
>
> //JDBC access
> Statement st =
> connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
> ResultSet.CONCUR_UPDATABLE);
> ResultSet rs = st.executeQuery("SELECT * FROM sometable WHERE id=...");
> rs.next();
> System.out.println(rs.getBoolean("someprop")); // value stored in DB
> rs.updateBoolean("vereinsFlugzeug", true);
> System.out.println(rs.getBoolean("someprop")); //Matches the
> value set above (true)
> rs.updateRow();
> // rs.refreshRow(); //fetches the value stored
> System.out.println(rs.getBoolean("someprop")); // always returns false.

In response to

Responses

Browse pgsql-jdbc by date

  From Date Subject
Next Message PG Bug reporting form 2020-01-26 03:39:49 BUG #16232: Database server connection limit exceeding
Previous Message PG Bug reporting form 2020-01-25 19:05:22 BUG #16230: Boolean column stick to "false" after calling updateRow() on updateable ResultSet