Fix trailing whitespace
[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
af2d4155 6sub _subquery_remap_select {
fdd10824 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
af2d4155 27 my @outside_select_list = map {
28 if (is_Alias) {
29 Identifier($_->{to});
30 } else {
31 $_;
32 }
33 } @inside_select_list;
34
35 return (
36 inside_select_list => \@inside_select_list,
37 outside_select_list => \@outside_select_list,
912a19a2 38 default_inside_alias => $default_inside_alias||'me',
af2d4155 39 );
40}
41
42sub _subquery_remap {
43 my ($self, $orig_select) = @_;
44
45 my $gensym_count;
46 my %select_remap = $self->_subquery_remap_select($orig_select);
47
48 my $default_inside_alias = $select_remap{default_inside_alias};
49 my @inside_select_list = @{$select_remap{inside_select_list}};
50 my @outside_select_list = @{$select_remap{outside_select_list}};
51
fdd10824 52 my %alias_map = map {
53 if (is_Alias and is_Identifier $_->{from}) {
6b9e9259 54 +(
55 join('.',@{$_->{from}{elements}}) => Identifier($_->{to}),
56 $_->{from}{elements}[-1] => Identifier($_->{to}),
57 )
fdd10824 58 } elsif (is_Identifier) {
6b9e9259 59 +(
60 join('.',@{$_->{elements}}) => $_,
61 $_->{elements}[-1] => $_,
62 )
fdd10824 63 } else {
64 +()
65 }
66 } @inside_select_list;
67
fdd10824 68 my @inside_order;
69 my $inner_body = do {
70 my $order = $orig_select->{from};
71 while (is_Order $order) {
72 push @inside_order, $order;
73 $order = $order->{from};
74 }
75 $order;
76 };
77
78 my $order_gensym_count;
79 my @outside_order = map {
80 my $by = $_->{by};
81 if (is_Identifier $by) {
82 $default_inside_alias ||= $by->{elements}[0]
83 if @{$by->{elements}} == 2;
84 my $mapped_by
85 = $alias_map{join('.', @{$by->{elements}})}
86 ||= do {
87 if (
88 @{$by->{elements}} == 2
89 and $by->{elements}[0] eq $default_inside_alias
90 ) {
91 push @inside_select_list, $by;
92 $by;
93 } else {
94 my $name = sprintf("ORDER__BY__%03i",++$order_gensym_count);
95 push @inside_select_list, Alias($name, $by);
96 Identifier($name);
97 }
98 };
f5ba44a5 99 Order($mapped_by, $_->{reverse}, $_->{nulls});
fdd10824 100 } else {
ce86e12a 101 my $name = sprintf("ORDER__BY__%03i",++$order_gensym_count);
102 push @inside_select_list, Alias($name, $by);
f5ba44a5 103 Order(Identifier($name), $_->{reverse}, $_->{nulls});
fdd10824 104 }
105 } @inside_order;
106
107 $default_inside_alias ||= 'me';
108
109 return (
110 inside_select_list => \@inside_select_list,
111 outside_select_list => \@outside_select_list,
112 inside_order => \@inside_order,
113 outside_order => \@outside_order,
114 default_inside_alias => $default_inside_alias,
115 inner_body => $inner_body,
116 );
117}
118
1191;