Hi Julian,

Oh, I see. Thank you for the hint!  I just subscribed to the list.

Best,
Xiaoying

On Mon, Mar 28, 2022 at 11:53 AM Julian Hyde <[email protected]> wrote:

> 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
> >>
>
>

Reply via email to