Repository navigation
HIVE-28480: Disable SMB on partition hash generator mismatch across join branches… - #5406
Conversation
|
The patch seems reasonable. LGTM |
| @@ -0,0 +1,39 @@ | |||
| CREATE TABLE t_asj_18 (k STRING, v INT); | |||
There was a problem hiding this comment.
I confirmed this test case reproduces the issue explained in the JIRA ticket
| Boolean prevRsHasUniformTrait = null; | ||
| for (Operator<? extends OperatorDesc> parentOp : joinOp.getParentOperators()) { | ||
| // Assertion of mandatory single parent is already being done in bucket version check earlier | ||
| Operator<?> op = parentOp.getParentOperators().get(0); |
There was a problem hiding this comment.
Can I assume we want to find ReduceSinkOperator-1 of Operators -> ReduceSinkOperator-1 -> Operators -> ReduceSinkOperator-2(parentOp) ->JoinOperator?
There was a problem hiding this comment.
Yes. The ReduceSinkOperator-2 -> JoinOperator get replaced by MERGEJOIN operator for SMB. We want to ensure the RS before these in both join branches are using same partitioning logic.
|
@okumin if this looks good, please merge the PR |
|
@himanshu-mishra Sorry, I don't have the right to merge a PR as I am not a committer. You need approval of any committer who is ideally an expert of SMB join. |
|
@kasakrisz can you please review or add reviewer |
kasakrisz
left a comment
There was a problem hiding this comment.
This is a good candidate to fix this issue, but have you checked why the reducer traits are different?
| while (op != null && !(op instanceof TableScanOperator || op instanceof ReduceSinkOperator | ||
| || op instanceof CommonJoinOperator)) { | ||
| // If op has parents it is guaranteed to be 1. | ||
| List<Operator<?>> parents = op.getParentOperators(); | ||
| Preconditions.checkState(parents.size() == 0 || parents.size() == 1); | ||
| op = parents.size() == 1 ? parents.get(0) : null; | ||
| } |
There was a problem hiding this comment.
There are several utility methods to find operators in branches of a plan in ql.exec.OperatorUtils
OperatorUtils.find*Operator*()
Is it possible to use one of them to find parent RS operators?
There was a problem hiding this comment.
There isn't a utility method there that returns first ancestor operator encountered from given set of classes. Here, we are only interested in ancestor RS if that is the source of data for current RS, if TS, JOIN are encountered, they are the source, and we do not need verifying them.
There was a problem hiding this comment.
a few lines earlier the same while loop exists
hive/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConvertJoinMapJoin.java
Lines 853 to 859 in b13f529
Could you please extract these to a utility method and move it to OperatorUtils
There was a problem hiding this comment.
Thanks for reviewing. I'll incorporate it.
Consider the sample query SELECT * FROM (
SELECT k, COUNT(DISTINCT v), SUM(v)
FROM t_asj_18 GROUP BY k
) a LEFT JOIN (
SELECT k, COUNT(v)
FROM t_asj_18 GROUP BY k
) b ON a.k = b.k; In this query the aggregation |
|
@kasakrisz let me know if there are pending concerns. |
Sorry, I was occupied in the last few days. I left only one comment. |
|
|
@kasakrisz as you have approved the changes, can you help with merging the PR. |



… in previous RS
What changes were proposed in this pull request?
As SMB replaces last RS op from the joining branches and the JOIN op with MERGEJOIN, we need to ensure the RS before these RS, in both branches, are partitioning using same hash generator.
Hash code generator differs based on ReducerTraits.UNIFORM i.e. ReduceSinkOperator#computeMurmurHash() or ReduceSinkOperator#computeHashCode(), leading to different hash code for same value.
Skip SMB join in such cases.
Why are the changes needed?
It fixes bug that results in incorrect join result. Example query and behavior explanation is added in https://issues.apache.org/jira/browse/HIVE-28480
Does this PR introduce any user-facing change?
No
Is the change a dependency upgrade?
No
How was this patch tested?
Tested via
auto_sortmerge_join_18.qadded in this PR