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