CC: | radoslaw.pociecha [...] pl.hurra.com |
Subject: | selectall_arrayref returns $dbh |
Date: | Wed, 26 Mar 2008 16:29:57 +0100 |
To: | bug-DBI [...] rt.cpan.org |
From: | Konrad Kazmirek <konrad.kazmirek [...] pl.hurra.com> |
Hello!
I'd like to report a bug appearing when a SELECT statement with big
number of placeholders is executed through DBI's selectall_arrayref
method. We've tested it with DBI versions from 1.57 to 1.604.
We're generating IN statement for big number of values:
SELECT * FROM test_table WHERE id IN ( ?, ....... )
Properly invoked selectall_arrayref (using slice!) instead of ARRAYREF
returns $dbh used!
Bug is properly platform specific - method's result is wrong on Linux
Fedora (i686), but we recreate buggy result on FreeBSD (64-bit).
Configurations of machines tested are attached.
Our investigation suggests that bug is not database specific, I
reproduced it using mysql and Pg driver, (no error found in DBI trace).
I found that problem is when selectall_arrayref is executed as XSUB and
then bounced back to Perl implementation, which calls fetchall_arrayref
executed as XSUB and then bounced again as Perl method
(dbixst_bounce_method invokes perl method which executes by invoking
dbixst_bounce_method again). When selectall_arrayref ends, SP points on
first parameter ($dbh) and not the resulting array reference.
The bug appears only when memory for stack has to be reallocated before
perl method execution - proper number of parameters has to be passed so.
For example passing 2000, 4080, 8184, 16300 as parameters number won't
fail, because stack does not have to be reallocated during
dbixst_bounce_method execution.
But passing 2500, 5000, 8185, 16500 makes selectall_arrayref return $dbh.
Test case and test table creation script used are in attachment.
If any information given should be more detailed, please ask - I'll try
to answer if I could.
Best regards,
Konrad Kazmirek
CREATE TABLE test_table (
id INT PRIMARY KEY,
value VARCHAR(100)
);
uname -a
Linux kk565 2.6.23.15-80.fc7 #1 SMP Sun Feb 10 17:29:10 EST 2008 i686 i686 i386 GNU/Linux
perl -V
Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
Platform:
osname=linux, osvers=2.6.18-53.1.4.el5.bz358661.1, archname=i386-linux-thread-multi
uname='linux hammer2.fedora.redhat.com 2.6.18-53.1.4.el5.bz358661.1 #1 smp tue dec 18 14:48:27 est 2007 i686 athlon i386 gnulinux '
config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -Dversion=5.8.8 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dinstallprefix=/usr -Dprefix=/usr -Darchname=i386-linux -Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dinc_version_list=5.8.7 5.8.6 5.8.5 -Dscriptdir=/usr/bin'
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables',
cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -I/usr/include/gdbm'
ccversion='', gccversion='4.1.2 20070925 (Red Hat 4.1.2-27)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=4, prototype=define
Linker and Libraries:
ld='gcc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
libc=/lib/libc-2.6.so, so=so, useshrplib=true, libperl=libperl.so
gnulibc_version='2.6'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE'
cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -L/usr/local/lib'
Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY PERL_IMPLICIT_CONTEXT
PERL_MALLOC_WRAP USE_ITHREADS USE_LARGE_FILES
USE_PERLIO USE_REENTRANT_API
Built under linux
Compiled at Jan 31 2008 13:33:27
@INC:
/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.7/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.8
/usr/lib/perl5/site_perl/5.8.7
/usr/lib/perl5/site_perl/5.8.6
/usr/lib/perl5/site_perl/5.8.5
/usr/lib/perl5/site_perl
/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.7/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.6/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.8
/usr/lib/perl5/vendor_perl/5.8.7
/usr/lib/perl5/vendor_perl/5.8.6
/usr/lib/perl5/vendor_perl/5.8.5
/usr/lib/perl5/vendor_perl
/usr/lib/perl5/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/5.8.8
.
uname -a
FreeBSD sempro2 6.3-RELEASE FreeBSD 6.3-RELEASE #0: Thu Feb 14 12:41:53 CET 2008
perl -V
Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
Platform:
osname=freebsd, osvers=6.3-release, archname=amd64-freebsd
uname='freebsd sempro2 6.3-release freebsd 6.3-release #0: thu feb 14 12:41:53 cet 2008 root@sempro2:usrobjusrsrcsyssmp amd64 '
config_args='-sde -Dprefix=/usr/local -Darchlib=/usr/local/lib/perl5/5.8.8/mach -Dprivlib=/usr/local/lib/perl5/5.8.8 -Dman3dir=/usr/local/lib/perl5/5.8.8/perl/man/man3 -Dman1dir=/usr/local/man/man1 -Dsitearch=/usr/local/lib/perl5/site_perl/5.8.8/mach -Dsitelib=/usr/local/lib/perl5/site_perl/5.8.8 -Dscriptdir=/usr/local/bin -Dsiteman3dir=/usr/local/lib/perl5/5.8.8/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Ui_malloc -Ui_iconv -Uinstallusrbinperl -Dcc=cc -Duseshrplib -Dccflags=-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -Doptimize=-O2 -fno-strict-aliasing -pipe -Ud_dosuid -Ui_gdbm -Dusethreads=n -Dusemymalloc=y -Duse64bitint'
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=define use64bitall=define uselongdouble=undef
usemymalloc=y, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include',
optimize='-O2 -fno-strict-aliasing -pipe ',
cppflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include'
ccversion='', gccversion='3.4.6 [FreeBSD] 20060305', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -Wl,-E -L/usr/local/lib'
libpth=/usr/lib /usr/local/lib
libs=-lm -lcrypt -lutil
perllibs=-lm -lcrypt -lutil
libc=, so=so, useshrplib=true, libperl=libperl.so
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' -Wl,-R/usr/local/lib/perl5/5.8.8/mach/CORE'
cccdlflags='-DPIC -fPIC', lddlflags='-shared -L/usr/local/lib'
Characteristics of this binary (from libperl):
Compile-time options: MYMALLOC PERL_MALLOC_WRAP USE_64_BIT_ALL
USE_64_BIT_INT USE_LARGE_FILES USE_PERLIO
Locally applied patches:
defined-or
Built under freebsd
Compiled at Feb 14 2008 14:25:24
@INC:
/usr/local/lib/perl5/5.8.8/BSDPAN
/usr/local/lib/perl5/site_perl/5.8.8/mach
/usr/local/lib/perl5/site_perl/5.8.8
/usr/local/lib/perl5/site_perl
/usr/local/lib/perl5/5.8.8/mach
/usr/local/lib/perl5/5.8.8
.
#!/usr/bin/perl
use strict;
use warnings;
use Carp;
use Data::Dumper;
use DBI;
use Test::More tests => 1;
my ( $db_type, $db_name, $db_host, $db_user, $db_password )
= qw( mysql test_database localhost user 123 );
my ( $tst_table, $tst_field1 )
= qw( test_table id );
# NUMBERS that pass test: 2000, 4080, 8184, 16300
# NUMBERS that fail test: 2500, 5000, 8185, 16500
my $big_number = 8185;
my $dbh = DBI->connect('DBI:'.$db_type.':database='.$db_name.';host='.$db_host, $db_user, $db_password, { RaiseError=>1 } );
my $big_query = "SELECT * FROM $tst_table WHERE $tst_field1 IN ( " . ( join ',', map{ q{?} }(1..$big_number) ) . " ) FOR UPDATE";
my @values = map{ $_ }(1..$big_number);
# slice parameter is IMPORTANT to reproduce error
my $result = $dbh->selectall_arrayref( $big_query, {Slice=>{}}, @values );
# print Dumper $result;
is( ref $result, 'ARRAY', 'ARRAY REF should be returned!' );