Since .generated_pod is no longer shipped in-dist, move it to maint/
[dbsrgits/DBIx-Class-Historic.git] / t / search / subquery.t
1 use strict;
2 use warnings;
3
4 use Test::More;
5
6 use lib qw(t/lib);
7 use DBICTest;
8 use DBIC::SqlMakerTest;
9 use DBIx::Class::SQLMaker::LimitDialects;
10
11 my $ROWS = DBIx::Class::SQLMaker::LimitDialects->__rows_bindtype;
12
13 my $schema = DBICTest->init_schema();
14 my $art_rs = $schema->resultset('Artist');
15 my $cdrs = $schema->resultset('CD');
16
17 my @tests = (
18   {
19     rs => $cdrs,
20     search => \[ "title = ? AND year LIKE ?", [ title => 'buahaha' ], [ year => '20%' ] ],
21     attrs => { rows => 5 },
22     sqlbind => \[
23       "( SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE (title = ? AND year LIKE ?) LIMIT ?)",
24       [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'title' } => 'buahaha' ],
25       [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'year' } => '20%' ],
26       [ $ROWS => 5 ],
27     ],
28   },
29
30   {
31     rs => $cdrs,
32     search => {
33       artistid => { 'in' => $art_rs->search({}, { rows => 1 })->get_column( 'artistid' )->as_query },
34     },
35     sqlbind => \[
36       "( SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE artistid IN ( SELECT me.artistid FROM artist me LIMIT ? ) )",
37       [ $ROWS => 1 ],
38     ],
39   },
40
41   {
42     rs => $art_rs,
43     attrs => {
44       'select' => [
45         $cdrs->search({}, { rows => 1 })->get_column('id')->as_query,
46       ],
47     },
48     sqlbind => \[
49       "( SELECT (SELECT me.id FROM cd me LIMIT ?) FROM artist me )",
50       [ $ROWS => 1 ],
51     ],
52   },
53
54   {
55     rs => $art_rs,
56     attrs => {
57       '+select' => [
58         $cdrs->search({}, { rows => 1 })->get_column('id')->as_query,
59       ],
60     },
61     sqlbind => \[
62       "( SELECT me.artistid, me.name, me.rank, me.charfield, (SELECT me.id FROM cd me LIMIT ?) FROM artist me )",
63       [ $ROWS => 1 ],
64     ],
65   },
66
67   {
68     rs => $cdrs,
69     attrs => {
70       alias => 'cd2',
71       from => [
72         { cd2 => $cdrs->search({ artist => { '>' => 20 } })->as_query },
73       ],
74     },
75     sqlbind => \[
76       "( SELECT cd2.cdid, cd2.artist, cd2.title, cd2.year, cd2.genreid, cd2.single_track FROM (
77             SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE artist > ?
78           ) cd2
79         )",
80       [ { sqlt_datatype => 'integer', dbic_colname => 'artist' } => 20 ]
81     ],
82   },
83
84   {
85     rs => $art_rs,
86     attrs => {
87       from => [
88         { 'me' => 'artist' },
89         [
90           { 'cds' => $cdrs->search({}, { 'select' => [\'me.artist as cds_artist' ]})->as_query },
91           { 'me.artistid' => 'cds_artist' }
92         ]
93       ]
94     },
95     sqlbind => \[
96       "( SELECT me.artistid, me.name, me.rank, me.charfield FROM artist me JOIN (SELECT me.artist as cds_artist FROM cd me) cds ON me.artistid = cds_artist )"
97     ],
98   },
99
100   {
101     rs => $cdrs,
102     attrs => {
103       alias => 'cd2',
104       from => [
105         { cd2 => $cdrs->search(
106             { artist => { '>' => 20 } },
107             {
108                 alias => 'cd3',
109                 from => [
110                 { cd3 => $cdrs->search( { artist => { '<' => 40 } } )->as_query }
111                 ],
112             }, )->as_query },
113       ],
114     },
115     sqlbind => \[
116       "( SELECT cd2.cdid, cd2.artist, cd2.title, cd2.year, cd2.genreid, cd2.single_track
117         FROM
118           (SELECT cd3.cdid, cd3.artist, cd3.title, cd3.year, cd3.genreid, cd3.single_track
119             FROM
120               (SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
121                 FROM cd me WHERE artist < ?) cd3
122             WHERE artist > ?) cd2
123       )",
124       [ { sqlt_datatype => 'integer', dbic_colname => 'artist' } => 40 ],
125       [ { dbic_colname => 'artist' } => 20 ], # no rsrc in outer manual from - hence no resolution
126     ],
127   },
128
129   {
130     rs => $cdrs,
131     search => {
132       year => {
133         '=' => $cdrs->search(
134           { artistid => { '=' => \'me.artistid' } },
135           { alias => 'inner' }
136         )->get_column('year')->max_rs->as_query,
137       },
138     },
139     sqlbind => \[
140       "( SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE year = (SELECT MAX(inner.year) FROM cd inner WHERE artistid = me.artistid) )",
141     ],
142   },
143
144   {
145     rs => $cdrs,
146     attrs => {
147       alias => 'cd2',
148       from => [
149         { cd2 => $cdrs->search({ title => 'Thriller' })->as_query },
150       ],
151     },
152     sqlbind => \[
153       "(SELECT cd2.cdid, cd2.artist, cd2.title, cd2.year, cd2.genreid, cd2.single_track FROM (
154           SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track FROM cd me WHERE title = ?
155         ) cd2
156       )",
157       [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'title' }
158           => 'Thriller'
159       ]
160     ],
161   },
162 );
163
164
165 for my $i (0 .. $#tests) {
166   my $t = $tests[$i];
167   for my $p (1, 2) {  # repeat everything twice, make sure we do not clobber search arguments
168     is_same_sql_bind (
169       $t->{rs}->search ($t->{search}, $t->{attrs})->as_query,
170       $t->{sqlbind},
171       sprintf 'Testcase %d, pass %d', $i+1, $p,
172     );
173   }
174 }
175
176 done_testing;