refactor to add the rest of the setops
Matt S Trout [Mon, 15 Apr 2019 17:28:51 +0000 (17:28 +0000)]
lib/SQL/Abstract/ExtraClauses.pm
xt/clauses.t

index ae1ded5..af7dc52 100644 (file)
@@ -76,42 +76,45 @@ sub register_defaults {
       return $exp;
     });
   }
-
-  $self->clause_expander('select.union' => sub {
-    +(setop => $_[0]->expand_expr({
-                 -union => {
-                   queries => (ref($_[1]) eq 'ARRAY' ? $_[1] : [ $_[1] ]),
-                 }
-               }));
-  });
-  $self->clause_expander('select.union_all' => sub {
-    +(setop => $_[0]->expand_expr({
-                 -union => {
-                   type => 'all',
-                   queries => (ref($_[1]) eq 'ARRAY' ? $_[1] : [ $_[1] ]),
-                 }
-               }));
-  });
-  $self->expander(union => sub {
-    my ($self, undef, $args) = @_;
-    +{ -union => {
+  my $expand_setop = sub {
+    my ($self, $setop, $args) = @_;
+    +{ "-${setop}" => {
          %$args,
          queries => [ map $self->expand_expr($_), @{$args->{queries}} ],
     } };
-  });
+  };
+  $self->expanders(map +($_ => $expand_setop), qw(union intersect except));
 
   $self->clause_renderer('select.setop' => sub {
     my ($self, $setop) = @_;
     $self->render_aqt($setop);
   });
 
-  $self->renderer(union => sub {
-    my ($self, $args) = @_;
-    $self->join_clauses(
-      ' '.$self->format_keyword(join '_', 'union', ($args->{type}||())).' ',
-      map [ $self->render_aqt($_) ], @{$args->{queries}}
-    );
-  });
+  foreach my $setop (qw(union intersect except)) {
+    $self->renderer($setop => sub {
+      my ($self, $args) = @_;
+      $self->join_clauses(
+        ' '.$self->format_keyword(join '_', $setop, ($args->{type}||())).' ',
+        map [ $self->render_aqt($_) ], @{$args->{queries}}
+      );
+    });
+
+    $self->clause_expander("select.${setop}" => sub {
+      +(setop => $_[0]->expand_expr({
+                   "-${setop}" => {
+                     queries => (ref($_[1]) eq 'ARRAY' ? $_[1] : [ $_[1] ]),
+                   }
+                 }));
+    });
+    $self->clause_expander("select.${setop}_all" => sub {
+      +(setop => $_[0]->expand_expr({
+                   "-${setop}" => {
+                     type => 'all',
+                     queries => (ref($_[1]) eq 'ARRAY' ? $_[1] : [ $_[1] ]),
+                   }
+                 }));
+    });
+  }
 
   return $self;
 }
index a7d948d..66b971e 100644 (file)
@@ -164,7 +164,7 @@ is_same_sql(
   );
 }
 
-($sql) = $sqlac->select({
+$sql = $sqlac->select({
   select => { -as => [ \1, 'x' ] },
   union => { -select => { select => { -as => [ \2, 'x' ] } } },
   order_by => { -desc => 'x' },
@@ -175,4 +175,15 @@ is_same_sql(
   q{(SELECT 1 AS x) UNION (SELECT 2 AS x) ORDER BY x DESC},
 );
 
+$sql = $sqlac->select({
+  select => '*',
+  from => 'foo',
+  except => { -select => { select => '*', from => 'foo_exclusions' } }
+});
+
+is_same_sql(
+  $sql,
+  q{(SELECT * FROM foo) EXCEPT (SELECT * FROM foo_exclusions)},
+);
+
 done_testing;