[ic] Incorrect treatment of sizing of bigint/int8 in IC w/ Postgres
Peter
peter at pajamian.dhs.org
Thu Mar 18 10:05:57 UTC 2010
On 18/03/10 03:47, Chris Keane wrote:
>
> IC 5.7.2, Postgres 8.3
>
> In Table::DBI.pm the MAX_FIELD_LENGTH for each element in a table in a
> Postgres database is discovered with
>
> SELECT a.attnum,t.typname,a.attlen,a.atttypmod,a.attname FROM pg_class
> c,pg_attribute a,pg_type t WHERE c.relname='_TABLE_' AND a.attnum > 0
> AND a.attrelid = c.oid AND a.atttypid = t.oid ORDER BY a.attnum;
>
> at line 225. In the case of a field with type bigint or int8, the attlen
> returned is 8, which is quite correct. That indicates that the maximum
> value is 8 bytes of storage, a maximum value of 2^63, or
> 9223372036854775807. That's great!
>
> On the other hand, down at the if statement at line 757, namely:
> if( $stype=~/numeric/i or $stype=~/varbit/i ){
> $scfg->{LENGTH} = $slenvar;
> }
> else {
> $scfg->{LENGTH} = $len;
> }
> IC decides that the length of the bigint can't be more than 8 digits,
> which yields a maximum value of 99999999, which as you can see yields a
> much lower maximum than 9223372036854775807.
>
> Trying to write a slice containing a bigint > 99999999 yields an error:
> # Vend::Table::DBI - Length Exception! - Data length: 9 Field length: 8
> # Vend::Table::DBI - Length Exception - Table: userdb, Field: <field
> name>. Action to take: truncate_log
> which then proceeds to lop the final digit off the bigint and stores it.
> For example, if you try to write 123456789, IC will produce this error
> and actually write 12345678 instead.
> See how that could be a problem?
>
> Since this was a rather critical error for us, I applied the simplest
> possible hack just to stop the bleeding, namely to insert
> elsif ($stype =~/int8/i) {
> $scfg->{LENGTH} = 19;
> }
> into the above the above if statement. I suppose a better approach would
> have to be do something like
> elsif($ctype =~ /^int/i) {
> $scfg->{LENGTH} = length(2 ** (($len * 8)-1));
> }
>
> But either way it's a significant problem and I just wanted to point it
> out so it can be fixed for future releases.
Agreed this should be fixed. As a workaround you can comment out the
following line in userdb.pgsql:
Database userdb LENGTH_EXCEPTION_DEFAULT truncate_log
That will tell IC to ignore the length exception and pass the data onto
the db as-is. Of course if the data length really *is* too long then it
will die instead of truncating the data, but this may actually be
preferable to you anyways.
Peter
More information about the interchange-users
mailing list