Croak on invalid top-level special ops
Peter Rabbitson [Fri, 26 Sep 2014 12:02:04 +0000 (14:02 +0200)]
When they were originally introduced it never occured neither to me, nor
whoever reviewed that a plain special-op will not work at top level.
Add an extra check at the fallback point (ugly, but still effective)

Changes
lib/SQL/Abstract.pm
t/05in_between.t

diff --git a/Changes b/Changes
index da25766..0878f8c 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,6 +1,7 @@
 Revision history for SQL::Abstract
 
     - Fix erroneous behavior of is_literal_value($) wrt { -ident => ... }
+    - Explicitly croak on top-level special ops (they didn't work anyway)
 
 revision 1.79  2014-09-25
 ----------------------------
index 24a062f..01b241f 100644 (file)
@@ -629,6 +629,11 @@ sub _where_HASHREF {
 sub _where_unary_op {
   my ($self, $op, $rhs) = @_;
 
+  # top level special ops are illegal in general
+  # this includes the -ident/-value ops (dual purpose unary and special)
+  puke "Illegal use of top-level '-$op'"
+    if ! defined $self->{_nested_func_lhs} and List::Util::first {$op =~ $_->{regex}} @{$self->{special_ops}};
+
   if (my $op_entry = List::Util::first {$op =~ $_->{regex}} @{$self->{unary_ops}}) {
     my $handler = $op_entry->{handler};
 
@@ -653,7 +658,7 @@ sub _where_unary_op {
 
   my ($sql, @bind) = $self->_SWITCH_refkind ($rhs, {
     SCALAR =>   sub {
-      puke "Illegal use of top-level '$op'"
+      puke "Illegal use of top-level '-$op'"
         unless defined $self->{_nested_func_lhs};
 
       return (
index 1111998..fc3aa1d 100644 (file)
@@ -266,6 +266,17 @@ my @in_between_tests = (
     throws => qr/Argument passed to the 'IN' operator can not be undefined/,
     test => '-in with undef argument',
   },
+
+  {
+    where => { -in => [42] },
+    throws => qr/Illegal use of top-level '-in'/,
+    test => 'Top level -in',
+  },
+  {
+    where => { -between => [42, 69] },
+    throws => qr/Illegal use of top-level '-between'/,
+    test => 'Top level -between',
+  },
 );
 
 for my $case (@in_between_tests) {