Optimise out AND/OR clause in { -(not_)in => [undef] }
Dagfinn Ilmari Mannsåker [Wed, 4 Dec 2013 14:12:11 +0000 (14:12 +0000)]
lib/SQL/Abstract/Converter.pm
t/01generate.t

index 2d79ec9..7da6b74 100644 (file)
@@ -510,10 +510,16 @@ sub _where_hashpair_to_dq {
         my ($inop, $logic, $nullop) = $op =~ /^NOT/
           ? (-not_in => AND => { '!=' => undef })
           : (-in => OR => undef);
-        return $self->_expr_to_dq_ARRAYREF([
-            { $k => { $inop => [grep defined, @$rhs] } },
+        if (my @defined = grep defined, @$rhs) {
+          return $self->_expr_to_dq_ARRAYREF([
+            { $k => { $inop => \@defined } },
             { $k => $nullop },
           ], $logic);
+        } else {
+          return $self->_expr_to_dq_HASHREF({
+            $k => $nullop,
+          });
+        }
       }
       return $self->_literal_to_dq(
         $op =~ /^NOT/ ? $self->{sqltrue} : $self->{sqlfalse}
index c256b75..55d3dd8 100644 (file)
@@ -559,6 +559,13 @@ my @tests = (
               stmt_q => 'SELECT * FROM `test` WHERE ( ( `a` IN ( ? ) OR `a` IS NULL ) AND `b` NOT IN ( ? ) AND `b` IS NOT NULL )',
               bind => [ 42, 42 ],
       },
+      {
+              func => 'select',
+              args => ['test', '*', { a => { -in => [undef] }, b => { -not_in => [undef] } } ],
+              stmt => 'SELECT * FROM test WHERE ( a IS NULL AND b IS NOT NULL )',
+              stmt_q => 'SELECT * FROM `test` WHERE ( `a` IS NULL AND `b` IS NOT NULL )',
+              bind => [],
+      },
 );
 
 for my $t (@tests) {