@@ -68,9 +68,11 @@ use datafusion_optimizer::{
6868} ;
6969use datafusion_physical_expr:: create_physical_expr;
7070use datafusion_physical_expr_common:: physical_expr:: PhysicalExpr ;
71+ use datafusion_physical_optimizer:: PhysicalOptimizerContext ;
7172use datafusion_physical_optimizer:: PhysicalOptimizerRule ;
7273use datafusion_physical_optimizer:: optimizer:: PhysicalOptimizer ;
7374use datafusion_physical_plan:: ExecutionPlan ;
75+ use datafusion_physical_plan:: operator_statistics:: StatisticsRegistry ;
7476use datafusion_session:: Session ;
7577#[ cfg( feature = "sql" ) ]
7678use datafusion_sql:: {
@@ -191,11 +193,27 @@ pub struct SessionState {
191193 /// thus, changing dialect o PostgreSql is required
192194 function_factory : Option < Arc < dyn FunctionFactory > > ,
193195 cache_factory : Option < Arc < dyn CacheFactory > > ,
196+ /// Optional statistics registry for pluggable statistics providers.
197+ ///
198+ /// When set, physical optimizer rules can use this registry to obtain
199+ /// enhanced statistics (e.g., NDV overrides, histograms) beyond what
200+ /// is available from `ExecutionPlan::partition_statistics()`.
201+ statistics_registry : Option < StatisticsRegistry > ,
194202 /// Cache logical plans of prepared statements for later execution.
195203 /// Key is the prepared statement name.
196204 prepared_plans : HashMap < String , Arc < PreparedPlan > > ,
197205}
198206
207+ impl PhysicalOptimizerContext for SessionState {
208+ fn config_options ( & self ) -> & ConfigOptions {
209+ self . config_options ( )
210+ }
211+
212+ fn statistics_registry ( & self ) -> Option < & StatisticsRegistry > {
213+ self . statistics_registry . as_ref ( )
214+ }
215+ }
216+
199217impl Debug for SessionState {
200218 /// Prefer having short fields at the top and long vector fields near the end
201219 /// Group fields by
@@ -817,6 +835,14 @@ impl SessionState {
817835 self . config . options ( )
818836 }
819837
838+ /// Returns the statistics registry if one is configured.
839+ ///
840+ /// The registry provides pluggable statistics providers for enhanced
841+ /// cardinality estimation (e.g., NDV overrides, histograms).
842+ pub fn statistics_registry ( & self ) -> Option < & StatisticsRegistry > {
843+ self . statistics_registry . as_ref ( )
844+ }
845+
820846 /// Mark the start of the execution
821847 pub fn mark_start_execution ( & mut self ) {
822848 let config = Arc :: clone ( self . config . options ( ) ) ;
@@ -1006,6 +1032,7 @@ pub struct SessionStateBuilder {
10061032 runtime_env : Option < Arc < RuntimeEnv > > ,
10071033 function_factory : Option < Arc < dyn FunctionFactory > > ,
10081034 cache_factory : Option < Arc < dyn CacheFactory > > ,
1035+ statistics_registry : Option < StatisticsRegistry > ,
10091036 // fields to support convenience functions
10101037 analyzer_rules : Option < Vec < Arc < dyn AnalyzerRule + Send + Sync > > > ,
10111038 optimizer_rules : Option < Vec < Arc < dyn OptimizerRule + Send + Sync > > > ,
@@ -1047,6 +1074,7 @@ impl SessionStateBuilder {
10471074 runtime_env : None ,
10481075 function_factory : None ,
10491076 cache_factory : None ,
1077+ statistics_registry : None ,
10501078 // fields to support convenience functions
10511079 analyzer_rules : None ,
10521080 optimizer_rules : None ,
@@ -1103,6 +1131,7 @@ impl SessionStateBuilder {
11031131 runtime_env : Some ( existing. runtime_env ) ,
11041132 function_factory : existing. function_factory ,
11051133 cache_factory : existing. cache_factory ,
1134+ statistics_registry : existing. statistics_registry ,
11061135 // fields to support convenience functions
11071136 analyzer_rules : None ,
11081137 optimizer_rules : None ,
@@ -1424,6 +1453,16 @@ impl SessionStateBuilder {
14241453 self
14251454 }
14261455
1456+ /// Set a [`StatisticsRegistry`] for pluggable statistics providers.
1457+ ///
1458+ /// The registry allows physical optimizer rules to access enhanced statistics
1459+ /// (e.g., NDV overrides, histograms) beyond what is available from
1460+ /// `ExecutionPlan::partition_statistics()`.
1461+ pub fn with_statistics_registry ( mut self , registry : StatisticsRegistry ) -> Self {
1462+ self . statistics_registry = Some ( registry) ;
1463+ self
1464+ }
1465+
14271466 /// Register an `ObjectStore` to the [`RuntimeEnv`]. See [`RuntimeEnv::register_object_store`]
14281467 /// for more details.
14291468 ///
@@ -1491,6 +1530,7 @@ impl SessionStateBuilder {
14911530 runtime_env,
14921531 function_factory,
14931532 cache_factory,
1533+ statistics_registry,
14941534 analyzer_rules,
14951535 optimizer_rules,
14961536 physical_optimizer_rules,
@@ -1531,6 +1571,7 @@ impl SessionStateBuilder {
15311571 runtime_env,
15321572 function_factory,
15331573 cache_factory,
1574+ statistics_registry,
15341575 prepared_plans : HashMap :: new ( ) ,
15351576 } ;
15361577
0 commit comments