Fix trailing whitespace
[dbsrgits/Data-Query.git] / lib / Data / Query / Renderer / SQL / Slice / RowNumberOver.pm
CommitLineData
77585983 1package Data::Query::Renderer::SQL::Slice::RowNumberOver;
2
fdd10824 3use Data::Query::Constants;
4use Data::Query::ExprHelpers;
77585983 5use Moo::Role;
6
fdd10824 7with 'Data::Query::Renderer::SQL::Slice::SubqueryRemap';
8
fbf38b8e 9sub slice_subquery {
10 (limit => 1, offset => 1);
11}
12
8b2c306b 13sub slice_stability { }
14
77585983 15sub _render_slice {
16 my ($self, $dq) = @_;
17 die "Slice's inner is not a Select"
18 unless (my $orig_select = $dq->{from})->{type} eq DQ_SELECT;
fdd10824 19
20 my %remapped = $self->_subquery_remap($orig_select);
21
22 my @inside_select_list = @{$remapped{inside_select_list}};
23 my @outside_select_list = @{$remapped{outside_select_list}};
24 my @inside_order = @{$remapped{inside_order}};
25 my @outside_order = @{$remapped{outside_order}};
26 my $default_inside_alias = $remapped{default_inside_alias};
27 my $inner_body = $remapped{inner_body};
28
29 my $rno_name = 'rno__row__index';
30
e3335558 31 my $order = compose { Order($b->{by}, $b->{reverse}, $b->{nulls}, $a) }
fdd10824 32 @outside_order, undef;
33
34 my $rno_node = Alias($rno_name, $self->_rno_literal($order));
35
36 my $limit_plus_offset = +{
37 %{$dq->{limit}}, value => ($dq->{limit}{value}||0) + ($dq->{offset}{value}||0)
77585983 38 };
fdd10824 39
40 my $offset_plus = +{
41 %{$dq->{limit}}, value => ($dq->{offset}{value}||0)+1
77585983 42 };
fdd10824 43
44 return $self->_render(
45 Select(
46 \@outside_select_list,
47 Where(
48 Operator(
49 { 'SQL.Naive' => 'AND' },
50 [
51 Operator(
52 { 'SQL.Naive' => '>=' },
53 [ Identifier($rno_name), $offset_plus ],
54 ),
55 Operator(
56 { 'SQL.Naive' => '<=' },
57 [ Identifier($rno_name), $limit_plus_offset ],
58 ),
77585983 59 ]
fdd10824 60 ),
61 Alias(
62 $default_inside_alias,
63 Select(
64 [ @outside_select_list, $rno_node ],
65 Alias(
66 $default_inside_alias,
67 Select(
68 \@inside_select_list,
69 $inner_body
70 ),
71 ),
72 ),
73 )
74 )
75 )
76 );
77585983 77}
78
79sub _rno_literal {
80 my ($self, $order) = @_;
81 my ($order_str, @order_bind) = (
82 $order
3d84f4a9 83 ? @{$self->render($order)}
77585983 84 : ('')
85 );
86 return +{
87 type => DQ_LITERAL,
88 subtype => 'SQL',
89 literal => "ROW_NUMBER() OVER( $order_str )",
90 values => \@order_bind
91 };
92}
93
941;