1 package Data::Query::Renderer::SQL::Slice::FetchFirst;
3 use Data::Query::ExprHelpers;
6 sub _render_slice_limit {
9 ($dq->{from} ? $self->_render($dq->{from}) : ()),
10 $self->_format_keyword('FETCH FIRST'),
11 sprintf("%i", $dq->{limit}{value}),
12 $self->_format_keyword('ROWS ONLY')
16 sub _slice_type { 'FetchFirst' }
20 unless ($dq->{offset}) {
21 return $self->_render_slice_limit($dq);
23 unless ($dq->{order_is_stable}) {
24 die $self->_slice_type." limit style requires a stable order";
26 die "Slice's inner is not a Select"
27 unless is_Select my $orig_select = $dq->{from};
28 die "Slice's Select not followed by Order but order_is_stable set"
29 unless is_Order $orig_select->{from};
32 my $default_inside_alias;
34 my @inside_select_list = map {
37 } elsif (is_Identifier) {
38 my @el = @{$_->{elements}};
39 if (@el == 2 and $el[0] eq ($default_inside_alias ||= $el[0])) {
42 Alias(join('__', @el), $_);
45 Alias(sprintf("GENSYM__%03i",++$gensym_count), $_);
47 } @{$orig_select->{select}};
50 if (is_Alias and is_Identifier $_->{from}) {
51 +(join('.',@{$_->{from}{elements}}) => Identifier($_->{to}))
52 } elsif (is_Identifier) {
53 +(join('.',@{$_->{elements}}) => $_)
57 } @inside_select_list;
59 my @outside_select_list = map {
65 } @inside_select_list;
69 my $order = $orig_select->{from};
70 while (is_Order $order) {
71 push @order_nodes, $order;
72 $order = $order->{from};
77 my $order_gensym_count;
78 my @mapped_order = map {
80 if (is_Identifier $by) {
81 $default_inside_alias ||= $by->{elements}[0]
82 if @{$by->{elements}} == 2;
84 = $alias_map{join('.', @{$by->{elements}})}
87 @{$by->{elements}} == 2
88 and $by->{elements}[0] eq $default_inside_alias
92 my $name = sprintf("ORDER__BY__%03i",++$order_gensym_count);
93 push @inside_select_list, Alias($name, $by);
97 Order($mapped_by, $_->{reverse});
99 die "XXX not implemented yet";
103 $default_inside_alias ||= 'me';
105 my $limit_plus_offset = +{
106 %{$dq->{limit}}, value => $dq->{limit}{value} + $dq->{offset}{value}
109 return $self->_render(
111 $dq->{preserve_order}
113 \@outside_select_list,
115 Order($b->{by}, $b->{reverse}, $a)
118 Alias($default_inside_alias, $_)
127 @outside_select_list,
128 $dq->{preserve_order}
129 ? (grep @{$_->{elements}} == 1,
130 map $_->{by}, @mapped_order)
134 Order($b->{by}, !$b->{reverse}, $a)
138 $default_inside_alias,
140 undef, $limit_plus_offset,
142 \@inside_select_list,
144 Order($b->{by}, $b->{reverse}, $a)
145 } @order_nodes, $inner_body