working RowNumberOver
[dbsrgits/Data-Query.git] / lib / Data / Query / Renderer / SQL / Slice / SubqueryRemap.pm
CommitLineData
fdd10824 1package Data::Query::Renderer::SQL::Slice::SubqueryRemap;
2
3use Data::Query::ExprHelpers;
4use Moo::Role;
5
6sub _subquery_remap {
7 my ($self, $orig_select) = @_;
8
9 my $gensym_count;
10 my $default_inside_alias;
11
12 my @inside_select_list = map {
13 if (is_Alias) {
14 $_;
15 } elsif (is_Identifier) {
16 my @el = @{$_->{elements}};
17 if (@el == 2 and $el[0] eq ($default_inside_alias ||= $el[0])) {
18 $_;
19 } else {
20 Alias(join('__', @el), $_);
21 }
22 } else {
23 Alias(sprintf("GENSYM__%03i",++$gensym_count), $_);
24 }
25 } @{$orig_select->{select}};
26
27 my %alias_map = map {
28 if (is_Alias and is_Identifier $_->{from}) {
29 +(join('.',@{$_->{from}{elements}}) => Identifier($_->{to}))
30 } elsif (is_Identifier) {
31 +(join('.',@{$_->{elements}}) => $_)
32 } else {
33 +()
34 }
35 } @inside_select_list;
36
37 my @outside_select_list = map {
38 if (is_Alias) {
39 Identifier($_->{to});
40 } else {
41 $_;
42 }
43 } @inside_select_list;
44
45 my @inside_order;
46 my $inner_body = do {
47 my $order = $orig_select->{from};
48 while (is_Order $order) {
49 push @inside_order, $order;
50 $order = $order->{from};
51 }
52 $order;
53 };
54
55 my $order_gensym_count;
56 my @outside_order = map {
57 my $by = $_->{by};
58 if (is_Identifier $by) {
59 $default_inside_alias ||= $by->{elements}[0]
60 if @{$by->{elements}} == 2;
61 my $mapped_by
62 = $alias_map{join('.', @{$by->{elements}})}
63 ||= do {
64 if (
65 @{$by->{elements}} == 2
66 and $by->{elements}[0] eq $default_inside_alias
67 ) {
68 push @inside_select_list, $by;
69 $by;
70 } else {
71 my $name = sprintf("ORDER__BY__%03i",++$order_gensym_count);
72 push @inside_select_list, Alias($name, $by);
73 Identifier($name);
74 }
75 };
76 Order($mapped_by, $_->{reverse});
77 } else {
78 die "XXX not implemented yet";
79 }
80 } @inside_order;
81
82 $default_inside_alias ||= 'me';
83
84 return (
85 inside_select_list => \@inside_select_list,
86 outside_select_list => \@outside_select_list,
87 inside_order => \@inside_order,
88 outside_order => \@outside_order,
89 default_inside_alias => $default_inside_alias,
90 inner_body => $inner_body,
91 );
92}
93
941;