Xiaoying, I know why you didn’t receive the email. Your reply went through moderation, which indicates that you are not subscribed to dev@calcite. Please subscribe.
> On Mar 28, 2022, at 11:10 AM, Xiaoying Wang <[email protected]> > wrote: > > Hi Benchao, > > Thank you so much for the reply! I don't know why I didn't receive the > email but I found your answer at the archive website. > > I tried to add the `JoinConditionPushRule` as you suggested but the > filter cannot be pushed from the second join to the first, and the > code throws the same error. > > It is because the initial state of my query is `(R join1 S) join2 T`, > and the conditions pushed to join2 by `FilterIntoJoinRule` are `R.key > = T.key and S.key = T.key`. Neither `R.key = T.key` nor `S.key = > T.key` can be pushed into join1 because they both require `T.key`. So > both `leftBitmap.contains(inputBits)` and > `rightBitmap.contains(inputBits)` at [1] are false and the condition > cannot be pushed down into the first join. > > Do you think I need to add other rules to solve the problem? (I tried > to add several rules to alter the join order including > `JoinAssociateRule`, `JoinCommuteRule`, > `JoinPushThroughJoinRule.RIGHT/LEFT` but none of them were fired.) > > Best, > > Xiaoying > > [1] > https://github.com/apache/calcite/blob/master/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java#L2838 > > > On 2022/03/27 00:41:57 Benchao Li wrote: >> Hi Xiaoying, >> >> You can try to add `JoinConditionPushRule`[1] to solve the problem. >> >> According the rules you provide, you only have `FilterIntoJoinRule`, >> hence the filters will only be push into the second Join. >> The exception you see indicates that the first Join has no condition, >> and it cannot be handled by ENUMERABLE convention as you can see here[2] >> >> [1] >> https://github.com/apache/calcite/blob/master/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java#L281 >> [2] >> https://github.com/apache/calcite/blob/master/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java#L304 >> >> >> Xiaoying Wang <[email protected]> 于2022年3月26日周六 04:46写道: >> >>> Hi all, >>> >>> >>> I have a query joins three tables (star schema, T is the fact >>> table): "select * from R, S, T where R.key = T.key and S.key = T.key" and >>> want to use calcite to parse and generate the physical plan. >>> >>> >>> When I pass the query to a volcano planner, it throws the >>> CannotPlanException: >>> >>> >>> Exception in thread "main" >>> org.apache.calcite.plan.RelOptPlanner$CannotPlanException: There are not >>> enough rules to produce a node with desired properties: >>> convention=ENUMERABLE. >>> >>> Missing conversions are LogicalJoin[convention: NONE -> JDBC.DB1] (2 cases) >>> >>> There are 2 empty subsets: >>> Empty subset 0: rel#34:RelSubset#2.JDBC.DB1, the relevant part of the >>> original plan is as follows >>> 14:LogicalJoin(condition=[true], joinType=[inner]) >>> 1:JdbcTableScan(subset=[rel#12:RelSubset#0.JDBC.DB1], table=[[DB1, R]]) >>> 3:JdbcTableScan(subset=[rel#13:RelSubset#1.JDBC.DB1], table=[[DB1, S]]) >>> >>> Empty subset 1: rel#36:RelSubset#4.JDBC.DB1, the relevant part of the >>> original plan is as follows >>> 17:LogicalJoin(condition=[true], joinType=[inner]) >>> 14:LogicalJoin(subset=[rel#15:RelSubset#2.NONE], condition=[true], >>> joinType=[inner]) >>> 1:JdbcTableScan(subset=[rel#12:RelSubset#0.JDBC.DB1], table=[[DB1, R]]) >>> 3:JdbcTableScan(subset=[rel#13:RelSubset#1.JDBC.DB1], table=[[DB1, S]]) >>> 7:JdbcTableScan(subset=[rel#16:RelSubset#3.JDBC.DB1], table=[[DB1, T]]) >>> >>> >>> >>> I tried to rewrite the query, and found that as long as T is not the last >>> relation (e.g. "select * from T, R, S where R.key = T.key and S.key = >>> T.key"), there is no error. I think it means that the join order in the >>> initial logical plan makes the difference, so I tried to add the >>> JoinAssociateRule. However, I found this rule was not applied by the >>> optimizer because of the convocation not match. Using the above example, >>> for 17:LogicalJoin the convocation of 14:LogicalJoin and 7:JdbcTableScan >>> are not the same ( at here: >>> >>> https://github.com/apache/calcite/blob/e42b85a45bd16dd58db1546736e653deda5463fe/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleCall.java#L358 >>> ). >>> >>> >>> These are the rules in the planner: >>> >>> [FilterIntoJoinRule, JoinAssociateRule, JoinCommuteRule, >>> JdbcToEnumerableConverterRule(in:JDBC.DB1,out:ENUMERABLE), >>> JdbcJoinRule(in:NONE,out:JDBC.DB1), JdbcProjectRule(in:NONE,out:JDBC.DB1), >>> JdbcFilterRule(in:NONE,out:JDBC.DB1), >>> JdbcAggregateRule(in:NONE,out:JDBC.DB1), >>> JdbcSortRule(in:NONE,out:JDBC.DB1), JdbcUnionRule(in:NONE,out:JDBC.DB1), >>> JdbcIntersectRule(in:NONE,out:JDBC.DB1), >>> JdbcMinusRule(in:NONE,out:JDBC.DB1), >>> JdbcTableModificationRule(in:NONE,out:JDBC.DB1), >>> JdbcValuesRule(in:NONE,out:JDBC.DB1), FilterSetOpTransposeRule, >>> ProjectRemoveRule] >>> >>> >>> I'm very new to Calcite. I'm not sure whether I missed some rules or I have >>> to implement something to make it work. Can anyone help me on this? >>> >>> Best, >>> >>> Xiaoying >>> >> >> >> -- >> >> Best, >> Benchao Li >>
