whitespace
[dbsrgits/Data-Query.git] / lib / Data / Query / Renderer / SQL / Slice / GenericSubquery.pm
CommitLineData
01d7143b 1package Data::Query::Renderer::SQL::Slice::GenericSubquery;
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($orig_select);
13 my $first_from = $remapped{inner_body};
14 $first_from = $first_from->{from} if is_Where($first_from);
15 while (is_Join $first_from) {
16 $first_from = $first_from->{left};
17 }
18 $first_from = $first_from->{from} if is_Alias($first_from);
19 my $first_order = $remapped{inside_order}[0]{by};
20 my $count_col = $first_order->{elements}[-1];
21 my $count_alias = 'rownum__emulation';
22 my $count_sel = Select(
23 [ Operator({ 'SQL.Naive' => 'apply' }, [ Identifier('COUNT'), Identifier('*') ]) ],
24 Where(
25 Operator(
e31249d4 26 { 'SQL.Naive' => ($remapped{inside_order}[0]{reverse} ? '>' : '<') },
27 [
28 Identifier($count_alias, $count_col),
29 $remapped{outside_order}[0]{by}
30 ]
01d7143b 31 ),
32 Alias($count_alias, $first_from)
33 )
34 );
35 my $count_where = Operator(
36 { 'SQL.Naive' => ($dq->{offset} ? 'BETWEEN' : '<') },
37 [ $count_sel, (
38 $dq->{offset}
39 ? (
40 $dq->{offset},
41 {
42 %{$dq->{limit}},
43 value => $dq->{limit}{value}+$dq->{offset}{value}-1
44 }
45 )
46 : ($dq->{limit})
47 )
48 ]
49 );
50 return $self->render(
51 Select(
52 $remapped{outside_select_list},
53 (compose { no warnings 'once'; Order($b->{by}, $b->{reverse}, $a) }
54 @{$remapped{outside_order}},
55 Where(
56 $count_where,
57 Alias(
58 $remapped{default_inside_alias},
59 Select(
60 $remapped{inside_select_list},
61 $remapped{inner_body},
62 )
63 )
64 )
65 )
66 )
67 );
68}
69
701;