don't negate undef in Slice/FetchFirst
[dbsrgits/Data-Query.git] / lib / Data / Query / Renderer / SQL / Slice / FetchFirst.pm
CommitLineData
0446ca9c 1package Data::Query::Renderer::SQL::Slice::FetchFirst;
2
6b45ffe4 3use Data::Query::ExprHelpers;
0446ca9c 4use Moo::Role;
5
fdd10824 6with 'Data::Query::Renderer::SQL::Slice::SubqueryRemap';
7
3482f7c8 8sub _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 18sub slice_stability {
19 (offset => 'requires');
20}
21
3482f7c8 22sub _slice_type { 'FetchFirst' }
23
0446ca9c 24sub _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
971;