1 package Data::Query::Renderer::SQL::Slice::GenericSubquery;
3 use Data::Query::ExprHelpers;
6 with 'Data::Query::Renderer::SQL::Slice::SubqueryRemap';
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 # Should we simply strip until we reach a join/alias/etc. here?
15 $first_from = $first_from->{from}{from} if is_Having($first_from);
16 $first_from = $first_from->{from} if is_Where($first_from);
17 while (is_Join $first_from) {
18 $first_from = $first_from->{left};
20 $first_from = $first_from->{from} if is_Alias($first_from);
21 my $first_order = $remapped{inside_order}[0]{by};
22 my $count_col = $first_order->{elements}[-1];
23 my $count_alias = 'rownum__emulation';
24 my $count_sel = Select(
25 [ Operator({ 'SQL.Naive' => 'apply' }, [ Identifier('COUNT'), Identifier('*') ]) ],
28 { 'SQL.Naive' => ($remapped{inside_order}[0]{reverse} ? '>' : '<') },
30 Identifier($count_alias, $count_col),
31 $remapped{outside_order}[0]{by}
34 Alias($count_alias, $first_from)
37 my $count_where = Operator(
38 { 'SQL.Naive' => ($dq->{offset} ? 'BETWEEN' : '<') },
45 value => $dq->{limit}{value}+$dq->{offset}{value}-1
54 $remapped{outside_select_list},
55 (compose { no warnings 'once'; Order($b->{by}, $b->{reverse}, $a) }
56 @{$remapped{outside_order}},
60 $remapped{default_inside_alias},
62 $remapped{inside_select_list},
63 $remapped{inner_body},