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]

Reply via email to