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/;
 

Reply via email to