From: Daniel Ruoso Date: Tue, 30 Nov 2010 13:24:35 +0000 (-0300) Subject: do not use "me" on the related_resultset pessimization X-Git-Tag: v0.08190~1^2~8 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=f3cfaac640901858c6d9983758e5485ae9baf30f;hp=8d656b21a2745da7ce24bf7fca2e3b28fe37ec58;p=dbsrgits%2FDBIx-Class.git do not use "me" on the related_resultset pessimization This was requested by ribasushi, but it is still incomplete. Added a TODO test with the expected final query. Problem is: the alias is defined in $source->_resolve_join, which is completely disconnected from the search context so it cannot receive a different alias --- diff --git a/lib/DBIx/Class/Relationship/Base.pm b/lib/DBIx/Class/Relationship/Base.pm index 2fba9bb..050c056 100644 --- a/lib/DBIx/Class/Relationship/Base.pm +++ b/lib/DBIx/Class/Relationship/Base.pm @@ -451,13 +451,21 @@ sub related_resultset { # since we don't have the extended condition, we need to step # back, get a resultset for the current row and do a # search_related there. + my $row_srcname = $source->source_name; - my $base_rs = $source->schema->resultset($row_srcname); + my $base_rs_class = $source->resultset_class; + my $base_rs_attr = $source->resultset_attributes; + my $base_rs = $base_rs_class->new + ($source, + { + %$base_rs_attr, + alias => $source->storage->relname_to_table_alias(lc($row_srcname).'__row',1) + }); my $alias = $base_rs->current_source_alias; my %identity = map { ( "${alias}.${_}" => $self->get_column($_) ) } $source->primary_columns; my $row_rs = $base_rs->search(\%identity); - - $row_rs->search_related($rel, $query, $attrs); + my $related = $row_rs->related_resultset($rel, { %$attrs, alias => 'me' }); + $related->search($query); } else { # when we have the extended condition or we have a simple diff --git a/t/relationship/custom.t b/t/relationship/custom.t index 8f7ce8d..9809a65 100644 --- a/t/relationship/custom.t +++ b/t/relationship/custom.t @@ -43,17 +43,31 @@ my @cds_80s = $cds_80s_rs->all; is(@cds_80s, 6, '6 80s cds found (1980 - 1985)'); map { ok($_->year < 1990 && $_->year > 1979) } @cds_80s; +# this is the current version, enhanced version below. my $cds_90s_rs = $artist2->cds_90s; is_same_sql_bind($cds_90s_rs->as_query, '(SELECT cds_90s.cdid, cds_90s.artist, cds_90s.title, cds_90s.year, cds_90s.genreid,'. - 'cds_90s.single_track FROM artist me JOIN cd cds_90s ON ( cds_90s.artist = me.artistid'. - ' AND ( cds_90s.year < ? AND cds_90s.year > ? ) ) WHERE ( me.artistid = ? ))', + ' cds_90s.single_track FROM artist artist__row JOIN cd cds_90s ON ( cds_90s.artist = artist__row.artistid'. + ' AND ( cds_90s.year < ? AND cds_90s.year > ? ) ) WHERE ( artist__row.artistid = ? ))', [ [ 'cds_90s.year' => 2000 ], [ 'cds_90s.year' => 1989 ], - [ 'me.artistid' => 5 ], + [ 'artist__row.artistid' => 5 ], ]); +TODO: { + local $TODO = 'enhanced aliasing in search_related'; + my $cds_90s_rs = $artist2->cds_90s; + is_same_sql_bind($cds_90s_rs->as_query, + '(SELECT me.cdid, me.artist, me.title, me.year, me.genreid,'. + ' me.single_track FROM artist artist__row JOIN cd me ON ( me.artist = artist__row.artistid'. + ' AND ( me.year < ? AND me.year > ? ) ) WHERE ( artist__row.artistid = ? ))', + [ + [ 'me.year' => 2000 ], + [ 'me.year' => 1989 ], + [ 'artist__row.artistid' => 5 ], + ]); +} my @cds_90s = $cds_90s_rs->all; is(@cds_90s, 6, '6 90s cds found (1990 - 1995) even with non-optimized search'); map { ok($_->year < 2000 && $_->year > 1989) } @cds_90s;