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 | |
8b2c306b |
18 | sub slice_stability { |
19 | (offset => 'requires'); |
20 | } |
21 | |
3482f7c8 |
22 | sub _slice_type { 'FetchFirst' } |
23 | |
0446ca9c |
24 | sub _render_slice { |
25 | my ($self, $dq) = @_; |
26 | unless ($dq->{offset}) { |
3482f7c8 |
27 | return $self->_render_slice_limit($dq); |
0446ca9c |
28 | } |
29 | unless ($dq->{order_is_stable}) { |
3482f7c8 |
30 | die $self->_slice_type." limit style requires a stable order"; |
0446ca9c |
31 | } |
32 | die "Slice's inner is not a Select" |
6b45ffe4 |
33 | unless is_Select my $orig_select = $dq->{from}; |
22f934ee |
34 | die "Slice's Select not followed by Order but order_is_stable set" |
35 | unless is_Order $orig_select->{from}; |
36 | |
fdd10824 |
37 | my %remapped = $self->_subquery_remap($orig_select); |
22f934ee |
38 | |
fdd10824 |
39 | my @inside_select_list = @{$remapped{inside_select_list}}; |
40 | my @outside_select_list = @{$remapped{outside_select_list}}; |
41 | my @inside_order = @{$remapped{inside_order}}; |
42 | my @outside_order = @{$remapped{outside_order}}; |
43 | my $default_inside_alias = $remapped{default_inside_alias}; |
44 | my $inner_body = $remapped{inner_body}; |
22f934ee |
45 | |
0446ca9c |
46 | my $limit_plus_offset = +{ |
47 | %{$dq->{limit}}, value => $dq->{limit}{value} + $dq->{offset}{value} |
48 | }; |
22f934ee |
49 | |
9fcc2256 |
50 | return $self->_render( |
51 | map { |
0446ca9c |
52 | $dq->{preserve_order} |
9fcc2256 |
53 | ? Select( |
54 | \@outside_select_list, |
55 | compose { |
e3335558 |
56 | Order($b->{by}, $b->{reverse}, $b->{nulls}, $a) |
60cbee33 |
57 | } ( |
fdd10824 |
58 | @outside_order, |
60cbee33 |
59 | Alias($default_inside_alias, $_) |
60 | ) |
9fcc2256 |
61 | ) |
62 | : $_ |
60cbee33 |
63 | } ( |
64 | Slice( |
9fcc2256 |
65 | undef, $dq->{limit}, |
66 | Select( |
67 | [ |
1bfa648a |
68 | @outside_select_list, |
9fcc2256 |
69 | $dq->{preserve_order} |
70 | ? (grep @{$_->{elements}} == 1, |
fdd10824 |
71 | map $_->{by}, @outside_order) |
9fcc2256 |
72 | : (), |
73 | ], |
74 | compose { |
710a5e2c |
75 | Order($b->{by}, !$b->{reverse}, -($b->{nulls}||0), $a) |
9fcc2256 |
76 | } ( |
fdd10824 |
77 | @outside_order, |
9fcc2256 |
78 | Alias( |
79 | $default_inside_alias, |
80 | Slice( |
81 | undef, $limit_plus_offset, |
82 | Select( |
83 | \@inside_select_list, |
84 | compose { |
e3335558 |
85 | Order($b->{by}, $b->{reverse}, $b->{nulls}, $a) |
fdd10824 |
86 | } @inside_order, $inner_body |
9fcc2256 |
87 | ) |
88 | ) |
89 | ) |
90 | ) |
91 | ) |
92 | ) |
60cbee33 |
93 | ) |
6b45ffe4 |
94 | ); |
0446ca9c |
95 | } |
96 | |
97 | 1; |