Commit | Line | Data |
fdd10824 |
1 | package Data::Query::Renderer::SQL::Slice::SubqueryRemap; |
2 | |
3 | use Data::Query::ExprHelpers; |
4 | use Moo::Role; |
5 | |
6 | sub _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 | |
94 | 1; |