Commit | Line | Data |
0446ca9c |
1 | package Data::Query::Renderer::SQL::Slice::FetchFirst; |
2 | |
6b45ffe4 |
3 | use Data::Query::ExprHelpers; |
0446ca9c |
4 | use Moo::Role; |
5 | |
fdd10824 |
6 | with 'Data::Query::Renderer::SQL::Slice::SubqueryRemap'; |
7 | |
3482f7c8 |
8 | sub _render_slice_limit { |
9 | my ($self, $dq) = @_; |
10 | return [ |
11 | ($dq->{from} ? $self->_render($dq->{from}) : ()), |
12 | $self->_format_keyword('FETCH FIRST'), |
13 | sprintf("%i", $dq->{limit}{value}), |
14 | $self->_format_keyword('ROWS ONLY') |
15 | ]; |
16 | } |
17 | |
fbf38b8e |
18 | sub slice_subquery { |
19 | (offset => 1); |
20 | } |
21 | |
8b2c306b |
22 | sub slice_stability { |
23 | (offset => 'requires'); |
24 | } |
25 | |
3482f7c8 |
26 | sub _slice_type { 'FetchFirst' } |
27 | |
0446ca9c |
28 | sub _render_slice { |
29 | my ($self, $dq) = @_; |
30 | unless ($dq->{offset}) { |
3482f7c8 |
31 | return $self->_render_slice_limit($dq); |
0446ca9c |
32 | } |
33 | unless ($dq->{order_is_stable}) { |
3482f7c8 |
34 | die $self->_slice_type." limit style requires a stable order"; |
0446ca9c |
35 | } |
36 | die "Slice's inner is not a Select" |
6b45ffe4 |
37 | unless is_Select my $orig_select = $dq->{from}; |
22f934ee |
38 | |
fdd10824 |
39 | my %remapped = $self->_subquery_remap($orig_select); |
22f934ee |
40 | |
fdd10824 |
41 | my @inside_select_list = @{$remapped{inside_select_list}}; |
42 | my @outside_select_list = @{$remapped{outside_select_list}}; |
43 | my @inside_order = @{$remapped{inside_order}}; |
44 | my @outside_order = @{$remapped{outside_order}}; |
45 | my $default_inside_alias = $remapped{default_inside_alias}; |
46 | my $inner_body = $remapped{inner_body}; |
22f934ee |
47 | |
0446ca9c |
48 | my $limit_plus_offset = +{ |
49 | %{$dq->{limit}}, value => $dq->{limit}{value} + $dq->{offset}{value} |
50 | }; |
22f934ee |
51 | |
9fcc2256 |
52 | return $self->_render( |
53 | map { |
f8a557c2 |
54 | ($dq->{preserve_order} and @outside_order) |
9fcc2256 |
55 | ? Select( |
56 | \@outside_select_list, |
57 | compose { |
e3335558 |
58 | Order($b->{by}, $b->{reverse}, $b->{nulls}, $a) |
60cbee33 |
59 | } ( |
fdd10824 |
60 | @outside_order, |
60cbee33 |
61 | Alias($default_inside_alias, $_) |
62 | ) |
9fcc2256 |
63 | ) |
64 | : $_ |
60cbee33 |
65 | } ( |
66 | Slice( |
9fcc2256 |
67 | undef, $dq->{limit}, |
68 | Select( |
69 | [ |
1bfa648a |
70 | @outside_select_list, |
9fcc2256 |
71 | $dq->{preserve_order} |
72 | ? (grep @{$_->{elements}} == 1, |
fdd10824 |
73 | map $_->{by}, @outside_order) |
9fcc2256 |
74 | : (), |
75 | ], |
76 | compose { |
710a5e2c |
77 | Order($b->{by}, !$b->{reverse}, -($b->{nulls}||0), $a) |
9fcc2256 |
78 | } ( |
fdd10824 |
79 | @outside_order, |
9fcc2256 |
80 | Alias( |
81 | $default_inside_alias, |
82 | Slice( |
83 | undef, $limit_plus_offset, |
84 | Select( |
85 | \@inside_select_list, |
86 | compose { |
e3335558 |
87 | Order($b->{by}, $b->{reverse}, $b->{nulls}, $a) |
fdd10824 |
88 | } @inside_order, $inner_body |
9fcc2256 |
89 | ) |
90 | ) |
91 | ) |
92 | ) |
93 | ) |
94 | ) |
60cbee33 |
95 | ) |
6b45ffe4 |
96 | ); |
0446ca9c |
97 | } |
98 | |
99 | 1; |