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;
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.