From: Matt S Trout Date: Sat, 13 Apr 2019 04:16:38 +0000 (+0000) Subject: delete from, update using, join using X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=scpubgit%2FQ-Branch.git;a=commitdiff_plain;h=e0eb8d26a5a2548ac7f015b66512981a730474ac delete from, update using, join using --- diff --git a/lib/SQL/Abstract/Clauses.pm b/lib/SQL/Abstract/Clauses.pm index 2f6619a..b12dbca 100644 --- a/lib/SQL/Abstract/Clauses.pm +++ b/lib/SQL/Abstract/Clauses.pm @@ -91,7 +91,7 @@ sub _expand_select_clause_order_by { sub _expand_update_clause_target { my ($self, $target) = @_; - +(target => $self->expand_expr($target, -ident)); + +(target => $self->_expand_maybe_list_expr($target, -ident)); } sub _expand_update_clause_set { diff --git a/lib/SQL/Abstract/ExtraClauses.pm b/lib/SQL/Abstract/ExtraClauses.pm index 78680da..b874be5 100644 --- a/lib/SQL/Abstract/ExtraClauses.pm +++ b/lib/SQL/Abstract/ExtraClauses.pm @@ -27,6 +27,12 @@ sub new { $new->{expand_op}{as} = '_expand_op_as'; $new->{expand}{as} = '_expand_op_as'; $new->{render}{as} = '_render_as'; + splice(@{$new->{clauses_of}{update}}, 2, 0, 'from'); + splice(@{$new->{clauses_of}{delete}}, 1, 0, 'using'); + $new->{expand_clause}{'update.from'} = '_expand_select_clause_from'; + $new->{expand_clause}{'delete.using'} = sub { + +(using => $_[0]->_expand_from_list(undef, $_[1])); + }; return $new; } @@ -71,6 +77,12 @@ sub _expand_join { if (my $as = delete $proto{as}) { $proto{to} = { -as => [ $proto{to}, ref($as) eq 'ARRAY' ? @$as : $as ] }; } + if (defined($proto{using}) and ref(my $using = $proto{using}) ne 'HASH') { + $proto{using} = { -row => [ + map [ $self->expand_expr($_, -ident) ], + ref($using) eq 'ARRAY' ? @$using: $using + ] }; + } my %ret = map +($_ => $self->expand_expr($proto{$_}, -ident)), sort keys %proto; return +{ -join => \%ret }; @@ -95,7 +107,7 @@ sub _render_join { ) ], [ $self->render_aqt( - map +($_->{-ident} or $_->{-as} ? $_ : { -row => [ $_ ] }), $args->{to} + map +($_->{-ident} || $_->{-as} ? $_ : { -row => [ $_ ] }), $args->{to} ) ], ($args->{on} ? ( [ $self->_sqlcase('on') ], diff --git a/xt/clauses.t b/xt/clauses.t index 5546d86..450b616 100644 --- a/xt/clauses.t +++ b/xt/clauses.t @@ -38,4 +38,54 @@ is_same_sql_bind( is_same_sql($sql, q{SELECT a FROM (VALUES (1, 2), (3, 4)) AS t(a,b)}); +($sql) = $sqlac->update({ + update => 'employees', + set => { sales_count => { sales_count => { '+', \1 } } }, + from => 'accounts', + where => { + 'accounts.name' => { '=' => \"'Acme Corporation'" }, + 'employees.id' => { -ident => 'accounts.sales_person' }, + } +}); + +is_same_sql( + $sql, + q{UPDATE employees SET sales_count = sales_count + 1 FROM accounts + WHERE accounts.name = 'Acme Corporation' + AND employees.id = accounts.sales_person + } +); + +($sql) = $sqlac->update({ + update => [ qw(tab1 tab2) ], + set => { + 'tab1.column1' => { -ident => 'value1' }, + 'tab1.column2' => { -ident => 'value2' }, + }, + where => { 'tab1.id' => { -ident => 'tab2.id' } }, +}); + +is_same_sql( + $sql, + q{UPDATE tab1, tab2 SET tab1.column1 = value1, tab1.column2 = value2 + WHERE tab1.id = tab2.id} +); + +is_same_sql( + $sqlac->delete({ + from => 'x', + using => 'y', + where => { 'x.id' => { -ident => 'y.x_id' } } + }), + q{DELETE FROM x USING y WHERE x.id = y.x_id} +); + +is_same_sql( + $sqlac->select({ + select => [ 'x.*', 'y.*' ], + from => [ 'x', -join => [ 'y', using => 'y_id' ] ], + }), + q{SELECT x.*, y.* FROM x JOIN y USING (y_id)}, +); + done_testing;