This is an automated email from the ASF dual-hosted git repository.
morrySnow 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 51cff8155f3 [fix](tablet-prune) Prefer equality bounds when pruning
hash tablets (#69068)
51cff8155f3 is described below
commit 51cff8155f33d2ad15ff421c4f3dab975973b55a
Author: feiniaofeiafei <[email protected]>
AuthorDate: Thu Oct 15 14:29:49 2026 +0800
[fix](tablet-prune) Prefer equality bounds when pruning hash tablets
(#69068)
### What problem does this PR solve?
Problem Summary: When an equality bound and an IN predicate coexist on a
hash distribution column, the pruner enumerates the IN values even
though the equality already restricts the column to one value. Prefer
inclusive, equal bounds before IN enumeration so redundant IN predicates
cannot widen the candidate tablet set. Keep scan predicates unchanged,
including when the equality contradicts the IN list.
### Release note
Improve tablet pruning when equality bounds and IN predicates coexist on
hash distribution columns.
---
.../doris/planner/HashDistributionPruner.java | 19 ++++----
.../doris/planner/HashDistributionPrunerTest.java | 54 ++++++++++++++++++++++
2 files changed, 64 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 747bb17a6ad..432dcf76af0 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
@@ -102,18 +102,19 @@ public class HashDistributionPruner implements
DistributionPruner {
// return all subPartition
return getAllTabletIds();
}
+ // 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 getAllTabletIds();
}
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 a475b923874..7d565bccfc7 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
@@ -41,6 +41,60 @@ import java.util.Set;
public class HashDistributionPrunerTest {
+ @Test
+ public void testEqualityWithInPredicate() {
+ List<Tablet> tablets = Lists.newArrayList();
+ for (long i = 0; i < 32; i++) {
+ tablets.add(new LocalTablet(i));
+ }
+ MaterializedIndex index = new MaterializedIndex();
+ index.appendTablets(tablets);
+ 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, index, columns, filters, tablets.size(), true);
+ Set<Long> equalityTablets = Sets.newHashSet(pruner.prune());
+ Assertions.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));
+ Assertions.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);
+ Assertions.assertEquals(15, pruner.prune().size());
+
+ // A non-inclusive bound must not be treated as an equality.
+ filters.put("company_code", companyFilter);
+ companyFilter.lowerBoundInclusive = false;
+ Assertions.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));
+ Assertions.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]