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 | die "Slice's Select not followed by Order but order_is_stable set" |
39 | unless is_Order $orig_select->{from}; |
40 | |
fdd10824 |
41 | my %remapped = $self->_subquery_remap($orig_select); |
22f934ee |
42 | |
fdd10824 |
43 | my @inside_select_list = @{$remapped{inside_select_list}}; |
44 | my @outside_select_list = @{$remapped{outside_select_list}}; |
45 | my @inside_order = @{$remapped{inside_order}}; |
46 | my @outside_order = @{$remapped{outside_order}}; |
47 | my $default_inside_alias = $remapped{default_inside_alias}; |
48 | my $inner_body = $remapped{inner_body}; |
22f934ee |
49 | |
0446ca9c |
50 | my $limit_plus_offset = +{ |
51 | %{$dq->{limit}}, value => $dq->{limit}{value} + $dq->{offset}{value} |
52 | }; |
22f934ee |
53 | |
9fcc2256 |
54 | return $self->_render( |
55 | map { |
0446ca9c |
56 | $dq->{preserve_order} |
9fcc2256 |
57 | ? Select( |
58 | \@outside_select_list, |
59 | compose { |
e3335558 |
60 | Order($b->{by}, $b->{reverse}, $b->{nulls}, $a) |
60cbee33 |
61 | } ( |
fdd10824 |
62 | @outside_order, |
60cbee33 |
63 | Alias($default_inside_alias, $_) |
64 | ) |
9fcc2256 |
65 | ) |
66 | : $_ |
60cbee33 |
67 | } ( |
68 | Slice( |
9fcc2256 |
69 | undef, $dq->{limit}, |
70 | Select( |
71 | [ |
1bfa648a |
72 | @outside_select_list, |
9fcc2256 |
73 | $dq->{preserve_order} |
74 | ? (grep @{$_->{elements}} == 1, |
fdd10824 |
75 | map $_->{by}, @outside_order) |
9fcc2256 |
76 | : (), |
77 | ], |
78 | compose { |
710a5e2c |
79 | Order($b->{by}, !$b->{reverse}, -($b->{nulls}||0), $a) |
9fcc2256 |
80 | } ( |
fdd10824 |
81 | @outside_order, |
9fcc2256 |
82 | Alias( |
83 | $default_inside_alias, |
84 | Slice( |
85 | undef, $limit_plus_offset, |
86 | Select( |
87 | \@inside_select_list, |
88 | compose { |
e3335558 |
89 | Order($b->{by}, $b->{reverse}, $b->{nulls}, $a) |
fdd10824 |
90 | } @inside_order, $inner_body |
9fcc2256 |
91 | ) |
92 | ) |
93 | ) |
94 | ) |
95 | ) |
96 | ) |
60cbee33 |
97 | ) |
6b45ffe4 |
98 | ); |
0446ca9c |
99 | } |
100 | |
101 | 1; |