You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Vladimir Sitnikov (JIRA)" <ji...@apache.org> on 2015/02/10 14:24:13 UTC

[jira] [Commented] (CALCITE-595) planner doesn't care about cheaper transformation plan

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

Vladimir Sitnikov commented on CALCITE-595:
-------------------------------------------

I wonder if some kind of assert can be created that validates presence of explainTerms override in case RelNode has fields.

> planner doesn't care about cheaper transformation plan 
> -------------------------------------------------------
>
>                 Key: CALCITE-595
>                 URL: https://issues.apache.org/jira/browse/CALCITE-595
>             Project: Calcite
>          Issue Type: Bug
>            Reporter: Vladimir Dolzhenko
>            Assignee: Julian Hyde
>
> The rule splits the condition - the 1st part to TableScan another keeps to a LogicalFilter.
> Despite of rule execution - another plan (with split condition) even has not been calculated - computeSelfCost executes only in case of null condition.
> {code}
> @Test public void testAnotherTableFilter() throws Exception {
>     final SchemaPlus rootSchema = Frameworks.createRootSchema(true);
>     rootSchema.add("ANOTHER", new AnotherTable());
>     final FrameworkConfig config = Frameworks.newConfigBuilder()
>         .parserConfig(SqlParser.Config.DEFAULT)
>         .defaultSchema(rootSchema)
>         .traitDefs((List<RelTraitDef>) null)
>         .programs(Programs.heuristicJoinOrder(Programs.RULE_SET, true, 2))
>         .build();
>     Planner planner = Frameworks.getPlanner(config);
>     SqlNode parse = planner.parse("select * from ANOTHER where name='a' AND type='b'");
>     SqlNode validate = planner.validate(parse);
>     RelNode convert = planner.convert(validate);
>     RelTraitSet traitSet = planner.getEmptyTraitSet()
>         .replace(EnumerableConvention.INSTANCE);
>     RelNode transform = planner.transform(0, traitSet, convert);
>     final String actual = toString(transform);
>     assertThat(actual, containsString("EnumerableProject(NAME=[$0], TYPE=[$1])\n" +
>         "  EnumerableFilter(condition=[=(CAST($0):VARCHAR(1) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\", 'a')])\n" +
>         "    AnotherTableScan(table=[[ANOTHER]])"));
>   }
>   public class AnotherTable extends AbstractTable implements TranslatableTable {
>     public RelNode toRel(RelOptTable.ToRelContext context,
>                          RelOptTable relOptTable) {
>       return new AnotherTableScan( context.getCluster(),
>           context.getCluster().traitSetOf( EnumerableConvention.INSTANCE ),
>           relOptTable );
>     }
>     public RelDataType getRowType(RelDataTypeFactory typeFactory) {
>       RelDataTypeFactory.FieldInfoBuilder builder = typeFactory.builder();
>       builder.add("NAME", typeFactory.createJavaType( String.class) );
>       builder.add("TYPE", typeFactory.createJavaType( String.class) );
>       return builder.build();
>     }
>   }
>   static class AnotherTableScanRule extends RelOptRule {
>     private AnotherTableScanRule() {
>       super(
>           operand(
>               LogicalFilter.class,
>               operand(AnotherTableScan.class, any())));
>     }
>     public void onMatch( RelOptRuleCall call ) {
>       final LogicalFilter filter = call.rel( 0 );
>       final AnotherTableScan tableScan = call.rel( 1 );
>       final RexNode newScanCondition = filter.getCondition();
>       final RelTraitSet restTableScanTraitSet = tableScan.getTraitSet();
>       final RelNode newTableScan = tableScan.copy( restTableScanTraitSet, ImmutableList.<RelNode>of(), newScanCondition );
>       RexNode newFilterCondition =
>           newScanCondition.getKind() == SqlKind.AND ? RelOptUtil.conjunctions( newScanCondition ).get( 0 ) : newScanCondition;
>       System.out.println(newScanCondition + " > " + newScanCondition);
>       final RelTraitSet filterTraitSet = filter.getTraitSet();
>       final RelNode wrappedFilter = filter.copy( filterTraitSet, newTableScan, newFilterCondition );
>       call.transformTo( wrappedFilter );
>     }
>   }
>   public static class AnotherTableScan extends TableScan implements EnumerableRel {
>     private final RexNode condition;
>     public AnotherTableScan(RelOptCluster cluster, RelTraitSet traits, RelOptTable table) {
>       this(cluster, traits, table, null);
>     }
>     public AnotherTableScan(RelOptCluster cluster, RelTraitSet traits, RelOptTable table, RexNode condition) {
>       super(cluster, traits, table);
>       this.condition = condition;
>     }
>     public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
>       return null;
>     }
>     @Override
>     public void register(RelOptPlanner planner) {
>       planner.addRule(new AnotherTableScanRule());
>     }
>     public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs, RexNode condition) {
>       assert inputs.isEmpty();
>       final AnotherTableScan tableScan = new AnotherTableScan(getCluster(), traitSet, getTable(), condition);
>       return tableScan;
>     }
>     @Override
>     public RelOptCost computeSelfCost(RelOptPlanner planner) {
>       final RelOptCost relOptCost = super.computeSelfCost(planner);
>       final RelOptCost cost = relOptCost.multiplyBy(1f / (RelOptUtil.conjunctions(condition).size() + 1));
>       System.out.println(condition + " = " + cost);
>       return cost;
>     }
>   }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)