clean up EC _expand_select
[scpubgit/Q-Branch.git] / t / 05in_between.t
index 1111998..5bcbe55 100644 (file)
@@ -174,6 +174,17 @@ my @in_between_tests = (
     bind => [],
     test => '-in multi-line subquery test',
   },
+
+  # check that the outer paren opener is not too agressive
+  # note: this syntax *is not legal* on SQLite (maybe others)
+  #       see end of https://rt.cpan.org/Ticket/Display.html?id=99503
+  {
+    where => { foo => { -in => \ '(SELECT 1) UNION (SELECT 2)' } },
+    stmt => 'WHERE foo IN ( (SELECT 1) UNION (SELECT 2) )',
+    bind => [],
+    test => '-in paren-opening works on balanced pairs only',
+  },
+
   {
     where => {
       customer => { -in => \[
@@ -266,6 +277,61 @@ my @in_between_tests = (
     throws => qr/Argument passed to the 'IN' operator can not be undefined/,
     test => '-in with undef argument',
   },
+
+  {
+    where => { -in => [ 'bob', 4, 2 ] },
+    stmt => ' WHERE (bob IN (?, ?))',
+    bind => [ 4, 2 ],
+    test => 'Top level -in',
+  },
+# This works but then SQL::Abstract::Tree breaks - something for a later commit
+#  {
+#    where => { -in => [ { -list => [ qw(x y) ] }, { -list => [ 1, 3 ] }, { -list => [ 2, 4 ] } ] },
+#    stmt => ' WHERE ((x, y) IN ((?, ?), (?, ?))',
+#    bind => [ 1, 3, 2, 4 ],
+#    test => 'Top level -in with list args',
+#  },
+  {
+    where => { -between => [42, 69] },
+    throws => qr/Fatal: Operator 'BETWEEN' requires/,
+    test => 'Top level -between with broken args',
+  },
+  {
+    where => {
+      -between => [
+        { -op => [ '+', { -ident => 'foo' }, 2 ] },
+        3, 4
+      ],
+    },
+    stmt => ' WHERE (foo + ? BETWEEN ? AND ?)',
+    bind => [ 2, 3, 4 ],
+    test => 'Top level -between with useful LHS',
+  },
+  {
+    where => {
+      -in => [
+        { -row => [ 'x', 'y' ] },
+        { -row => [ 1, 2 ] },
+        { -row => [ 3, 4 ] },
+      ],
+    },
+    stmt => ' WHERE (x, y) IN ((?, ?), (?, ?))',
+    bind => [ 1..4 ],
+    test => 'Complex top-level -in',
+  },
+  {
+    where => { -is => [ 'bob', undef ] },
+    stmt => ' WHERE bob IS NULL',
+    bind => [],
+    test => 'Top level -is ok',
+  },
+  {
+    where => { -op => [ in => x => 1, 2, 3 ] },
+    stmt => ' WHERE x IN (?, ?, ?)',
+    bind => [ 1, 2, 3 ],
+    test => 'Raw -op passes through correctly'
+  },
+
 );
 
 for my $case (@in_between_tests) {
@@ -274,7 +340,7 @@ for my $case (@in_between_tests) {
     local $SQL::Abstract::Test::parenthesis_significant = $case->{parenthesis_significant};
     my $label = $case->{test} || 'in-between test';
 
-    my $sql = SQL::Abstract->new ($case->{args} || {});
+    my $sql = SQL::Abstract->new($case->{args} || {});
 
     if (my $e = $case->{throws}) {
       my $stmt;
@@ -283,17 +349,19 @@ for my $case (@in_between_tests) {
     }
     else {
       my ($stmt, @bind);
-      warnings_are {
-        ($stmt, @bind) = $sql->where($case->{where});
-      } [], "$label gives no warnings";
-
-      is_same_sql_bind(
-        $stmt,
-        \@bind,
-        $case->{stmt},
-        $case->{bind},
-        "$label generates correct SQL and bind",
-      ) || diag_where ( $case->{where} );
+      lives_ok {
+        warnings_are {
+          ($stmt, @bind) = $sql->where($case->{where});
+        } [], "$label gives no warnings";
+  
+        is_same_sql_bind(
+          $stmt,
+          \@bind,
+          $case->{stmt},
+          $case->{bind},
+          "$label generates correct SQL and bind",
+        ) || diag dumper ({ where => $case->{where}, exp => $sql->_expand_expr($case->{where}) });
+      } || diag dumper ({ where => $case->{where}, exp => $sql->_expand_expr($case->{where}) });
     }
   }
 }