This is an automated email from the ASF dual-hosted git repository.
hello-stephen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new f697dfa973c [fix](fe) Revert semi join constraint matching fix (#65546)
f697dfa973c is described below
commit f697dfa973c32f5bf59639bc1b31602a8caf6da6
Author: shuke <[email protected]>
AuthorDate: Fri Jul 17 11:46:08 2026 +0800
[fix](fe) Revert semi join constraint matching fix (#65546)
Related PR: #65205
Problem Summary:
PR #65205 introduced a correctness issue in leading hint planning by
changing how semi/anti join constraints are matched. This PR reverts
merge commit `cbccdafa41adfff73e683ac1dfcae46638c16d48` in full,
restoring the previous planner behavior while a correct fix is prepared.
---
.../org/apache/doris/nereids/hint/LeadingHint.java | 17 +-
.../apache/doris/nereids/hint/LeadingHintTest.java | 219 ---------------------
2 files changed, 5 insertions(+), 231 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/hint/LeadingHint.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/hint/LeadingHint.java
index 45df90d3d1d..7f67311204d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/hint/LeadingHint.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/hint/LeadingHint.java
@@ -416,20 +416,13 @@ public class LeadingHint extends Hint {
continue;
}
- if (joinConstraint.getJoinType().isSemiOrAntiJoin()) {
- if (!LongBitmap.isSubset(joinConstraint.getMinLeftHand(),
joinTableBitmap)
- ||
!LongBitmap.isSubset(joinConstraint.getMinRightHand(), joinTableBitmap)) {
+ if (joinConstraint.getJoinType().isSemiJoin()) {
+ if (LongBitmap.isSubset(joinConstraint.getRightHand(),
leftTableBitmap)
+ && !LongBitmap.isSubset(joinConstraint.getRightHand(),
leftTableBitmap)) {
continue;
}
-
- Long constrainedSide =
joinConstraint.getJoinType().isRightSemiOrAntiJoin()
- ? joinConstraint.getLeftHand() :
joinConstraint.getRightHand();
- if (LongBitmap.isOverlap(constrainedSide, leftTableBitmap)
- && !constrainedSide.equals(leftTableBitmap)) {
- continue;
- }
- if (LongBitmap.isOverlap(constrainedSide, rightTableBitmap)
- && !constrainedSide.equals(rightTableBitmap)) {
+ if (LongBitmap.isSubset(joinConstraint.getRightHand(),
rightTableBitmap)
+ &&
!joinConstraint.getRightHand().equals(rightTableBitmap)) {
continue;
}
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/hint/LeadingHintTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/hint/LeadingHintTest.java
deleted file mode 100644
index 00f0c45437f..00000000000
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/hint/LeadingHintTest.java
+++ /dev/null
@@ -1,219 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.nereids.hint;
-
-import org.apache.doris.common.Pair;
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
-import org.apache.doris.nereids.trees.plans.JoinType;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-public class LeadingHintTest {
-
- @Test
- public void testLeftSemiJoinConstrainedSideMatchesExactly() {
- LeadingHint leading = new LeadingHint("Leading");
- long leftHand = LongBitmap.newBitmap(0);
- long rightHand = LongBitmap.newBitmap(1);
- long extraTable = LongBitmap.newBitmap(2);
- JoinConstraint semiJoinConstraint = addJoinConstraint(leading,
leftHand, rightHand,
- JoinType.LEFT_SEMI_JOIN);
-
- Pair<JoinConstraint, Boolean> exactReversed =
leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(leftHand, rightHand), rightHand,
leftHand);
- assertMatchedJoinConstraint(semiJoinConstraint, exactReversed, true);
-
- Pair<JoinConstraint, Boolean> withoutRetainedSide =
leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(rightHand, extraTable), rightHand,
extraTable);
- assertNoMatchedJoinConstraint(withoutRetainedSide);
-
- Pair<JoinConstraint, Boolean> withExtraTable =
leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(leftHand, rightHand, extraTable),
- LongBitmap.newBitmapUnion(rightHand, extraTable),
- leftHand);
- assertNoMatchedJoinConstraint(withExtraTable);
- }
-
- @Test
- public void testLeftAntiJoinConstrainedSideMatchesExactly() {
- LeadingHint leading = new LeadingHint("Leading");
- long leftHand = LongBitmap.newBitmap(0);
- long rightHand = LongBitmap.newBitmap(1);
- long extraTable = LongBitmap.newBitmap(2);
- JoinConstraint antiJoinConstraint = addJoinConstraint(leading,
leftHand, rightHand,
- JoinType.LEFT_ANTI_JOIN);
-
- Pair<JoinConstraint, Boolean> exactReversed =
leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(leftHand, rightHand), rightHand,
leftHand);
- assertMatchedJoinConstraint(antiJoinConstraint, exactReversed, true);
-
- Pair<JoinConstraint, Boolean> withExtraTable =
leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(leftHand, rightHand, extraTable),
- LongBitmap.newBitmapUnion(rightHand, extraTable),
- leftHand);
- assertNoMatchedJoinConstraint(withExtraTable);
- }
-
- @Test
- public void testRightSemiJoinConstrainedSideMatchesExactly() {
- LeadingHint leading = new LeadingHint("Leading");
- long leftHand = LongBitmap.newBitmap(0);
- long rightHand = LongBitmap.newBitmap(1);
- long extraTable = LongBitmap.newBitmap(2);
- JoinConstraint semiJoinConstraint = addJoinConstraint(leading,
leftHand, rightHand,
- JoinType.RIGHT_SEMI_JOIN);
-
- Pair<JoinConstraint, Boolean> exact = leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(leftHand, rightHand), leftHand,
rightHand);
- assertMatchedJoinConstraint(semiJoinConstraint, exact, false);
-
- Pair<JoinConstraint, Boolean> withoutConstrainedSide =
leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(rightHand, extraTable), rightHand,
extraTable);
- assertNoMatchedJoinConstraint(withoutConstrainedSide);
-
- Pair<JoinConstraint, Boolean> withExtraTable =
leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(leftHand, rightHand, extraTable),
- LongBitmap.newBitmapUnion(leftHand, extraTable),
- rightHand);
- assertNoMatchedJoinConstraint(withExtraTable);
- }
-
- @Test
- public void testRightAntiJoinConstrainedSideMatchesExactly() {
- LeadingHint leading = new LeadingHint("Leading");
- long leftHand = LongBitmap.newBitmap(0);
- long rightHand = LongBitmap.newBitmap(1);
- long extraTable = LongBitmap.newBitmap(2);
- JoinConstraint antiJoinConstraint = addJoinConstraint(leading,
leftHand, rightHand,
- JoinType.RIGHT_ANTI_JOIN);
-
- Pair<JoinConstraint, Boolean> exact = leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(leftHand, rightHand), leftHand,
rightHand);
- assertMatchedJoinConstraint(antiJoinConstraint, exact, false);
-
- Pair<JoinConstraint, Boolean> withExtraTable =
leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(leftHand, rightHand, extraTable),
- LongBitmap.newBitmapUnion(leftHand, extraTable),
- rightHand);
- assertNoMatchedJoinConstraint(withExtraTable);
- }
-
- @Test
- public void testCompositeLeftSemiAndAntiJoinConstrainedSideCanNotBeSplit()
{
- assertCompositeConstrainedSideCanNotBeSplit(JoinType.LEFT_SEMI_JOIN);
- assertCompositeConstrainedSideCanNotBeSplit(JoinType.LEFT_ANTI_JOIN);
- }
-
- @Test
- public void
testCompositeRightSemiAndAntiJoinConstrainedSideCanNotBeSplit() {
- assertCompositeConstrainedSideCanNotBeSplit(JoinType.RIGHT_SEMI_JOIN);
- assertCompositeConstrainedSideCanNotBeSplit(JoinType.RIGHT_ANTI_JOIN);
- }
-
- @Test
- public void testCompositeLeftSemiAndAntiJoinRetainedSideCanUseMinHand() {
- assertCompositeRetainedSideCanUseMinHand(JoinType.LEFT_SEMI_JOIN);
- assertCompositeRetainedSideCanUseMinHand(JoinType.LEFT_ANTI_JOIN);
- }
-
- @Test
- public void testCompositeRightSemiAndAntiJoinRetainedSideCanUseMinHand() {
- assertCompositeRetainedSideCanUseMinHand(JoinType.RIGHT_SEMI_JOIN);
- assertCompositeRetainedSideCanUseMinHand(JoinType.RIGHT_ANTI_JOIN);
- }
-
- private JoinConstraint addJoinConstraint(LeadingHint leading, long
leftHand, long rightHand,
- JoinType joinType) {
- JoinConstraint joinConstraint = new JoinConstraint(leftHand,
rightHand, leftHand, rightHand, joinType, true);
- leading.getJoinConstraintList().add(joinConstraint);
- return joinConstraint;
- }
-
- private JoinConstraint addJoinConstraint(LeadingHint leading, long
minLeftHand, long minRightHand,
- long leftHand, long rightHand, JoinType joinType) {
- JoinConstraint joinConstraint = new JoinConstraint(minLeftHand,
minRightHand, leftHand, rightHand,
- joinType, true);
- leading.getJoinConstraintList().add(joinConstraint);
- return joinConstraint;
- }
-
- private void assertCompositeConstrainedSideCanNotBeSplit(JoinType
joinType) {
- LeadingHint leading = new LeadingHint("Leading");
- long leftHand = LongBitmap.newBitmap(0);
- long rightHand = LongBitmap.newBitmap(1);
- long extraTable = LongBitmap.newBitmap(2);
- long joinTable = LongBitmap.newBitmapUnion(leftHand, rightHand,
extraTable);
-
- if (joinType.isRightSemiOrAntiJoin()) {
- JoinConstraint joinConstraint = addJoinConstraint(leading,
leftHand, rightHand,
- LongBitmap.newBitmapUnion(leftHand, extraTable),
rightHand, joinType);
-
- Pair<JoinConstraint, Boolean> exact = leading.getJoinConstraint(
- joinTable, LongBitmap.newBitmapUnion(leftHand,
extraTable), rightHand);
- assertMatchedJoinConstraint(joinConstraint, exact, false);
-
- Pair<JoinConstraint, Boolean> splitConstrainedSide =
leading.getJoinConstraint(
- joinTable, leftHand, LongBitmap.newBitmapUnion(rightHand,
extraTable));
- assertNoMatchedJoinConstraint(splitConstrainedSide);
- } else {
- JoinConstraint joinConstraint = addJoinConstraint(leading,
leftHand, rightHand,
- leftHand, LongBitmap.newBitmapUnion(rightHand,
extraTable), joinType);
-
- Pair<JoinConstraint, Boolean> exact = leading.getJoinConstraint(
- joinTable, leftHand, LongBitmap.newBitmapUnion(rightHand,
extraTable));
- assertMatchedJoinConstraint(joinConstraint, exact, false);
-
- Pair<JoinConstraint, Boolean> splitConstrainedSide =
leading.getJoinConstraint(
- joinTable, LongBitmap.newBitmapUnion(leftHand,
extraTable), rightHand);
- assertNoMatchedJoinConstraint(splitConstrainedSide);
- }
- }
-
- private void assertCompositeRetainedSideCanUseMinHand(JoinType joinType) {
- LeadingHint leading = new LeadingHint("Leading");
- long leftHand = LongBitmap.newBitmap(0);
- long rightHand = LongBitmap.newBitmap(1);
- long extraTable = LongBitmap.newBitmap(2);
-
- JoinConstraint joinConstraint;
- if (joinType.isRightSemiOrAntiJoin()) {
- joinConstraint = addJoinConstraint(leading, leftHand, rightHand,
- leftHand, LongBitmap.newBitmapUnion(rightHand,
extraTable), joinType);
- } else {
- joinConstraint = addJoinConstraint(leading, leftHand, rightHand,
- LongBitmap.newBitmapUnion(leftHand, extraTable),
rightHand, joinType);
- }
-
- Pair<JoinConstraint, Boolean> minRetainedSide =
leading.getJoinConstraint(
- LongBitmap.newBitmapUnion(leftHand, rightHand), leftHand,
rightHand);
- assertMatchedJoinConstraint(joinConstraint, minRetainedSide, false);
- }
-
- private void assertMatchedJoinConstraint(JoinConstraint expected,
Pair<JoinConstraint, Boolean> actual,
- boolean reversed) {
- Assertions.assertSame(expected, actual.first);
- Assertions.assertTrue(actual.second);
- Assertions.assertEquals(reversed, actual.first.isReversed());
- }
-
- private void assertNoMatchedJoinConstraint(Pair<JoinConstraint, Boolean>
actual) {
- Assertions.assertNull(actual.first);
- Assertions.assertTrue(actual.second);
- }
-}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]