--- /dev/null
+package Data::Query::Renderer::SQL::Slice::GenericSubquery;
+
+use Data::Query::ExprHelpers;
+use Moo::Role;
+
+with 'Data::Query::Renderer::SQL::Slice::SubqueryRemap';
+
+sub _render_slice {
+ my ($self, $dq) = @_;
+ die "Slice's inner is not a Select"
+ unless is_Select my $orig_select = $dq->{from};
+ my %remapped = $self->_subquery_remap($orig_select);
+ my $first_from = $remapped{inner_body};
+ $first_from = $first_from->{from} if is_Where($first_from);
+ while (is_Join $first_from) {
+ $first_from = $first_from->{left};
+ }
+ $first_from = $first_from->{from} if is_Alias($first_from);
+ my $first_order = $remapped{inside_order}[0]{by};
+ my $count_col = $first_order->{elements}[-1];
+ my $count_alias = 'rownum__emulation';
+ my $count_sel = Select(
+ [ Operator({ 'SQL.Naive' => 'apply' }, [ Identifier('COUNT'), Identifier('*') ]) ],
+ Where(
+ Operator(
+ { 'SQL.Naive' => ($first_order->{reverse} ? '>' : '<') },
+ [ Identifier($count_alias, $count_col), $first_order ]
+ ),
+ Alias($count_alias, $first_from)
+ )
+ );
+ my $count_where = Operator(
+ { 'SQL.Naive' => ($dq->{offset} ? 'BETWEEN' : '<') },
+ [ $count_sel, (
+ $dq->{offset}
+ ? (
+ $dq->{offset},
+ {
+ %{$dq->{limit}},
+ value => $dq->{limit}{value}+$dq->{offset}{value}-1
+ }
+ )
+ : ($dq->{limit})
+ )
+ ]
+ );
+ return $self->render(
+ Select(
+ $remapped{outside_select_list},
+ (compose { no warnings 'once'; Order($b->{by}, $b->{reverse}, $a) }
+ @{$remapped{outside_order}},
+ Where(
+ $count_where,
+ Alias(
+ $remapped{default_inside_alias},
+ Select(
+ $remapped{inside_select_list},
+ $remapped{inner_body},
+ )
+ )
+ )
+ )
+ )
+ );
+}
+
+1;