DBIx::ContextualFetch trouble
[prev]
[thread]
[next]
[Date index for 2004/12/27]
Hi,
As I reported earlier in
http://groups.kasei.com/mail/arc/cdbi-talk/2004-11/msg00046.html
during the test phase of DBIx::ContextualFetch on 5.8.5
(and now on 5.8.6 too) I get
Use of uninitialized value in subroutine entry at
DBIx-ContextualFetch-1.01/blib/lib/DBIx/ContextualFetch.pm line 51.
It started to really bother me now as I get similar warnings while I am
using CDBI. Before attacking the code of CDBI I tried to look at the test
suit of DBIx::ContextualFetch.
The first thing I got stuck with is that I don't understand this sub
in the test code:
sub make_sth {
my $sql = shift;
(my $sth = $dbh->prepare($sql))->execute;
return $sth;
}
It does not pass anything to execute();
but during the test cases some of the SQL strings passed to the
sub contain placeholders (?). As it seems I get the above warning
exactly in those cases when the query was prepared with a placeholder
but no actual value was supplied to execute.
I changed the above function to
sub make_sth {
my $sql = shift;
(my $sth = $dbh->prepare($sql))->execute(@_);
return $sth;
}
passing @_ to execute and changed the test cases to pass a parameter
to the make_sth sub. First of all I could eliminate all the warning
which looks good but:
It seems that in some cases the value passed to make_sth is used
and in other case it is not. Included a patch to the test file
that shows such cases. I'd appreciat if someone who actually understand
how this module should work would look at it.
regards
Gabor
ps. SVK rocks
=== t/01.t
==================================================================
--- t/01.t (revision 449)
+++ t/01.t (local)
@@ -6,7 +6,7 @@
BEGIN {
eval "use DBD::SQLite";
- plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 17);
+ plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 30);
}
use File::Temp qw/tempfile/;
@@ -24,7 +24,7 @@
sub make_sth {
my $sql = shift;
- (my $sth = $dbh->prepare($sql))->execute;
+ (my $sth = $dbh->prepare($sql))->execute(@_);
return $sth;
}
@@ -51,8 +51,39 @@
my $sth = make_sth("SELECT * FROM foo ORDER BY id");
my @got = $sth->fetchall;
is $got[1]->[1], "Barney", 'fetchall @';
+ is @got, 2, 'fetchall @ count';
}
+{ # fetchall @
+ my $sth = make_sth("SELECT * FROM foo WHERE id > ? ORDER BY id", 0);
+ my @got = $sth->fetchall(0); # parameter irrelevant here
+ is @got, 2, 'fetchall @ count';
+}
+
+{ # fetchall @
+ my $sth = make_sth("SELECT * FROM foo WHERE id > ? ORDER BY id", 0);
+ my @got = $sth->fetchall(100); # parameter irrelevant here
+ is @got, 2, 'fetchall @ count';
+}
+
+{ # fetchall @
+ my $sth = make_sth("SELECT * FROM foo WHERE id > ? ORDER BY id", 1);
+ my @got = $sth->fetchall(0); # parameter irrelevant here
+ is @got, 1, 'fetchall @ count';
+}
+
+{ # fetchall @
+ my $sth = make_sth("SELECT * FROM foo WHERE id > ? ORDER BY id", 1);
+ my @got = $sth->fetchall(1); # parameter irrelevant here
+ is @got, 1, 'fetchall @ count';
+}
+
+{ # fetchall @
+ my $sth = make_sth("SELECT * FROM foo WHERE id > ? ORDER BY id", 2);
+ my @got = $sth->fetchall(1); # parameter irrelevant here
+ is @got, 0, 'fetchall @ count';
+}
+
{ # fetchall $
my $sth = make_sth("SELECT * FROM foo ORDER BY id");
my $got = $sth->fetchall;
@@ -72,25 +103,44 @@
}
{ # select_row
- my $sth = make_sth("SELECT * FROM foo WHERE id = ?");
+ my $sth = make_sth("SELECT * FROM foo WHERE id = ?", 1);
my ($id, $name) = $sth->select_row(1);
is $name, "Fred", "select_row";
}
{ # select_col
- my $sth = make_sth("SELECT name FROM foo where id > ? ORDER BY id");
+ my $sth = make_sth("SELECT name FROM foo WHERE id > ? ORDER BY id", 0); # is parameter irrelevant ?
my @names = $sth->select_col(0);
+ is $names[0], "Fred", "select_col";
is $names[1], "Barney", "select_col";
+ is @names, 2, '> 0 count';
}
+{ # select_col
+ my $sth = make_sth("SELECT name FROM foo WHERE id > ? ORDER BY id", 0); # is parameter irrelevant ?
+ my @names = $sth->select_col(1);
+ is $names[0], "Barney", "select_col";
+ is @names, 1, '> 0 count';
+}
+
+{ # select_col
+ my $sth = make_sth("SELECT name FROM foo WHERE id > ? ORDER BY id", 100); # is parameter irrelevant ?
+ my @names = $sth->select_col(1);
+ is $names[0], "Barney", "select_col";
+ is @names, 1, '> 1 count';
+}
+
+
{ # select_val
- my $sth = make_sth("SELECT name FROM foo where id = ?");
+ my $sth = make_sth("SELECT name FROM foo where id = ?", 1); # is parameter irrelevant ?
my $name = $sth->select_val(1);
is $name, "Fred", "select_val";
+ my $noname = $sth->select_val(2);
+ is $noname, "Barney", "select_val where id=1";
}
{ # Execute binding
- my $sth = make_sth("SELECT * FROM foo WHERE id > ? ORDER BY id");
+ my $sth = $dbh->prepare("SELECT * FROM foo WHERE id > ? ORDER BY id");
$sth->execute([0], [ \my ($id, $name) ]);
$sth->fetch;
is $id, 1, "bound id 1";
@@ -100,3 +150,12 @@
is $name, "Barney", "name = Barney";
}
+# The warning we get when we prepare an SQL with a place holder but then execute it
+# without a parameter looks like this:
+# qr/Use of uninitialized value in subroutine entry/;
+# Probably DBIx::ContextFetch should die in such cases.
+# The warning arrives from the
+# _untaint_execute subroutine
+# from the
+# my $ret = $sth->SUPER::execute(@_);
+# line