From: Matt S Trout Date: Mon, 7 May 2012 06:16:12 +0000 (+0000) Subject: MOAR order X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=3482f7c839ade756df8a233453fc03c8b8160620;hp=119e511bed25c51b7414d071eff57fba747eb1d3;p=dbsrgits%2FData-Query.git MOAR order --- diff --git a/lib/Data/Query/Renderer/SQL/Pg.pm b/lib/Data/Query/Renderer/SQL/Pg.pm new file mode 100644 index 0000000..bc55ec4 --- /dev/null +++ b/lib/Data/Query/Renderer/SQL/Pg.pm @@ -0,0 +1,9 @@ +package Data::Query::Renderer::SQL::Pg; + +use Moo; + +extends 'Data::Query::Renderer::SQL::Naive'; + +with 'Data::Query::Renderer::SQL::Slice::LimitOffset'; + +1; diff --git a/lib/Data/Query/Renderer/SQL/Slice/FetchFirst.pm b/lib/Data/Query/Renderer/SQL/Slice/FetchFirst.pm index c45f836..e3d8372 100644 --- a/lib/Data/Query/Renderer/SQL/Slice/FetchFirst.pm +++ b/lib/Data/Query/Renderer/SQL/Slice/FetchFirst.pm @@ -5,18 +5,25 @@ use Data::Query::Constants qw( ); use Moo::Role; +sub _render_slice_limit { + my ($self, $dq) = @_; + return [ + ($dq->{from} ? $self->_render($dq->{from}) : ()), + $self->_format_keyword('FETCH FIRST'), + sprintf("%i", $dq->{limit}{value}), + $self->_format_keyword('ROWS ONLY') + ]; +} + +sub _slice_type { 'FetchFirst' } + sub _render_slice { my ($self, $dq) = @_; unless ($dq->{offset}) { - return [ - ($dq->{from} ? $self->_render($dq->{from}) : ()), - $self->_format_keyword('FETCH FIRST'), - sprintf("%i", $dq->{limit}{value}), - $self->_format_keyword('ROWS ONLY') - ]; + return $self->_render_slice_limit($dq); } unless ($dq->{order_is_stable}) { - die "FetchFirst limit style requires a stable order"; + die $self->_slice_type." limit style requires a stable order"; } die "Slice's inner is not a Select" unless (my $orig_select = $dq->{from})->{type} eq DQ_SELECT; @@ -32,7 +39,7 @@ sub _render_slice { } my $key; if ($s->{type} eq DQ_IDENTIFIER) { - if (@{$s->{elements}} == 2) { + if (!$name and @{$s->{elements}} == 2) { $default_inside_alias ||= $s->{elements}[0]; if ($s->{elements}[0] eq $default_inside_alias) { $alias_map{join('.',@{$s->{elements}})} = $s; @@ -44,7 +51,8 @@ sub _render_slice { $name ||= join('__', @{$s->{elements}}); $key = join('.', @{$s->{elements}}); } else { - die "XXX not implemented yet"; + die "XXX not implemented yet" unless $name; + $key = "$s"; } $name ||= sprintf("GENSYM__%03i",++$gensym_count); push @inside_select_list, +{ @@ -65,19 +73,28 @@ sub _render_slice { while ($order->{type} eq DQ_ORDER) { my $by = $order->{by}; if ($by->{type} eq DQ_IDENTIFIER) { + $default_inside_alias ||= $by->{elements}[0] + if @{$by->{elements}} == 2; $order_map{$by} = $alias_map{join('.', @{$by->{elements}})} ||= do { - my $name = sprintf("ORDER__BY__%03i",++$order_gensym_count); - push @inside_select_list, +{ - type => DQ_ALIAS, - from => $by, - to => $name - }; - +{ - type => DQ_IDENTIFIER, - elements => [ $name ], - }; + if ( + @{$by->{elements}} == 2 + and $by->{elements}[0] eq $default_inside_alias + ) { + $by; + } else { + my $name = sprintf("ORDER__BY__%03i",++$order_gensym_count); + push @inside_select_list, +{ + type => DQ_ALIAS, + from => $by, + to => $name + }; + +{ + type => DQ_IDENTIFIER, + elements => [ $name ], + }; + } }; } else { die "XXX not implemented yet"; diff --git a/lib/Data/Query/Renderer/SQL/Slice/SkipFirst.pm b/lib/Data/Query/Renderer/SQL/Slice/SkipFirst.pm new file mode 100644 index 0000000..f922fa1 --- /dev/null +++ b/lib/Data/Query/Renderer/SQL/Slice/SkipFirst.pm @@ -0,0 +1,9 @@ +package Data::Query::Renderer::SQL::Slice::SkipFirst; + +use Moo::Role; + +with 'Data::Query::Renderer::SQL::Slice::FirstSkip'; + +sub _slice_order { qw(offset limit) } + +1; diff --git a/lib/Data/Query/Renderer/SQL/Slice/Top.pm b/lib/Data/Query/Renderer/SQL/Slice/Top.pm new file mode 100644 index 0000000..124564d --- /dev/null +++ b/lib/Data/Query/Renderer/SQL/Slice/Top.pm @@ -0,0 +1,23 @@ +package Data::Query::Renderer::SQL::Slice::Top; + +use Data::Query::Constants qw( + DQ_SELECT DQ_ALIAS DQ_IDENTIFIER DQ_ORDER DQ_SLICE +); +use Moo::Role; + +with 'Data::Query::Renderer::SQL::Slice::FetchFirst'; + +sub _render_slice_limit { + my ($self, $dq) = @_; + my $basic = $self->_render($dq->{from}); + return [ + $basic->[0], + $self->_format_keyword('TOP'), + sprintf("%i", $dq->{limit}{value}), + @{$basic}[1..$#$basic] + ]; +} + +sub _slice_type { 'Top' } + +1;