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 1b194fd39a3 [fix](partition pruning) Preserve partition predicate
across scan copies (#67798)
1b194fd39a3 is described below
commit 1b194fd39a39546143cb719c6aad4aecb71a7418
Author: morrySnow <[email protected]>
AuthorDate: Fri Sep 11 14:40:45 2026 +0800
[fix](partition pruning) Preserve partition predicate across scan copies
(#67798)
## Problem
A query with a valid partition predicate can be rejected by a
`require_partition_filter` SQL block rule when partition pruning
initially selects both a non-empty partition and an empty partition.
## Cause
Partition pruning records that the scan has a partition predicate.
Empty-partition pruning then copies the scan through the one-argument
`withSelectedPartitionIds` method, which reset that flag to `false`. The
table-stream scan override had the same copy behavior.
## Reproduction
Create a range-partitioned table where the middle partition is empty,
enable `require_partition_filter`, and query with a predicate spanning
the first two partitions (for example, `id < 10`). The scan is reduced
to the non-empty first partition, but the query is incorrectly rejected
as missing a partition filter.
## Fix
- Preserve the existing partition-predicate flag when copying regular
and table-stream OLAP scans with a new selected-partition list.
- Keep the explicit two-argument overload available for callers that
intentionally set the flag.
- Add unit coverage for both scan types and regression coverage for a
predicate spanning a non-empty and an empty partition.
## Testing
- `LogicalOlapScanTest` (6 tests)
- Full FE build and checkstyle
- `sql_block_rule_p0/test_sql_block_rule.groovy`
- Runtime verification for valid and missing partition predicates
---
.../nereids/trees/plans/logical/LogicalOlapScan.java | 2 +-
.../plans/logical/LogicalOlapTableStreamScan.java | 2 +-
.../trees/plans/logical/LogicalOlapScanTest.java | 19 +++++++++++++++++++
.../sql_block_rule_p0/test_sql_block_rule.groovy | 11 ++++++++++-
4 files changed, 31 insertions(+), 3 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java
index cdbf9b9019e..608a79a75be 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java
@@ -565,7 +565,7 @@ public class LogicalOlapScan extends LogicalCatalogRelation
implements OlapScan,
* withSelectedPartitionIds
*/
public LogicalOlapScan withSelectedPartitionIds(List<Long>
selectedPartitionIds) {
- return withSelectedPartitionIds(selectedPartitionIds, false);
+ return withSelectedPartitionIds(selectedPartitionIds,
hasPartitionPredicate);
}
/**
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapTableStreamScan.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapTableStreamScan.java
index 2378719d692..4630d4236ed 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapTableStreamScan.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapTableStreamScan.java
@@ -315,7 +315,7 @@ public class LogicalOlapTableStreamScan extends
LogicalOlapScan {
*/
@Override
public LogicalOlapTableStreamScan withSelectedPartitionIds(List<Long>
selectedPartitionIdsd) {
- return withSelectedPartitionIds(selectedPartitionIdsd, false);
+ return withSelectedPartitionIds(selectedPartitionIdsd,
hasPartitionPredicate);
}
/**
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScanTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScanTest.java
index a1e1570e415..0195f136968 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScanTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScanTest.java
@@ -244,4 +244,23 @@ public class LogicalOlapScanTest {
Assertions.assertNotSame(scan1, snapshot);
}
+ @Test
+ public void
testWithSelectedPartitionIdsPreservesPartitionPredicateFlagForAllScanTypes() {
+ LogicalOlapScan scan = createMockScan(ImmutableList.of())
+ .withSelectedPartitionIds(ImmutableList.of(), true);
+
+ LogicalOlapScan copiedScan =
scan.withSelectedPartitionIds(ImmutableList.of());
+
+ Assertions.assertTrue(copiedScan.hasPartitionPredicate());
+
+ OlapTableStream stream = Mockito.mock(OlapTableStream.class);
+ LogicalOlapTableStreamScan streamScan = (LogicalOlapTableStreamScan)
scan
+ .withPreSnapshot(Optional.of(stream));
+ streamScan = streamScan.withSelectedPartitionIds(ImmutableList.of(),
true);
+
+ LogicalOlapTableStreamScan copiedStreamScan =
streamScan.withSelectedPartitionIds(ImmutableList.of());
+
+ Assertions.assertTrue(copiedStreamScan.hasPartitionPredicate());
+ }
+
}
diff --git
a/regression-test/suites/sql_block_rule_p0/test_sql_block_rule.groovy
b/regression-test/suites/sql_block_rule_p0/test_sql_block_rule.groovy
index 29645fe9ed5..b4898dc7e64 100644
--- a/regression-test/suites/sql_block_rule_p0/test_sql_block_rule.groovy
+++ b/regression-test/suites/sql_block_rule_p0/test_sql_block_rule.groovy
@@ -211,7 +211,7 @@ suite("test_sql_block_rule", "nonConcurrent") {
"""
sql """
- INSERT INTO a_partitioned_table_for_sql_block_rule VALUES(1, 5,
11),(6,1,5),(11,8,5);
+ INSERT INTO a_partitioned_table_for_sql_block_rule VALUES(1, 5,
11),(11,8,5);
"""
sql """
@@ -257,6 +257,15 @@ suite("test_sql_block_rule", "nonConcurrent") {
assertEquals(1, filteredPartitionRows.size())
assertEquals("1", filteredPartitionRows[0][0].toString())
+ def filteredRowsIncludingEmptyPartition = sql """
+ SELECT id
+ FROM a_partitioned_table_for_sql_block_rule
+ WHERE id < 10
+ ORDER BY id
+ """
+ assertEquals(1, filteredRowsIncludingEmptyPartition.size())
+ assertEquals("1", filteredRowsIncludingEmptyPartition[0][0].toString())
+
def explicitlySelectedPartitionRows = sql """
SELECT id
FROM a_partitioned_table_for_sql_block_rule PARTITION(p1)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]