From: Matt S Trout Date: Sun, 29 Jul 2012 15:20:05 +0000 (+0000) Subject: more functional select list generation X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=22f934ee20bc7241e3a88f2bfeb9e8d5d7735f99;p=dbsrgits%2FData-Query.git more functional select list generation --- diff --git a/lib/Data/Query/Renderer/SQL/Slice/FetchFirst.pm b/lib/Data/Query/Renderer/SQL/Slice/FetchFirst.pm index 3579215..f7be0b2 100644 --- a/lib/Data/Query/Renderer/SQL/Slice/FetchFirst.pm +++ b/lib/Data/Query/Renderer/SQL/Slice/FetchFirst.pm @@ -25,43 +25,58 @@ sub _render_slice { } die "Slice's inner is not a Select" unless is_Select my $orig_select = $dq->{from}; - my %alias_map; + die "Slice's Select not followed by Order but order_is_stable set" + unless is_Order $orig_select->{from}; + my $gensym_count; - my (@inside_select_list, @outside_select_list); my $default_inside_alias; - SELECT: foreach my $s (@{$orig_select->{select}}) { - my $name; - if (is_Alias $s) { - $name = $s->{to}; - $s = $s->{from}; - } - my $key; - if (is_Identifier $s) { - 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; - push @inside_select_list, $s; - push @outside_select_list, $s; - next SELECT; - } + + my @inside_select_list = map { + if (is_Alias) { + $_; + } elsif (is_Identifier) { + my @el = @{$_->{elements}}; + if (@el == 2 and $el[0] eq ($default_inside_alias ||= $el[0])) { + $_; + } else { + Alias(join('__', @el), $_); } - $name ||= join('__', @{$s->{elements}}); - $key = join('.', @{$s->{elements}}); } else { - die "XXX not implemented yet" unless $name; - $key = "$s"; + Alias(sprintf("GENSYM__%03i",++$gensym_count), $_); } - $name ||= sprintf("GENSYM__%03i",++$gensym_count); - push @inside_select_list, Alias($name, $s); - push @outside_select_list, $alias_map{$key} = Identifier($name); - } - my $order = $orig_select->{from}; + } @{$orig_select->{select}}; + + my %alias_map = map { + if (is_Alias and is_Identifier $_->{from}) { + +(join('.',@{$_->{from}{elements}}) => Identifier($_->{to})) + } elsif (is_Identifier) { + +(join('.',@{$_->{elements}}) => $_) + } else { + +() + } + } @inside_select_list; + + my @outside_select_list = map { + if (is_Alias) { + Identifier($_->{to}); + } else { + $_; + } + } @inside_select_list; + + my @order_nodes; + my $inner_body = do { + my $order = $orig_select->{from}; + while (is_Order $order) { + push @order_nodes, $order; + $order = $order->{from}; + } + $order; + }; + my $order_gensym_count; - die "Slice's Select not followed by Order but order_is_stable set" - unless is_Order $order; - my (@order_nodes, %order_map); - while (is_Order $order) { + my %order_map; + foreach my $order (@order_nodes) { my $by = $order->{by}; if (is_Identifier $by) { $default_inside_alias ||= $by->{elements}[0] @@ -83,14 +98,14 @@ sub _render_slice { } else { die "XXX not implemented yet"; } - push @order_nodes, $order; - $order = $order->{from}; } + $default_inside_alias ||= 'me'; + my $limit_plus_offset = +{ %{$dq->{limit}}, value => $dq->{limit}{value} + $dq->{offset}{value} }; - my $inner_body = $order; + return $self->_render( map { $dq->{preserve_order}