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