This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.2 by this push:
     new f2bd86ef1a3 branch-4.2: [fix](tablet-prune) Prefer equality bounds 
when pruning hash tablets #69068 (#69759)
f2bd86ef1a3 is described below

commit f2bd86ef1a31083992948ec79664217a20bcc8dd
Author: feiniaofeiafei <[email protected]>
AuthorDate: Thu Oct 29 09:43:40 2026 +0800

    branch-4.2: [fix](tablet-prune) Prefer equality bounds when pruning hash 
tablets #69068 (#69759)
    
    Cherry-picked from https://github.com/apache/doris/pull/69068
---
 .../doris/planner/HashDistributionPruner.java      | 19 ++++----
 .../doris/planner/HashDistributionPrunerTest.java  | 52 ++++++++++++++++++++++
 2 files changed, 62 insertions(+), 9 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/HashDistributionPruner.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/HashDistributionPruner.java
index acdbeeffa70..2d9e89f1394 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/planner/HashDistributionPruner.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/planner/HashDistributionPruner.java
@@ -100,18 +100,19 @@ public class HashDistributionPruner implements 
DistributionPruner {
             // return all subPartition
             return Lists.newArrayList(bucketsList);
         }
+        // An equality bound is more selective than an IN predicate on the 
same column.
+        // Keep the remaining predicates for row filtering, including 
contradictory IN values.
+        if (filter.lowerBoundInclusive && filter.upperBoundInclusive
+                && filter.lowerBound != null && filter.upperBound != null
+                && 0 == filter.lowerBound.compareLiteral(filter.upperBound)) {
+            hashKey.pushColumn(filter.lowerBound, keyColumn.getDataType());
+            Collection<Long> result = prune(columnId + 1, hashKey, complex);
+            hashKey.popColumn();
+            return result;
+        }
         InPredicate inPredicate = filter.getInPredicate();
         if (null == inPredicate
                 || inPredicate.getInElementNum() * complex > 
Config.max_distribution_pruner_recursion_depth) {
-            // equal one value
-            if (filter.lowerBoundInclusive && filter.upperBoundInclusive
-                    && filter.lowerBound != null && filter.upperBound != null
-                    && 0 == 
filter.lowerBound.compareLiteral(filter.upperBound)) {
-                hashKey.pushColumn(filter.lowerBound, keyColumn.getDataType());
-                Collection<Long> result = prune(columnId + 1, hashKey, 
complex);
-                hashKey.popColumn();
-                return result;
-            }
             // return all SubPartition
             return Lists.newArrayList(bucketsList);
         }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/planner/HashDistributionPrunerTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/planner/HashDistributionPrunerTest.java
index 185a1ac1a7a..5c525011d75 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/planner/HashDistributionPrunerTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/planner/HashDistributionPrunerTest.java
@@ -38,6 +38,58 @@ import java.util.Set;
 
 public class HashDistributionPrunerTest {
 
+    @Test
+    public void testEqualityWithInPredicate() {
+        List<Long> tabletIds = Lists.newArrayList();
+        for (long i = 0; i < 32; i++) {
+            tabletIds.add(i);
+        }
+        List<Column> columns = Lists.newArrayList(
+                new Column("warehouse_code", PrimitiveType.VARCHAR, false),
+                new Column("company_code", PrimitiveType.VARCHAR, false));
+        PartitionColumnFilter warehouseFilter = new PartitionColumnFilter();
+        warehouseFilter.setLowerBound(new StringLiteral("574DCB"), true);
+        warehouseFilter.setUpperBound(new StringLiteral("574DCB"), true);
+        PartitionColumnFilter companyFilter = new PartitionColumnFilter();
+        companyFilter.setLowerBound(new StringLiteral("W4114040299"), true);
+        companyFilter.setUpperBound(new StringLiteral("W4114040299"), true);
+        Map<String, PartitionColumnFilter> filters = new CaseInsensitiveMap();
+        filters.put("warehouse_code", warehouseFilter);
+        filters.put("company_code", companyFilter);
+        HashDistributionPruner pruner = new HashDistributionPruner(
+                null, tabletIds, columns, filters, tabletIds.size(), true);
+        Set<Long> equalityTablets = Sets.newHashSet(pruner.prune());
+        Assert.assertEquals(1, equalityTablets.size());
+
+        List<Expr> values = Lists.newArrayList();
+        for (String value : new String[] {"5744695112-6", 
"82330212MACFCLM3XD", "W0102990195",
+                "W0200475371", "W0200475371-1", "W0200475371-2", 
"W0200475371-3", "W4114040299",
+                "W5744621073", "W5744632948", "W5744644793", "W5744644949", 
"W5744655527",
+                "W5744659100", "W5744664563", "W5744668072", "W5744689390", 
"W5744690883"}) {
+            values.add(new StringLiteral(value));
+        }
+        companyFilter.setInPredicate(new InPredicate(new SlotRef(null, 
"company_code"), values, false));
+        Assert.assertEquals(equalityTablets, Sets.newHashSet(pruner.prune()));
+
+        // IN-only pruning must still enumerate all of its values.
+        PartitionColumnFilter inOnlyFilter = new PartitionColumnFilter();
+        inOnlyFilter.setInPredicate(companyFilter.getInPredicate());
+        filters.put("company_code", inOnlyFilter);
+        Assert.assertEquals(15, pruner.prune().size());
+
+        // A non-inclusive bound must not be treated as an equality.
+        filters.put("company_code", companyFilter);
+        companyFilter.lowerBoundInclusive = false;
+        Assert.assertEquals(15, pruner.prune().size());
+        companyFilter.lowerBoundInclusive = true;
+
+        // An equality outside the IN list still provides a safe candidate 
tablet.
+        // The contradictory predicates are evaluated by the scan, not by this 
pruner.
+        companyFilter.setInPredicate(new InPredicate(new SlotRef(null, 
"company_code"),
+                Lists.<Expr>newArrayList(new StringLiteral("W0200475371")), 
false));
+        Assert.assertEquals(equalityTablets, Sets.newHashSet(pruner.prune()));
+    }
+
     @Test
     public void test() {
         List<Long> tabletIds = Lists.newArrayListWithExpectedSize(300);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to