make between work as a binop
[scpubgit/Q-Branch.git] / lib / SQL / Abstract.pm
index d10aeae..131126b 100644 (file)
@@ -40,6 +40,8 @@ my @BUILTIN_SPECIAL_OPS = (
   {regex => qr/^ (?: not \s )? between $/ix, handler => sub { die "NOPE" }},
   {regex => qr/^ is (?: \s+ not )?     $/ix, handler => sub { die "NOPE" }},
   {regex => qr/^ (?: not \s )? in      $/ix, handler => sub { die "NOPE" }},
+  {regex => qr/^ ident                 $/ix, handler => sub { die "NOPE" }},
+  {regex => qr/^ value                 $/ix, handler => sub { die "NOPE" }},
 );
 
 #======================================================================
@@ -170,10 +172,8 @@ sub new {
   push @{$opt{special_ops}}, @BUILTIN_SPECIAL_OPS;
 
   if ($class->isa('DBIx::Class::SQLMaker')) {
-    push @{$opt{special_ops}}, our $DBIC_Compat_Op ||= {
-      regex => qr/^(?:ident|value|(?:not\s)?in)$/i, handler => sub { die "NOPE" }
-    };
     $opt{is_dbic_sqlmaker} = 1;
+    $opt{disable_old_special_ops} = 1;
   }
 
   # unary operators
@@ -204,6 +204,12 @@ sub new {
     -bind => sub { shift; +{ @_ } },
     -in => '_expand_in',
     -not_in => '_expand_in',
+    -tuple => sub {
+      my ($self, $node, $args) = @_;
+      +{ $node => [ map $self->expand_expr($_), @$args ] };
+    },
+    -between => '_expand_between',
+    -not_between => '_expand_between',
   };
 
   $opt{expand_op} = {
@@ -232,7 +238,7 @@ sub new {
   }
 
   $opt{render} = {
-    (map +("-$_", "_render_$_"), qw(op func bind ident literal list)),
+    (map +("-$_", "_render_$_"), qw(op func bind ident literal tuple)),
     %{$opt{render}||{}}
   };
 
@@ -733,6 +739,7 @@ sub _expand_expr_hashpair_op {
 
     if (
       (our $Expand_Depth) == 1
+      and $self->{disable_old_special_ops}
       and List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}}
     ) {
       puke "Illegal use of top-level '-$op'"
@@ -977,6 +984,8 @@ sub _expand_op_is {
 
 sub _expand_between {
   my ($self, $op, $vv, $k) = @_;
+  $op =~ s/^-//;
+  $k = shift @{$vv = [ @$vv ]} unless defined $k;
   local our $Cur_Col_Meta = $k;
   my @rhs = map $self->_expand_expr($_),
               ref($vv) eq 'ARRAY' ? @$vv : $vv;
@@ -997,13 +1006,12 @@ sub _expand_between {
 sub _expand_in {
   my ($self, $raw, $vv, $k) = @_;
   $k = shift @{$vv = [ @$vv ]} unless defined $k;
-  local our $Cur_Col_Meta = $k;
   my $op = $self->_normalize_op($raw);
   if (my $literal = is_literal_value($vv)) {
     my ($sql, @bind) = @$literal;
     my $opened_sql = $self->_open_outer_paren($sql);
     return +{ -op => [
-      $op, $self->_expand_ident(-ident => $k),
+      $op, $self->expand_expr($k, -ident),
       [ { -literal => [ $opened_sql, @bind ] } ]
     ] };
   }
@@ -1022,7 +1030,7 @@ sub _expand_in {
 
   return +{ -op => [
     $op,
-    $self->_expand_ident(-ident => $k),
+    $self->expand_expr($k, -ident),
     \@rhs
   ] };
 }
@@ -1072,10 +1080,10 @@ sub _render_ident {
   return $self->_convert($self->_quote($ident));
 }
 
-sub _render_list {
-  my ($self, $list) = @_;
-  my @parts = grep length($_->[0]), map [ $self->render_aqt($_) ], @$list;
-  return join(', ', map $_->[0], @parts), map @{$_}[1..$#$_], @parts;
+sub _render_tuple {
+  my ($self, $values) = @_;
+  my ($sql, @bind) = $self->_render_op([ ',', @$values ]);
+  return "($sql)", @bind;  
 }
 
 sub _render_func {
@@ -1192,7 +1200,7 @@ sub _render_op_multop {
   return '' unless @parts;
   return @{$parts[0]} if @parts == 1;
   my ($final_sql) = join(
-    ' '.$self->_sqlcase(join ' ', split '_', $op).' ',
+    ($op eq ',' ? '' : ' ').$self->_sqlcase(join ' ', split '_', $op).' ',
     map $_->[0], @parts
   );
   return (
@@ -1346,17 +1354,10 @@ sub _table  {
 
 sub _expand_maybe_list_expr {
   my ($self, $expr, $default) = @_;
-  my $e = do {
-    if (ref($expr) eq 'ARRAY') {
-      return { -list => [
-        map $self->expand_expr($_, $default), @$expr
-      ] } if @$expr > 1;
-      $expr->[0]
-    } else {
-      $expr
-    }
-  };
-  return $self->expand_expr($e, $default);
+  return +{ -op => [ ',',
+    map $self->expand_expr($_, $default),
+      ref($expr) eq 'ARRAY' ? @$expr : $expr
+  ] };
 }
 
 # highly optimized, as it's called way too often