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]