Commit | Line | Data |
7d0fb8c0 |
1 | package Data::Query::Renderer::SQL::MySQL; |
2 | |
944c72bc |
3 | sub map_descending (&;@) { |
4 | my ($block, $in) = @_; |
5 | local $_ = $in; |
6 | $_ = $block->($_) if ref($_) eq 'HASH'; |
7 | if (ref($_) eq 'REF' and ref($$_) eq 'HASH') { |
8 | $$_; |
9 | } elsif (ref($_) eq 'HASH') { |
10 | my $mapped = $_; |
11 | local $_; |
12 | +{ map +($_ => &map_descending($block, $mapped->{$_})), keys %$mapped }; |
13 | } elsif (ref($_) eq 'ARRAY') { |
14 | [ map &map_descending($block, $_), @$_ ] |
15 | } else { |
16 | $_ |
17 | } |
18 | } |
19 | |
20 | use Data::Query::Constants; |
21 | use Data::Query::ExprHelpers; |
7d0fb8c0 |
22 | use Moo; |
23 | |
24 | extends 'Data::Query::Renderer::SQL::Naive'; |
25 | |
26 | with 'Data::Query::Renderer::SQL::Slice::LimitXY'; |
27 | |
28 | sub _insert_default_values { |
29 | my ($self) = @_; |
30 | $self->_format_keyword('VALUES'), qw( ( ) ); |
31 | } |
32 | |
944c72bc |
33 | foreach my $type (qw(update delete)) { |
34 | around "_render_${type}" => sub { |
35 | my ($orig, $self) = (shift, shift); |
36 | $self->$orig($self->_maybe_double_subquery(@_)); |
37 | }; |
38 | } |
39 | |
40 | sub _maybe_double_subquery { |
41 | my ($self, $dq) = @_; |
42 | my $target = $dq->{target}; |
43 | my $new = { %$dq }; |
44 | foreach my $key (qw(set where)) { |
45 | next unless $dq->{$key}; |
46 | $new->{$key} = map_descending { |
47 | if (is_Select) { |
48 | my $found; |
49 | scan_dq_nodes(do { |
50 | if (is_Identifier($target)) { |
51 | my $ident = $target->{elements}[0]; |
52 | +{ DQ_IDENTIFIER ,=> sub { |
53 | my @el = @{$_[0]->{elements}}; |
54 | $found = 1 if @el == 1 and $el[0] eq $ident; |
55 | } |
56 | }; |
57 | } elsif (is_Literal($target)) { |
58 | my $ident = $target->{literal} or die "Can't handle complex literal"; |
59 | +{ DQ_LITERAL ,=> sub { |
60 | my $lit = $_[0]->{literal}; |
61 | $found = 1 if $lit and $lit eq $ident; |
62 | } |
63 | }; |
64 | } else { |
65 | die "Can't handle target type ".$target->{type}; |
66 | } |
67 | }, $_); |
68 | if ($found) { |
69 | \Select([ Identifier('*') ], Alias('_forced_double_subquery', $_)); |
70 | } else { |
71 | $_ |
72 | } |
73 | } else { |
74 | $_ |
75 | } |
76 | } $dq->{$key}; |
77 | } |
78 | $new; |
79 | } |
80 | |
7d0fb8c0 |
81 | 1; |