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