Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HandleError receives statement handle, despite the docs #155

Open
rwfranks opened this issue Oct 27, 2024 · 5 comments
Open

HandleError receives statement handle, despite the docs #155

rwfranks opened this issue Oct 27, 2024 · 5 comments

Comments

@rwfranks
Copy link

Transcribed verbatim from CPAN RT#122744, warts and all.

Tue Aug 08 05:20:08 2017 victor [...] vsespb.ru - Ticket created
Subject: HandleError receives statement handle, despite the docs

Docs says HandleError receives DBI handle

The subroutine is called with three parameters: the error message string that RaiseError
and PrintError would use, the DBI handle being used, and the first value being returned
by the method that failed (typically undef).

but actually sometimes it receives a statement handle (DBI::st).

need to either fix docs or code

@rwfranks
Copy link
Author

Tue Aug 08 08:29:54 2017 REHSACK [...] cpan.org - Correspondence added

Can you please provide a sample code that demonstrates this thesis? Including 'perl -v' output, DBI version etc.?

Tue Aug 08 08:29:55 2017 The RT System itself - Status changed from 'new' to 'open'

@rwfranks
Copy link
Author

Wed Aug 09 04:40:43 2017 TIMB [...] cpan.org - Correspondence added

On Tue Aug 08 10:20:08 2017, vsespb wrote:

> Docs says HandleError receives DBI handle
> ===
> The subroutine is called with three parameters: the error message
> string that RaiseError and PrintError would use, the DBI handle being
> used, and the first value being returned by the method that failed
> (typically undef).
> ===
> but actually sometimes it receives a statement handle (DBI::st).

"the DBI handle being used" means it'll be called with a database handle when the error occurred on a database handle, and called with a statement handle when the error occurred on a statement handle. Some methods might be called on a database handle but internally they create and use a statement handle, such as the select_* methods.

I'd be delighted if you can find a case where the above isn't true.
Or if you'd suggest a concise improvement to the docs that would have avoided the misunderstanding.
Meanwhile I'll code the ticket. It'll reopen if you reply.
Thanks.

Wed Aug 09 04:40:44 2017 TIMB [...] cpan.org - Status changed from 'open' to 'rejected'

@rwfranks
Copy link
Author

Fri Aug 11 09:07:43 2017 victor [...] vsespb.ru - Correspondence added

PoC script (involves inheritance):

=======================
package MyDBI::db;
use parent qw( -norequire DBI::db );
package MyDBI::st;
use parent qw( -norequire DBI::st );
package MyDBI;
use parent qw( -norequire DBI );
sub handle_error {
    my ($err_str, $handle, ) = @_;

    print "HANDLE IN ERROR is [", ref($handle), "], error is :", $err_str, "\n";
};

sub new {
    my $self = MyDBI->connect(
        'DBI:mysql:host=127.0.0.1;database=test', 'root', '',
        {
            AutoInactiveDestroy    => 1,
            RootClass              => 'MyDBI',
            HandleError            => \&handle_error,
        }
    );

    $self;
};
package main;

use strict;
use warnings;
use DBI;
use DBD::mysql;
use Data::Dumper;

my $dbh = MyDBI::new();


$dbh->{AutoCommit}=0;
$dbh->do("drop table if exists innodb_deadlock_maker ");
$dbh->do("create table innodb_deadlock_maker(a int primary key) engine=innodb;");


print "STATEHANDLE TEST...\n";
if (fork()) {
    $dbh->do("set transaction isolation level serializable;");
    my $sth = $dbh->prepare("insert into innodb_deadlock_maker values(1);");
    $sth->execute();
    $sth->finish();
    sleep 1;
    $sth = $dbh->prepare("insert into innodb_deadlock_maker values(0);");
    $sth->execute();
    $sth->finish();
    sleep 1;
    $dbh->do("drop table if exists innodb_deadlock_maker ");
}
else {
    $dbh = MyDBI::new();
    $dbh->do("set transaction isolation level serializable;");
    my $sth = $dbh->prepare("select * from innodb_deadlock_maker for update;");
    $sth->execute();
    $sth->finish;
    sleep 2;
    exit;
}
$dbh->rollback();
print "STATEHANDLE TEST FINISH\n";
__END__
=======================
Output:

STATEHANDLE TEST...
HANDLE IN ERROR is [MyDBI::st], error is :DBD::mysql::st execute failed: Deadlock found when trying to get lock; try restarting transaction
STATEHANDLE TEST FINISH

