Skip to content

Commit c2059f1

Browse files
Pengcheng Xiongjulianhyde
authored andcommitted
[CALCITE-953] Improve RelMdPredicates to deal with RexLiteral (Pengcheng Xiong)
1 parent c48c341 commit c2059f1

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@
3535
import org.apache.calcite.rex.RexBuilder;
3636
import org.apache.calcite.rex.RexCall;
3737
import org.apache.calcite.rex.RexInputRef;
38+
import org.apache.calcite.rex.RexLiteral;
3839
import org.apache.calcite.rex.RexNode;
3940
import org.apache.calcite.rex.RexPermuteInputsShuttle;
4041
import org.apache.calcite.rex.RexUtil;
4142
import org.apache.calcite.rex.RexVisitorImpl;
4243
import org.apache.calcite.sql.SqlKind;
44+
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
4345
import org.apache.calcite.util.BitSets;
4446
import org.apache.calcite.util.BuiltInMethod;
4547
import org.apache.calcite.util.ImmutableBitSet;
@@ -147,6 +149,7 @@ public RelOptPredicateList getPredicates(TableScan table) {
147149
*/
148150
public RelOptPredicateList getPredicates(Project project) {
149151
RelNode child = project.getInput();
152+
final RexBuilder rexBuilder = project.getCluster().getRexBuilder();
150153
RelOptPredicateList childInfo =
151154
RelMetadataQuery.getPulledUpPredicates(child);
152155

@@ -175,6 +178,20 @@ public RelOptPredicateList getPredicates(Project project) {
175178
projectPullUpPredicates.add(r);
176179
}
177180
}
181+
182+
// Project can also generate constants. We need to include them.
183+
for (Ord<RexNode> expr : Ord.zip(project.getProjects())) {
184+
if (RexLiteral.isNullLiteral(expr.e)) {
185+
projectPullUpPredicates.add(
186+
rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL,
187+
rexBuilder.makeInputRef(project, expr.i)));
188+
} else if (expr.e instanceof RexLiteral) {
189+
final RexLiteral literal = (RexLiteral) expr.e;
190+
projectPullUpPredicates.add(
191+
rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
192+
rexBuilder.makeInputRef(project, expr.i), literal));
193+
}
194+
}
178195
return RelOptPredicateList.of(projectPullUpPredicates);
179196
}
180197

core/src/test/java/org/apache/calcite/test/RelMetadataTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,31 @@ private void checkPredicates(RelOptCluster cluster, RelOptTable empTable,
10791079
assertThat(predicates.rightInferredPredicates.isEmpty(), is(true));
10801080
}
10811081

1082+
/**
1083+
* Unit test for
1084+
* {@link org.apache.calcite.rel.metadata.RelMdPredicates#getPredicates(Aggregate)}.
1085+
*/
1086+
@Test public void testPullUpPredicatesFromAggregation() {
1087+
final String sql = "select a, max(b) from (\n"
1088+
+ " select 1 as a, 2 as b from emp)subq\n"
1089+
+ "group by a";
1090+
final Aggregate rel = (Aggregate) convertSql(sql);
1091+
RelOptPredicateList inputSet = RelMetadataQuery.getPulledUpPredicates(rel);
1092+
ImmutableList<RexNode> pulledUpPredicates = inputSet.pulledUpPredicates;
1093+
assertThat(pulledUpPredicates.toString(), is("[=($0, 1)]"));
1094+
}
1095+
1096+
@Test public void testPullUpPredicatesFromProject() {
1097+
final String sql = "select deptno, mgr, x, 'y' as y from (\n"
1098+
+ " select deptno, mgr, cast(null as integer) as x\n"
1099+
+ " from emp\n"
1100+
+ " where mgr is null and deptno < 10)";
1101+
final RelNode rel = convertSql(sql);
1102+
RelOptPredicateList list = RelMetadataQuery.getPulledUpPredicates(rel);
1103+
assertThat(list.pulledUpPredicates.toString(),
1104+
is("[IS NULL($1), <($0, 10), IS NULL($2), =($3, 'y')]"));
1105+
}
1106+
10821107
/** Custom metadata interface. */
10831108
public interface ColType extends Metadata {
10841109
String getColType(int column);

core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ LogicalProject(EXPR$0=[CAST(CASE(IS NULL($1), IS NULL($0), IS NULL($0), IS NULL(
913913
</Resource>
914914
<Resource name="planAfter">
915915
<![CDATA[
916-
LogicalProject(EXPR$0=[CASE(IS NULL($1), IS NULL($0), CAST(=($1, $0)):BOOLEAN NOT NULL)])
916+
LogicalProject(EXPR$0=[CASE(IS NULL($1), false, CAST(=($1, 2)):BOOLEAN NOT NULL)])
917917
LogicalProject(EXPR$0=[2], EXPR$1=[null])
918918
LogicalValues(tuples=[[{ 0 }]])
919919
]]>
@@ -2908,10 +2908,10 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$
29082908
</Resource>
29092909
<Resource name="planAfter">
29102910
<![CDATA[
2911-
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$9], NAME=[$10])
2911+
LogicalProject(EMPNO=[10], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[10], NAME=[$10])
29122912
LogicalProject(EMPNO=[10], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[10], NAME=[$11])
2913-
LogicalJoin(condition=[AND(=(10, $10), =($9, $12))], joinType=[inner])
2914-
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, $0)])
2913+
LogicalJoin(condition=[=($9, 15)], joinType=[inner])
2914+
LogicalProject(EMPNO=[10], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[+($7, 10)])
29152915
LogicalProject(EMPNO=[10], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
29162916
LogicalFilter(condition=[=($0, 10)])
29172917
LogicalTableScan(table=[[CATALOG, SALES, EMP]])

0 commit comments

Comments
 (0)