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)