Addjust bug to show problem with rows => 1 + child rel
[dbsrgits/DBIx-Class.git] / t / prefetch / rows_bug.t
CommitLineData
a04af85f 1# Test to ensure we get a consistent result set wether or not we use the
2# prefetch option in combination rows (LIMIT).
3use strict;
4use warnings;
5
6use Test::More;
7use lib qw(t/lib);
8use DBICTest;
9
5624ba1f 10plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 3);
a04af85f 11
12my $schema = DBICTest->init_schema();
13my $no_prefetch = $schema->resultset('Artist')->search(
25cac750 14 undef,
15 { rows => 3 }
a04af85f 16);
17
18my $use_prefetch = $schema->resultset('Artist')->search(
25cac750 19 undef,
20 {
21 prefetch => 'cds',
22 rows => 3
23 }
a04af85f 24);
25
26my $no_prefetch_count = 0;
27my $use_prefetch_count = 0;
28
29is($no_prefetch->count, $use_prefetch->count, '$no_prefetch->count == $use_prefetch->count');
30
5624ba1f 31$no_prefetch_count++ while $no_prefetch->next;
32$use_prefetch_count++ while $use_prefetch->next;
33is(
34 $no_prefetch_count,
35 $use_prefetch_count,
36 "manual row count confirms consistency"
37 . " (\$no_prefetch_count == $no_prefetch_count, "
38 . " \$use_prefetch_count == $use_prefetch_count)"
39);
40
41$no_prefetch = $schema->resultset('Artist')->search(
42 undef,
43 { rows => 1 }
44);
45
46$use_prefetch = $schema->resultset('Artist')->search(
47 undef,
48 {
49 prefetch => 'cds',
50 rows => 1
51 }
52);
53
54my $prefetch_artist = $use_prefetch->first;
55my $normal_artist = $no_prefetch->first;
56
57is(
58 $prefetch_artist->cds->count,
59 $normal_artist->cds->count,
60 "Count of child rel with prefetch + rows => 1 is right"
61);
25cac750 62
63__END__
64The fix is to, when using prefetch, take the query and put it into a subquery
65joined to the tables we're prefetching from. This might result in the same
66table being joined once in the main subquery and once in the main query. This
67may actually resolve other, unknown edgecase bugs. It is also the right way
68to do prefetching. Optimizations can come later.
69
70This means that:
71 $foo_rs->search(
72 { ... },
73 {
74 prefetch => 'bar',
75 ...
76 },
77 );
78
79becomes:
80 my $temp = $foo_rs->search(
81 { ... },
82 {
83 join => 'bar',
84 ...
85 },
86 );
87 $foo_rs->storage->schema->resultset('foo')->search(
88 undef,
89 {
90 from => [
91 { me => $temp->as_query },
92 ],
93 prefetch => 'bar',
94 },
95 );
96
97Problem:
98 * The prefetch->join change needs to happen ONLY IF there are conditions
99 that depend on bar being joined.
5624ba1f 100 * Count of child rel.
25cac750 101 * How will this work when the $rs is further searched on? Those clauses
102 need to be added to the subquery, not the outer one. This is particularly
103 true if rows is added in the attribute later per the Pager.