add as support
Matt S Trout [Sat, 13 Apr 2019 01:54:51 +0000 (01:54 +0000)]
lib/SQL/Abstract.pm
lib/SQL/Abstract/ExtraClauses.pm
xt/clauses.t

index 1b021d2..74d5446 100644 (file)
@@ -1087,6 +1087,9 @@ sub _render_row {
 sub _render_func {
   my ($self, $rest) = @_;
   my ($func, @args) = @$rest;
+  if (ref($func) eq 'HASH') {
+    $func = $self->render_aqt($func);
+  }
   my @arg_sql;
   my @bind = map {
     my @x = @$_;
index a4da3d7..b6f83f2 100644 (file)
@@ -24,6 +24,9 @@ sub new {
   $new->{render}{from_list} = '_render_from_list';
   $new->{expand}{join} = '_expand_join';
   $new->{render}{join} = '_render_join';
+  $new->{expand_op}{as} = '_expand_op_as';
+  $new->{expand}{as} = '_expand_op_as';
+  $new->{render}{as} = '_render_as';
   return $new;
 }
 
@@ -40,7 +43,13 @@ sub _expand_from_list {
   my @list;
   my @args = ref($args) ? @$args : ($args);
   while (my $entry = shift @args) {
-    if (!ref($entry) and $entry =~ /^-/) {
+    if (!ref($entry) and $entry =~ /^-(.*)/) {
+      if ($1 eq 'as') {
+        $list[-1] = $self->expand_expr({ -as => [
+          $list[-1], map +(ref($_) eq 'ARRAY' ? @$_ : $_), shift(@args)
+        ]});
+        next;
+      }
       $entry = { $entry => shift @args };
     }
     my $aqt = $self->expand_expr($entry, -ident);
@@ -59,6 +68,9 @@ sub _expand_join {
       ? %$args
       : (to => $args->[0], @{$args}[1..$#$args])
   );
+  if (my $as = delete $proto{as}) {
+    $proto{to} = { -as => [ $proto{to}, ref($as) eq 'ARRAY' ? @$as : $as ] };
+  }
   my %ret = map +($_ => $self->expand_expr($proto{$_}, -ident)),
               sort keys %proto;
   return +{ -join => \%ret };
@@ -95,4 +107,25 @@ sub _render_join {
   return $self->_join_parts(' ', @parts);
 }
 
+sub _expand_op_as {
+  my ($self, undef, $vv, $k) = @_;
+  my @as = map $self->expand_expr($_, -ident),
+             (defined($k) ? ($k) : ()), ref($vv) eq 'ARRAY' ? @$vv : $vv;
+  return { -as => \@as };
+}
+
+sub _render_as {
+  my ($self, $args) = @_;
+  my ($thing, $as, @cols) = @$args;
+  return $self->_join_parts(
+    ' ',
+    [ $self->render_aqt($thing) ],
+    [ $self->_sqlcase('as') ],
+    [ @cols
+        ? $self->render_aqt({ -func => [ $as, @cols ] })
+        : $self->render_aqt($as)
+    ],
+  );
+}
+
 1;
index 1c88964..4fabc98 100644 (file)
@@ -9,7 +9,8 @@ my $sqlac = SQL::Abstract::ExtraClauses->new;
 my ($sql, @bind) = $sqlac->select({
   select => [ qw(artist.id artist.name), { -func => [ json_agg => 'cd' ] } ],
   from => [
-    artist => -join => [ cd => on => { 'cd.artist_id' => 'artist.id' } ],
+    { artists => { -as => 'artist' } },
+    -join => [ cds => as => 'cd' => on => { 'cd.artist_id' => 'artist.id' } ],
   ],
   where => { 'artist.genres', => { '@>', { -value => [ 'Rock' ] } } },
   order_by => 'artist.name',
@@ -21,7 +22,7 @@ is_same_sql_bind(
   $sql, \@bind,
   q{
     SELECT artist.id, artist.name, JSON_AGG(cd)
-    FROM artist JOIN cd ON cd.artist_id = artist.id
+    FROM artists AS artist JOIN cds AS cd ON cd.artist_id = artist.id
     WHERE artist.genres @> ?
     ORDER BY artist.name
     GROUP BY artist.id