From: Rob Kinyon Date: Sun, 1 Mar 2009 05:13:38 +0000 (+0000) Subject: Added more notes to the bottom of the failing testcase X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=25cac7505079bf6889f474b1820229b5a92f07bb;p=dbsrgits%2FDBIx-Class-Historic.git Added more notes to the bottom of the failing testcase --- diff --git a/t/98rows_prefetch.t b/t/98rows_prefetch.t index 10bc2a9..d7ec720 100644 --- a/t/98rows_prefetch.t +++ b/t/98rows_prefetch.t @@ -12,16 +12,16 @@ plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 2); my $schema = DBICTest->init_schema(); $schema->storage->debug(1); my $no_prefetch = $schema->resultset('Artist')->search( - undef, - { rows => 3 } + undef, + { rows => 3 } ); my $use_prefetch = $schema->resultset('Artist')->search( - undef, - { - prefetch => 'cds', - rows => 3 - } + undef, + { + prefetch => 'cds', + rows => 3 + } ); my $no_prefetch_count = 0; @@ -29,21 +29,76 @@ my $use_prefetch_count = 0; is($no_prefetch->count, $use_prefetch->count, '$no_prefetch->count == $use_prefetch->count'); -# 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. - 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)" - ); + 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)" + ); } +__END__ +my $rs1 = $schema->resultset('Artist')->search( + undef, { +# join => 'cds', + }, +); +warn ${$rs1->as_query}->[0], $/; +{ my @x = $rs1->all; warn "$#x\n"; } + +my $rs2 = $schema->resultset('Artist')->search( + undef, { + from => [{ + me => $rs1->as_query, + }], + prefetch => 'cds', + }, +); + +warn ${$rs2->as_query}->[0], $/; +{ my @x = $rs2->all; warn "$#x\n"; } + +__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. + +This means that: + $foo_rs->search( + { ... }, + { + prefetch => 'bar', + ... + }, + ); + +becomes: + my $temp = $foo_rs->search( + { ... }, + { + join => 'bar', + ... + }, + ); + $foo_rs->storage->schema->resultset('foo')->search( + undef, + { + from => [ + { me => $temp->as_query }, + ], + prefetch => 'bar', + }, + ); + +Problem: + * The prefetch->join change needs to happen ONLY IF there are conditions + that depend on bar being joined. + * How will this work when the $rs is further searched on? Those clauses + need to be added to the subquery, not the outer one. This is particularly + true if rows is added in the attribute later per the Pager.