You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Julian Hyde (Jira)" <ji...@apache.org> on 2020/06/18 19:16:00 UTC

[jira] [Comment Edited] (CALCITE-3923) Refactor how planner rules are parameterized

    [ https://issues.apache.org/jira/browse/CALCITE-3923?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17139934#comment-17139934 ] 

Julian Hyde edited comment on CALCITE-3923 at 6/18/20, 7:15 PM:
----------------------------------------------------------------

If the downstream project has customized a few rules, they will probably find that the constructors they are calling are now deprecated. The deprecated constructor will now create a Config, set its properties from the constructor arguments, and create a rule.

A typical example is [AggregateExpandDistinctAggregatesRule|https://github.com/apache/calcite/pull/2024/files#diff-b6682c064afafefacca7520cd0eb06abR105], which used to be
{code:java}
public AggregateExpandDistinctAggregatesRule(
      Class<? extends Aggregate> clazz,
      boolean useGroupingSets,
      RelBuilderFactory relBuilderFactory) {
    super(operand(clazz, any()), relBuilderFactory, null);
    this.useGroupingSets = useGroupingSets;
  }
{code}
and is now
{code:java}
@Deprecated
public AggregateExpandDistinctAggregatesRule(
      Class<? extends Aggregate> clazz,
      boolean useGroupingSets,
      RelBuilderFactory relBuilderFactory) {
    this(INSTANCE.config.withRelBuilderFactory(relBuilderFactory)
        .withOperandSupplier(b ->
            b.operand(clazz).anyInputs())
        .as(Config.class)
        .withUsingGroupingSets(useGroupingSets));
  }
{code}
If the project has
{code:java}
final RelOptRule myRule =
    new AggregateExpandDistinctAggregatesRule(MyAggregate.class, false, f);
{code}
that code will become
{code:java}
final RelOptRule myRule =
    AggregateExpandDistinctAggregatesRule.INSTANCE.config
        .withRelBuilderFactory(f) 
        .withOperandSupplier(b ->
            b.operand(MyAggregate.class).anyInputs())
        .as(AggregateExpandDistinctAggregatesRule.Config.class)
        .withUsingGroupingSets(false)
        .toRule();
{code}
If you are using IntelliJ, you can generate most of that code by applying IntelliJ's "inline" refactoring to the constructor.


was (Author: julianhyde):
If the downstream project has customized a few rules, they will probably find that the constructors they are calling are now deprecated. The deprecated constructor will now create a Config, set its properties from the constructor arguments, and create a rule.

A typical example is [AggregateExpandDistinctAggregatesRule |https://github.com/apache/calcite/pull/2024/files#diff-b6682c064afafefacca7520cd0eb06abR105] which used to be
{code:java}
public AggregateExpandDistinctAggregatesRule(
      Class<? extends Aggregate> clazz,
      boolean useGroupingSets,
      RelBuilderFactory relBuilderFactory) {
    super(operand(clazz, any()), relBuilderFactory, null);
    this.useGroupingSets = useGroupingSets;
  }
{code}
and is now
{code:java}
@Deprecated
public AggregateExpandDistinctAggregatesRule(
      Class<? extends Aggregate> clazz,
      boolean useGroupingSets,
      RelBuilderFactory relBuilderFactory) {
    this(INSTANCE.config.withRelBuilderFactory(relBuilderFactory)
        .withOperandSupplier(b ->
            b.operand(clazz).anyInputs())
        .as(Config.class)
        .withUsingGroupingSets(useGroupingSets));
  }
{code}
If the project has
{code:java}
final RelOptRule myRule =
    new AggregateExpandDistinctAggregatesRule(MyAggregate.class, false, f);
{code}
that code will become
{code:java}
final RelOptRule myRule =
    AggregateExpandDistinctAggregatesRule.INSTANCE.config
        .withRelBuilderFactory(f) 
        .withOperandSupplier(b ->
            b.operand(MyAggregate.class).anyInputs())
        .as(AggregateExpandDistinctAggregatesRule.Config.class)
        .withUsingGroupingSets(false)
        .toRule();
{code}
If you are using IntelliJ, you can generate most of that code by applying IntelliJ's "inline" refactoring to the constructor.

> Refactor how planner rules are parameterized
> --------------------------------------------
>
>                 Key: CALCITE-3923
>                 URL: https://issues.apache.org/jira/browse/CALCITE-3923
>             Project: Calcite
>          Issue Type: Bug
>            Reporter: Julian Hyde
>            Assignee: Julian Hyde
>            Priority: Major
>             Fix For: 1.24.0
>
>          Time Spent: 40m
>  Remaining Estimate: 0h
>
> People often want different variants of planner rules. An example is {{FilterJoinRule}}, which has a 'boolean smart’ parameter, a predicate (which returns whether to pull up filter conditions), operands (which determine the precise sub-classes of {{RelNode}} that the rule should match) and a {{RelBuilderFactory}} (which controls the type of {{RelNode}} created by this rule).
> Suppose you have an instance of {{FilterJoinRule}} and you want to change {{smart}} from true to false. The {{smart}} parameter is immutable (good!) but you can’t easily create a clone of the rule because you don’t know the values of the other parameters. Your instance might even be (unbeknownst to you) a sub-class with extra parameters and a private constructor.
> So, my proposal is to put all of the config information of a {{RelOptRule}} into a single {{config}} parameter that contains all relevant properties. Each sub-class of {{RelOptRule}} would have one constructor with just a ‘config’ parameter. Each config knows which sub-class of {{RelOptRule}} to create. Therefore it is easy to copy a config, change one or more properties, and create a new rule instance.
> Adding a property to a rule’s config does not require us to add or deprecate any constructors.
> The operands are part of the config, so if you have a rule that matches a {{EnumerableFilter}} on an {{EnumerableJoin}} and you want to make it match an {{EnumerableFilter}} on an {{EnumerableNestedLoopJoin}}, you can easily create one with one changed operand.
> The config is immutable and self-describing, so we can use it to automatically generate a unique description for each rule instance.
> (See the email thread [[DISCUSS] Refactor how planner rules are parameterized|https://lists.apache.org/thread.html/rfdf6f9b7821988bdd92b0377e3d293443a6376f4773c4c658c891cf9%40%3Cdev.calcite.apache.org%3E].)



--
This message was sent by Atlassian Jira
(v8.3.4#803005)