From: Matt S Trout Date: Tue, 16 Apr 2019 02:10:00 +0000 (+0000) Subject: with recursive test and bugfixes X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=scpubgit%2FQ-Branch.git;a=commitdiff_plain;h=f9f1fdcdafdb446bede69c98a8a5b64fd9fef09e with recursive test and bugfixes --- diff --git a/lib/SQL/Abstract/Clauses.pm b/lib/SQL/Abstract/Clauses.pm index fd98e73..18626c2 100644 --- a/lib/SQL/Abstract/Clauses.pm +++ b/lib/SQL/Abstract/Clauses.pm @@ -128,6 +128,10 @@ sub _expand_delete_clause_returning { sub _expand_statement { my ($self, $type, $args) = @_; my $ec = $self->{expand_clause}; + if ($args->{_}) { + $args = { %$args }; + $args->{$type} = delete $args->{_} + } return +{ "-${type}" => +{ map { my $val = $args->{$_}; diff --git a/lib/SQL/Abstract/ExtraClauses.pm b/lib/SQL/Abstract/ExtraClauses.pm index e29aea3..90716df 100644 --- a/lib/SQL/Abstract/ExtraClauses.pm +++ b/lib/SQL/Abstract/ExtraClauses.pm @@ -138,10 +138,10 @@ sub register_defaults { $self->clause_expander('select.with_recursive' => sub { my ($self, $with) = @_; my $exp = $self->$with_expander($with); - return +{ + return +(with => +{ %$exp, type => 'recursive' - }; + }); }); $self->clause_renderer('select.with' => sub { my ($self, $with) = @_; @@ -280,4 +280,9 @@ sub _render_alias { ); } +sub _expand_update_clause_target { + my ($self, $target) = @_; + +(target => $self->_expand_from_list(undef, $target)); +} + 1; diff --git a/xt/clauses.t b/xt/clauses.t index df6f2bf..758a2ea 100644 --- a/xt/clauses.t +++ b/xt/clauses.t @@ -197,4 +197,71 @@ is_same_sql( q{WITH (foo AS (SELECT 1)) SELECT * FROM foo}, ); +$sql = $sqlac->update({ + _ => [ 'tree_table', -join => { + to => { -select => { + with_recursive => [ + [ tree_with_path => qw(id parent_id path) ], + { -select => { + _ => [ + qw(id parent_id), + { -as => [ + { -cast => { -as => [ id => char => 255 ] } }, + 'path' + ] }, + ], + from => 'tree_table', + where => { parent_id => undef }, + union_all => { + -select => { + _ => [ qw(t.id t.parent_id), + { -as => [ + { -concat => [ 'r.path', \q{'/'}, 't.id' ] }, + 'path', + ] }, + ], + from => [ + tree_table => -as => t => + -join => { + to => 'tree_with_path', + as => 'r', + on => { 't.parent_id' => 'r.id' }, + }, + ], + } }, + } }, + ], + select => '*', + from => 'tree_with_path' + } }, + as => 'tree', + on => { 'tree.id' => 'tree_with_path.id' }, + } ], + set => { path => { -ident => [ qw(tree path) ] } }, +}); + +is_same_sql( + $sql, + q{ + UPDATE tree_table JOIN ( + WITH RECURSIVE (tree_with_path(id, parent_id, path) AS ( + ( + SELECT id, parent_id, CAST(id AS char(255)) AS path + FROM tree_table + WHERE parent_id IS NULL + ) + UNION ALL + ( + SELECT t.id, t.parent_id, CONCAT(r.path, '/', t.id) AS path + FROM tree_table AS t + JOIN tree_with_path AS r ON t.parent_id = r.id + ) + )) + SELECT * FROM tree_with_path + ) AS tree + ON tree.id = tree_with_path.id + SET path = tree.path + }, +); + done_testing;