Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
1.17.0
-
None
-
None
Description
In the context of a LEFT OUTER JOIN implemented via EnumerableCorrelate, the generated code for the selector does not check if the right object is null (which can be, since it is a LEFT join). This situation can lead to a NullPointerException.
The root cause is located in EnumerableCorrelate::implement method, which builds the selector expression using a ternary operator whose "if" and "else" statements are switched:
Expression selector = EnumUtils.joinSelector( joinType.returnsJustFirstInput() ? joinType.toJoinType() : JoinRelType.INNER, physType, ImmutableList.of(leftResult.physType, rightResult.physType));
This code works (by coincidence) in the case of an INNER join; but in case of LEFT, it will incorrectly call EnumUtils.joinSelector(...) with JoinRelType.INNER instead of JoinRelType.LEFT, which will produce the problematic generated code. Also, the current code in the context of a SEMI or ANTI join will throw an IllegalStateException when calling SemiJoinType::toJoinType.
If I am not mistaken, to fix this we just need to switch the ternary operator statements:
Expression selector = EnumUtils.joinSelector( joinType.returnsJustFirstInput() ? JoinRelType.INNER : joinType.toJoinType(), physType, ImmutableList.of(leftResult.physType, rightResult.physType));
Attachments
Issue Links
- blocks
-
CALCITE-2575 Release Calcite 1.18.0
- Closed
-
CALCITE-2621 Add rule to execute semi joins with correlation
- Closed
- links to