take more care in mangling SELECT when applying subquery limits
[dbsrgits/DBIx-Class.git] / t / sqlmaker / limit_dialects / rno.t
CommitLineData
a5f843e3 1use strict;
2use warnings;
3
4use Test::More;
5use lib qw(t/lib);
6use DBICTest;
7use DBIC::SqlMakerTest;
fcb7fcbb 8use DBIx::Class::SQLMaker::LimitDialects;
9
10my ($TOTAL, $OFFSET) = (
11 DBIx::Class::SQLMaker::LimitDialects->__total_bindtype,
12 DBIx::Class::SQLMaker::LimitDialects->__offset_bindtype,
13);
a5f843e3 14
15my $schema = DBICTest->init_schema;
16
a5f843e3 17$schema->storage->_sql_maker->limit_dialect ('RowNumberOver');
18
41eac664 19my $rs_selectas_col = $schema->resultset ('BooksInLibrary')->search ({}, {
20 '+select' => ['owner.name'],
21 '+as' => ['owner.name'],
22 join => 'owner',
23 rows => 1,
24});
a5f843e3 25
41eac664 26is_same_sql_bind(
27 $rs_selectas_col->as_query,
28 '(
760545fa 29 SELECT id, source, owner, title, price,
30 owner__name
41eac664 31 FROM (
760545fa 32 SELECT id, source, owner, title, price,
33 owner__name,
41eac664 34 ROW_NUMBER() OVER( ) AS rno__row__index
35 FROM (
36 SELECT me.id, me.source, me.owner, me.title, me.price,
760545fa 37 owner.name AS owner__name
41eac664 38 FROM books me
39 JOIN owners owner ON owner.id = me.owner
40 WHERE ( source = ? )
41 ) me
42 ) me
fcb7fcbb 43 WHERE rno__row__index >= ? AND rno__row__index <= ?
41eac664 44 )',
fcb7fcbb 45 [
46 [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' } => 'Library' ],
47 [ $OFFSET => 1 ],
48 [ $TOTAL => 1 ],
49 ],
41eac664 50);
51
760545fa 52$schema->storage->_sql_maker->quote_char ([qw/ [ ] /]);
53$schema->storage->_sql_maker->name_sep ('.');
41eac664 54
55my $rs_selectas_rel = $schema->resultset ('BooksInLibrary')->search ({}, {
56 '+select' => ['owner.name'],
57 '+as' => ['owner_name'],
58 join => 'owner',
760545fa 59 rows => 1,
41eac664 60});
61
62is_same_sql_bind(
63 $rs_selectas_rel->as_query,
64 '(
760545fa 65 SELECT [id], [source], [owner], [title], [price],
66 [owner_name]
41eac664 67 FROM (
760545fa 68 SELECT [id], [source], [owner], [title], [price],
69 [owner_name],
70 ROW_NUMBER() OVER( ) AS [rno__row__index]
41eac664 71 FROM (
760545fa 72 SELECT [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price],
73 [owner].[name] AS [owner_name]
74 FROM [books] [me]
75 JOIN [owners] [owner] ON [owner].[id] = [me].[owner]
76 WHERE ( [source] = ? )
77 ) [me]
78 ) [me]
fcb7fcbb 79 WHERE [rno__row__index] >= ? AND [rno__row__index] <= ?
41eac664 80 )',
fcb7fcbb 81 [
82 [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' } => 'Library' ],
83 [ $OFFSET => 1 ],
84 [ $TOTAL => 1 ],
85 ],
41eac664 86);
a5f843e3 87
d7632687 88{
69d3c270 89my $subq = $schema->resultset('Owners')->search({
90 'count.id' => { -ident => 'owner.id' },
91 'count.name' => 'fail', # no one would do this in real life
92}, { alias => 'owner' })->count_rs;
93
94my $rs_selectas_rel = $schema->resultset('BooksInLibrary')->search ({}, {
95 columns => [
96 { owner_name => 'owner.name' },
97 { owner_books => $subq->as_query },
98 ],
99 join => 'owner',
100 rows => 1,
101});
102
103is_same_sql_bind(
104 $rs_selectas_rel->as_query,
105 '(
106 SELECT [owner_name], [owner_books]
107 FROM (
108 SELECT [owner_name], [owner_books], ROW_NUMBER() OVER( ) AS [rno__row__index]
109 FROM (
110 SELECT [owner].[name] AS [owner_name],
111 ( SELECT COUNT( * ) FROM [owners] [owner]
112 WHERE [count].[id] = [owner].[id] and [count].[name] = ? ) AS [owner_books]
113 FROM [books] [me]
114 JOIN [owners] [owner] ON [owner].[id] = [me].[owner]
115 WHERE ( [source] = ? )
116 ) [me]
117 ) [me]
118 WHERE [rno__row__index] >= ? AND [rno__row__index] <= ?
119 )',
120 [
121 [ { dbic_colname => 'count.name' } => 'fail' ],
122 [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' } => 'Library' ],
123 [ $OFFSET => 1 ],
124 [ $TOTAL => 1 ],
125 ],
126);
127
128}{
129my $subq = $schema->resultset('Owners')->search({
130 'count.id' => { -ident => 'owner.id' },
131}, { alias => 'owner' })->count_rs;
132
133my $rs_selectas_rel = $schema->resultset('BooksInLibrary')->search ({}, {
134 columns => [
135 { owner_name => 'owner.name' },
136 { owner_books => $subq->as_query },
137 ],
138 join => 'owner',
139 rows => 1,
140});
141
142is_same_sql_bind(
143 $rs_selectas_rel->as_query,
144 '(
145 SELECT [owner_name], [owner_books]
146 FROM (
147 SELECT [owner_name], [owner_books], ROW_NUMBER() OVER( ) AS [rno__row__index]
148 FROM (
149 SELECT [owner].[name] AS [owner_name],
150 ( SELECT COUNT( * ) FROM [owners] [owner] WHERE [count].[id] = [owner].[id] ) AS [owner_books]
151 FROM [books] [me]
152 JOIN [owners] [owner] ON [owner].[id] = [me].[owner]
153 WHERE ( [source] = ? )
154 ) [me]
155 ) [me]
156 WHERE [rno__row__index] >= ? AND [rno__row__index] <= ?
157 )',
158 [
159 [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
160 => 'Library' ],
161 [ $OFFSET => 1 ],
162 [ $TOTAL => 1 ],
163 ],
164);
165
166}
167
168{
d7632687 169 my $rs = $schema->resultset('Artist')->search({}, {
170 columns => 'name',
171 offset => 1,
172 order_by => 'name',
173 });
174 local $rs->result_source->{name} = "weird \n newline/multi \t \t space containing \n table";
175
176 like (
177 ${$rs->as_query}->[0],
178 qr| weird \s \n \s newline/multi \s \t \s \t \s space \s containing \s \n \s table|x,
179 'Newlines/spaces preserved in final sql',
180 );
181}
182
f74d22e2 183{
184my $subq = $schema->resultset('Owners')->search({
185 'books.owner' => { -ident => 'owner.id' },
186}, { alias => 'owner', select => ['id'] } )->count_rs;
187
188my $rs_selectas_rel = $schema->resultset('BooksInLibrary')->search( { -exists => $subq->as_query }, { select => ['id','owner'], rows => 1 } );
189
190is_same_sql_bind(
191 $rs_selectas_rel->as_query,
192 '(
193 SELECT [id], [owner] FROM (
194 SELECT [id], [owner], ROW_NUMBER() OVER( ) AS [rno__row__index] FROM (
195 SELECT [me].[id], [me].[owner]
196 FROM [books] [me]
197 WHERE ( ( (EXISTS (
198 SELECT COUNT( * ) FROM [owners] [owner] WHERE ( [books].[owner] = [owner].[id] )
199 )) AND [source] = ? ) )
200 ) [me]
201 ) [me] WHERE [rno__row__index] >= ? AND [rno__row__index] <= ?
202 )',
203 [
204 [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' } => 'Library' ],
205 [ $OFFSET => 1 ],
206 [ $TOTAL => 1 ],
207 ],
208 'Pagination with sub-query in WHERE works'
209);
210
211}
212
d7632687 213
a5f843e3 214done_testing;