You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by za...@apache.org on 2022/11/28 15:18:55 UTC

[calcite] branch main updated: [CALCITE-5332] Facilitate PruneEmptyRules configuration by adding DEFAULT instances

This is an automated email from the ASF dual-hosted git repository.

zabetak pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new 085d65ac99 [CALCITE-5332] Facilitate PruneEmptyRules configuration by adding DEFAULT instances
085d65ac99 is described below

commit 085d65ac99f0eb87fcd8afce56192de92fd51c0d
Author: Stamatis Zampetakis <za...@gmail.com>
AuthorDate: Thu Oct 13 15:49:35 2022 +0200

    [CALCITE-5332] Facilitate PruneEmptyRules configuration by adding DEFAULT instances
    
    Creating new PruneEmptyRule instances with slightly different
    configurations (e.g., modify a rule to match FooProject.class instead
    of Project.class) is almost impossible for the following reasons:
    
    * ImmutableXXConfig classes are package private;
    * Constructors in PruneEmptyRules class are either deprecated or
    package private;
    * Existing configurations do not provide DEFAULT instances;
    * Configuration cannot be obtained from existing rules cause the latter
    are declared as RelOptRule (and not RelRule).
    
    Add DEFAULT configuration instances for each rule variant to provide
    users an achor point to modify the behavior of a rule and adhere to the
    RelRule interface, which requires all configs to have a DEFAULT
    instance.
    
    Close apache/calcite#2937
---
 .../apache/calcite/rel/rules/PruneEmptyRules.java  | 129 +++++++++++----------
 1 file changed, 65 insertions(+), 64 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/rel/rules/PruneEmptyRules.java b/core/src/main/java/org/apache/calcite/rel/rules/PruneEmptyRules.java
