From: Matt S Trout Date: Thu, 16 Aug 2012 17:53:39 +0000 (+0100) Subject: beginnings of RowNum.pm X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=98994ccc7c2b4526d76f0c3c67f4466eb7cfe3c8;p=dbsrgits%2FData-Query.git beginnings of RowNum.pm --- diff --git a/lib/Data/Query/Renderer/SQL/Slice/RowNum.pm b/lib/Data/Query/Renderer/SQL/Slice/RowNum.pm new file mode 100644 index 0000000..c14790a --- /dev/null +++ b/lib/Data/Query/Renderer/SQL/Slice/RowNum.pm @@ -0,0 +1,90 @@ +package Data::Query::Renderer::SQL::Slice::RowNum; + +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_select($orig_select); + my $inside_select = Alias( + $remapped{default_inside_alias}, + Select($remapped{inside_select_list}, $orig_select->{from}), + ); + unless ($dq->{offset}) { + return $self->render( + Select( + $remapped{outside_select_list}, + Where( + Operator( + { 'SQL.Naive' => '<=' }, + [ + Literal(SQL => 'ROWNUM'), + $dq->{limit} + ] + ), + $inside_select + ) + ) + ); + } + my ($limit_plus_offset, $offset_plus) = ( + { %{$dq->{limit}}, value => $dq->{limit}{value}+$dq->{offset}{value} }, + { %{$dq->{limit}}, value => $dq->{offset}{value}+1 } + ); + + my $rownum_name = 'rownum__index'; + + if ($dq->{order_is_stable}) { + return $self->render( + Select( + $remapped{outside_select_list}, + Where( + Operator( + { 'SQL.Naive' => '>=' }, + [ Identifier($rownum_name), $limit_plus_offset, ] + ), + Alias( + $remapped{default_inside_alias}, + Select( + [ @{$remapped{outside_select_list}}, + Alias($rownum_name, Literal(SQL => 'ROWNUM')) ], + Where( + Operator( + { 'SQL.Naive' => '<=' }, + [ Literal(SQL => 'ROWNUM'), $offset_plus ] + ), + $inside_select, + ) + ) + ) + ) + ) + ); + } else { + return $self->render( + Select( + $remapped{outside_select_list}, + Where( + Operator( + { 'SQL.Naive' => 'BETWEEN' }, + [ Identifier($rownum_name), $limit_plus_offset, $offset_plus ] + ), + Alias( + $remapped{default_inside_alias}, + Select( + [ @{$remapped{outside_select_list}}, + Alias($rownum_name, Literal(SQL => 'ROWNUM')) ], + $inside_select + ) + ) + ) + ) + ); + } +} + +1;