Class IntersectToDistinctRule

All Implemented Interfaces:
TransformationRule

@Enclosing public class IntersectToDistinctRule extends RelRule<IntersectToDistinctRule.Config> implements TransformationRule
Planner rule that translates a distinct Intersect (all = false) into a group of operators composed of Union, Aggregate, etc.

The rule has a configuration option to control whether it should also perform a (partial) aggregation pushdown in the union branches (default behavior).

See Also:
  • Constructor Details

  • Method Details

    • onMatch

      public void onMatch(RelOptRuleCall call)
      Description copied from class: RelOptRule
      Receives notification about a rule match. At the time that this method is called, call.rels holds the set of relational expressions which match the operands to the rule; call.rels[0] is the root expression.

      Typically a rule would check that the nodes are valid matches, creates a new expression, then calls back RelOptRuleCall.transformTo(org.apache.calcite.rel.RelNode, java.util.Map<org.apache.calcite.rel.RelNode, org.apache.calcite.rel.RelNode>, org.apache.calcite.plan.RelHintsPropagator) to register the expression.

      Specified by:
      onMatch in class RelOptRule
      Parameters:
      call - Rule call
      See Also:
    • onMatchAggregateOnUnion

      public void onMatchAggregateOnUnion(RelOptRuleCall call)
      Variant not performing a partial aggregation pushdown.

      Original query:

      
       SELECT job FROM "scott".emp WHERE deptno = 10
       INTERSECT
       SELECT job FROM "scott".emp WHERE deptno = 20
       

      Query after conversion:

      
       SELECT job
       FROM (
         SELECT job, 0 AS i FROM "scott".emp WHERE deptno = 10
         UNION ALL
         SELECT job, 1 AS i FROM "scott".emp WHERE deptno = 20
       )
       GROUP BY job
       HAVING COUNT(*) FILTER (WHERE i = 0) > 0
          AND COUNT(*) FILTER (WHERE i = 1) > 0
       
    • onMatchAggregatePushdown

      public void onMatchAggregatePushdown(RelOptRuleCall call)
      Variant performing a partial aggregation pushdown.

      Original query:

      
       SELECT job FROM "scott".emp WHERE deptno = 10
       INTERSECT
       SELECT job FROM "scott".emp WHERE deptno = 20
       

      Query after conversion:

      
       SELECT job
       FROM (
         SELECT job, COUNT(*) AS c
         FROM (
           SELECT job, COUNT(*) FROM "scott".emp
           WHERE deptno = 10 GROUP BY job
           UNION ALL
           SELECT job, COUNT(*) FROM "scott".emp
           WHERE deptno = 20 GROUP BY job)
         GROUP BY job)
       WHERE c = 2