Skip Menu |

This queue is for tickets about the DBI CPAN distribution.

Report information
The Basics
Id: 34446
Status: resolved
Priority: 0/
Queue: DBI

People
Owner: Nobody in particular
Requestors: konrad.kazmirek [...] pl.hurra.com
Cc:
AdminCc:

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



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!' );
Hi. Thanks for the report and especially the test case. I was able to reproduce it with my old DBD::mysql driver, but when I rebuilt the driver (with a recent DBI installed) the problem went away. The code in the DBI's Driver.xst and Driver_h.xst files gets embedded into the driver when it's built. So you need to rebuild the driver if those files change. I think this particular problem we fixed in DBI 1.602: Fixed potential coredump if stack reallocated while calling back into perl from XS code. Thanks to John Gardiner Myers. Please try rebuilding DBD::mysql with the latest DBI installed and see if that fixes the problem for you.
Subject: Re: [rt.cpan.org #34446] selectall_arrayref returns $dbh
Date: Wed, 23 Apr 2008 10:10:38 +0200
To: bug-DBI [...] rt.cpan.org
From: Konrad Kazmirek <konrad.kazmirek [...] pl.hurra.com>
Hi! I did exactly as you wrote (rebuilded DBD::mysql after DBI upgrade) - problem is solved. Thanks for response.
Fixed in earlier DBI release. Driver just needed to be rebuilt.