Cut down amount of calls to _resolve_aliastypes_from_select_args
Peter Rabbitson [Thu, 18 Apr 2013 15:14:21 +0000 (17:14 +0200)]
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/Storage/DBI.pm
lib/DBIx/Class/Storage/DBIHacks.pm

index c2e0e8c..cc9131c 100644 (file)
@@ -1837,20 +1837,12 @@ sub _rs_update_delete {
 
   # simplify the joinmap, so we can further decide if a subq is necessary
   if (!$needs_subq and @{$attrs->{from}} > 1) {
-    $attrs->{from} = $storage->_prune_unused_joins ($attrs->{from}, $attrs->{select}, $self->{cond}, $attrs);
-
-    # check if there are any joins left after the prune
-    if ( @{$attrs->{from}} > 1 ) {
-      $join_classifications = $storage->_resolve_aliastypes_from_select_args (
-        [ @{$attrs->{from}}[1 .. $#{$attrs->{from}}] ],
-        $attrs->{select},
-        $self->{cond},
-        $attrs
-      );
 
-      # any non-pruneable joins imply subq
-      $needs_subq = scalar keys %{ $join_classifications->{restricting} || {} };
-    }
+    ($attrs->{from}, $join_classifications) =
+      $storage->_prune_unused_joins ($attrs->{from}, $attrs->{select}, $self->{cond}, $attrs);
+
+    # any non-pruneable non-local restricting joins imply subq
+    $needs_subq = defined List::Util::first { $_ ne $attrs->{alias} } keys %{ $join_classifications->{restricting} || {} };
   }
 
   # check if the head is composite (by now all joins are thrown out unless $needs_subq)
index 570cf2b..c8ec48c 100644 (file)
@@ -2387,7 +2387,7 @@ sub _select_args {
       and
     @$ident != 1
   ) {
-    $ident = $self->_prune_unused_joins ($ident, $select, $where, $attrs);
+    ($ident) = $self->_prune_unused_joins ($ident, $select, $where, $attrs);
   }
 
 ###
index 5b4b56e..34b358c 100644 (file)
@@ -34,8 +34,8 @@ sub _prune_unused_joins {
 
   my $aliastypes = $self->_resolve_aliastypes_from_select_args(@_);
 
-  # don't care
-  delete $aliastypes->{joining};
+  my $orig_joins = delete $aliastypes->{joining};
+  my $orig_multiplying = $aliastypes->{multiplying};
 
   # a grouped set will not be affected by amount of rows. Thus any
   # {multiplying} joins can go
@@ -56,13 +56,17 @@ sub _prune_unused_joins {
 
   for my $j (@{$from}[1..$#$from]) {
     push @newfrom, $j if (
-      (! $j->[0]{-alias}) # legacy crap
+      (! defined $j->[0]{-alias}) # legacy crap
         ||
       $need_joins{$j->[0]{-alias}}
     );
   }
 
-  return \@newfrom;
+  return ( \@newfrom, {
+    multiplying => { map { $need_joins{$_} ? ($_  => $orig_multiplying->{$_}) : () } keys %$orig_multiplying },
+    %$aliastypes,
+    joining => { map { $_ => $orig_joins->{$_} } keys %need_joins },
+  } );
 }
 
 #
@@ -175,13 +179,10 @@ sub _adjust_select_args_for_complex_prefetch {
     local $self->{_use_join_optimizer} = 1;
 
     # throw away multijoins since we def. do not care about those inside the subquery
-    my $inner_from = $self->_prune_unused_joins ($from, $inner_select, $where, {
+    my ($inner_from, $inner_aliastypes) = $self->_prune_unused_joins ($from, $inner_select, $where, {
       %$inner_attrs, _force_prune_multiplying_joins => 1
     });
 
-    my $inner_aliastypes =
-      $self->_resolve_aliastypes_from_select_args( $inner_from, $inner_select, $where, $inner_attrs );
-
     # uh-oh a multiplier (which is not us) left in, this is a problem
     if (
       $inner_aliastypes->{multiplying}