@@ -70,8 +70,10 @@ use datafusion_physical_expr::create_physical_expr;
7070use datafusion_physical_expr:: expression_analyzer:: ExpressionAnalyzerRegistry ;
7171use datafusion_physical_expr_common:: physical_expr:: PhysicalExpr ;
7272use datafusion_physical_optimizer:: PhysicalOptimizerRule ;
73+ use datafusion_physical_optimizer:: PhysicalOptimizerContext ;
7374use datafusion_physical_optimizer:: optimizer:: PhysicalOptimizer ;
7475use datafusion_physical_plan:: ExecutionPlan ;
76+ use datafusion_physical_plan:: operator_statistics:: StatisticsRegistry ;
7577use datafusion_session:: Session ;
7678#[ cfg( feature = "sql" ) ]
7779use datafusion_sql:: {
@@ -194,11 +196,27 @@ pub struct SessionState {
194196 /// thus, changing dialect o PostgreSql is required
195197 function_factory : Option < Arc < dyn FunctionFactory > > ,
196198 cache_factory : Option < Arc < dyn CacheFactory > > ,
199+ /// Optional statistics registry for pluggable statistics providers.
200+ ///
201+ /// When set, physical optimizer rules can use this registry to obtain
202+ /// enhanced statistics (e.g., NDV overrides, histograms) beyond what
203+ /// is available from `ExecutionPlan::partition_statistics()`.
204+ statistics_registry : Option < StatisticsRegistry > ,
197205 /// Cache logical plans of prepared statements for later execution.
198206 /// Key is the prepared statement name.
199207 prepared_plans : HashMap < String , Arc < PreparedPlan > > ,
200208}
201209
210+ impl PhysicalOptimizerContext for SessionState {
211+ fn config_options ( & self ) -> & ConfigOptions {
212+ self . config_options ( )
213+ }
214+
215+ fn statistics_registry ( & self ) -> Option < & StatisticsRegistry > {
216+ self . statistics_registry . as_ref ( )
217+ }
218+ }
219+
202220impl Debug for SessionState {
203221 /// Prefer having short fields at the top and long vector fields near the end
204222 /// Group fields by
@@ -824,6 +842,14 @@ impl SessionState {
824842 self . config . options ( )
825843 }
826844
845+ /// Returns the statistics registry if one is configured.
846+ ///
847+ /// The registry provides pluggable statistics providers for enhanced
848+ /// cardinality estimation (e.g., NDV overrides, histograms).
849+ pub fn statistics_registry ( & self ) -> Option < & StatisticsRegistry > {
850+ self . statistics_registry . as_ref ( )
851+ }
852+
827853 /// Mark the start of the execution
828854 pub fn mark_start_execution ( & mut self ) {
829855 let config = Arc :: clone ( self . config . options ( ) ) ;
@@ -1019,6 +1045,7 @@ pub struct SessionStateBuilder {
10191045 runtime_env : Option < Arc < RuntimeEnv > > ,
10201046 function_factory : Option < Arc < dyn FunctionFactory > > ,
10211047 cache_factory : Option < Arc < dyn CacheFactory > > ,
1048+ statistics_registry : Option < StatisticsRegistry > ,
10221049 // fields to support convenience functions
10231050 analyzer_rules : Option < Vec < Arc < dyn AnalyzerRule + Send + Sync > > > ,
10241051 optimizer_rules : Option < Vec < Arc < dyn OptimizerRule + Send + Sync > > > ,
@@ -1061,6 +1088,7 @@ impl SessionStateBuilder {
10611088 runtime_env : None ,
10621089 function_factory : None ,
10631090 cache_factory : None ,
1091+ statistics_registry : None ,
10641092 // fields to support convenience functions
10651093 analyzer_rules : None ,
10661094 optimizer_rules : None ,
@@ -1118,6 +1146,7 @@ impl SessionStateBuilder {
11181146 runtime_env : Some ( existing. runtime_env ) ,
11191147 function_factory : existing. function_factory ,
11201148 cache_factory : existing. cache_factory ,
1149+ statistics_registry : existing. statistics_registry ,
11211150 // fields to support convenience functions
11221151 analyzer_rules : None ,
11231152 optimizer_rules : None ,
@@ -1448,6 +1477,16 @@ impl SessionStateBuilder {
14481477 self
14491478 }
14501479
1480+ /// Set a [`StatisticsRegistry`] for pluggable statistics providers.
1481+ ///
1482+ /// The registry allows physical optimizer rules to access enhanced statistics
1483+ /// (e.g., NDV overrides, histograms) beyond what is available from
1484+ /// `ExecutionPlan::partition_statistics()`.
1485+ pub fn with_statistics_registry ( mut self , registry : StatisticsRegistry ) -> Self {
1486+ self . statistics_registry = Some ( registry) ;
1487+ self
1488+ }
1489+
14511490 /// Register an `ObjectStore` to the [`RuntimeEnv`]. See [`RuntimeEnv::register_object_store`]
14521491 /// for more details.
14531492 ///
@@ -1516,6 +1555,7 @@ impl SessionStateBuilder {
15161555 runtime_env,
15171556 function_factory,
15181557 cache_factory,
1558+ statistics_registry,
15191559 analyzer_rules,
15201560 optimizer_rules,
15211561 physical_optimizer_rules,
@@ -1558,6 +1598,7 @@ impl SessionStateBuilder {
15581598 runtime_env,
15591599 function_factory,
15601600 cache_factory,
1601+ statistics_registry,
15611602 prepared_plans : HashMap :: new ( ) ,
15621603 } ;
15631604
0 commit comments