File: fetch_first.t

package info (click to toggle)
libdbix-class-perl 0.082844-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,320 kB
  • sloc: perl: 27,215; sql: 322; sh: 29; makefile: 16
file content (231 lines) | stat: -rw-r--r-- 7,254 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
use strict;
use warnings;

use Test::More;
use lib qw(t/lib);
use DBICTest ':DiffSQL';

my $schema = DBICTest->init_schema;

# based on toplimit.t
delete $schema->storage->_sql_maker->{_cached_syntax};
$schema->storage->_sql_maker->limit_dialect ('FetchFirst');

my $books_45_and_owners = $schema->resultset ('BooksInLibrary')->search ({}, {
  prefetch => 'owner', rows => 2, offset => 3,
  columns => [ grep { $_ ne 'title' } $schema->source('BooksInLibrary')->columns ],
});

for my $null_order (
  undef,
  '',
  {},
  [],
  [{}],
) {
  my $rs = $books_45_and_owners->search ({}, {order_by => $null_order });
  is_same_sql_bind(
      $rs->as_query,
      '(SELECT me.id, me.source, me.owner, me.price, owner__id, owner__name
          FROM (
            SELECT me.id, me.source, me.owner, me.price, owner.id AS owner__id, owner.name AS owner__name
              FROM books me
              JOIN owners owner ON owner.id = me.owner
            WHERE ( source = ? )
            ORDER BY me.id
            FETCH FIRST 5 ROWS ONLY
          ) me
        ORDER BY me.id DESC
        FETCH FIRST 2 ROWS ONLY
       )',
    [ [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
        => 'Library' ] ],
  );
}


for my $ord_set (
  {
    order_by => \'title DESC',
    order_inner => 'title DESC',
    order_outer => 'ORDER__BY__001 ASC',
    order_req => 'ORDER__BY__001 DESC',
    exselect_outer => 'ORDER__BY__001',
    exselect_inner => 'title AS ORDER__BY__001',
  },
  {
    order_by => { -asc => 'title'  },
    order_inner => 'title ASC',
    order_outer => 'ORDER__BY__001 DESC',
    order_req => 'ORDER__BY__001 ASC',
    exselect_outer => 'ORDER__BY__001',
    exselect_inner => 'title AS ORDER__BY__001',
  },
  {
    order_by => { -desc => 'title' },
    order_inner => 'title DESC',
    order_outer => 'ORDER__BY__001 ASC',
    order_req => 'ORDER__BY__001 DESC',
    exselect_outer => 'ORDER__BY__001',
    exselect_inner => 'title AS ORDER__BY__001',
  },
  {
    order_by => 'title',
    order_inner => 'title',
    order_outer => 'ORDER__BY__001 DESC',
    order_req => 'ORDER__BY__001',
    exselect_outer => 'ORDER__BY__001',
    exselect_inner => 'title AS ORDER__BY__001',
  },
  {
    order_by => [ qw{ title me.owner}   ],
    order_inner => 'title, me.owner',
    order_outer => 'ORDER__BY__001 DESC, me.owner DESC',
    order_req => 'ORDER__BY__001, me.owner',
    exselect_outer => 'ORDER__BY__001',
    exselect_inner => 'title AS ORDER__BY__001',
  },
  {
    order_by => ['title', { -desc => 'bar' } ],
    order_inner => 'title, bar DESC',
    order_outer => 'ORDER__BY__001 DESC, ORDER__BY__002 ASC',
    order_req => 'ORDER__BY__001, ORDER__BY__002 DESC',
    exselect_outer => 'ORDER__BY__001, ORDER__BY__002',
    exselect_inner => 'title AS ORDER__BY__001, bar AS ORDER__BY__002',
  },
  {
    order_by => { -asc => [qw{ title bar }] },
    order_inner => 'title ASC, bar ASC',
    order_outer => 'ORDER__BY__001 DESC, ORDER__BY__002 DESC',
    order_req => 'ORDER__BY__001 ASC, ORDER__BY__002 ASC',
    exselect_outer => 'ORDER__BY__001, ORDER__BY__002',
    exselect_inner => 'title AS ORDER__BY__001, bar AS ORDER__BY__002',
  },
  {
    order_by => [
      'title',
      { -desc => [qw{bar}] },
      { -asc  => [qw{me.owner sensors}]},
    ],
    order_inner => 'title, bar DESC, me.owner ASC, sensors ASC',
    order_outer => 'ORDER__BY__001 DESC, ORDER__BY__002 ASC, me.owner DESC, ORDER__BY__003 DESC',
    order_req => 'ORDER__BY__001, ORDER__BY__002 DESC, me.owner ASC, ORDER__BY__003 ASC',
    exselect_outer => 'ORDER__BY__001, ORDER__BY__002, ORDER__BY__003',
    exselect_inner => 'title AS ORDER__BY__001, bar AS ORDER__BY__002, sensors AS ORDER__BY__003',
  },

  {
    order_by => [
      'name',
    ],
    order_inner => 'name',
    order_outer => 'name DESC',
    order_req => 'name',
  },
) {
  my $o_sel = $ord_set->{exselect_outer}
    ? ', ' . $ord_set->{exselect_outer}
    : ''
  ;
  my $i_sel = $ord_set->{exselect_inner}
    ? ', ' . $ord_set->{exselect_inner}
    : ''
  ;

  my $rs = $books_45_and_owners->search ({}, {order_by => $ord_set->{order_by}});

  # query actually works
  ok( defined $rs->count, 'Query actually works' );

  is_same_sql_bind(
    $rs->as_query,
    "(SELECT me.id, me.source, me.owner, me.price, owner__id, owner__name
        FROM (
          SELECT me.id, me.source, me.owner, me.price, owner__id, owner__name$o_sel
            FROM (
              SELECT me.id, me.source, me.owner, me.price, owner.id AS owner__id, owner.name AS owner__name$i_sel
                FROM books me
                JOIN owners owner ON owner.id = me.owner
              WHERE ( source = ? )
              ORDER BY $ord_set->{order_inner}
              FETCH FIRST 5 ROWS ONLY
            ) me
          ORDER BY $ord_set->{order_outer}
          FETCH FIRST 2 ROWS ONLY
        ) me
      ORDER BY $ord_set->{order_req}
    )",
    [ [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
        => 'Library' ] ],
  );

}

