start of moving and/or to ops
[scpubgit/Q-Branch.git] / lib / SQL / Abstract.pm
index fefaf94..c75bd6f 100644 (file)
@@ -545,7 +545,8 @@ sub _expand_expr {
   if (ref($expr) eq 'HASH') {
     if (keys %$expr > 1) {
       $logic ||= 'and';
-      return +{ "-${logic}" => [
+      return +{ -op => [
+        $logic,
         map $self->_expand_expr_hashpair($_ => $expr->{$_}, $logic),
           sort keys %$expr
       ] };
@@ -574,7 +575,7 @@ sub _expand_expr {
       } elsif ($elref eq 'HASH') {
         push @res, $self->_expand_expr($el);
       } else {
-        die "unimplemented"
+        die "notreached";
       }
     }
     return { '-'.$logic => \@res };
@@ -588,7 +589,6 @@ sub _expand_expr {
     }
     return +{ -value => $expr };
   }
-  #::Ddie([ HUH => $expr ]);
   die "notreached";
 }
 
@@ -618,12 +618,13 @@ sub _expand_expr_hashpair {
       return { -ident => $v };
     }
     if ($k eq '-not') {
-      return { -not => $self->_expand_expr($v) };
+      return { -op => [ 'not', $self->_expand_expr($v) ] };
     }
     if (my ($rest) = $k =~/^-not[_ ](.*)$/) {
-      return +{ -not =>
+      return +{ -op => [
+        'not',
         $self->_expand_expr_hashpair("-${rest}", $v, $logic)
-      };
+      ] };
     }
     if (my ($logic) = $k =~ /^-(and|or)$/i) {
       if (ref($v) eq 'HASH') {
@@ -800,9 +801,17 @@ sub _expand_expr_hashpair {
               . "to say ...{ \$inequality_op => [ -and => \@values ] }... instead)"
           ;
         }
-        return $self->{sqltrue} unless @values;
       }
-      return $self->{sqlfalse} unless @values;
+      unless (@values) {
+        # try to DWIM on equality operators
+        my $op = join ' ', split '_', $vk;
+        return
+          $op =~ $self->{equality_op}   ? $self->{sqlfalse}
+        : $op =~ $self->{like_op}       ? belch("Supplying an empty arrayref to '@{[ uc $op]}' is deprecated") && $self->{sqlfalse}
+        : $op =~ $self->{inequality_op} ? $self->{sqltrue}
+        : $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 +{ $logic => [
         map $self->_expand_expr_hashpair($k => { $vk => $_ }),
           @values
@@ -858,9 +867,7 @@ sub _expand_expr_hashpair {
     }
     return +{ -literal => [ $self->_quote($k).' '.$sql, @bind ] };
   }
-  ::Ddie([ HUH => { $k => $v } ]);
   die "notreached";
-  return { $k => $v };
 }
 
 sub _recurse_where {
@@ -1279,12 +1286,16 @@ sub _where_op_OP {
         ? "${expr_sql} ${op_sql}"
         : "${op_sql} ${expr_sql}"
     );
-    return ($final_sql, @bind);
-  } elsif (@args == 2) {
-     my ($l, $r) = map [ $self->_recurse_where($_) ], @args;
+    return (($op eq 'not' ? '('.$final_sql.')' : $final_sql), @bind);
+  } else {
+     my @parts = map [ $self->_recurse_where($_) ], @args;
+     my ($final_sql) = map +($op =~ /^(and|or)$/ ? "(${_})" : $_), join(
+       ' '.$self->_sqlcase($final_op).' ',
+       map $_->[0], @parts
+     );
      return (
-       $l->[0].' '.$self->_sqlcase($final_op).' '.$r->[0],
-       @{$l}[1..$#$l], @{$r}[1..$#$r]
+       $final_sql,
+       map @{$_}[1..$#$_], @parts
      );
   }
   die "unhandled";