index 34780e1cf3..acfafc1224 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/PruneEmptyRules.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/PruneEmptyRules.java
@@ -94,14 +94,7 @@ public abstract class PruneEmptyRules {
    * <li>Union(Empty, Empty) becomes Empty
    * </ul>
    */
-  public static final RelOptRule UNION_INSTANCE =
-      ImmutableUnionEmptyPruneRuleConfig.of()
-          .withOperandSupplier(b0 ->
-              b0.operand(Union.class).unorderedInputs(b1 ->
-                  b1.operand(Values.class)
-                      .predicate(Values::isEmpty).noInputs()))
-          .withDescription("Union")
-          .toRule();
+  public static final RelOptRule UNION_INSTANCE = UnionEmptyPruneRuleConfig.DEFAULT.toRule();
 
 
   /**
@@ -115,14 +108,7 @@ public abstract class PruneEmptyRules {
    * <li>Minus(Empty, Rel) becomes Empty
    * </ul>
    */
-  public static final RelOptRule MINUS_INSTANCE =
-      ImmutableMinusEmptyPruneRuleConfig.of()
-          .withOperandSupplier(b0 ->
-              b0.operand(Minus.class).unorderedInputs(b1 ->
-                  b1.operand(Values.class).predicate(Values::isEmpty)
-                      .noInputs()))
-          .withDescription("Minus")
-          .toRule();
+  public static final RelOptRule MINUS_INSTANCE = MinusEmptyPruneRuleConfig.DEFAULT.toRule();
 
   /**
    * Rule that converts a
@@ -137,13 +123,7 @@ public abstract class PruneEmptyRules {
    * </ul>
    */
   public static final RelOptRule INTERSECT_INSTANCE =
-      ImmutableIntersectEmptyPruneRuleConfig.of()
-          .withOperandSupplier(b0 ->
-              b0.operand(Intersect.class).unorderedInputs(b1 ->
-                  b1.operand(Values.class).predicate(Values::isEmpty)
-                      .noInputs()))
-          .withDescription("Intersect")
-          .toRule();
+      IntersectEmptyPruneRuleConfig.DEFAULT.toRule();
 
   private static boolean isEmpty(RelNode node) {
     if (node instanceof Values) {
@@ -174,10 +154,7 @@ public abstract class PruneEmptyRules {
    * the table is empty or not.
    */
   public static final RelOptRule EMPTY_TABLE_INSTANCE =
-      ImmutableZeroMaxRowsRuleConfig.of()
-          .withOperandSupplier(b0 -> b0.operand(TableScan.class).noInputs())
-          .withDescription("PruneZeroRowsTable")
-          .toRule();
+      ImmutableZeroMaxRowsRuleConfig.DEFAULT.toRule();
 
   /**
    * Rule that converts a {@link org.apache.calcite.rel.core.Project}
@@ -190,10 +167,7 @@ public abstract class PruneEmptyRules {
    * </ul>
    */
   public static final RelOptRule PROJECT_INSTANCE =
-      ImmutableRemoveEmptySingleRuleConfig.of()
-          .withDescription("PruneEmptyProject")
-          .withOperandFor(Project.class, project -> true)
-          .toRule();
+      RemoveEmptySingleRule.RemoveEmptySingleRuleConfig.PROJECT.toRule();
 
   /**
    * Rule that converts a {@link org.apache.calcite.rel.core.Filter}
@@ -206,10 +180,7 @@ public abstract class PruneEmptyRules {
    * </ul>
    */
   public static final RelOptRule FILTER_INSTANCE =
-      ImmutableRemoveEmptySingleRuleConfig.of()
-          .withDescription("PruneEmptyFilter")
-          .withOperandFor(Filter.class, singleRel -> true)
-          .toRule();
+      RemoveEmptySingleRule.RemoveEmptySingleRuleConfig.FILTER.toRule();
 
   /**
    * Rule that converts a {@link org.apache.calcite.rel.core.Sort}
@@ -222,10 +193,7 @@ public abstract class PruneEmptyRules {
    * </ul>
    */
   public static final RelOptRule SORT_INSTANCE =
-      ImmutableRemoveEmptySingleRuleConfig.of()
-          .withDescription("PruneEmptySort")
-          .withOperandFor(Sort.class, singleRel -> true)
-          .toRule();
+      RemoveEmptySingleRule.RemoveEmptySingleRuleConfig.SORT.toRule();
 
   /**
    * Rule that converts a {@link org.apache.calcite.rel.core.Sort}
@@ -238,11 +206,7 @@ public abstract class PruneEmptyRules {
    * </ul>
    */
   public static final RelOptRule SORT_FETCH_ZERO_INSTANCE =
-      ImmutableSortFetchZeroRuleConfig.of()
-          .withOperandSupplier(b ->
-              b.operand(Sort.class).anyInputs())
-          .withDescription("PruneSortLimit0")
-          .toRule();
+      SortFetchZeroRuleConfig.DEFAULT.toRule();
 
   /**
    * Rule that converts an {@link org.apache.calcite.rel.core.Aggregate}
@@ -260,10 +224,7 @@ public abstract class PruneEmptyRules {
    * @see AggregateValuesRule
    */
   public static final RelOptRule AGGREGATE_INSTANCE =
-      ImmutableRemoveEmptySingleRuleConfig.of()
-          .withDescription("PruneEmptyAggregate")
-          .withOperandFor(Aggregate.class, Aggregate::isNotGrandTotal)
-          .toRule();
+      RemoveEmptySingleRule.RemoveEmptySingleRuleConfig.AGGREGATE.toRule();
 
   /**
    * Rule that converts a {@link org.apache.calcite.rel.core.Join}
@@ -279,14 +240,7 @@ public abstract class PruneEmptyRules {
    * </ul>
    */
   public static final RelOptRule JOIN_LEFT_INSTANCE =
-      ImmutableJoinLeftEmptyRuleConfig.of()
-          .withOperandSupplier(b0 ->
-              b0.operand(Join.class).inputs(
-                  b1 -> b1.operand(Values.class)
-                      .predicate(Values::isEmpty).noInputs(),
-                  b2 -> b2.operand(RelNode.class).anyInputs()))
-          .withDescription("PruneEmptyJoin(left)")
-          .toRule();
+      JoinLeftEmptyRuleConfig.DEFAULT.toRule();
 
   /**
    * Rule that converts a {@link org.apache.calcite.rel.core.Join}
@@ -302,14 +256,7 @@ public abstract class PruneEmptyRules {
    * </ul>
    */
   public static final RelOptRule JOIN_RIGHT_INSTANCE =
-      ImmutableJoinRightEmptyRuleConfig.of()
-          .withOperandSupplier(b0 ->
-              b0.operand(Join.class).inputs(
-                  b1 -> b1.operand(RelNode.class).anyInputs(),
-                  b2 -> b2.operand(Values.class).predicate(Values::isEmpty)
-                      .noInputs()))
-          .withDescription("PruneEmptyJoin(right)")
-          .toRule();
+      JoinRightEmptyRuleConfig.DEFAULT.toRule();
 
   /** Planner rule that converts a single-rel (e.g. project, sort, aggregate or
    * filter) on top of the empty relational expression into empty. */
@@ -363,6 +310,19 @@ public abstract class PruneEmptyRules {
     /** Rule configuration. */
     @Value.Immutable
     public interface RemoveEmptySingleRuleConfig extends PruneEmptyRule.Config {
+      RemoveEmptySingleRuleConfig PROJECT = ImmutableRemoveEmptySingleRuleConfig.of()
+          .withDescription("PruneEmptyProject")
+          .withOperandFor(Project.class, project -> true);
+      RemoveEmptySingleRuleConfig FILTER = ImmutableRemoveEmptySingleRuleConfig.of()
+          .withDescription("PruneEmptyFilter")
+          .withOperandFor(Filter.class, singleRel -> true);
+      RemoveEmptySingleRuleConfig SORT = ImmutableRemoveEmptySingleRuleConfig.of()
+          .withDescription("PruneEmptySort")
+          .withOperandFor(Sort.class, singleRel -> true);
+      RemoveEmptySingleRuleConfig AGGREGATE = ImmutableRemoveEmptySingleRuleConfig.of()
+          .withDescription("PruneEmptyAggregate")
+          .withOperandFor(Aggregate.class, Aggregate::isNotGrandTotal);
+
       @Override default RemoveEmptySingleRule toRule() {
         return new RemoveEmptySingleRule(this);
       }
@@ -381,6 +341,13 @@ public abstract class PruneEmptyRules {
   /** Configuration for a rule that prunes empty inputs from a Minus. */
   @Value.Immutable
   public interface UnionEmptyPruneRuleConfig extends PruneEmptyRule.Config {
+    UnionEmptyPruneRuleConfig DEFAULT = ImmutableUnionEmptyPruneRuleConfig.of()
+        .withOperandSupplier(b0 ->
+            b0.operand(Union.class).unorderedInputs(b1 ->
+                b1.operand(Values.class)
+                    .predicate(Values::isEmpty).noInputs()))
+        .withDescription("Union");
+
     @Override default PruneEmptyRule toRule() {
       return new PruneEmptyRule(this) {
         @Override public void onMatch(RelOptRuleCall call) {
@@ -413,6 +380,12 @@ public abstract class PruneEmptyRules {
   /** Configuration for a rule that prunes empty inputs from a Minus. */
   @Value.Immutable
   public interface MinusEmptyPruneRuleConfig extends PruneEmptyRule.Config {
+    MinusEmptyPruneRuleConfig DEFAULT = ImmutableMinusEmptyPruneRuleConfig.of()
+        .withOperandSupplier(
+            b0 -> b0.operand(Minus.class).unorderedInputs(
+                b1 -> b1.operand(Values.class).predicate(Values::isEmpty).noInputs()))
+        .withDescription("Minus");
+
     @Override default PruneEmptyRule toRule() {
       return new PruneEmptyRule(this) {
         @Override public void onMatch(RelOptRuleCall call) {
@@ -451,6 +424,13 @@ public abstract class PruneEmptyRules {
    * is empty. */
   @Value.Immutable
   public interface IntersectEmptyPruneRuleConfig extends PruneEmptyRule.Config {
+    IntersectEmptyPruneRuleConfig DEFAULT = ImmutableIntersectEmptyPruneRuleConfig.of()
+        .withOperandSupplier(b0 ->
+            b0.operand(Intersect.class).unorderedInputs(b1 ->
+                b1.operand(Values.class).predicate(Values::isEmpty)
+                    .noInputs()))
+        .withDescription("Intersect");
+
     @Override default PruneEmptyRule toRule() {
       return new PruneEmptyRule(this) {
         @Override public void onMatch(RelOptRuleCall call) {
@@ -466,6 +446,10 @@ public abstract class PruneEmptyRules {
   /** Configuration for a rule that prunes a Sort if it has limit 0. */
   @Value.Immutable
   public interface SortFetchZeroRuleConfig extends PruneEmptyRule.Config {
+    SortFetchZeroRuleConfig DEFAULT = ImmutableSortFetchZeroRuleConfig.of()
+        .withOperandSupplier(b -> b.operand(Sort.class).anyInputs())
+        .withDescription("PruneSortLimit0");
+
     @Override default PruneEmptyRule toRule() {
       return new PruneEmptyRule(this) {
         @Override public void onMatch(RelOptRuleCall call) {
@@ -492,6 +476,13 @@ public abstract class PruneEmptyRules {
    * empty. */
   @Value.Immutable
   public interface JoinLeftEmptyRuleConfig extends PruneEmptyRule.Config {
+    JoinLeftEmptyRuleConfig DEFAULT = ImmutableJoinLeftEmptyRuleConfig.of()
+        .withOperandSupplier(b0 ->
+            b0.operand(Join.class).inputs(
+                b1 -> b1.operand(Values.class).predicate(Values::isEmpty).noInputs(),
+                b2 -> b2.operand(RelNode.class).anyInputs()))
+        .withDescription("PruneEmptyJoin(left)");
+
     @Override default PruneEmptyRule toRule() {
       return new PruneEmptyRule(this) {
         @Override public void onMatch(RelOptRuleCall call) {
@@ -523,6 +514,13 @@ public abstract class PruneEmptyRules {
    * empty. */
   @Value.Immutable
   public interface JoinRightEmptyRuleConfig extends PruneEmptyRule.Config {
+    JoinRightEmptyRuleConfig DEFAULT = ImmutableJoinRightEmptyRuleConfig.of()
+        .withOperandSupplier(b0 ->
+            b0.operand(Join.class).inputs(
+                b1 -> b1.operand(RelNode.class).anyInputs(),
+                b2 -> b2.operand(Values.class).predicate(Values::isEmpty).noInputs()))
+        .withDescription("PruneEmptyJoin(right)");
+
     @Override default PruneEmptyRule toRule() {
       return new PruneEmptyRule(this) {
         @Override public void onMatch(RelOptRuleCall call) {
@@ -561,6 +559,9 @@ public abstract class PruneEmptyRules {
    * is empty or not. If the stats are not available then the rule is a noop. */
   @Value.Immutable
   public interface ZeroMaxRowsRuleConfig extends PruneEmptyRule.Config {
+    ZeroMaxRowsRuleConfig DEFAULT = ImmutableZeroMaxRowsRuleConfig.of()
+        .withOperandSupplier(b0 -> b0.operand(TableScan.class).noInputs())
+        .withDescription("PruneZeroRowsTable");
 
     @Override default PruneEmptyRule toRule() {
       return new PruneEmptyRule(this) {