Description
A TableScan that does not have a Project as its parent cannot be matched by any UnifyRules and thus cannot be substituted by a projected materialization; while the same TableScan with an identity projection could.
@Test public void testJoinMaterialization2() { String q = "select *\n" + "from \"emps\"\n" + "join \"depts\" using (\"deptno\")"; checkMaterialize("select \"deptno\", \"empid\", \"name\", \"salary\", \"commission\" from \"emps\"", q); }
In the above test case, the initial Rel was like:
LogicalProject(...) LogicalJoin(...) TableScan(table=[[hr, emps]]) TableScan(table=[[hr, depts]])
And the queryDescendent TableScan(table=[[hr, emps]]) cannot be matched by any UnifyRules that could have matched LogicalProject(<identity_project_list>, TableScan(table=[[hr, emps]])).
The following changes would make this test case pass. Not sure if this would be the best fix, but it is at least a good illustration of the problem.
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java index 7762bf7..ccece75 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java @@ -2861,9 +2861,6 @@ public static RelNode permute( public static RelNode createProject(final RelFactories.ProjectFactory factory, final RelNode child, final List<Integer> posList) { RelDataType rowType = child.getRowType(); - if (Mappings.isIdentity(posList, rowType.getFieldCount())) { - return child; - } final List<String> fieldNames = rowType.getFieldNames(); final RexBuilder rexBuilder = child.getCluster().getRexBuilder(); return factory.createProject(child, diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java index 50f22c1..b0a519a 100644 --- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java +++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java @@ -2240,6 +2240,8 @@ protected RelNode createJoin( } } + leftRel = leftRel instanceof Project ? leftRel : RelOptUtil.createProject(leftRel, ImmutableIntList.identity(leftRel.getRowType().getFieldCount())); + rightRel = rightRel instanceof Project ? rightRel : RelOptUtil.createProject(rightRel, ImmutableIntList.identity(rightRel.getRowType().getFieldCount())); final Join originalJoin = (Join) RelFactories.DEFAULT_JOIN_FACTORY.createJoin(leftRel, rightRel, joinCond, joinType, ImmutableSet.<String>of(), false);