1 package Data::Query::Renderer::SQL::Slice::FetchFirst;
3 use Data::Query::ExprHelpers;
6 with 'Data::Query::Renderer::SQL::Slice::SubqueryRemap';
8 sub _render_slice_limit {
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')
23 (offset => 'requires');
26 sub _slice_type { 'FetchFirst' }
30 unless ($dq->{offset}) {
31 return $self->_render_slice_limit($dq);
33 unless ($dq->{order_is_stable}) {
34 die $self->_slice_type." limit style requires a stable order";
36 die "Slice's inner is not a Select"
37 unless is_Select my $orig_select = $dq->{from};
38 die "Slice's Select not followed by Order but order_is_stable set"
39 unless is_Order $orig_select->{from};
41 my %remapped = $self->_subquery_remap($orig_select);
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};
50 my $limit_plus_offset = +{
51 %{$dq->{limit}}, value => $dq->{limit}{value} + $dq->{offset}{value}
54 return $self->_render(
58 \@outside_select_list,
60 Order($b->{by}, $b->{reverse}, $b->{nulls}, $a)
63 Alias($default_inside_alias, $_)
74 ? (grep @{$_->{elements}} == 1,
75 map $_->{by}, @outside_order)
79 Order($b->{by}, !$b->{reverse}, -($b->{nulls}||0), $a)
83 $default_inside_alias,
85 undef, $limit_plus_offset,
89 Order($b->{by}, $b->{reverse}, $b->{nulls}, $a)
90 } @inside_order, $inner_body