1 package Data::Query::Renderer::SQL::Slice::GenericSubquery;
3 use Data::Query::ExprHelpers;
6 with 'Data::Query::Renderer::SQL::Slice::SubqueryRemap';
9 (limit => 1, offset => 1);
13 (limit => 'requires', offset => 'requires');
18 die "Slice's inner is not a Select"
19 unless is_Select my $orig_select = $dq->{from};
20 my %remapped = $self->_subquery_remap($orig_select);
21 my $first_from = $remapped{inner_body};
22 # Should we simply strip until we reach a join/alias/etc. here?
23 STRIP: while ($first_from) {
24 if (is_Group($first_from)) {
25 $first_from = $first_from->{from};
27 } elsif (is_Where($first_from)) {
28 $first_from = $first_from->{from};
30 } elsif (is_Join($first_from)) {
31 $first_from = $first_from->{left};
36 die "WHAT" unless $first_from;
37 $first_from = $first_from->{from} if is_Alias($first_from);
39 foreach my $i (0..$#{$remapped{inside_order}}) {
40 my $order = $remapped{inside_order}[$i];
41 my $outside = $remapped{outside_order}[$i];
42 if (is_Identifier($order->{by})
44 (@{$order->{by}{elements}} == 2
45 and $order->{by}{elements}[0] eq $remapped{default_inside_alias})
46 or (@{$order->{by}{elements}} == 1))
49 $outside->{by}, $order->{by}{elements}[-1], $order->{reverse},
57 my $count_alias = 'rownum__emulation';
58 my ($op_and, $op_or) = map +{ 'SQL.Naive' => $_ }, qw(AND OR);
59 my $count_cond = compose {
61 my $rhs = Identifier($count_alias, $b->[1]);
62 ($lhs, $rhs) = ($rhs, $lhs) if $b->[2];
63 my $no_nulls = ($b->[3]||'') eq 'none';
69 Operator({ 'SQL.Naive' => 'IS NOT NULL' }, [ $lhs ]),
70 Operator({ 'SQL.Naive' => 'IS NULL' }, [ $rhs ]),
74 } Operator({ 'SQL.Naive' => '>' }, [ $lhs, $rhs ]);
85 map Operator({ 'SQL.Naive' => 'IS NULL' }, [ $_ ]),
90 } Operator({ 'SQL.Naive' => '=' }, [ $lhs, $rhs ])),
98 my $count_sel = Select(
99 [ Operator({ 'SQL.Naive' => 'apply' }, [ Identifier('COUNT'), Identifier('*') ]) ],
102 Alias($count_alias, $first_from)
105 my $count_where = Operator(
106 { 'SQL.Naive' => ($dq->{offset} ? 'BETWEEN' : '<') },
113 value => $dq->{limit}{value}+$dq->{offset}{value}-1
120 return $self->render(
122 $remapped{outside_select_list},
123 (compose { no warnings 'once'; Order($b->{by}, $b->{reverse}, $b->{nulls}, $a) }
124 @{$remapped{outside_order}},
128 $remapped{default_inside_alias},
130 $remapped{inside_select_list},
131 $remapped{inner_body},