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