=======================

Versions:
$ perl -MDBI\ 1000
DBI version 1000 required--this is only version 1.634.
BEGIN failed--compilation aborted.

$ perl -MDBD::mysql\ 1000
DBD::mysql version 1000 required--this is only version 4.033.
BEGIN failed--compilation aborted.

$ perl -V
Summary of my perl5 (revision 5 version 22 subversion 1) configuration:
   
  Platform:
    osname=linux, osvers=3.16.0, archname=x86_64-linux-gnu-thread-multi
    uname='linux localhost 3.16.0 #1 smp debian 3.16.0 x86_64 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dcc=x86_64-linux-gnu-gcc -Dcpp=x86_64-linux-gnu-cpp -Dld=x86_64-linux-gnu-gcc -Dccflags=-DDEBIAN -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Dldflags= -Wl,-Bsymbolic-functions -Wl,-z,relro -Dlddlflags=-shared -Wl,-Bsymbolic-functions -Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.22 -Darchlib=/usr/lib/x86_64-linux-gnu/perl/5.22 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/x86_64-linux-gnu/perl5/5.22 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.22.1 -Dsitearch=/usr/local/lib/x86_64-linux-gnu/perl/5.22.1 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -Uversiononly -DDEBUGGING=-g -Doptimize=-O2 -dEs -Duseshrplib -Dlibperl=libperl.so.5.22.1'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='x86_64-linux-gnu-gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='5.3.1 20160311', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='x86_64-linux-gnu-gcc', ldflags =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=libc-2.21.so, so=so, useshrplib=true, libperl=libperl.so.5.22
    gnulibc_version='2.21'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib -fstack-protector-strong'


