Skip Menu |

This queue is for tickets about the DBD-Informix CPAN distribution.

Report information
The Basics
Id: 32975
Status: resolved
Worked: 2.5 hours (150 min)
Priority: 0/
Queue: DBD-Informix

People
Owner: j.leffler [...] acm.org
Requestors: siracusa [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in:
  • 2007.0914
  • 0.55
  • 0.58
  • 0.60
  • 0.62
  • 0.95
  • 0.97003
  • 0.97005
  • 1.00.PC1
  • 1.00.PC2
  • 1.03.PC1
  • 1.04.PC1
  • 2003.03.0303
  • 2003.03.0400
  • 2003.03.0401
  • 2003.04
  • 2005.01
  • 2005.02
  • 2007.0225
  • 2007.0226
  • 2007.0826
  • 2007.0903
  • 2007.0904
Fixed in: 2008.0229



Subject: Inserting into a SERIAL8 column does not populate $sth->{'ix_sqlerrd'}[1]
The following script demonstrates the problem: --- #!/usr/bin/perl use strict; use DBI; my $dbh = DBI->connect('dbi:Informix:test@test', 'test', 'mysecret', { AutoCommit => 1, RaiseError => 1 }); $dbh->do('CREATE TABLE serial_test (id serial, num int)'); $dbh->do('CREATE TABLE serial8_test (id serial8, num int)'); my $sth = $dbh->prepare('INSERT INTO serial_test (id, num) VALUES (0, 1)'); $sth->execute; print "Inserted value (serial): ", $sth->{'ix_sqlerrd'}[1], "\n"; my $sth = $dbh->prepare('INSERT INTO serial8_test (id, num) VALUES (0, 1)'); $sth->execute; print "Inserted value (serial8): ", $sth->{'ix_sqlerrd'}[1], "\n"; $dbh->do('DROP TABLE serial_test'); $dbh->do('DROP TABLE serial8_test'); $dbh->disconnect; --- Expected output: Inserted value (serial): 1 Inserted value (serial8): 1 Actual output: Inserted value (serial): 1 Inserted value (serial8): 0 This is perl 5.8.8, DBD::Informix 2007.0914 and (I *think*) CSDK 2.81.UC3.LINUX-I32. (If there's a way for me to determine the CSDK version directly from a DBD::Informix install alone, let me know.)
RT-Send-CC: dbd.informix [...] gmail.com
Dear John, Thank you for the bug report. The basic diagnosis is correct: DBD::Informix does not provide you with a way to locate the inserted SERIAL8 value. A the C level, the sqlca.sqlerrd[1] element is a 4-byte integer which won't reliably hold 8-byte serial values. That leaves us with a variety of possible solutions, and I'd be interested in your view on which is most appropriate. The ESQL/C function to obtain the last SERIAL8 value is ifx_getserial8(). Options I see include: 1. Provide a function to be called - that maps to ifx_getserial8(). 2. Fake it: if sqlca.sqlerrd[1] is requested and the value is 0, then poke at ifx_getserial8() to see if that is non-zero, and return whichever is appropriate. 3. Define sqlca.sqlerrd[6] as a fake entry that always returns ifx_getserial8()'s value. 4. Define sqlca.sqlserial8 as a fake entry that always returns ifx_getserial8()'s value. Of these, (1) presents notational issues - there's a mechanism, but I'd have to look it up. (3) is vulnerable if the genuine sqlca ever changes - an unlikely possibility, but not completely out of the question. Actually, I think it needs to change so that sqlerrm is way bigger than 72 characters, if nothing else. (2) is not wholly reliable - some idiot somewhere will have both a SERIAL and a SERIAL8 column in a single table. Complicating my life is the fact that there is impending support for BIGINT and BIGSERIAL in the next version of IDS, which use true 8-byte integers instead of the 10-byte weirdness that is INT8 and SERIAL8. I just went to check what the function is for that, and it appears I found an omission in the client-side design for ESQL/C; ODBC and JDBC were taken care of, but not ESQL/C. (So, you could claim some credit for finding a bug in an as-yet released version of CSDK.) There is time to fix it before the GA, but it means I don't know what the actual solution will be as I type. At this point, my inclination is towards adding sqlca.sqlserial8 (and sqlca.bigserial) which do whatever is appropriate to obtain the value. I'm not wholly sold on that and would listen to any suggestions you have. FYI: The attributes $drh->{ix_ProductName} and drh->{ix_ProductVersion} give the ESQL/C product name and version number as an integer. These are documented in the driver attributes section of 'perldoc DBD::Informix'. -- Jonathan Leffler <jleffler@earthlink.net> <jleffler@us.ibm.com> Guardian of DBD::Informix 2007.0914 -- see http://dbi.perl.org/ "I don't suffer from insanity - I enjoy every minute of it!"
From: siracusa [...] gmail.com
On Wed Feb 06 20:16:20 2008, JOHNL wrote: Show quoted text
> A the C level, the sqlca.sqlerrd[1] element is a 4-byte integer
Yeah, I figured as much, but since when is a Perl API constrained by such details? ;) Show quoted text
> 1. Provide a function to be called - that maps to ifx_getserial8(). > [...] > 4. Define sqlca.sqlserial8 as a fake entry that always returns > ifx_getserial8()'s value.
These two look the most promising to me. What is DBINFO('serial8') doing under the covers? (Calling ifx_getserial8(), or something even lower level?) Is it worth emulating the entire DBINFO() "API" in DBD::Informix? $sth->dbinfo(...)? At the very least, it would remove the need to keep thinking of names for these things and let you just copy the DBINFO(...) args. Anyway, I have no strong feelings about the interface, so long as I can get it in some way. (I need this because my ORM's API promises that an object fronting a row in a table with a serial column will be correctly populated with the chosen serial value after the object is insert()ed. Currently, I can't fulfill that promise for tables with serial8 columns in Informix.)
RT-Send-CC: dbd.informix [...] gmail.com
I've introduced $h->{ix_serial} for serial, $h->{ix_serial8} for serial8, and will add $h->{ix_bigserial} once I get CSDK 3.50 and IDS 11.50 installed. These can be used on any handle, I believe - you can find the (limited) testing in t/t10sqlca.t and t/t95int8.t. The code is not yet properly protected for ESQL/C 5.x which does not have INT8 support. -- Jonathan Leffler <jleffler@earthlink.net> <jleffler@us.ibm.com> Guardian of DBD::Informix 2008.0229 -- see http://dbi.perl.org/ "I don't suffer from insanity - I enjoy every minute of it!"
Subject: Re: [rt.cpan.org #32975] Inserting into a SERIAL8 column does not populate $sth->{'ix_sqlerrd'}[1]
Date: Sat, 1 Mar 2008 10:00:10 -0800
To: bug-DBD-Informix [...] rt.cpan.org
From: "Jonathan Leffler" <jonathan.leffler [...] gmail.com>
Dear John, DBD::Informix 2008.0229 is out with this fixed. On Wed, Feb 6, 2008 at 9:06 PM, John Siracusa via RT < bug-DBD-Informix@rt.cpan.org> wrote: Show quoted text
> > Queue: DBD-Informix > Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=32975 > > > On Wed Feb 06 20:16:20 2008, JOHNL wrote:
> > A the C level, the sqlca.sqlerrd[1] element is a 4-byte integer
> > Yeah, I figured as much, but since when is a Perl API constrained by such > details? ;) >
> > 1. Provide a function to be called - that maps to ifx_getserial8(). > > [...] > > 4. Define sqlca.sqlserial8 as a fake entry that always returns > > ifx_getserial8()'s value.
> > These two look the most promising to me. What is DBINFO('serial8') doing > under the covers? > (Calling ifx_getserial8(), or something even lower level?) Is it worth > emulating the entire > DBINFO() "API" in DBD::Informix? $sth->dbinfo(...)? At the very least, > it would remove the > need to keep thinking of names for these things and let you just copy the > DBINFO(...) args. > > Anyway, I have no strong feelings about the interface, so long as I can > get it in some way. (I > need this because my ORM's API promises that an object fronting a row in a > table with a > serial column will be correctly populated with the chosen serial value > after the object is > insert()ed. Currently, I can't fulfill that promise for tables with > serial8 columns in Informix.) >
You can use $h->{ix_serial} to get a serial value (new), and $h->{ix_serial8} to get the serial8 value. I'll be adding $h->{ix_bigserial} when I've tested with CSDK 3.50 and IDS 11.50. DBINFO is a server-side function that grabs the data that would be sent back to the client to become part of the SQLCA structure. -- Jonathan Leffler <jonathan.leffler@gmail.com> #include <disclaimer.h> Guardian of DBD::Informix - v2008.0229 - http://dbi.perl.org "Blessed are we who can laugh at ourselves, for we shall never cease to be amused."
This item is closed. -- Jonathan Leffler <jleffler@earthlink.net> <jleffler@us.ibm.com> Guardian of DBD::Informix 2007.0914 -- see http://dbi.perl.org/ "I don't suffer from insanity - I enjoy every minute of it!"