Re: DBD::Informix Test Error On 64bit Linux (RHEL4.4)

Re: DBD::Informix Test Error On 64bit Linux (RHEL4.4)

am 22.02.2007 21:12:16 von dbd.informix

------=_Part_10860_27820585.1172175136801
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On 2/22/07, Jim Kenedy wrote:
>
> Note: This was previously posted on c.d.i but should have been posted
> here (as kindly noted by Jonathan Leffler). Also included are the
> run output with DBI_TRACE=3 as well as the perl -Ilib BugReport
> output.
> ------------------------------------------------------------ --------------
>
> I'm trying to install this module using Bundle::DBD::Informix but the
> t/t20error.t test is failing.
>
> I've narrowed it down to the fact that in t/t20error.t the ISAM error
> number in $msg is incorrect (here it's 4294967196 when it should be
> 100):
> DBD::Informix::st execute failed: SQL: -239: Could not insert new row
> - duplicate value in a UNIQUE INDEX column.
> ISAM: 4294967196: ISAM error: duplicate value for a record with
> unique key. at t/t20error.t line 44.
>
> Does anyone have an idea why the ISAM error is incorrect? I've
> checked that all components are 64 bit.



Yes...in dbdimp.ec, in the function dbd_ix_fmterror(), there is the code:


/* Format ISAM (secondary) error */
if (sqlca.sqlerrd[1] != 0)
{
if (rgetmsg(sqlca.sqlerrd[1], errbuf, sizeof(errbuf)) != 0)
strcpy(errbuf, "<>");
sprintf(fmtbuf, errbuf, sqlca.sqlerrm);
sprintf(isambuf, "ISAM: %ld: %s", sqlca.sqlerrd[1], fmtbuf);
}
else
isambuf[0] = '\0';

On your 64-bit platform, %ld is consuming 8 bytes - but sqlca.sqlerrd[1] is
an int4 (see $INFORMIXDIR/incl/esql/sqlca.h). We need to make the format
and the value self-consistent - one way to do that is to cast sqlca.sqlerrd[1]
to long. This will work on 32-bit and 64-bit platforms - so it is a
reasonable fix. The alternative more complex fix is to use string
concatenation and the macros in esqltype.h - PRId_ixInt4 - to yield:

sprintf(isambuf, "ISAM: " PRId_ixInt4 " %s", sqlca.sqlerrd[1].fmtbuf);

The long term fix will more likely add the cast - the ISAM errors are
actually relatively small (-1 .. -200 or thereabouts, usually - and
certainly nowhere near the 32-bit limits), so it is slightly simpler to
understand. What I'll need to understand is how (if) my 64-bit Sun SPARC
tests passed - and how you got the string information out.

The trace information did help - it crystallized where I needed to look.

Version Info...
> Kernel: Linux ahost.aserver.com 2.6.9-42.0.3.ELsmp #1 SMP Fri Oct 6
> 06:28:26 CDT 2006 x86_64 x86_64 x86_64 GNU/Linux
>
> Perl: v5.8.5 built for x86_64-linux-thread-multi
>
> Esql: IBM Informix CSDK Version 2.90, IBM Informix-ESQL Version
> 2.90.FC4
>
> IDS Version 10.00.FC5 installed locally, and connecting using
> onsoctcp. And running the exact same statements in dbaccess correctly
> shows ISAM error
> number 100.





############################################################ ####
> ### export DBI_TRACE=3; sh testone.sh t/t20error.t ####################
>
> DBI 1.53-ithread default trace level set to 0x0/3 (pid 12543)
> # DBI->connect('dbi:Informix:stores', '', '');
> # Connect Attribute: ChopBlanks => 1
> -> DBI->connect(dbi:Informix:stores, , ****, HASH(0x506430))
> -> DBI->install_driver(Informix) for linux perl=5.008005 pid=12543
> ruid=0 euid=0
> install_driver: DBD::Informix version 2005.02 loaded from
> blib/lib/DBD/Informix.pm
> New DBI::dr (for DBD::Informix::dr, parent=, id=)
> dbih_setup_handle(DBI::dr=HASH(0x6bc180)=>DBI::dr=HASH(0x848 d30),
> DBD::Informix::dr, 0, Null!)
> dbih_make_com(Null!, 0, DBD::Informix::dr, 192, 0) thr#505010
> <- install_driver= DBI::dr=HASH(0x6bc180)
> [...lots of snipping...]
> -> prepare for DBD::Informix::db (DBI::db=HASH(0x848d10)~0x84a4c0
> ' INSERT INTO dbd_ix_err01 VALUES(0, 'Gee Whizz!') ') thr#505010
> New DBI::st (for DBD::Informix::st, parent=DBI::db=HASH(0x84a4c0),
> id=)
> dbih_setup_handle(DBI::st=HASH(0x84a860)=>DBI::st=HASH(0x84a 470),
> DBD::Informix::st, 84a880, Null!)
> dbih_make_com(DBI::db=HASH(0x84a4c0), 82c990, DBD::Informix::st,
> 360, 0) thr#505010
> -->> DBD::Informix::dbd_ix_st_prepare()
> -->> DBD::Informix::dbd_ix_setbindnum()
> <<-- DBD::Informix::dbd_ix_setbindnum()
> number of described fields 0
> dbd_ix_st_prepare() ALLOCATE descriptor d_000000002
> dbd_ix_st_prepare() DEALLOCATE DESCRIPTOR d_000000002
> dbd_ix_st_prepare'imp_sth->n_ocols: 0
> <<-- DBD::Informix::dbd_ix_st_prepare()
> <- prepare= DBI::st=HASH(0x84a860) at t20error.t line 34
> -> execute for DBD::Informix::st (DBI::st=HASH(0x84a860)~0x84a470)
> thr#505010
> -->> DBD::Informix::dbd_ix_st_execute()
> -->> DBD::Informix::dbd_ix_exec()
> ---- EXECUTE p_000000002 - no parameters
> <<-- DBD::Informix::dbd_ix_exec()
> <<-- DBD::Informix::dbd_ix_st_execute()
> <- execute= 1 at t20error.t line 37
> -> execute for DBD::Informix::st (DBI::st=HASH(0x84a860)~0x84a470)
> thr#505010
> !! ERROR: -239 'SQL: -239: Could not insert new row - duplicate
> value in a UNIQUE INDEX column.
> ISAM: 4294967196: ISAM error: duplicate value for a record with
> unique key.' (err#0)
> <- execute= undef at t20error.t line 44
> not ok 4
> -> $DBI::errstr (&) FETCH from lasth=HASH
> >> DBD::Informix::st::errstr
> <- $DBI::errstr= 'SQL: -239: Could not insert new row - duplicate
> value in a UNIQUE INDEX column.
> ISAM: 4294967196: ISAM error: duplicate value for a record with unique
> key.'
> -> $DBI::errstr (&) FETCH from lasth=HASH
> >> DBD::Informix::st::errstr
> <- $DBI::errstr= 'SQL: -239: Could not insert new row - duplicate
> value in a UNIQUE INDEX column.
> ISAM: 4294967196: ISAM error: duplicate value for a record with unique
> key.'
> [...more snippage...]
>

Thank you for the complete bug report information.

--
Jonathan Leffler #include
Guardian of DBD::Informix v2005.02 -- see http://dbi.perl.org
"I don't suffer from insanity; I enjoy every minute of it!"

------=_Part_10860_27820585.1172175136801--