Characteristics of this binary (from libperl): 
  Compile-time options: HAS_TIMES MULTIPLICITY PERLIO_LAYERS
                        PERL_DONT_CREATE_GVSV
                        PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
                        PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
                        PERL_NEW_COPY_ON_WRITE PERL_PRESERVE_IVUV
                        USE_64_BIT_ALL USE_64_BIT_INT USE_ITHREADS
                        USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE
                        USE_LOCALE_CTYPE USE_LOCALE_NUMERIC USE_LOCALE_TIME
                        USE_PERLIO USE_PERL_ATOF USE_REENTRANT_API
  Locally applied patches:
        DEBPKG:debian/cpan_definstalldirs - Provide a sensible INSTALLDIRS default for modules installed from CPAN.
        DEBPKG:debian/db_file_ver - http://bugs.debian.org/340047 Remove overly restrictive DB_File version check.
        DEBPKG:debian/doc_info - Replace generic man(1) instructions with Debian-specific information.
        DEBPKG:debian/enc2xs_inc - http://bugs.debian.org/290336 Tweak enc2xs to follow symlinks and ignore missing @INC directories.
        DEBPKG:debian/errno_ver - http://bugs.debian.org/343351 Remove Errno version check due to upgrade problems with long-running processes.
        DEBPKG:debian/libperl_embed_doc - http://bugs.debian.org/186778 Note that libperl-dev package is required for embedded linking
        DEBPKG:fixes/respect_umask - Respect umask during installation
        DEBPKG:debian/writable_site_dirs - Set umask approproately for site install directories
        DEBPKG:debian/extutils_set_libperl_path - EU:MM: set location of libperl.a under /usr/lib
        DEBPKG:debian/no_packlist_perllocal - Don't install .packlist or perllocal.pod for perl or vendor
        DEBPKG:debian/fakeroot - Postpone LD_LIBRARY_PATH evaluation to the binary targets.
        DEBPKG:debian/instmodsh_doc - Debian policy doesn't install .packlist files for core or vendor.
        DEBPKG:debian/ld_run_path - Remove standard libs from LD_RUN_PATH as per Debian policy.
        DEBPKG:debian/libnet_config_path - Set location of libnet.cfg to /etc/perl/Net as /usr may not be writable.
        DEBPKG:debian/mod_paths - Tweak @INC ordering for Debian
        DEBPKG:debian/prune_libs - http://bugs.debian.org/128355 Prune the list of libraries wanted to what we actually need.
        DEBPKG:fixes/net_smtp_docs - [rt.cpan.org #36038] http://bugs.debian.org/100195 Document the Net::SMTP 'Port' option
        DEBPKG:debian/perlivp - http://bugs.debian.org/510895 Make perlivp skip include directories in /usr/local
        DEBPKG:debian/deprecate-with-apt - http://bugs.debian.org/747628 Point users to Debian packages of deprecated core modules
        DEBPKG:debian/squelch-locale-warnings - http://bugs.debian.org/508764 Squelch locale warnings in Debian package maintainer scripts
        DEBPKG:debian/skip-upstream-git-tests - Skip tests specific to the upstream Git repository
        DEBPKG:debian/patchlevel - http://bugs.debian.org/567489 List packaged patches for 5.22.1-9 in patchlevel.h
        DEBPKG:debian/skip-kfreebsd-crash - http://bugs.debian.org/628493 [perl #96272] Skip a crashing test case in t/op/threads.t on GNU/kFreeBSD
        DEBPKG:fixes/document_makemaker_ccflags - http://bugs.debian.org/628522 [rt.cpan.org #68613] Document that CCFLAGS should include $Config{ccflags}
        DEBPKG:debian/find_html2text - http://bugs.debian.org/640479 Configure CPAN::Distribution with correct name of html2text
        DEBPKG:debian/perl5db-x-terminal-emulator.patch - http://bugs.debian.org/668490 Invoke x-terminal-emulator rather than xterm in perl5db.pl
        DEBPKG:debian/cpan-missing-site-dirs - http://bugs.debian.org/688842 Fix CPAN::FirstTime defaults with nonexisting site dirs if a parent is writable
        DEBPKG:fixes/memoize_storable_nstore - [rt.cpan.org #77790] http://bugs.debian.org/587650 Memoize::Storable: respect 'nstore' option not respected
        DEBPKG:debian/regen-skip - Skip a regeneration check in unrelated git repositories
        DEBPKG:debian/makemaker-pasthru - http://bugs.debian.org/758471 Pass LD settings through to subdirectories
        DEBPKG:fixes/pod_man_reproducible_date - http://bugs.debian.org/759405 Support POD_MAN_DATE in Pod::Man for the left-hand footer
        DEBPKG:debian/locale-robustness - http://bugs.debian.org/782068 [perl #124310] Make t/run/locale.t survive missing locales masked by LC_ALL
        DEBPKG:fixes/podman-utc - http://bugs.debian.org/780259 Make the embedded date from Pod::Man reproducible
        DEBPKG:fixes/podman-utc-docs - http://bugs.debian.org/780259 Documentation and test suite updates for UTC fix
        DEBPKG:fixes/podman-empty-date - http://bugs.debian.org/780259 Support an empty POD_MAN_DATE environment variable
        DEBPKG:fixes/podman-pipe - http://bugs.debian.org/777405 Better errors for man pages from standard input
        DEBPKG:debian/pod2man-customized - Update porting/customized.dat for pod2man modifications
        DEBPKG:debian/makemaker-manext - http://bugs.debian.org/247370 Make EU::MakeMaker honour MANnEXT settings in generated manpage headers
        DEBPKG:debian/makemaker_customized - Update t/porting/customized.dat for files patched in Debian
        DEBPKG:debian/do-not-record-build-date - [6baa8db] http://bugs.debian.org/774422 [perl #125830] Allow overriding the compile time in "perl -V" output
        DEBPKG:fixes/podman-source-date-epoch - http://bugs.debian.org/801621 Make Pod::Man honor the SOURCE_DATE_EPOCH environment variable
        DEBPKG:fixes/podman-source-date-epoch-cleanups - http://bugs.debian.org/801621 Coding style and documentation for SOURCE_EPOCH_DATE
        DEBPKG:fixes/podman-source-date-epoch-testfix - http://bugs.debian.org/807086 Guard for building with SOURCE_DATE_EPOCH or POD_MAN_DATE set
        DEBPKG:debian/devel-ppport-reproducibility - http://bugs.debian.org/801523 Sort the list of XS code files when generating RealPPPort.xs
        DEBPKG:fixes/encode-unicode-bom - http://bugs.debian.org/798727 [rt.cpan.org #107043] Address https://rt.cpan.org/Public/Bug/Display.html?id=107043
        DEBPKG:debian/encode-unicode-bom-doc - http://bugs.debian.org/798727 Document Debian backport of Encode::Unicode fix
        DEBPKG:debian/kfreebsd-softupdates - http://bugs.debian.org/796798 Work around Debian Bug#796798
        DEBPKG:fixes/autodie-scope - http://bugs.debian.org/798096 Fix a scoping issue with "no autodie" and the "system" sub
        DEBPKG:debian/debugperl-compat-fix - [perl #127212] http://bugs.debian.org/810326 Disable PERL_TRACK_MEMPOOL for debugging builds
        DEBPKG:fixes/CVE-2015-8607_file_spec_taint_fix - http://bugs.debian.org/810719 [perl #126862] ensure File::Spec::canonpath() preserves taint
        DEBPKG:fixes/mkstemp-umask - http://bugs.debian.org/810924 [perl #127322] [e57270b] Fix umask for mkstemp(3) calls
        DEBPKG:fixes/crosscompile-no-targethost - [perl #127234] Fix the Configure escape with usecrosscompile but no targethost
        DEBPKG:fixes/podlators-no-encode - [rt.cpan.org #111156] Degrade gracefully if utf8 is requested but Encode is not available
        DEBPKG:debian/cross-time-hires - [rt.cpan.org #111391] Add an environment variable to skip running configuration probes
        DEBPKG:fixes/encode-unicode-pod - Unicode.pm: Fix POD error
        DEBPKG:fixes/memoize-pod - [rt.cpan.org #89441] Fix POD errors in Memoize
        DEBPKG:fixes/ok-pod - Added encoding for pod.
        DEBPKG:fixes/CVE-2016-2381_duplicate_env - remove duplicate environment variables from environ
  Built under linux

  Compiled at Mar 13 2016 11:54:18
  %ENV:
    PERLBREW_BASHRC_VERSION="0.76"
    PERLBREW_HOME="/home/vse/.perlbrew"
    PERLBREW_ROOT="/home/vse/perl5/perlbrew"
  @INC:
    /etc/perl
    /usr/local/lib/x86_64-linux-gnu/perl/5.22.1
    /usr/local/share/perl/5.22.1
    /usr/lib/x86_64-linux-gnu/perl5/5.22
    /usr/share/perl5
    /usr/lib/x86_64-linux-gnu/perl/5.22
    /usr/share/perl/5.22
    /usr/local/lib/site_perl
    /usr/lib/x86_64-linux-gnu/perl-base

Fri Aug 11 09:07:53 2017 victor [...] vsespb.ru - Status changed from 'rejected' to 'open'

@rwfranks
Copy link
Author

Sun Jan 28 11:30:33 2018 TIMB [...] cpan.org - Correspondence added

Thanks for the test case, and sorry for the delay replying.
I think your example demonstrates what I said earlier, "Some methods might be called on a database handle but internally they create and use a statement handle, such as the select_* methods."

Sun Jan 28 11:30:34 2018 TIMB [...] cpan.org - Status changed from 'open' to 'rejected'

@rwfranks
Copy link
Author

Sun Jan 28 12:18:28 2018 victor [...] vsespb.ru - Correspondence added

On Sun Jan 28 19:30:33 2018, TIMB wrote:

Thanks for the test case, and sorry for the delay replying.
I think your example demonstrates what I said earlier, "Some methods
might be called on a database handle but internally they create and
use a statement handle, such as the select_* methods."

"the DBI handle being used" means it'll be called with a database handle when the error occurred on a database handle, and called with a statement handle when the error occurred on a statement handle. Some methods might be called on a database handle but internally they create and use a statement handle, such as the select_* methods

Ok, I understand this. I think this really vague.

  1. The package is named DBI. There is connect method, which returns database handle. So people may think that "DBI handle" referrs to handle of class DBI (under the hood that it's
    not blessed to 'DBI', but it's internals already)

  2. If clever people don't think that way and understand that "DBI handle being used" means "any kind of object, which is used internally by DBI class and subclasses, which can
    be referred as "handle" in this documentation", then it still does not help, because to use that object (call method, ready properties etc) you should understand it's interface,
    i.e. you should have exhausive list of classes, that can be used here.

I propose changing docs to:

The subroutine is called with three parameters: the error message string that RaiseError and PrintError would use,
handle being used (database handle or statement handle, depending of internal implementation of the method that failed), and the first value
being returned by the method that failed (typically undef).

Sun Jan 28 12:19:39 2018 victor [...] vsespb.ru - Status changed from 'rejected' to 'open'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant