X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2Fprefetch%2Frows_bug.t;h=6e849f2d4b48497b622d73c7339e05e728b84b38;hb=61fd5dfcb33d602247d07297a24810635482263d;hp=821c84e8d6eb2f9ac76341eb7d75c98168107448;hpb=e9bd1473080b4aaf94e2be97329d74703d41a353;p=dbsrgits%2FDBIx-Class-Historic.git diff --git a/t/prefetch/rows_bug.t b/t/prefetch/rows_bug.t index 821c84e..6e849f2 100644 --- a/t/prefetch/rows_bug.t +++ b/t/prefetch/rows_bug.t @@ -4,77 +4,82 @@ use strict; use warnings; use Test::More; +use Test::Exception; use lib qw(t/lib); use DBICTest; -plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 2); +plan tests => 7; my $schema = DBICTest->init_schema(); + + my $no_prefetch = $schema->resultset('Artist')->search( undef, { rows => 3 } ); my $use_prefetch = $schema->resultset('Artist')->search( - undef, + [ # search deliberately contrived + { 'artwork.cd_id' => undef }, + { 'tracks.title' => { '!=' => 'blah-blah-1234568' }} + ], { prefetch => 'cds', - rows => 3 + join => { cds => [qw/artwork tracks/] }, + rows => 3, + order_by => { -desc => 'name' }, } ); -my $no_prefetch_count = 0; -my $use_prefetch_count = 0; - is($no_prefetch->count, $use_prefetch->count, '$no_prefetch->count == $use_prefetch->count'); +is( + scalar ($no_prefetch->all), + scalar ($use_prefetch->all), + "Amount of returned rows is right" +); + +my $artist_many_cds = $schema->resultset('Artist')->search ( {}, { + join => 'cds', + group_by => 'me.artistid', + having => \ 'count(cds.cdid) > 1', +})->first; + -TODO: { - local $TODO = "This is a difficult bug to fix, workaround is not to use prefetch with rows"; - $no_prefetch_count++ while $no_prefetch->next; - $use_prefetch_count++ while $use_prefetch->next; - is( - $no_prefetch_count, - $use_prefetch_count, - "manual row count confirms consistency" - . " (\$no_prefetch_count == $no_prefetch_count, " - . " \$use_prefetch_count == $use_prefetch_count)" - ); -} +$no_prefetch = $schema->resultset('Artist')->search( + { artistid => $artist_many_cds->id }, + { rows => 1 } +); -__END__ -The fix is to, when using prefetch, take the query and put it into a subquery -joined to the tables we're prefetching from. This might result in the same -table being joined once in the main subquery and once in the main query. This -may actually resolve other, unknown edgecase bugs. It is also the right way -to do prefetching. Optimizations can come later. +$use_prefetch = $no_prefetch->search ({}, { prefetch => 'cds' }); -This means that: - $foo_rs->search( - { ... }, - { - prefetch => 'bar', - ... - }, - ); +my $normal_artist = $no_prefetch->single; +my $prefetch_artist = $use_prefetch->find({ name => $artist_many_cds->name }); +my $prefetch2_artist = $use_prefetch->first; -becomes: - my $temp = $foo_rs->search( - { ... }, - { - join => 'bar', - ... - }, - ); - $foo_rs->storage->schema->resultset('foo')->search( - undef, - { - from => [ - { me => $temp->as_query }, - ], - prefetch => 'bar', - }, - ); +is( + $prefetch_artist->cds->count, + $normal_artist->cds->count, + "Count of child rel with prefetch + rows => 1 is right (find)" +); +is( + $prefetch2_artist->cds->count, + $normal_artist->cds->count, + "Count of child rel with prefetch + rows => 1 is right (first)" +); -Problem: - * The prefetch->join change needs to happen ONLY IF there are conditions - that depend on bar being joined. +is ( + scalar ($prefetch_artist->cds->all), + scalar ($normal_artist->cds->all), + "Amount of child rel rows with prefetch + rows => 1 is right (find)" +); +is ( + scalar ($prefetch2_artist->cds->all), + scalar ($normal_artist->cds->all), + "Amount of child rel rows with prefetch + rows => 1 is right (first)" +); + +throws_ok ( + sub { $use_prefetch->single }, + qr/resultsets prefetching has_many/, + 'single() with multiprefetch is illegal', +);