Fix -values not being handled properly with NULLs
Peter Rabbitson [Wed, 16 Jul 2014 11:50:55 +0000 (13:50 +0200)]
Changes
lib/SQL/Abstract.pm
t/22op_value.t

diff --git a/Changes b/Changes
index 48cc17a..e2935f9 100644 (file)
--- a/Changes
+++ b/Changes
@@ -2,6 +2,7 @@ Revision history for SQL::Abstract
 
     - New attribute 'escape_char' allowing for proper escape of quote_chars
       present in an identifier
+    - Treat { -value => undef } as plain undef in all cases
 
 revision 1.78  2014-05-28
 ----------------------------
index 85d5957..1c7ba4d 100644 (file)
@@ -689,6 +689,14 @@ sub _where_op_VALUE {
   # in case we are called as a top level special op (no '=')
   my $lhs = shift;
 
+  # special-case NULL
+  if (! defined $rhs) {
+    return $lhs
+      ? $self->_convert($self->_quote($lhs)) . ' IS NULL'
+      : undef
+    ;
+  }
+
   my @bind =
     $self->_bindtype (
       ($lhs || $self->{_nested_func_lhs}),
@@ -765,6 +773,11 @@ sub _where_hashpair_HASHREF {
     # so that -not_foo works correctly
     $op =~ s/^not_/NOT /i;
 
+    # another retarded special case: foo => { $op => { -value => undef } }
+    if (ref $val eq 'HASH' and keys %$val == 1 and exists $val->{-value} and ! defined $val->{-value} ) {
+      $val = undef;
+    }
+
     my ($sql, @bind);
 
     # CASE: col-value logic modifiers
index 00cb5c5..2992ff6 100644 (file)
@@ -40,6 +40,38 @@ for my $col_btype (0,1) {
         )
     ],
   );
+
+  {
+    local $SIG{__WARN__} = sub { warn @_ unless $_[0] =~ /Supplying an undefined argument to '(?:NOT )?LIKE'/ };
+
+    ($sql, @bind) = $sql_maker->where ({
+      c1 => undef,
+      c2 => { -value => undef },
+      c3 => { '=' => { -value => undef } },
+      c4 => { '!=' => { -value => undef } },
+      c5 => { '<>' => { -value => undef } },
+      c6 => { '-like' => { -value => undef } },
+      c7 => { '-not_like' => { -value => undef } },
+      c8 => { 'is' => { -value => undef } },
+      c9 => { 'is not' => { -value => undef } },
+    });
+
+    is_same_sql_bind (
+      $sql,
+      \@bind,
+      "WHERE  ${q}c1${q} IS NULL
+          AND ${q}c2${q} IS NULL
+          AND ${q}c3${q} IS NULL
+          AND ${q}c4${q} IS NOT NULL
+          AND ${q}c5${q} IS NOT NULL
+          AND ${q}c6${q} IS NULL
+          AND ${q}c7${q} IS NOT NULL
+          AND ${q}c8${q} IS NULL
+          AND ${q}c9${q} IS NOT NULL
+      ",
+      [],
+    );
+  }
 }}
 
 done_testing;