Skip Menu |

This queue is for tickets about the DBIx-Class CPAN distribution.

Report information
The Basics
Id: 63360
Status: rejected
Priority: 0/
Queue: DBIx-Class

People
Owner: Nobody in particular
Requestors: ryantate [...] ryantate.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.08124
Fixed in: (no value)



Subject: Prefetches not merged when calling search twice
Attempted:Modifying a resultset to add a second prefetch, like so: my $rs = $schema->resultset('Artist')->search( { }, { prefetch => ['cds'], } ); $rs->search( {}, { prefetch => ['stalkers'], } ); Expected: Both relationships ('cds', 'stalkers') would be prefetched. Docs state that "'join', 'prefetch', '+select', '+as' attributes are merged into the existing ones from the original resultset." http://search.cpan.org/~frew/DBIx-Class- 0.08124/lib/DBIx/Class/ResultSet.pm#Resolving_conditions_and_attributes Saw: The first specified prefetch is performed, but not the second. Only by specifying both prefetch relationships at once, the first time, can you get DBIx::Class to prefetch both relationships. A failing test case follows below (and is attached). DBIx::Class 0.08124 and perl is " v5.8.7 built for i486-linux-gnu-thread-multi" package MySchema::Result::Artist; use base qw/DBIx::Class::Core/; __PACKAGE__->table('artist'); __PACKAGE__->add_columns(artistid => {is_auto_increment => 1, data_type => 'integer'}, name => {}); __PACKAGE__->set_primary_key('artistid'); __PACKAGE__->has_many('cds' => 'MySchema::Result::Cd'); __PACKAGE__->has_many('stalkers' => 'MySchema::Result::Stalker'); 1; package MySchema::Result::Cd; use base qw/DBIx::Class::Core/; __PACKAGE__->table('cd'); __PACKAGE__->add_columns(cdid => {is_auto_increment => 1, data_type => 'integer'}, artist => {}, title => {}); __PACKAGE__->set_primary_key('cdid'); __PACKAGE__->belongs_to('artist' => 'MySchema::Result::Artist'); 1; package MySchema::Result::Stalker; use base qw/DBIx::Class::Core/; __PACKAGE__->table('stalker'); __PACKAGE__->add_columns(stalkerid => { is_auto_increment => 1, data_type => 'integer' }, name => {}, artist =>{}); __PACKAGE__->set_primary_key('stalkerid'); __PACKAGE__->belongs_to('artist' => 'MySchema::Result::Artist'); 1; package MySchema; use base 'DBIx::Class::Schema'; use strict; use warnings; __PACKAGE__->register_class($_, "MySchema::Result::$_") foreach qw(Artist Cd Stalker); 1; package main; use Test::More; plan tests => 1; my $schema = MySchema->connect("dbi:SQLite:dbname=:memory"); my $last_db_action = {}; $schema->storage->debugcb(sub{ ($last_db_action->{op}, $last_db_action->{info}) = @_; note "DB: $_[1]"; }); $schema->storage->debug(1); $schema->deploy({ add_drop_table => 1 }); $schema->populate('Artist', [ [qw/name/], (['Michael Jackson'],['Eminem']) ]); $schema->populate('Cd', [ [qw/title artist/], ['Thriller', $schema->resultset('Artist')->find({name =>'Michael Jackson'})->id ], ['Bad', $schema->resultset('Artist')->find({name =>'Michael Jackson'})->id ], ['The Marshall Mathers LP', $schema->resultset('Artist')->find({name =>'Eminem'})->id ], ]); $schema->populate('Stalker', [ [qw/name artist/], ['Foo Followbottoms', $schema->resultset('Artist')->find({name =>'Michael Jackson'})->id ], ['Bar Rightbehindyou', $schema->resultset('Artist')->find({name =>'Michael Jackson'})->id ], ['Baz Rightbehindyou', $schema->resultset('Artist')->find({name =>'Eminem'})->id ], ]); my $rs = $schema->resultset('Artist')->search( { }, { prefetch => ['cds'], } ); $rs->search( {}, { prefetch => ['stalkers'], } ); note "Reading first artist"; my $artist = $rs->first; note "Read " . $artist->name; note "Reading artist cds and stalkers"; my $artist_with_relations = $artist->name . "; " . $artist->cds->first->title . "; " . $artist- Show quoted text
>stalkers->first->name;
note "Read $artist_with_relations"; like($last_db_action->{info}, qr/LEFT JOIN/, "Prefetching correctly merged from two searches on one resultset");
Subject: dbixc_prefetch.t
package MySchema::Result::Artist; use base qw/DBIx::Class::Core/; __PACKAGE__->table('artist'); __PACKAGE__->add_columns(artistid => {is_auto_increment => 1, data_type => 'integer'}, name => {}); __PACKAGE__->set_primary_key('artistid'); __PACKAGE__->has_many('cds' => 'MySchema::Result::Cd'); __PACKAGE__->has_many('stalkers' => 'MySchema::Result::Stalker'); 1; package MySchema::Result::Cd; use base qw/DBIx::Class::Core/; __PACKAGE__->table('cd'); __PACKAGE__->add_columns(cdid => {is_auto_increment => 1, data_type => 'integer'}, artist => {}, title => {}); __PACKAGE__->set_primary_key('cdid'); __PACKAGE__->belongs_to('artist' => 'MySchema::Result::Artist'); 1; package MySchema::Result::Stalker; use base qw/DBIx::Class::Core/; __PACKAGE__->table('stalker'); __PACKAGE__->add_columns(stalkerid => { is_auto_increment => 1, data_type => 'integer' }, name => {}, artist =>{}); __PACKAGE__->set_primary_key('stalkerid'); __PACKAGE__->belongs_to('artist' => 'MySchema::Result::Artist'); 1; package MySchema; use base 'DBIx::Class::Schema'; use strict; use warnings; __PACKAGE__->register_class($_, "MySchema::Result::$_") foreach qw(Artist Cd Stalker); 1; package main; use Test::More; plan tests => 1; my $schema = MySchema->connect("dbi:SQLite:dbname=:memory"); my $last_db_action = {}; $schema->storage->debugcb(sub{ ($last_db_action->{op}, $last_db_action->{info}) = @_; note "DB: $_[1]"; }); $schema->storage->debug(1); $schema->deploy({ add_drop_table => 1 }); $schema->populate('Artist', [ [qw/name/], (['Michael Jackson'],['Eminem']) ]); $schema->populate('Cd', [ [qw/title artist/], ['Thriller', $schema->resultset('Artist')->find({name =>'Michael Jackson'})->id ], ['Bad', $schema->resultset('Artist')->find({name =>'Michael Jackson'})->id ], ['The Marshall Mathers LP', $schema->resultset('Artist')->find({name =>'Eminem'})->id ], ]); $schema->populate('Stalker', [ [qw/name artist/], ['Foo Followbottoms', $schema->resultset('Artist')->find({name =>'Michael Jackson'})->id ], ['Bar Rightbehindyou', $schema->resultset('Artist')->find({name =>'Michael Jackson'})->id ], ['Baz Rightbehindyou', $schema->resultset('Artist')->find({name =>'Eminem'})->id ], ]); my $rs = $schema->resultset('Artist')->search( { }, { prefetch => ['cds'], } ); $rs->search( {}, { prefetch => ['stalkers'], } ); note "Reading first artist"; my $artist = $rs->first; note "Read " . $artist->name; note "Reading artist cds and stalkers"; my $artist_with_relations = $artist->name . "; " . $artist->cds->first->title . "; " . $artist->stalkers->first->name; note "Read $artist_with_relations"; like($last_db_action->{info}, qr/LEFT JOIN/, "Prefetching correctly merged from two searches on one resultset");
From: ryantate [...] ryantate.com
IGNORE I forgot to reassign the new resultset..... NO BUG On Fri Nov 26 16:59:59 2010, ryantate@ryantate.com wrote: Show quoted text
> Attempted:Modifying a resultset to add a second prefetch, like so: > > my $rs = $schema->resultset('Artist')->search( > { > }, > { > prefetch => ['cds'], > } > ); > $rs->search( > {}, > { > prefetch => ['stalkers'], > } > ); > > Expected: Both relationships ('cds', 'stalkers') would be prefetched. > Docs state that "'join', > 'prefetch', '+select', '+as' attributes are merged into the existing > ones from the original > resultset." http://search.cpan.org/~frew/DBIx-Class- > 0.08124/lib/DBIx/Class/ResultSet.pm#Resolving_conditions_and_attributes > > Saw: The first specified prefetch is performed, but not the second. > Only by specifying both > prefetch relationships at once, the first time, can you get > DBIx::Class to prefetch both > relationships. > > A failing test case follows below (and is attached). DBIx::Class > 0.08124 and perl is " v5.8.7 > built for i486-linux-gnu-thread-multi" > > package MySchema::Result::Artist; > use base qw/DBIx::Class::Core/; > __PACKAGE__->table('artist'); > __PACKAGE__->add_columns(artistid => {is_auto_increment => 1, > data_type => 'integer'}, > name => {}); > __PACKAGE__->set_primary_key('artistid'); > __PACKAGE__->has_many('cds' => 'MySchema::Result::Cd'); > __PACKAGE__->has_many('stalkers' => 'MySchema::Result::Stalker'); > 1; > > package MySchema::Result::Cd; > use base qw/DBIx::Class::Core/; > __PACKAGE__->table('cd'); > __PACKAGE__->add_columns(cdid => {is_auto_increment => 1, data_type => > 'integer'}, > artist => {}, title => {}); > __PACKAGE__->set_primary_key('cdid'); > __PACKAGE__->belongs_to('artist' => 'MySchema::Result::Artist'); > 1; > > > package MySchema::Result::Stalker; > use base qw/DBIx::Class::Core/; > __PACKAGE__->table('stalker'); > __PACKAGE__->add_columns(stalkerid => { is_auto_increment => 1, > data_type => 'integer' > }, name => {}, artist =>{}); > __PACKAGE__->set_primary_key('stalkerid'); > __PACKAGE__->belongs_to('artist' => 'MySchema::Result::Artist'); > 1; > > > package MySchema; > use base 'DBIx::Class::Schema'; > > use strict; > use warnings; > > __PACKAGE__->register_class($_, "MySchema::Result::$_") foreach > qw(Artist Cd Stalker); > > 1; > > package main; > use Test::More; > plan tests => 1; > > my $schema = MySchema->connect("dbi:SQLite:dbname=:memory"); > my $last_db_action = {}; > $schema->storage->debugcb(sub{ ($last_db_action->{op}, > $last_db_action->{info}) = @_; > note "DB: $_[1]"; }); > $schema->storage->debug(1); > $schema->deploy({ add_drop_table => 1 }); > $schema->populate('Artist', [ > [qw/name/], > (['Michael Jackson'],['Eminem']) > ]); > > $schema->populate('Cd', [ > [qw/title artist/], > ['Thriller', $schema->resultset('Artist')->find({name =>'Michael > Jackson'})->id > ], > ['Bad', $schema->resultset('Artist')->find({name =>'Michael > Jackson'})->id ], > ['The Marshall Mathers LP', $schema->resultset('Artist')-
> >find({name
> =>'Eminem'})->id ], > ]); > > $schema->populate('Stalker', [ > [qw/name artist/], > ['Foo Followbottoms', $schema->resultset('Artist')->find({name > =>'Michael > Jackson'})->id ], > ['Bar Rightbehindyou', $schema->resultset('Artist')->find({name > =>'Michael > Jackson'})->id ], > ['Baz Rightbehindyou', $schema->resultset('Artist')->find({name > =>'Eminem'})->id ], > ]); > > my $rs = $schema->resultset('Artist')->search( > { > }, > { > prefetch => ['cds'], > } > ); > $rs->search( > {}, > { > prefetch => ['stalkers'], > } > ); > > note "Reading first artist"; > my $artist = $rs->first; > note "Read " . $artist->name; > note "Reading artist cds and stalkers"; > my $artist_with_relations = $artist->name . "; " . $artist->cds-
> >first->title . "; " . $artist- > >stalkers->first->name;
> note "Read $artist_with_relations"; > like($last_db_action->{info}, qr/LEFT JOIN/, "Prefetching correctly > merged from two searches > on one resultset");
not a bug as you already found out