Author: turnstep
Date: Mon Jul 20 11:45:16 2009
New Revision: 13090
Modified:
DBD-Pg/trunk/Changes
DBD-Pg/trunk/quote.c
DBD-Pg/trunk/t/12placeholders.t
Log:
Quick fixes to quote_bool, needs review.
Modified: DBD-Pg/trunk/Changes
==============================================================================
--- DBD-Pg/trunk/Changes (original)
+++ DBD-Pg/trunk/Changes Mon Jul 20 11:45:16 2009
@@ -4,6 +4,7 @@
- Make quoting of int, floats, and names much safer. (CPAN bug #41565) [GSM]
- Make quoting of geometric types respect all valid chars (CPAN bug #41565)
[GSM]
+ - Fix quoting of booleans to respect more Perlish variants (CPAN bug #41565)
[GSM]
- Return ints and bools-cast-to-number from the db as true Perlish numbers.
(CPAN bug #47619) [GSM]
- Fix backslash quoting of arrays (CPAN bug #46732) [GSM]
Modified: DBD-Pg/trunk/quote.c
==============================================================================
--- DBD-Pg/trunk/quote.c (original)
+++ DBD-Pg/trunk/quote.c Mon Jul 20 11:45:16 2009
@@ -269,33 +269,44 @@
}
+/* Return TRUE, FALSE, or throws an error */
char * quote_bool(const char *value, STRLEN len, STRLEN *retlen, int estring)
{
dTHX;
char *result;
- long int int_value;
- STRLEN max_len=6;
- len = 0;
- if (isDIGIT(*(const char*)value)) {
- /* For now -- will go away when quote* take SVs */
- int_value = atoi(value);
- } else {
- int_value = 42; /* Not true, not false. Just is */
+ /* Things that are true: t, T, 1, true, TRUE, 0E0, 0 but true */
+ if (
+ (1 == len && (0 == strncasecmp(value, "t", 1) || '1' == *value))
+ ||
+ (4 == len && 0 == strncasecmp(value, "true", 4))
+ ||
+ (3 == len && 0 == strncasecmp(value, "0e0", 3))
+ ||
+ (10 == len && 0 == strncasecmp(value, "0 but true", 10))
+ ) {
+ New(0, result, 5, char);
+ strncpy(result,"TRUE\0",5);
+ *retlen = 4;
+ return result;
}
- New(0, result, max_len, char);
-
- if (0 == int_value)
+
+ /* Things that are false: f, F, 0, false, FALSE, 0, zero-length string
*/
+ if (
+ (1 == len && (0 == strncasecmp(value, "f", 1) || '0' == *value))
+ ||
+ (5 == len && 0 == strncasecmp(value, "false", 5))
+ ||
+ (0 == len)
+ ) {
+ New(0, result, 6, char);
strncpy(result,"FALSE\0",6);
- else if (1 == int_value)
- strncpy(result,"TRUE\0",5);
- else
- croak("Error: Bool must be either 1 or 0");
-
- *retlen = strlen(result);
- assert(*retlen+1 <= max_len);
+ *retlen = 5;
+ return result;
+ }
- return result;
+ croak("Invalid boolean value");
+
}
char * quote_int(const char *string, STRLEN len, STRLEN *retlen, int estring)
Modified: DBD-Pg/trunk/t/12placeholders.t
==============================================================================
--- DBD-Pg/trunk/t/12placeholders.t (original)
+++ DBD-Pg/trunk/t/12placeholders.t Mon Jul 20 11:45:16 2009
@@ -17,7 +17,7 @@
if (! defined $dbh) {
plan skip_all => 'Connection to database failed, cannot continue
testing';
}
-plan tests => 213;
+plan tests => 237;
my $t='Connect to database for placeholder testing';
isnt ($dbh, undef, $t);
@@ -27,7 +27,7 @@
$dbh->do('SET escape_string_warning = false');
}
-my ($sth, $result, $SQL, $qresult);
+my ($result, $SQL, $qresult);
# Make sure that quoting works properly.
$t='Quoting works properly';
@@ -129,7 +129,7 @@
}
$t='Prepare with backslashes inside quotes works';
-my $SQL = q{SELECT setting FROM pg_settings WHERE name = 'backslash_quote'};
+$SQL = q{SELECT setting FROM pg_settings WHERE name = 'backslash_quote'};
$count = $dbh->selectall_arrayref($SQL)->[0];
my $backslash = defined $count ? $count->[0] : 0;
my $scs = $dbh->{pg_standard_conforming_strings};
@@ -390,9 +390,59 @@
is($got, $expected, $t);
}
-## Test quoting of geometric types
+## Test quoting of booleans
+my %booltest = (
+undef => 'NULL',
+'t' => 'TRUE',
+'T' => 'TRUE',
+'true' => 'TRUE',
+'TRUE' => 'TRUE',
+1 => 'TRUE',
+01 => 'TRUE',
+'1' => 'TRUE',
+'0E0' => 'TRUE',
+'0e0' => 'TRUE',
+'0 but true' => 'TRUE',
+'0 BUT TRUE' => 'TRUE',
+'f' => 'FALSE',
+'F' => 'FALSE',
+0 => 'FALSE',
+00 => 'FALSE',
+'0' => 'FALSE',
+'false' => 'FALSE',
+'FALSE' => 'FALSE',
+12 => 'ERROR',
+'01' => 'ERROR',
+'00' => 'ERROR',
+' false' => 'ERROR',
+' TRUE' => 'ERROR',
+'FALSEY' => 'ERROR',
+'trueish' => 'ERROR',
+'0E0E0' => 'ERROR', ## Jungle love...
+'0 but truez' => 'ERROR',
+);
+while (my ($name,$val) = each %booltest) {
+ $name = undef if $name eq 'undef';
+ $t = sprintf 'Boolean quoting of %s',
+ defined $name ? qq{"$name"} : 'undef';
+ eval { $result = $dbh->quote($name, {pg_type => PG_BOOL}); };
+ if ($@) {
+ if ($val eq 'ERROR' and $@ =~ /Invalid boolean/) {
+ pass $t;
+ }
+ else {
+ fail "Failure at $t: $...@\n";
+ }
+ $dbh->rollback();
+ }
+ else {
+ is ($result, $val, $t);
+ }
+}
+
+## Test quoting of geometric types
my @geotypes = qw/point line lseg box path polygon circle/;