lift injection validation
[scpubgit/Q-Branch.git] / lib / SQL / Abstract.pm
index e137e54..6a037fb 100644 (file)
@@ -193,6 +193,7 @@ sub new {
     -bool => '_expand_bool',
     -and => '_expand_andor',
     -or => '_expand_andor',
+    -nest => '_expand_nest',
   };
 
   $opt{expand_op} = {
@@ -200,14 +201,15 @@ sub new {
     'not between' => '_expand_between',
     'in' => '_expand_in',
     'not in' => '_expand_in',
-    'ident' => sub {
+    (map +($_ => sub {
       my ($self, $op, $arg, $k) = @_;
       return +{ -op => [
         $self->{cmp},
         $self->_expand_ident(-ident => $k),
         $self->_expand_expr({ '-'.$op => $arg }),
       ] };
-    },
+    }), qw(ident value)),
+    'nest' => '_expand_nest',
   };
 
   $opt{render} = {
@@ -595,22 +597,8 @@ sub _expand_expr_hashpair {
     }
     puke "Supplying an empty left hand side argument is not supported";
   }
+  $self->_assert_pass_injection_guard($k =~ /^-(.*)$/s) if $k =~ /^-/;
   if ($k =~ /^-/) {
-    $self->_assert_pass_injection_guard($k =~ /^-(.*)$/s);
-    if ($k eq '-nest') {
-      # DBIx::Class requires a nest warning to be emitted once but the private
-      # method it overrode to do so no longer exists
-      if ($self->{is_dbic_sqlmaker}) {
-        unless (our $Nest_Warned) {
-          belch(
-            "-nest in search conditions is deprecated, you most probably wanted:\n"
-            .q|{..., -and => [ \%cond0, \@cond1, \'cond2', \[ 'cond3', [ col => bind ] ], etc. ], ... }|
-          );
-          $Nest_Warned = 1;
-        }
-      }
-      return $self->_expand_expr($v);
-    }
     if (my ($rest) = $k =~/^-not[_ ](.*)$/) {
       return +{ -op => [
         'not',
@@ -692,15 +680,11 @@ sub _expand_expr_hashpair {
           . "You probably wanted ...-and => [ -$op => COND1, -$op => COND2 ... ]";
     }
     if (my $x = $self->{expand_op}{$op}) {
+      local our $Cur_Col_Meta = $k;
       return $self->$x($op, $vv, $k);
     }
-    if ($op eq 'value') {
+    if ($op eq 'value' and not defined($vv)) {
       return $self->_expand_expr({ $k, undef }) unless defined($vv);
-      return +{ -op => [
-        $self->{cmp},
-        $self->_expand_ident(-ident => $k),
-        { -bind => [ $k, $vv ] }
-      ] };
     }
     if ($op =~ /^is(?: not)?$/) {
       puke "$op can only take undef as argument"
@@ -713,13 +697,10 @@ sub _expand_expr_hashpair {
       return +{ -op => [ $op.' null', $self->_expand_ident(-ident => $k) ] };
     }
     if ($op =~ /^(and|or)$/) {
-      if (ref($vv) eq 'HASH') {
-        return +{ -op => [
-          $op,
-          map $self->_expand_expr({ $k, { $_ => $vv->{$_} } }),
-            sort keys %$vv
-        ] };
-      }
+      return $self->_expand_andor('-'.$op, [
+        map +{ $k, { $_ => $vv->{$_} } },
+          sort keys %$vv
+      ]);
     }
     if (my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}}) {
       return { -op => [ $op, $self->_expand_ident(-ident => $k), $vv ] };
@@ -757,11 +738,10 @@ sub _expand_expr_hashpair {
         : $op =~ $self->{not_like_op}   ? belch("Supplying an empty arrayref to '@{[ uc $op]}' is deprecated") && $self->sqltrue
         : puke "operator '$op' applied on an empty array (field '$k')";
       }
-      return +{ -op => [
-        $logic =~ /^-(.*)$/,
-        map $self->_expand_expr({ $k => { $vk => $_ } }),
+      return $self->_expand_andor($logic => [
+        map +{ $k => { $vk => $_ } },
           @values
-      ] };
+      ]);
     }
     if (
       !defined($vv)
@@ -795,9 +775,9 @@ sub _expand_expr_hashpair {
         ? shift(@{$v = [ @$v ]})
         : '-'.($self->{logic} || 'or')
     );
-    return $self->_expand_expr({
+    return $self->_expand_andor(
       $this_logic => [ map +{ $k => $_ }, @$v ]
-    });
+    );
   }
   if (my $literal = is_literal_value($v)) {
     unless (length $k) {
@@ -942,6 +922,22 @@ sub _expand_in {
   ] };
 }
 
+sub _expand_nest {
+  my ($self, $op, $v) = @_;
+  # DBIx::Class requires a nest warning to be emitted once but the private
+  # method it overrode to do so no longer exists
+  if ($self->{is_dbic_sqlmaker}) {
+    unless (our $Nest_Warned) {
+      belch(
+        "-nest in search conditions is deprecated, you most probably wanted:\n"
+        .q|{..., -and => [ \%cond0, \@cond1, \'cond2', \[ 'cond3', [ col => bind ] ], etc. ], ... }|
+      );
+      $Nest_Warned = 1;
+    }
+  }
+  return $self->_expand_expr($v);
+}
+
 sub _recurse_where {
   my ($self, $where, $logic) = @_;