PostgreSQL JDBC: Inserts/Updates on ResultSet fail when using column aliases. Exception 'The column name {0} was not found in this ResultSet'

From: Stefan Reiser <s(dot)reiser(at)tu-braunschweig(dot)de>
To: pgsql-jdbc(at)postgresql(dot)org
Subject: PostgreSQL JDBC: Inserts/Updates on ResultSet fail when using column aliases. Exception 'The column name {0} was not found in this ResultSet'
Date: 2010-12-29 02:48:45
Message-ID: 4D1AA18D.9000709@tu-braunschweig.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

Hello,

I found that any calls to insertRow() or updateRow() on an updateable
ResultSet will raise an exception if any column aliases were used in the
query.

For example an update on "SELECT foo AS bar FROM ..." leads to the
exception "The column name foo was not found in this ResultSet."

The reason is that there is a confusion between column names and column
labels in org.postgresql.jdbc2.AbstractJdbc2ResultSet .
Internaly it uses findColumn("foo") to look up the column's index by
it's name, but fails because findColumn() works with column labels
instead of names.

For my own needs I have patched AbstractJdbc2ResultSet.java from
version 8.4-702 by introducing another HashMap that maps column names to
indexes in addition to the already existing one which does the mapping
for column labels. (I'm using the patched version for about two weeks
now with no more problems so far.)

Here is the changed file:
http://home.arcor.de/stefanreiser/docs/postgresql/AbstractJdbc2ResultSet.java

The following detailed description of the problem and the changes I have
made can also be found in the header comment of that file.

Regards
Stefan Reiser

/* 2010-12-15/2010-12-29, errors:

If column name aliases were used in the query (e.g. "SELECT foo AS
bar") then
the calls to updateRowBuffer() in updateRow() and insertRow() fail
with the
exception "The column name foo was not found in this ResultSet."

Reason: Confusion between column names and column labels.

In detail:
1) updateRow() uses the columns' _names_ for creating an sql update
statement.
These names come from the keySet of HashMap "updateValues" as
defined in
protected void updateValue(...) {
...
updateValues.put(fields[columnIndex -
1].getColumnName(connection), value);
...
}

2) The update then is successfully committed to the database. After
that,
updateRowBuffer() is called and raises an exception (i.e. the
committed data does not become visible in the ResultSet) :

Method updateRowBuffer() uses the column name from
updateValues.keySet()
to lookup the corresponding index via findColumn(key). But
findColumn(key)
expects column _labels_, so the column is not found if name !=
label.

3) A similar problem exists in insertRow(). The same goes for
isUpdateable() if
column aliases were used for any primary key fields.

Workaround: Don't use any column aliases in your sql query :-(

Solution:
- This patch introduces a second HashMap: "columnNameToIndexMap".
- The old "columnNameIndexMap" was renamed to
"columnLabelToIndexMap".
- Method
private int findColumnIndex(String columnName) was renamed to
private int findColumnIndexByLabel(String columnLabel).
- A new method private int findColumnIndexByName(String
columnName) was
created and is now called from updateRowBuffer() and from
isUpdateable().

Todo:
- Is the case-insensitive behaviour in the method
"findColumnIndexByName"
correct according to specifications?
*/

Browse pgsql-jdbc by date

  From Date Subject
Next Message Achilleas Mantzios 2010-12-29 11:25:44 Re: PostgreSQL Authentication and Pooling in JBoss : static 'postgres' user VS dynamic jboss user
Previous Message Stefan Reiser 2010-12-29 02:44:34 PostgreSQL JDBC: Inserts/Updates on ResultSet fail when using column aliases. Exception 'The column name {0} was not found in this ResultSet'