Skip Menu |

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

Report information
The Basics
Id: 7673
Status: resolved
Priority: 0/
Queue: DBD-SQLite

People
Owner: Nobody in particular
Requestors: jeff [...] jsnider.net
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.05
Fixed in: (no value)



Subject: Very large integers are coerced into 32 bits
=pod I'm using DBD::SQLite 1.05 on Perl 5.8.0. Integer columns in SQLite 3 can be up to 64 bits, but when fetched via DBD::SQLite, they appear as 32 bits. This code: =cut use DBI; $dbh = DBI->connect("dbi:SQLite:"); $dbh->do("create table test (valint integer,valtxt text)"); $dbh->do("insert into test (valint,valtxt) values (?,?)",{},3041030247,3041030247); print "integer =".$dbh->selectrow_array("select valint from test")."\n"; print "text =".$dbh->selectrow_array("select valtxt from test")."\n"; =pod prints this on my system: integer =-1253937049 text =3041030247 using the sqlite3 tool, I can see that the data is in the file correctly. I think I found the problem, but I don't know enough of perl xs coding and c to know if this is safe. Here's the patch: --- DBD-SQLite-1.05/dbdimp.c Sun Aug 29 05:11:57 2004 +++ DBD-SQLite-1.05.tweak/dbdimp.c Thu Sep 16 15:41:05 2004 @@ -473,7 +473,7 @@ int col_type = sqlite3_column_type(imp_sth->stmt, i); switch(col_type) { case SQLITE_INTEGER: - sv_setiv(AvARRAY(av)[i], sqlite3_column_int(imp_sth->stmt, i)); + sv_setnv(AvARRAY(av)[i], (double)sqlite3_column_int64(imp_sth->stmt, i)); break; case SQLITE_FLOAT: sv_setnv(AvARRAY(av)[i], sqlite3_column_double(imp_sth->stmt, i)); It does produce the desired effect though: integer =3041030247 text =3041030247 Thanks for your hard work bringing this great DB to Perl! =cut
=pod I'm using DBD::SQLite 1.05 on Perl 5.8.0. Integer columns in SQLite 3 can be up to 64 bits, but when fetched via DBD::SQLite, they appear as 32 bits. This code: =cut use DBI; $dbh = DBI->connect("dbi:SQLite:"); $dbh->do("create table test (valint integer,valtxt text)"); $dbh->do("insert into test (valint,valtxt) values (?,?)",{},3041030247,3041030247); print "integer =".$dbh->selectrow_array("select valint from test")."\n"; print "text =".$dbh->selectrow_array("select valtxt from test")."\n"; =pod prints this on my system: integer =-1253937049 text =3041030247 using the sqlite3 tool, I can see that the data is in the file correctly. I think I found the problem, but I don't know enough of perl xs coding and c to know if this is safe. Here's the patch: --- DBD-SQLite-1.05/dbdimp.c Sun Aug 29 05:11:57 2004 +++ DBD-SQLite-1.05.tweak/dbdimp.c Thu Sep 16 15:41:05 2004 @@ -473,7 +473,7 @@ int col_type = sqlite3_column_type(imp_sth->stmt, i); switch(col_type) { case SQLITE_INTEGER: - sv_setiv(AvARRAY(av)[i], sqlite3_column_int(imp_sth->stmt, i)); + sv_setnv(AvARRAY(av)[i], (double)sqlite3_column_int64(imp_sth->stmt, i)); break; case SQLITE_FLOAT: sv_setnv(AvARRAY(av)[i], sqlite3_column_double(imp_sth->stmt, i)); It does produce the desired effect though: integer =3041030247 text =3041030247 Thanks for your hard work bringing this great DB to Perl! =cut
[guest - Thu Sep 16 17:37:37 2004]: I've run into this problem also. The suggested fix converts the integer to a double (not good...). Here's a fix that conditionally uses sqlite3_column_int64 based on Perl's USE_64_BIT_INT define. There may be a better place and/or way to do it, but this worked for me. Thanks! *** orig/DBD-SQLite-1.07/dbdimp.c Mon Oct 4 13:02:21 2004 --- DBD-SQLite-1.07/dbdimp.c Mon Dec 13 16:38:56 2004 *************** *** 474,480 **** --- 474,484 ---- int col_type = sqlite3_column_type(imp_sth->stmt, i); switch(col_type) { case SQLITE_INTEGER: + #if defined(USE_64_BIT_INT) + sv_setiv(AvARRAY(av)[i], sqlite3_column_int64 (imp_sth->stmt, i)); + #else sv_setiv(AvARRAY(av)[i], sqlite3_column_int(imp_sth- Show quoted text
>stmt, i));
+ #endif break; case SQLITE_FLOAT: sv_setnv(AvARRAY(av)[i], sqlite3_column_double (imp_sth->stmt, i));