The sequence support in the module relies on checking the return value
of $dbh->do(). It, however, never returns a false value if there were
no error. So an update which touches zero rows will return a string
"0E0", which has numeric value of 0 but has boolean value of true.
This behavir is actually documented by DBI. This feature and its
handling by DBD::PgLite leads to nextval() being broken for cases when
no table corresponding to a sequence existed, or when such a table had
no rows.
The attached patch fixes the problem.
I hope it will get included into the next version.
Cheers,
Anton.
Subject: | pglite.patch |
--- lib/DBD/PgLite.pm.orig 2008-11-04 12:15:15.000000000 +0100
+++ lib/DBD/PgLite.pm 2008-11-04 12:16:02.000000000 +0100
@@ -148,9 +148,9 @@ sub _nextval {
my $tries;
while (1) {
my $rc = $dbh->do("update pglite_seq set last_value = last_value + 1, is_locked = 1 where sequence_name = ? and is_locked = 0 and is_called = 1",{},$sn);
- last if $rc;
+ last if $rc && $rc > 0;
$rc = $dbh->do("update pglite_seq set is_locked = 1 where sequence_name = ? and is_locked = 0 and is_called = 0",{},$sn);
- last if $rc;
+ last if $rc && $rc > 0;
Time::HiRes::sleep(0.05);
die "Too many tries trying to update sequence '$sn' - need manual fix?" if ++$tries > 20;
}
@@ -193,7 +193,7 @@ sub _setval {
while (1) {
my $rc = $dbh->do("update pglite_seq set last_value = ?, is_called = ? where sequence_name = ? and is_locked = 0",
{}, $val, $called, $sn);
- last if $rc;
+ last if $rc && $rc > 0;
Time::HiRes::sleep(0.05);
die "Too many tries trying to update sequence '$sn' - need manual fix?" if ++$tries > 20;
}