tmp
[scpubgit/Q-Branch.git] / lib / SQL / Abstract.pm
index c065f2c..23a9dd6 100644 (file)
@@ -38,7 +38,6 @@ our $AUTOLOAD;
 # See section WHERE: BUILTIN SPECIAL OPERATORS below for implementation
 my @BUILTIN_SPECIAL_OPS = (
   {regex => qr/^ (?: not \s )? between $/ix, handler => sub { die "NOPE" }},
-  {regex => qr/^ (?: not \s )? in      $/ix, handler => sub { die "NOPE" }},
   {regex => qr/^ is (?: \s+ not )?     $/ix, handler => sub { die "NOPE" }},
 );
 
@@ -171,7 +170,7 @@ sub new {
 
   if ($class->isa('DBIx::Class::SQLMaker')) {
     push @{$opt{special_ops}}, our $DBIC_Compat_Op ||= {
-      regex => qr/^(?:ident|value)$/i, handler => sub { die "NOPE" }
+      regex => qr/^(?:ident|value|(?:not\s)?in)$/i, handler => sub { die "NOPE" }
     };
     $opt{is_dbic_sqlmaker} = 1;
   }
@@ -556,6 +555,8 @@ sub where {
   return wantarray ? ($sql, @bind) : $sql;
 }
 
+{ our $Default_Scalar_To = -value }
+
 sub expand_expr {
   my ($self, $expr, $default_scalar_to) = @_;
   local our $Default_Scalar_To = $default_scalar_to if $default_scalar_to;
@@ -577,6 +578,12 @@ sub render_expr {
   $self->render_aqt($self->expand_expr($expr));
 }
 
+sub _normalize_op {
+  my ($self, $raw) = @_;
+  s/^-(?=[a-z])//, s/\s+/_/g for my $op = lc $raw;
+  $op;
+}
+
 sub _expand_expr {
   my ($self, $expr) = @_;
   our $Expand_Depth ||= 0; local $Expand_Depth = $Expand_Depth + 1;
@@ -687,10 +694,7 @@ sub _expand_expr_hashpair_ident {
 sub _expand_expr_scalar {
   my ($self, $expr) = @_;
 
-  if (my $d = our $Default_Scalar_To) {
-    return $self->_expand_expr({ $d => $expr });
-  }
-  return $self->_expand_value(-value => $expr);
+  return $self->_expand_expr({ (our $Default_Scalar_To) => $expr });
 }
 
 sub _expand_expr_hashpair_scalar {
@@ -704,13 +708,13 @@ sub _expand_expr_hashpair_scalar {
 sub _expand_expr_hashpair_op {
   my ($self, $k, $v) = @_;
 
-  my $op = $k;
-  $op =~ s/^-// if length($op) > 1;
+  my $op = $self->_normalize_op($k);
+
   $self->_assert_pass_injection_guard($op);
 
   # Ops prefixed with -not_ get converted
 
-  if (my ($rest) = $op =~/^not[_ ](.*)$/) {
+  if (my ($rest) = $op =~/^not_(.*)$/) {
     return +{ -op => [
       'not',
       $self->_expand_expr({ "-${rest}", $v })
@@ -720,6 +724,8 @@ sub _expand_expr_hashpair_op {
 
   { # Old SQLA compat
 
+    my $op = join(' ', split '_', $op);
+
     # the old special op system requires illegality for top-level use
 
     if (
@@ -778,9 +784,10 @@ sub _expand_expr_hashtriple {
 
   my $ik = $self->_expand_ident(-ident => $k);
 
-  my $op = join ' ', split '_', (map lc, $vk =~ /^-?(.*)$/)[0];
+  my $op = $self->_normalize_op($vk);
   $self->_assert_pass_injection_guard($op);
-  if ($op =~ s/ [_\s]? \d+ $//x ) {
+
+  if ($op =~ s/ _? \d+ $//x ) {
     return $self->_expand_expr($k, { $vk, $vv });
   }
   if (my $x = $self->{expand_op}{$op}) {
@@ -788,6 +795,9 @@ sub _expand_expr_hashtriple {
     return $self->$x($op, $vv, $k);
   }
   { # Old SQLA compat
+
+    my $op = join(' ', split '_', $op);
+
     if (my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}}) {
       return { -op => [ $op, $ik, $vv ] };
     }
@@ -841,7 +851,10 @@ sub _expand_expr_hashtriple {
 }
 
 sub _dwim_op_to_is {
-  my ($self, $op, $empty, $fail) = @_;
+  my ($self, $raw, $empty, $fail) = @_;
+
+  my $op = $self->_normalize_op($raw);
+
   if ($op =~ /^not$/i) {
     return 0;
   }
@@ -1092,6 +1105,8 @@ sub _render_op {
 
   { # Old SQLA compat
 
+    my $op = join(' ', split '_', $op);
+
     my $us = List::Util::first { $op =~ $_->{regex} } @{$self->{special_ops}};
     if ($us and @args > 1) {
       puke "Special op '${op}' requires first value to be identifier"
@@ -1185,14 +1200,15 @@ sub _render_op_not {
 sub _render_unop_prefix {
   my ($self, $op, $v) = @_;
   my ($expr_sql, @bind) = $self->render_aqt($v->[0]);
-  my $op_sql = $self->_sqlcase($op);
+
+  my $op_sql = $self->_sqlcase(join ' ', split '_', $op);
   return ("${op_sql} ${expr_sql}", @bind);
 }
 
 sub _render_unop_postfix {
   my ($self, $op, $v) = @_;
   my ($expr_sql, @bind) = $self->render_aqt($v->[0]);
-  my $op_sql = $self->_sqlcase($op);
+  my $op_sql = $self->_sqlcase(join ' ', split '_', $op);
   return ($expr_sql.' '.$op_sql, @bind);
 }