This is an automated email from the ASF dual-hosted git repository. libenchao pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push: new 725b71e5af [CALCITE-5391] JoinOnUniqueToSemiJoinRule should preserve field names, if possible 725b71e5af is described below commit 725b71e5af13f2b8725a8da9762c21659c52e507 Author: Scott Reynolds <sreyno...@twilio.com> AuthorDate: Fri Nov 18 15:12:45 2022 -0800 [CALCITE-5391] JoinOnUniqueToSemiJoinRule should preserve field names, if possible Why: When rewriting the query for a semi join, the `JoinOnUniqueToSemiJoinRule` pushes a new project via `RelBuilder`. This project is *almost* a good copy of the original `Project` -- it is just missing the field names. How: This change uses `RelDataType` of the `Project` to get the field names for the new `Project` pushed on the `Relbuilder` stack. This is similar to what is done in `SemiJoinRule#perform` --- .../org/apache/calcite/rel/rules/SemiJoinRule.java | 2 +- .../org/apache/calcite/test/RelOptRulesTest.java | 15 ++++++++++++ .../org/apache/calcite/test/RelOptRulesTest.xml | 27 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinRule.java b/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinRule.java index ef2623a710..d6f8941327 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinRule.java @@ -283,7 +283,7 @@ public abstract class SemiJoinRule default: throw new AssertionError(join.getJoinType()); } - builder.project(project.getProjects()); + builder.project(project.getProjects(), project.getRowType().getFieldNames()); call.transformTo(builder.build()); } } diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java index a1262be913..08dd3edb15 100644 --- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java @@ -1181,6 +1181,21 @@ class RelOptRulesTest extends RelOptTestBase { .check(); } + /** + * Test case of + * <a href="https://issues.apache.org/jira/browse/CALCITE-5391">[CALCITE-5391] + * JoinOnUniqueToSemiJoinRule should preserve field names, if possible</a>. */ + @Test void testSemiJoinRuleWithJoinOnUniqueInputWithAlias() { + final String sql = "select emp.deptno as department_id, emp.sal as salary\n" + + "from emp\n" + + "where exists(select * from dept where emp.deptno = dept.deptno)"; + sql(sql) + .withDecorrelate(true) + .withTrim(true) + .withRule(CoreRules.JOIN_ON_UNIQUE_TO_SEMI_JOIN) + .check(); + } + /** Test case for * <a href="https://issues.apache.org/jira/browse/CALCITE-1495">[CALCITE-1495] * SemiJoinRule should not apply to RIGHT and FULL JOIN</a>. */ diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml index 27010f6367..333a84b07d 100644 --- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml +++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml @@ -12362,6 +12362,33 @@ LogicalJoin(condition=[=($7, $9)], joinType=[semi]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalProject(DEPTNO=[$0]) LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) +]]> + </Resource> + </TestCase> + <TestCase name="testSemiJoinRuleWithJoinOnUniqueInputWithAlias"> + <Resource name="sql"> + <![CDATA[select emp.deptno as department_id, emp.sal as salary +from emp +where exists(select * from dept where emp.deptno = dept.deptno)]]> + </Resource> + <Resource name="planBefore"> + <![CDATA[ +LogicalProject(DEPARTMENT_ID=[$1], SALARY=[$0]) + LogicalJoin(condition=[=($1, $2)], joinType=[inner]) + LogicalProject(SAL=[$5], DEPTNO=[$7]) + LogicalTableScan(table=[[CATALOG, SALES, EMP]]) + LogicalProject(DEPTNO=[$0]) + LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) +]]> + </Resource> + <Resource name="planAfter"> + <![CDATA[ +LogicalProject(DEPARTMENT_ID=[$1], SALARY=[$0]) + LogicalJoin(condition=[=($1, $2)], joinType=[semi]) + LogicalProject(SAL=[$5], DEPTNO=[$7]) + LogicalTableScan(table=[[CATALOG, SALES, EMP]]) + LogicalProject(DEPTNO=[$0]) + LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) ]]> </Resource> </TestCase>