This is an automated email from the ASF dual-hosted git repository.
xiong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new a81cfb2 [CALCITE-5036] RelMdPredicates support to analyze constant
key for the operator of IS_NOT_DISTINCT_FROM
a81cfb2 is described below
commit a81cfb2ad001589929e190939cf4db928ebac386
Author: xurenhe <[email protected]>
AuthorDate: Thu Mar 10 20:30:03 2022 +0800
[CALCITE-5036] RelMdPredicates support to analyze constant key for the
operator of IS_NOT_DISTINCT_FROM
---
.../calcite/rel/metadata/RelMdPredicates.java | 9 ++-
.../org/apache/calcite/test/RelOptRulesTest.java | 31 +++++++--
.../org/apache/calcite/test/RelOptRulesTest.xml | 75 +++++++++++++++++-----
3 files changed, 92 insertions(+), 23 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
index 00aae1b..e194c82 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
@@ -278,11 +278,18 @@ public class RelMdPredicates
final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
+ // Simplify condition using RexSimplify.
+ final RexNode condition = filter.getCondition();
+ final RexExecutor executor =
+ Util.first(filter.getCluster().getPlanner().getExecutor(),
RexUtil.EXECUTOR);
+ final RexSimplify simplify = new RexSimplify(rexBuilder,
RelOptPredicateList.EMPTY, executor);
+ final RexNode simplifiedCondition = simplify.simplify(condition);
+
return Util.first(inputInfo, RelOptPredicateList.EMPTY)
.union(rexBuilder,
RelOptPredicateList.of(rexBuilder,
RexUtil.retainDeterministic(
- RelOptUtil.conjunctions(filter.getCondition()))));
+ RelOptUtil.conjunctions(simplifiedCondition))));
}
/**
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 a6bddd1..8aef5b8 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -3978,7 +3978,28 @@ class RelOptRulesTest extends RelOptTestBase {
@Test void testPullConstantIntoProject() {
final String sql = "select deptno, deptno + 1, empno + deptno\n"
- + "from sales.emp where deptno = 10";
+ + "from sales.emp\n"
+ + "where deptno = 10";
+ sql(sql).withPre(getTransitiveProgram())
+ .withRule(CoreRules.JOIN_PUSH_TRANSITIVE_PREDICATES,
+ CoreRules.PROJECT_REDUCE_EXPRESSIONS)
+ .check();
+ }
+
+ @Test void testPullConstantIntoProjectWithIsNotDistinctFrom() {
+ final String sql = "select deptno, deptno + 1, empno + deptno\n"
+ + "from sales.emp\n"
+ + "where deptno is not distinct from 10";
+ sql(sql).withPre(getTransitiveProgram())
+ .withRule(CoreRules.JOIN_PUSH_TRANSITIVE_PREDICATES,
+ CoreRules.PROJECT_REDUCE_EXPRESSIONS)
+ .check();
+ }
+
+ @Test void testPullConstantIntoProjectWithIsNotDistinctFromForNull() {
+ final String sql = "select mgr, deptno\n"
+ + "from sales.emp\n"
+ + "where mgr is not distinct from null";
sql(sql).withPre(getTransitiveProgram())
.withRule(CoreRules.JOIN_PUSH_TRANSITIVE_PREDICATES,
CoreRules.PROJECT_REDUCE_EXPRESSIONS)
@@ -5582,8 +5603,8 @@ class RelOptRulesTest extends RelOptTestBase {
@Test void testAggregateConstantKeyRule3() {
final String sql = "select job\n"
+ "from sales.emp\n"
- + "where sal is null and job = 'Clerk'\n"
- + "group by sal, job\n"
+ + "where mgr is null and job = 'Clerk'\n"
+ + "group by mgr, job\n"
+ "having count(*) > 3";
sql(sql).withRule(CoreRules.AGGREGATE_ANY_PULL_UP_CONSTANTS)
.check();
@@ -5596,8 +5617,8 @@ class RelOptRulesTest extends RelOptTestBase {
@Test void testAggregateDynamicFunction() {
final String sql = "select hiredate\n"
+ "from sales.emp\n"
- + "where sal is null and hiredate = current_timestamp\n"
- + "group by sal, hiredate\n"
+ + "where mgr is null and hiredate = current_timestamp\n"
+ + "group by mgr, hiredate\n"
+ "having count(*) > 3";
sql(sql).withRule(CoreRules.AGGREGATE_ANY_PULL_UP_CONSTANTS)
.check();
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 1614355..a748e54 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -130,8 +130,8 @@ LogicalProject(C=[$1])
<Resource name="sql">
<![CDATA[select job
from sales.emp
-where sal is null and job = 'Clerk'
-group by sal, job
+where mgr is null and job = 'Clerk'
+group by mgr, job
having count(*) > 3]]>
</Resource>
<Resource name="planBefore">
@@ -139,8 +139,8 @@ having count(*) > 3]]>
LogicalProject(JOB=[$1])
LogicalFilter(condition=[>($2, 3)])
LogicalAggregate(group=[{0, 1}], agg#0=[COUNT()])
- LogicalProject(SAL=[$5], JOB=[$2])
- LogicalFilter(condition=[AND(IS NULL($5), =($2, 'Clerk'))])
+ LogicalProject(MGR=[$3], JOB=[$2])
+ LogicalFilter(condition=[AND(IS NULL($3), =($2, 'Clerk'))])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
@@ -148,10 +148,10 @@ LogicalProject(JOB=[$1])
<![CDATA[
LogicalProject(JOB=[$1])
LogicalFilter(condition=[>($2, 3)])
- LogicalProject(SAL=[$0], JOB=['Clerk':VARCHAR(10)], $f2=[$1])
+ LogicalProject(MGR=[$0], JOB=['Clerk':VARCHAR(10)], $f2=[$1])
LogicalAggregate(group=[{0}], agg#0=[COUNT()])
- LogicalProject(SAL=[$5])
- LogicalFilter(condition=[AND(IS NULL($5), =($2, 'Clerk'))])
+ LogicalProject(MGR=[$3])
+ LogicalFilter(condition=[AND(IS NULL($3), =($2, 'Clerk'))])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
@@ -160,8 +160,8 @@ LogicalProject(JOB=[$1])
<Resource name="sql">
<![CDATA[select hiredate
from sales.emp
-where sal is null and hiredate = current_timestamp
-group by sal, hiredate
+where mgr is null and hiredate = current_timestamp
+group by mgr, hiredate
having count(*) > 3]]>
</Resource>
<Resource name="planBefore">
@@ -169,8 +169,8 @@ having count(*) > 3]]>
LogicalProject(HIREDATE=[$1])
LogicalFilter(condition=[>($2, 3)])
LogicalAggregate(group=[{0, 1}], agg#0=[COUNT()])
- LogicalProject(SAL=[$5], HIREDATE=[$4])
- LogicalFilter(condition=[AND(IS NULL($5), =($4, CURRENT_TIMESTAMP))])
+ LogicalProject(MGR=[$3], HIREDATE=[$4])
+ LogicalFilter(condition=[AND(IS NULL($3), =($4, CURRENT_TIMESTAMP))])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
@@ -178,10 +178,10 @@ LogicalProject(HIREDATE=[$1])
<![CDATA[
LogicalProject(HIREDATE=[$1])
LogicalFilter(condition=[>($2, 3)])
- LogicalProject(SAL=[$0], HIREDATE=[CURRENT_TIMESTAMP], $f2=[$1])
+ LogicalProject(MGR=[$0], HIREDATE=[CURRENT_TIMESTAMP], $f2=[$1])
LogicalAggregate(group=[{0}], agg#0=[COUNT()])
- LogicalProject(SAL=[$5])
- LogicalFilter(condition=[AND(IS NULL($5), =($4, CURRENT_TIMESTAMP))])
+ LogicalProject(MGR=[$3])
+ LogicalFilter(condition=[AND(IS NULL($3), =($4, CURRENT_TIMESTAMP))])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
@@ -4152,9 +4152,8 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2],
MGR=[$3], HIREDATE=[$4], SAL=[$
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4],
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], EMPNO0=[$9], ENAME0=[$10],
JOB0=[$11], MGR0=[$12], HIREDATE0=[$13], SAL0=[$14], COMM0=[$15],
DEPTNO0=[$16], SLACKER0=[$17])
LogicalJoin(condition=[=($16, $7)], joinType=[inner])
- LogicalFilter(condition=[SEARCH($7, Sarg[(-∞..4), (4..6), (6..+∞)])])
- LogicalFilter(condition=[NOT(OR(=($7, 4), =($7, 6)))])
- LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalFilter(condition=[NOT(OR(=($7, 4), =($7, 6)))])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalFilter(condition=[SEARCH($7, Sarg[(-∞..4), (4..6), (6..+∞)])])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
@@ -6673,6 +6672,48 @@ LogicalProject(DEPTNO=[10], EXPR$1=[11], EXPR$2=[+($0,
10)])
]]>
</Resource>
</TestCase>
+ <TestCase name="testPullConstantIntoProjectWithIsNotDistinctFrom">
+ <Resource name="sql">
+ <![CDATA[select deptno, deptno + 1, empno + deptno
+from sales.emp
+where deptno is not distinct from 10]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(DEPTNO=[$7], EXPR$1=[+($7, 1)], EXPR$2=[+($0, $7)])
+ LogicalFilter(condition=[OR(AND(IS NULL($7), IS NULL(10)), IS TRUE(=($7,
10)))])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalProject(DEPTNO=[10], EXPR$1=[11], EXPR$2=[+($0, 10)])
+ LogicalFilter(condition=[OR(AND(IS NULL($7), IS NULL(10)), IS TRUE(=($7,
10)))])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testPullConstantIntoProjectWithIsNotDistinctFromForNull">
+ <Resource name="sql">
+ <![CDATA[select mgr, deptno
+from sales.emp
+where mgr is not distinct from null]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(MGR=[$3], DEPTNO=[$7])
+ LogicalFilter(condition=[OR(AND(IS NULL($3), IS NULL(null:INTEGER)), IS
TRUE(=($3, null)))])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalProject(MGR=[null:INTEGER], DEPTNO=[$7])
+ LogicalFilter(condition=[OR(AND(IS NULL($3), IS NULL(null:INTEGER)), IS
TRUE(=($3, null)))])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
<TestCase name="testPullConstantThroughAggregateAllConst">
<Resource name="sql">
<![CDATA[select 4, 2+3, max(five) from (