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)