f8a7e79760e1e5558cb66ba73e6cf0b7fec4085d
[dbsrgits/DBIx-Class.git] / t / search / subquery.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings FATAL => 'all';
5
6 use Data::Dumper;
7
8 use Test::More;
9
10 BEGIN {
11     eval "use SQL::Abstract 1.49";
12     plan $@
13         ? ( skip_all => "Needs SQLA 1.49+" )
14         : ( tests => 6 );
15 }
16
17 use lib qw(t/lib);
18 use DBICTest;
19 use DBIC::SqlMakerTest;
20
21 my $schema = DBICTest->init_schema();
22 my $art_rs = $schema->resultset('Artist');
23 my $cdrs = $schema->resultset('CD');
24
25 {
26   my $cdrs2 = $cdrs->search({
27     artist_id => { 'in' => $art_rs->search({}, { rows => 1 })->get_column( 'id' )->as_query },
28   });
29
30   my $arr = $cdrs2->as_query;
31   my ($query, @bind) = @{$$arr};
32   is_same_sql_bind(
33     $query, \@bind,
34     "SELECT me.cdid,me.artist,me.title,me.year,me.genreid,me.single_track FROM cd me WHERE artist_id IN ( SELECT id FROM artist me LIMIT 1 )",
35     [],
36   );
37 }
38
39 TODO: {
40   local $TODO = "'+select' doesn't work with as_query yet.";
41   my $rs = $art_rs->search(
42     {},
43     {
44       '+select' => [
45         $cdrs->search({}, { rows => 1 })->get_column('id')->as_query,
46       ],
47       '+as' => [
48         'cdid',
49       ],
50     },
51   );
52
53   my $arr = $rs->as_query;
54   my ($query, @bind) = @{$$arr};
55   is_same_sql_bind(
56     $query, \@bind,
57     "SELECT me.artistid, me.name, me.rank, me.charfield, (SELECT id FROM cds LIMIT 1) AS cdid FROM artist me",
58     [],
59   );
60 }
61
62 # simple from
63 {
64   my $rs = $cdrs->search(
65     {},
66     {
67       alias => 'cd2',
68       from => [
69         { cd2 => $cdrs->search({ id => { '>' => 20 } })->as_query },
70       ],
71     },
72   );
73
74   my $arr = $rs->as_query;
75   my ($query, @bind) = @{$$arr};
76   is_same_sql_bind(
77     $query, \@bind,
78     "SELECT cd2.cdid, cd2.artist, cd2.title, cd2.year, cd2.genreid, cd2.single_track FROM (SELECT me.cdid,me.artist,me.title,me.year,me.genreid,me.single_track FROM cd me WHERE id > 20) cd2",
79     [],
80   );
81 }
82
83 # nested from
84 {
85   my $art_rs2 = $schema->resultset('Artist')->search({}, 
86   {
87     from => [ { 'me' => 'artist' }, 
88       [ { 'cds' => $cdrs->search({},{ 'select' => [\'me.artist as cds_artist' ]})->as_query },
89       { 'me.artistid' => 'cds_artist' } ] ]
90   });
91
92   my $arr = $art_rs2->as_query;
93   my ($query, @bind) = @{$$arr};
94   is_same_sql_bind(
95     $query, \@bind,
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
102 # nested subquery in from
103 {
104   my $rs = $cdrs->search(
105     {},
106     {
107       alias => 'cd2',
108       from => [
109         { cd2 => $cdrs->search(
110             { id => { '>' => 20 } }, 
111             { 
112                 alias => 'cd3',
113                 from => [ 
114                 { cd3 => $cdrs->search( { id => { '<' => 40 } } )->as_query }
115                 ],
116             }, )->as_query },
117       ],
118     },
119   );
120
121   my $arr = $rs->as_query;
122   my ($query, @bind) = @{$$arr};
123   is_same_sql_bind(
124     $query, \@bind,
125     "SELECT cd2.cdid, cd2.artist, cd2.title, cd2.year, cd2.genreid, cd2.single_track 
126       FROM 
127         (SELECT cd3.cdid,cd3.artist,cd3.title,cd3.year,cd3.genreid,cd3.single_track 
128           FROM 
129             (SELECT me.cdid,me.artist,me.title,me.year,me.genreid,me.single_track 
130               FROM cd me WHERE id < 40) cd3
131           WHERE id > 20) cd2",
132     [],
133   );
134
135 }
136
137 {
138   my $rs = $cdrs->search({
139     year => {
140       '=' => $cdrs->search(
141         { artistid => { '=' => \'me.artistid' } },
142         { alias => 'inner' }
143       )->get_column('year')->max_rs->as_query,
144     },
145   });
146   my $arr = $rs->as_query;
147   my ($query, @bind) = @{$$arr};
148   is_same_sql_bind(
149     $query, \@bind,
150     "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)",
151     [],
152   );
153 }
154
155 __END__