The comment for `AllPredicates`[1] has explained the difference. Can this answer your question?
The difference with respect to BuiltInMetadata.Predicates provider is that > this provider tries to extract ALL predicates even if they are not applied > on the output expressions of the relational expression; we rely on > RexTableInputRef to reference origin columns in > org.apache.calcite.rel.core.TableScan for the result predicates. [1] https://github.com/apache/calcite/blob/9a07b1194bf82410c8583292f4eef7b0f289c594/core/src/main/java/org/apache/calcite/rel/metadata/BuiltInMetadata.java#L670-L675 Jiajun Xie <jiajunbernou...@gmail.com> 于2023年1月16日周一 16:40写道: > Hi Benchao, > Thanks very much for your email. > > I understand `RelMetadataQuery#getAllPredicates` cannot get all predicates > because some optimized cases cannot push/pull predicates. > > But I think the function name and code comment[1] are misleading, > *getAllPredicates* cannot get all predicates. > And your case should be handled by > `RelMetadataQuery#getPulledUpPredicates`[2] > instead of `RelMetadataQuery#getAllPredicates`. > > [1] > > https://github.com/apache/calcite/blob/413eded693a9087402cc1a6eefeca7a29445d337/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java#L855 > [2] > > https://github.com/apache/calcite/blob/413eded693a9087402cc1a6eefeca7a29445d337/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java#L836 > > On Sun, 15 Jan 2023 at 21:12, Benchao Li <libenc...@apache.org> wrote: > > > Hi Jiajun, > > > > For outer join, the semantic is different for predicates in condition and > > where, for example: > > Q1: select * from emp left join dept on emp.deptno = dept.deptno > > Q2: select * from emp left join dept on true where emp.deptno = > dept.deptno > > > > The semantic is different for Q1 and Q2. Q1 will output all the records > > from emp, including the records which fail to join from dept. However, Q2 > > will only output the records which successfully join some records from > > dept. > > > > This is the reason why we cannot push/pull the predicates from outer > joins > > conditions. Hope this helps. > > > > Jiajun Xie <jiajunbernou...@gmail.com> 于2023年1月12日周四 16:47写道: > > > > > Hello, all. > > > > > > I try to use RelMetadataQuery#getAllPredicates get predicate, > > > but I get null for outer join query that left column name is same as > > right > > > column name. > > > ``` > > > final RelNode rel = sql("select name as dname from emp left outer join > > > dept" > > > + " on emp.deptno = dept.deptno").toRel(); > > > final RelMetadataQuery mq = rel.getCluster().getMetadataQuery(); > > > final RelOptPredicateList r = mq.getAllPredicates(rel); > > > assertNull(r); > > > ``` > > > > > > > > > After commenting on two pieces of code: > > > 1. RelMdAllPredicates#getAllPredicates > > > ``` > > > if (join.getJoinType().isOuterJoin()) { > > > // We cannot map origin of this expression. > > > return null; > > > } > > > 2. RelMdExpressionLineage#getExpressionLineage > > > ``` > > > if (rel.getJoinType().isOuterJoin()) { > > > // If we reference the inner side, we will bail out > > > if (rel.getJoinType() == JoinRelType.LEFT) { > > > ImmutableBitSet rightFields = ImmutableBitSet.range( > > > nLeftColumns, rel.getRowType().getFieldCount()); > > > if (inputFieldsUsed.intersects(rightFields)) { > > > // We cannot map origin of this expression. > > > return null; > > > } > > > } else if (rel.getJoinType() == JoinRelType.RIGHT) { > > > ImmutableBitSet leftFields = ImmutableBitSet.range( > > > 0, nLeftColumns); > > > if (inputFieldsUsed.intersects(leftFields)) { > > > // We cannot map origin of this expression. > > > return null; > > > } > > > } else { > > > // We cannot map origin of this expression. > > > return null; > > > } > > > } > > > I can get the results I need > > > ``` > > > final RelNode rel = sql("select name as dname from emp left outer join > > > dept" > > > + " on emp.deptno = dept.deptno").toRel(); > > > final RelMetadataQuery mq = rel.getCluster().getMetadataQuery(); > > > final RelOptPredicateList r = mq.getAllPredicates(rel); > > > assertThat(r.pulledUpPredicates.get(0).toString(), > > > equalTo("=([CATALOG, SALES, EMP].#0.$7, [CATALOG, SALES, > > > DEPT].#0.$0)")); > > > ``` > > > > > > > > > It seems that we deliberately return null > > > in RelMetadataQuery#getAllPredicates . Can someone tell me why? Thanks! > > > > > > > > > -- > > > > Best, > > Benchao Li > > > -- Best, Benchao Li