On Mon, Dec 06, 2004 at 10:09:25AM +0100, Steffen Goeldner wrote:
> Jonathan Leffler wrote:
> 
> >Testing null handling in DBD::Informix 2004.02 (pre-release), I'm
> >getting a warning from Perl:
> >
> >Use of uninitialized value in subroutine entry at t/t91udts.t line 97.
> 
> Some day I got the same warning (in another DBD). It was a call like:
> 
>   $sth->set_err($n, $s);
> 
> where $s was undef.

Ah, thanks.

$ DBI_TRACE=9 perl -MDBI -we '$SIG{__WARN__}=sub{ dump }; 
DBI->connect("dbi:NullP:test","","")->set_err(1,undef)'
 ...
    -> set_err in DBD::_::common for DBD::NullP::db 
(DBI::db=HASH(0x8286288)~0x8286ad0 1 undef) thr#81c6000
    !! ERROR: 1 undef (err#1)
    <- set_err= undef at -e line 1
Abort trap (core dumped)

#10 0x80e7beb in Perl_report_uninit (my_perl=0x81c6000) at sv.c:611
#11 0x80ed008 in Perl_sv_2pv_flags (my_perl=0x81c6000, sv=0x82caf84, 
lp=0xbfbff288, flags=2) at sv.c:3208
#12 0x80f0b6f in Perl_sv_catsv_flags (my_perl=0x81c6000, dsv=0x8286c60, 
ssv=0x82caf84, flags=2) at sv.c:4457
#13 0x282c1f67 in XS_DBI_dispatch (my_perl=0x81c6000, cv=0x8323d8c) at 
DBI.xs:2869
#14 0x80e594e in Perl_pp_entersub (my_perl=0x81c6000) at pp_hot.c:2890

Umm. That's the code which constructs the PrintError/RaiseError
message ("<class> <method> failed: <errstr>"). The warning is because
errstr is undef at that point, because that's what set_err set it to,
because that's what you asked it to do.

I've appended a provisional patch.

Now, the question is, should a driver be allowed to set an error state
without providing an error string?
Should a (more useful) warning be generated by set_err?
Should set_err set errstr to a default like "(errstr undef)"?

Tim.

--- DBI.xs      (revision 583)
+++ DBI.xs      (working copy)
@@ -2870,7 +2870,10 @@
        sprintf(intro,"%s %s %s: ", HvNAME(DBIc_IMP_STASH(imp_xxh)), 
err_meth_name,
            SvTRUE(err_sv) ? "failed" : is_warning ? "warning" : "information");
        msg = sv_2mortal(newSVpv(intro,0));
-       sv_catsv(msg, DBIc_ERRSTR(imp_xxh));
+       if (SvOK(DBIc_ERRSTR(imp_xxh))
+           sv_catsv(msg, DBIc_ERRSTR(imp_xxh));
+       else
+           sv_catpv(msg, "(errstr undef)");

        if (    DBIc_has(imp_xxh, DBIcf_ShowErrorStatement)
            && (DBIc_TYPE(imp_xxh) == DBIt_ST || ima_flags & IMA_SHOW_ERR_STMT)

Reply via email to