One more fail-case missed in 135ac69dd
Peter Rabbitson [Thu, 4 Sep 2014 10:19:48 +0000 (12:19 +0200)]
Now the test attached to RT#98161 actually passes... le sigh

At this point I am very wary of the entire codepath: yes, it is clearly the
right thing to do, and the logic is sound, but odd edge cases keep popping
up like this... OTOH there is no way to properly do equality inferrence
without this entire dance, in other words: rock&hardplace. Hopefully the
test suites will shake this out, apologoies to all affected :(

lib/DBIx/Class/Storage/DBIHacks.pm
t/sqlmaker/dbihacks_internals.t

index da09d12..f13be43 100644 (file)
@@ -1086,10 +1086,12 @@ sub _collapse_cond {
     return unless $fin_idx;
 
     $fin = ( keys %$fin_idx == 1 ) ? (values %$fin_idx)[0] : {
-      -or => [ map
-        { ref $fin_idx->{$_} eq 'HASH' ? %{$fin_idx->{$_}} : $fin_idx->{$_} }
-        sort keys %$fin_idx
-      ]
+      -or => [ map {
+        # unroll single-element hashes
+        ( ref $fin_idx->{$_} eq 'HASH' and keys %{$fin_idx->{$_}} == 1 )
+          ? %{$fin_idx->{$_}}
+          : $fin_idx->{$_}
+      } sort keys %$fin_idx ]
     };
   }
   else {
index 32ec846..a225cdc 100644 (file)
@@ -147,6 +147,16 @@ for my $t (
 
   ) ),
   {
+    where => { -or => [ -and => [ foo => { '!=', undef }, bar => { -in => [ 69, 42 ] } ], foo => { '=', { -value => undef } } ] },
+    sql => 'WHERE ( foo IS NOT NULL AND bar IN ( ?, ? ) ) OR foo IS NULL',
+    collapsed_sql => 'WHERE foo IS NULL OR ( bar IN ( ?, ? ) AND foo IS NOT NULL )',
+    cc_result => { -or => [
+      foo => undef,
+      { bar => { -in => [ 69, 42 ] }, foo => { '!=', undef } }
+    ] },
+    efcc_result => {},
+  },
+  {
     where => { -or => [ rank => { '=' => \13 }, charfield => { '=' => undef }, artistid => { '=' => 1 }, genreid => { '=' => \['?', 2] } ] },
     sql => 'WHERE rank = 13 OR charfield IS NULL OR artistid = ? OR genreid = ?',
     collapsed_sql => 'WHERE artistid = ? OR charfield IS NULL OR genreid = ? OR rank = 13',