You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by gi...@apache.org on 2026/04/13 14:25:54 UTC

(datafusion) branch main updated: physical_optimizer: preserve_file_partitions when num file groups < target_partitions (#21533)

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

github-bot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new 0143dfe169 physical_optimizer: preserve_file_partitions when num file groups < target_partitions (#21533)
0143dfe169 is described below

commit 0143dfe1692a7a56a72c736041d93797ef651642
Author: Jayant Shrivastava <ja...@datadoghq.com>
AuthorDate: Mon Apr 13 10:19:26 2026 -0400

    physical_optimizer: preserve_file_partitions when num file groups < target_partitions (#21533)
    
    ## Rationale for this change
    
    `datafusion.optimizer.preserve_file_partitions` would not actually
    preserve the file partitions when the number of file groups is less than
    the target_partitions. This is unexpected behavior. If a user wants to
    preserve file partitions, it is because they want to avoid repartitions.
    
    Before
    ```
      ProjectionExec
        AggregateExec: mode=FinalPartitioned, gby=[f_dkey, timestamp]
          RepartitionExec: partitioning=Hash([f_dkey, timestamp], 4), input_partitions=3
            AggregateExec: mode=Partial, gby=[f_dkey, timestamp]
              DataSourceExec: file_groups=3, projection=[timestamp, value, f_dkey]
    ```
    After
    ```
      ProjectionExec
        AggregateExec: mode=SinglePartitioned, gby=[f_dkey, timestamp]
          DataSourceExec: file_groups=3, projection=[timestamp, value, f_dkey]
    ```
    
    ## What changes are included in this PR?
    
    This change fixes that by updating 1 line in the `enforce_distribution`
    optimizer rule.
    
    ## Are these changes tested?
    
    Yes. In the `preserve_file_partitions` SLT.
    
    ## Are there any user-facing changes?
    
    No.
---
 .../physical-optimizer/src/enforce_distribution.rs |  8 +++-
 .../test_files/preserve_file_partitioning.slt      | 54 ++++++++++++++++++++++
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/datafusion/physical-optimizer/src/enforce_distribution.rs b/datafusion/physical-optimizer/src/enforce_distribution.rs
index ea47c12030..87d0943610 100644
--- a/datafusion/physical-optimizer/src/enforce_distribution.rs
+++ b/datafusion/physical-optimizer/src/enforce_distribution.rs
@@ -1328,8 +1328,14 @@ pub fn ensure_distribution(
                 })
             );
 
-            let allow_subset_satisfy_partitioning = current_partitions
+            let allow_subset_satisfy_partitioning = (current_partitions
                 >= subset_satisfaction_threshold
+                // `preserve_file_partitions` exposes existing file-group
+                // partitioning to the optimizer. Respect it when the only
+                // reason to repartition would be to increase partition count
+                // beyond the preserved file-group count.
+                || (config.optimizer.preserve_file_partitions > 0
+                    && current_partitions < target_partitions))
                 && !is_partitioned_join
                 && !requires_grouping_id;
 
diff --git a/datafusion/sqllogictest/test_files/preserve_file_partitioning.slt b/datafusion/sqllogictest/test_files/preserve_file_partitioning.slt
index 48d99625ea..175d7d90cd 100644
--- a/datafusion/sqllogictest/test_files/preserve_file_partitioning.slt
+++ b/datafusion/sqllogictest/test_files/preserve_file_partitioning.slt
@@ -698,6 +698,60 @@ A dev 772.4
 B prod 614.4
 C prod 2017.6
 
+##########
+# TEST 13: Partitioned Join where Number of File Groups is less than target_partitions
+# With preserve_file_partitions enabled, we should still avoid repartitioning
+##########
+
+statement ok
+set datafusion.execution.target_partitions = 4;
+
+statement ok
+set datafusion.optimizer.preserve_file_partitions = 1;
+
+query TT
+EXPLAIN SELECT f_dkey, timestamp,
+       COUNT(*), AVG(value)
+FROM fact_table
+GROUP BY f_dkey, timestamp;
+----
+logical_plan
+01)Projection: fact_table.f_dkey, fact_table.timestamp, count(Int64(1)) AS count(*), avg(fact_table.value)
+02)--Aggregate: groupBy=[[fact_table.f_dkey, fact_table.timestamp]], aggr=[[count(Int64(1)), avg(fact_table.value)]]
+03)----TableScan: fact_table projection=[timestamp, value, f_dkey]
+physical_plan
+01)ProjectionExec: expr=[f_dkey@0 as f_dkey, timestamp@1 as timestamp, count(Int64(1))@2 as count(*), avg(fact_table.value)@3 as avg(fact_table.value)]
+02)--AggregateExec: mode=SinglePartitioned, gby=[f_dkey@2 as f_dkey, timestamp@0 as timestamp], aggr=[count(Int64(1)), avg(fact_table.value)]
+03)----DataSourceExec: file_groups={3 groups: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/preserve_file_partitioning/fact/f_dkey=A/data.parquet], [WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/preserve_file_partitioning/fact/f_dkey=B/data.parquet], [WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/preserve_file_partitioning/fact/f_dkey=C/data.parquet]]}, projection=[timestamp, value, f_dkey], file_type=parquet
+
+query TPIR rowsort
+SELECT f_dkey, timestamp,
+       COUNT(*), AVG(value)
+FROM fact_table
+GROUP BY f_dkey, timestamp;
+----
+A 2023-01-01T09:00:00 1 95.5
+A 2023-01-01T09:00:10 1 102.3
+A 2023-01-01T09:00:20 1 98.7
+A 2023-01-01T09:12:20 1 105.1
+A 2023-01-01T09:12:30 1 100
+A 2023-01-01T09:12:40 1 150
+A 2023-01-01T09:12:50 1 120.8
+B 2023-01-01T09:00:00 1 75.2
+B 2023-01-01T09:00:10 1 82.4
+B 2023-01-01T09:00:20 1 78.9
+B 2023-01-01T09:00:30 1 85.6
+B 2023-01-01T09:12:30 1 80
+B 2023-01-01T09:12:40 1 120
+B 2023-01-01T09:12:50 1 92.3
+C 2023-01-01T09:00:00 1 300.5
+C 2023-01-01T09:00:10 1 285.7
+C 2023-01-01T09:00:20 1 310.2
+C 2023-01-01T09:00:30 1 295.8
+C 2023-01-01T09:00:40 1 300
+C 2023-01-01T09:12:40 1 250
+C 2023-01-01T09:12:50 1 275.4
+
 ##########
 # CLEANUP
 ##########


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org