[Bast-commits] r8731 - in DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class: . Storage

ribasushi at dev.catalyst.perl.org ribasushi at dev.catalyst.perl.org
Wed Feb 17 07:43:28 GMT 2010


Author: ribasushi
Date: 2010-02-17 07:43:28 +0000 (Wed, 17 Feb 2010)
New Revision: 8731

Modified:
   DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSet.pm
   DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSetColumn.pm
   DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSource.pm
   DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/Storage/DBI.pm
Log:
Now collapse is a flag, not a list

Modified: DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSet.pm
===================================================================
--- DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSet.pm	2010-02-17 00:06:01 UTC (rev 8730)
+++ DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSet.pm	2010-02-17 07:43:28 UTC (rev 8731)
@@ -536,7 +536,7 @@
 
   # Run the query
   my $rs = $self->search ($query, {result_class => $self->result_class, %$attrs});
-  if (keys %{$rs->_resolved_attrs->{collapse}}) {
+  if ($rs->_resolved_attrs->{collapse}) {
     my $row = $rs->next;
     carp "Query returned more than one row" if $rs->next;
     return $row;
@@ -723,7 +723,7 @@
 
   my $attrs = $self->_resolved_attrs_copy;
 
-  if (keys %{$attrs->{collapse}}) {
+  if ($attrs->{collapse}) {
     $self->throw_exception(
       'single() can not be used on resultsets prefetching has_many. Use find( \%cond ) or next() instead'
     );
@@ -991,7 +991,7 @@
 sub _collapse_result {
     my ( $self, $as_proto, $row_ref ) = @_;
 
-    my $collapse = keys %{ $self->{_attrs}{collapse} || {} };
+    my $collapse = $self->_resolved_attrs->{collapse};
     my $rows     = [];
     my @row      = @$row_ref;
     do {
@@ -1226,7 +1226,7 @@
 
   # if we multi-prefetch we group_by primary keys only as this is what we would
   # get out of the rs via ->next/->all. We *DO WANT* to clobber old group_by regardless
-  if ( keys %{$attrs->{collapse}}  ) {
+  if ($attrs->{collapse}) {
     $sub_attrs->{group_by} = [ map { "$attrs->{alias}.$_" } ($rsrc->primary_columns) ]
   }
 
@@ -1296,7 +1296,7 @@
 
   my @obj;
 
-  if (keys %{$self->_resolved_attrs->{collapse}}) {
+  if ($self->_resolved_attrs->{collapse}) {
     # Using $self->cursor->all is really just an optimisation.
     # If we're collapsing has_many prefetches it probably makes
     # very little difference, and this is cleaner than hacking
@@ -2831,7 +2831,6 @@
     }
   }
   else {
-
     # otherwise we intialise select & as to empty
     $attrs->{select} = [];
     $attrs->{as}     = [];
@@ -2921,8 +2920,8 @@
     }
   }
 
-  $attrs->{collapse} ||= {};
   if ( my $prefetch = delete $attrs->{prefetch} ) {
+    $attrs->{collapse} = 1;
     $prefetch = $self->_merge_attr( {}, $prefetch );
 
     my $prefetch_ordering = [];
@@ -2948,8 +2947,7 @@
       }
     }
 
-    my @prefetch =
-      $source->_resolve_prefetch( $prefetch, $alias, $join_map, $prefetch_ordering, $attrs->{collapse} );
+    my @prefetch = $source->_resolve_prefetch( $prefetch, $alias, $join_map, $prefetch_ordering );
 
     # we need to somehow mark which columns came from prefetch
     $attrs->{_prefetch_select} = [ map { $_->[0] } @prefetch ];
@@ -2961,6 +2959,30 @@
     $attrs->{_collapse_order_by} = \@$prefetch_ordering;
   }
 
+  # run through the resulting joinstructure (starting from our current slot)
+  # and unset collapse if proven unnesessary
+  if ($attrs->{collapse} && ref $attrs->{from} eq 'ARRAY') {
+
+    if (@{$attrs->{from}} > 1) {
+
+      # find where our table-spec starts and consider only things after us
+      my @fromlist = @{$attrs->{from}};
+      while (@fromlist) {
+        my $t = shift @fromlist;
+        $t = $t->[0] if ref $t eq 'ARRAY';  #me vs join from-spec mismatch
+        last if ($t->{-alias} && $t->{-alias} eq $alias);
+      }
+
+      if (@fromlist) {
+        $attrs->{collapse} = scalar grep { ! $_->[0]{-is_single} } (@fromlist);
+      }
+    }
+    else {
+      # no joins - no collapse
+      $attrs->{collapse} = 0;
+    }
+  }
+
   # if both page and offset are specified, produce a combined offset
   # even though it doesn't make much sense, this is what pre 081xx has
   # been doing

Modified: DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSetColumn.pm
===================================================================
--- DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSetColumn.pm	2010-02-17 00:06:01 UTC (rev 8730)
+++ DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSetColumn.pm	2010-02-17 07:43:28 UTC (rev 8731)
@@ -44,7 +44,7 @@
 
   $rs->throw_exception('column must be supplied') unless $column;
 
-  my $orig_attrs = $rs->_resolved_attrs;
+  my $orig_attrs = $rs->_resolved_attrs_copy;
 
   # If $column can be found in the 'as' list of the parent resultset, use the
   # corresponding element of its 'select' list (to keep any custom column
@@ -91,7 +91,7 @@
 
   # {collapse} would mean a has_many join was injected, which in turn means
   # we need to group *IF WE CAN* (only if the column in question is unique)
-  if (!$new_attrs->{group_by} && keys %{$orig_attrs->{collapse}}) {
+  if (!$new_attrs->{group_by} && $orig_attrs->{collapse}) {
 
     # scan for a constraint that would contain our column only - that'd be proof
     # enough it is unique

Modified: DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSource.pm
===================================================================
--- DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSource.pm	2010-02-17 00:06:01 UTC (rev 8730)
+++ DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/ResultSource.pm	2010-02-17 07:43:28 UTC (rev 8731)
@@ -1378,7 +1378,7 @@
 # in the supplied relationships.
 
 sub _resolve_prefetch {
-  my ($self, $pre, $alias, $alias_map, $order, $collapse, $pref_path) = @_;
+  my ($self, $pre, $alias, $alias_map, $order, $pref_path) = @_;
   $pref_path ||= [];
 
   if (not defined $pre) {
@@ -1386,15 +1386,15 @@
   }
   elsif( ref $pre eq 'ARRAY' ) {
     return
-      map { $self->_resolve_prefetch( $_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ) }
+      map { $self->_resolve_prefetch( $_, $alias, $alias_map, $order, [ @$pref_path ] ) }
         @$pre;
   }
   elsif( ref $pre eq 'HASH' ) {
     my @ret =
     map {
-      $self->_resolve_prefetch($_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ),
+      $self->_resolve_prefetch($_, $alias, $alias_map, $order, [ @$pref_path ] ),
       $self->related_source($_)->_resolve_prefetch(
-               $pre->{$_}, "${alias}.$_", $alias_map, $order, $collapse, [ @$pref_path, $_] )
+               $pre->{$_}, "${alias}.$_", $alias_map, $order, [ @$pref_path, $_] )
     } keys %$pre;
     return @ret;
   }
@@ -1427,14 +1427,11 @@
 
       #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
       #              values %{$rel_info->{cond}};
-      $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ];
-        # action at a distance. prepending the '.' allows simpler code
-        # in ResultSet->_collapse_result
       my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
                     keys %{$rel_info->{cond}};
       my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
                    ? @{$rel_info->{attrs}{order_by}}
-   
+
                 : (defined $rel_info->{attrs}{order_by}
                        ? ($rel_info->{attrs}{order_by})
                        : ()));

Modified: DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/Storage/DBI.pm
===================================================================
--- DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/Storage/DBI.pm	2010-02-17 00:06:01 UTC (rev 8730)
+++ DBIx-Class/0.08/branches/prefetch/lib/DBIx/Class/Storage/DBI.pm	2010-02-17 07:43:28 UTC (rev 8731)
@@ -1793,8 +1793,8 @@
   # see if we need to tear the prefetch apart otherwise delegate the limiting to the
   # storage, unless software limit was requested
   if (
-    #limited has_many
-    ( $attrs->{rows} && keys %{$attrs->{collapse}} )
+    # limited collapsing has_many
+    ( $attrs->{rows} && $attrs->{collapse} )
        ||
     # limited prefetch with RNO subqueries
     (




More information about the Bast-commits mailing list