working RowNum.pm
[dbsrgits/Data-Query.git] / lib / Data / Query / Renderer / SQL / Slice / RowNum.pm
CommitLineData
98994ccc 1package Data::Query::Renderer::SQL::Slice::RowNum;
2
3use Data::Query::ExprHelpers;
4use Moo::Role;
5
6with 'Data::Query::Renderer::SQL::Slice::SubqueryRemap';
7
8sub _render_slice {
9 my ($self, $dq) = @_;
10 die "Slice's inner is not a Select"
11 unless is_Select my $orig_select = $dq->{from};
12 my %remapped = $self->_subquery_remap_select($orig_select);
13 my $inside_select = Alias(
14 $remapped{default_inside_alias},
15 Select($remapped{inside_select_list}, $orig_select->{from}),
16 );
17 unless ($dq->{offset}) {
18 return $self->render(
19 Select(
20 $remapped{outside_select_list},
21 Where(
22 Operator(
23 { 'SQL.Naive' => '<=' },
24 [
25 Literal(SQL => 'ROWNUM'),
26 $dq->{limit}
27 ]
28 ),
29 $inside_select
30 )
31 )
32 );
33 }
34 my ($limit_plus_offset, $offset_plus) = (
35 { %{$dq->{limit}}, value => $dq->{limit}{value}+$dq->{offset}{value} },
36 { %{$dq->{limit}}, value => $dq->{offset}{value}+1 }
37 );
38
39 my $rownum_name = 'rownum__index';
40
41 if ($dq->{order_is_stable}) {
42 return $self->render(
43 Select(
44 $remapped{outside_select_list},
45 Where(
46 Operator(
47 { 'SQL.Naive' => '>=' },
29b2dace 48 [ Identifier($rownum_name), $offset_plus ]
98994ccc 49 ),
50 Alias(
51 $remapped{default_inside_alias},
52 Select(
53 [ @{$remapped{outside_select_list}},
54 Alias($rownum_name, Literal(SQL => 'ROWNUM')) ],
55 Where(
56 Operator(
57 { 'SQL.Naive' => '<=' },
29b2dace 58 [ Literal(SQL => 'ROWNUM'), $limit_plus_offset ]
98994ccc 59 ),
60 $inside_select,
61 )
62 )
63 )
64 )
65 )
66 );
67 } else {
68 return $self->render(
69 Select(
70 $remapped{outside_select_list},
71 Where(
72 Operator(
73 { 'SQL.Naive' => 'BETWEEN' },
29b2dace 74 [ Identifier($rownum_name), $offset_plus, $limit_plus_offset ]
98994ccc 75 ),
76 Alias(
77 $remapped{default_inside_alias},
78 Select(
79 [ @{$remapped{outside_select_list}},
80 Alias($rownum_name, Literal(SQL => 'ROWNUM')) ],
81 $inside_select
82 )
83 )
84 )
85 )
86 );
87 }
88}
89
901;