Обсуждение: Bug in metadata.getColumns()/ORDINAL_POSITION

Поиск
Список
Период
Сортировка

Bug in metadata.getColumns()/ORDINAL_POSITION

От
"j.random.programmer"
Дата:
Hi:

This is using postgres 8.2.x and the latest 8.2-504
JDBC driver.

I have a table, defined like so:

test=# \d queue_stat;
Table "public.queue_stat"
      Column       |            Type             |
  Modifiers
-------------------------------------------------------
 queue_stat_id     | bigint                      | not
null default nextval

('queue_stat_queue_stat_id_seq'::regclass)
 start_time        | timestamp without time zone |
 finish_time       | timestamp without time zone |
 processing_error  | text                        |
 status            | character varying(24)       |
 fullpath_scan_dir | character varying(255)      |
========================================
Note, there are 6 columns defined, total in the table.

This snippet of code:
-------------------------------------------------------
String columnpattern = "%";    //all columns
ResultSet rs = md.getColumns(
    catalogname, schemaname, tablename, columnpattern);
QueryUtil.ensureScrollable(rs);
rs.beforeFirst();
while (rs.next())
    {
    String colname     = rs.getString    ("COLUMN_NAME");
    int datatype         = rs.getInt        ("DATA_TYPE");
    String typename = rs.getString    ("TYPE_NAME");
    int    colsize         = rs.getInt        ("COLUMN_SIZE");
    int nullable         = rs.getInt        ("NULLABLE");
    String remarks     = rs.getString    ("REMARKS");
    int    colnum        = rs.getInt        ("ORDINAL_POSITION");
--------------------------------------------------

gives me information about each column. I need the
ordinal
position because I have written a O/R tool that uses
the ordinal
position returned by the database meta data to
generate
methods like:

   result_set.getString(1)

etc.

Here's the bug.

For the above table (queue_stat), I get (via my o/r
tool):

INFO    1  >>>> Processing table: queue_stat
[colname=queue_stat_id,     colnum=1,
typename=bigserial]
[colname=start_time,           colnum=2,
typename=timestamp]
[colname=finish_time,          colnum=3,
typename=timestamp]
[colname=processing_error, colnum=5, typename=text]
[colname=status,                  colnum=6,
typename=varchar]
[colname=fullpath_scan_dir, colnum=7,
typename=varchar]

NOTE, THE COLNUM (via ("ORDINAL_POSITION")) returns:
    1, 2, 3, 5, 6, 7

This is WRONG. It should be:
    1, 2, 3, 4, 5, 6

Of course, this results in all sorts of problems when
the tool
tries to say:

   result_set.getString(7)

So in a nutshell: there seems to be a bug in:

ResultSet rs = md.getColumns(
    catalogname, schemaname, tablename, columnpattern);

as far as the:
    "ORDINAL_POSITION" column is concerned.

This is a pretty serious bug for any O/R tool. I have
not
encountered this problem before, so something must
have
changed, either in the database or in the driver. Very
weird...

Best regards,
--j




____________________________________________________________________________________
Do you Yahoo!?
Everyone is raving about the all-new Yahoo! Mail beta.
http://new.mail.yahoo.com

Re: Bug in metadata.getColumns()/ORDINAL_POSITION

От
Kris Jurka
Дата:

On Fri, 16 Feb 2007, j.random.programmer wrote:

> This is using postgres 8.2.x and the latest 8.2-504
> JDBC driver.
>
> [DatabaseMetaData.getColumns returns wrong ordinal_position like so:]
>
> NOTE, THE COLNUM (via ("ORDINAL_POSITION")) returns:
>     1, 2, 3, 5, 6, 7
>
> This is WRONG. It should be:
>     1, 2, 3, 4, 5, 6
>

Turns out this is a problem with dropped columns:

CREATE TABLE test (a int, b int, c int);
ALTER TABLE test DROP b;
SELECT attname, attnum FROM pg_attribute
     WHERE attnum > 0 AND attrelid = 'test'::regclass;

            attname            | attnum
------------------------------+--------
  a                            |      1
  ........pg.dropped.2........ |      2
  c                            |      3
(3 rows)

So we need to do our own counting in getColumns instead of relying on
attnum.  I'll look at a fix, but for the moment a workaround would be to
recreate your table without any dropped columns.

Kris Jurka

Re: Bug in metadata.getColumns()/ORDINAL_POSITION

От
"j.random.programmer"
Дата:
This is a quick followup to my earlier post. Upon
further
testing, this bug reliably and reproducably happens
when an "alter table" command is used on the database.

For for example:

test=# create table foo(x int, y varchar(5));

At this point, the jdbc metadata (md) method:

md.getColumns(
 catalogname, schemaname, tablename, "%");

returns the correct ORDINAL_POSITION for x and y.

x -- >1
y ---> 2

Now, let's do this:

test=# alter table foo add z text;
ALTER TABLE
test=# alter table foo drop z;
ALTER TABLE
test=# alter table foo drop y;
ALTER TABLE
test=# alter table foo add a varchar(10);


md.getColumns(
 catalogname, schemaname, tablename, "%");

now returns
x --> 1
a --> 4

and that's the bug right there.

Should be

a  ---> 2  (NOT 4)

since there are only 2 columsn in the database
at this point.


Maybe the database is not updating the system tables
properly when columns are altered/dropped ? Or is
this something in the driver ?

Either way, this totally breaks any O/R mapping tool.

Best regards,

-j





____________________________________________________________________________________
TV dinner still cooling?
Check out "Tonight's Picks" on Yahoo! TV.
http://tv.yahoo.com/

Re: Bug in metadata.getColumns()/ORDINAL_POSITION

От
Tom Lane
Дата:
"j.random.programmer" <javadesigner@yahoo.com> writes:
> This is a quick followup to my earlier post. Upon
> further
> testing, this bug reliably and reproducably happens
> when an "alter table" command is used on the database.

So the problem is that it's returning pg_attribute.attnum without any
consideration for earlier dropped columns.  Not sure how expensive it'd
be to get the current logical column number, though --- at a minimum one
would have to select all the table's pg_attribute rows :-(

            regards, tom lane

Re: Bug in metadata.getColumns()/ORDINAL_POSITION

От
Kris Jurka
Дата:

On Sat, 17 Feb 2007, Tom Lane wrote:

> "j.random.programmer" <javadesigner@yahoo.com> writes:
>> This is a quick followup to my earlier post. Upon
>> further
>> testing, this bug reliably and reproducably happens
>> when an "alter table" command is used on the database.
>
> So the problem is that it's returning pg_attribute.attnum without any
> consideration for earlier dropped columns.  Not sure how expensive it'd
> be to get the current logical column number, though --- at a minimum one
> would have to select all the table's pg_attribute rows :-(
>

I've fixed this in CVS when running against 8.4 and later servers by using
the row_number window function as was suggested elsewhere:

http://archives.postgresql.org/pgsql-general/2009-11/msg01067.php

Kris Jurka