New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix the reverse scan null predicate missing issue for JOIN case #2606
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -580,8 +580,11 @@ private AbstractPlanNode getSelectSubPlanForJoin(BranchNode joinNode, | |
// InnerPlan is an IndexScan. In this case the inner and inner-outer | ||
// non-index join expressions (if any) are in the otherExpr. The former should stay as | ||
// an IndexScanPlan predicate and the latter stay at the NLJ node as a join predicate | ||
List<AbstractExpression> innerExpr = filterSingleTVEExpressions(innerAccessPath.otherExprs); | ||
joinClauses.addAll(innerAccessPath.otherExprs); | ||
ArrayList<AbstractExpression> otherExprs = new ArrayList<AbstractExpression>(); | ||
// PLEASE do not update the "innerAccessPath.otherExprs", it may be reused | ||
// for other path evaluation on the other outer side join. | ||
List<AbstractExpression> innerExpr = filterSingleTVEExpressions(innerAccessPath.otherExprs, otherExprs); | ||
joinClauses.addAll(otherExprs); | ||
AbstractExpression indexScanPredicate = ExpressionUtil.combine(innerExpr); | ||
((IndexScanPlanNode)innerPlan).setPredicate(indexScanPredicate); | ||
} | ||
|
@@ -644,19 +647,22 @@ else if (canHaveNLIJ) { | |
/** | ||
* A method to filter out single TVE expressions. | ||
* | ||
* @param expr List of expressions. | ||
* @param expr List of single TVE expressions. | ||
* @param otherExprs List of expressions other than TVE. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The opposite of "single-TVE expressions" is NOT "expressions other than TVE" it is "multi-TVE expressions". I am hoping that the other possible case -- zero-TVE expressions (constant conditions) -- are not getting mixed in here! Also, change all comments to hyphenate "single-TVE". A "single TVE expression" can be mistaken to mean "one that IS just a TVE". A "single-TVE expression" more clearly expresses "one that only HAS one TVE". |
||
* @return List of single TVE expressions from the input collection. | ||
* They are also removed from the input. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is now a lie. |
||
*/ | ||
private static List<AbstractExpression> filterSingleTVEExpressions(List<AbstractExpression> exprs) { | ||
private static List<AbstractExpression> filterSingleTVEExpressions(List<AbstractExpression> exprs, | ||
List<AbstractExpression> otherExprs) { | ||
List<AbstractExpression> singleTVEExprs = new ArrayList<AbstractExpression>(); | ||
for (AbstractExpression expr : exprs) { | ||
List<TupleValueExpression> tves = ExpressionUtil.getTupleValueExpressions(expr); | ||
if (tves.size() == 1) { | ||
singleTVEExprs.add(expr); | ||
} else { | ||
otherExprs.add(expr); | ||
} | ||
} | ||
exprs.removeAll(singleTVEExprs); | ||
return singleTVEExprs; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this comment. Can you identify the method where the innerAccessPath.otherExprs element needs to be reused? Can you identify a specific case where we want to extract a single-TVE expression into innerExpr and also keep it available in innerAccessPath.otherExprs?
Is the idea that we extract all single-TVE expressions as just a first pass to get conditions that MIGHT be indexable on the one specific side, and we don't care yet about the TVEs' tables because we will check that we are on the correct side (for that table) later? I could believe that, but, for the sake of query performance, I would want some confirmation that the final plan does not leave behind a completely redundant join condition that was already enforced by the child scan (either as an index-covered predicate or as a scan post-predicate).
I am suspicious that this SEEMs to specifically solve a join-of-reverse-scan-with-null case.
Does this mean that a reverse scan could still have a null-handling bug in the non-join case?
Or can you explain how this join mis-handling was specifically causing a null handling bug --
was it really a more general bug, and this reverse scan null case just happened to be the one reproducer we found -- one of many possible symptoms of a missing filter?