# with groupby
is_same_sql_bind (
  $books_45_and_owners->search ({}, { group_by => 'title', order_by => 'title' })->as_query,
  '(SELECT me.id, me.source, me.owner, me.price, owner.id, owner.name
      FROM (
        SELECT me.id, me.source, me.owner, me.price, me.title
          FROM (
            SELECT me.id, me.source, me.owner, me.price, me.title
              FROM (
                SELECT me.id, me.source, me.owner, me.price, me.title
                  FROM books me
                  JOIN owners owner ON owner.id = me.owner
                WHERE ( source = ? )
                GROUP BY title
                ORDER BY title
                FETCH FIRST 5 ROWS ONLY
              ) me
            ORDER BY title DESC
            FETCH FIRST 2 ROWS ONLY
          ) me
        ORDER BY title
      ) me
      JOIN owners owner ON owner.id = me.owner
    WHERE ( source = ? )
    ORDER BY title
  )',
  [ map { [
    { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
      => 'Library' ]
  } (1,2) ],
);

# test deprecated column mixing over join boundaries
my $rs_selectas_top = $schema->resultset ('BooksInLibrary')->search ({}, {
  '+select' => ['owner.name'],
  '+as' => ['owner_name'],
  join => 'owner',
  rows => 1
});

is_same_sql_bind( $rs_selectas_top->search({})->as_query,
                  '(SELECT
                      me.id, me.source, me.owner, me.title, me.price, owner.name
                    FROM books me
                    JOIN owners owner ON owner.id = me.owner
                    WHERE ( source = ? )
                    FETCH FIRST 1 ROWS ONLY
                   )',
                  [ [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' }
                    => 'Library' ] ],
                );

{
  my $rs = $schema->resultset('Artist')->search({}, {
    columns => 'artistid',
    offset => 1,
    order_by => 'artistid',
  });
  local $rs->result_source->{name} = "weird \n newline/multi \t \t space containing \n table";

  like (
    ${$rs->as_query}->[0],
    qr| weird \s \n \s newline/multi \s \t \s \t \s space \s containing \s \n \s table|x,
    'Newlines/spaces preserved in final sql',
  );
}

done_testing;