@@ -48,6 +48,7 @@ use datafusion_execution::{
4848use datafusion_expr:: {
4949 dml:: InsertOp , Expr , SortExpr , TableProviderFilterPushDown , TableType ,
5050} ;
51+ use datafusion_physical_expr:: schema_rewriter:: PhysicalExprAdapterFactory ;
5152use datafusion_physical_expr_common:: sort_expr:: LexOrdering ;
5253use datafusion_physical_plan:: { empty:: EmptyExec , ExecutionPlan , Statistics } ;
5354use futures:: { future, stream, Stream , StreamExt , TryStreamExt } ;
@@ -99,6 +100,8 @@ pub struct ListingTableConfig {
99100 schema_source : SchemaSource ,
100101 /// Optional [`SchemaAdapterFactory`] for creating schema adapters
101102 schema_adapter_factory : Option < Arc < dyn SchemaAdapterFactory > > ,
103+ /// Optional [`PhysicalExprAdapterFactory`] for creating physical expression adapters
104+ physical_expr_adapter_factory : Option < Arc < dyn PhysicalExprAdapterFactory > > ,
102105}
103106
104107impl ListingTableConfig {
@@ -281,6 +284,7 @@ impl ListingTableConfig {
281284 options : Some ( listing_options) ,
282285 schema_source : self . schema_source ,
283286 schema_adapter_factory : self . schema_adapter_factory ,
287+ physical_expr_adapter_factory : self . physical_expr_adapter_factory ,
284288 } )
285289 }
286290
@@ -300,6 +304,7 @@ impl ListingTableConfig {
300304 options : _,
301305 schema_source,
302306 schema_adapter_factory,
307+ physical_expr_adapter_factory,
303308 } = self ;
304309
305310 let ( schema, new_schema_source) = match file_schema {
@@ -322,6 +327,7 @@ impl ListingTableConfig {
322327 options : Some ( options) ,
323328 schema_source : new_schema_source,
324329 schema_adapter_factory,
330+ physical_expr_adapter_factory,
325331 } )
326332 }
327333 None => internal_err ! ( "No `ListingOptions` set for inferring schema" ) ,
@@ -364,6 +370,7 @@ impl ListingTableConfig {
364370 options : Some ( options) ,
365371 schema_source : self . schema_source ,
366372 schema_adapter_factory : self . schema_adapter_factory ,
373+ physical_expr_adapter_factory : self . physical_expr_adapter_factory ,
367374 } )
368375 }
369376 None => config_err ! ( "No `ListingOptions` set for inferring schema" ) ,
@@ -415,6 +422,26 @@ impl ListingTableConfig {
415422 pub fn schema_adapter_factory ( & self ) -> Option < & Arc < dyn SchemaAdapterFactory > > {
416423 self . schema_adapter_factory . as_ref ( )
417424 }
425+
426+ /// Set the [`PhysicalExprAdapterFactory`] for the [`ListingTable`]
427+ ///
428+ /// The expression adapter factory is used to create physical expression adapters that can
429+ /// handle schema evolution and type conversions when evaluating expressions
430+ /// with different schemas than the table schema.
431+ ///
432+ /// If not provided, a default physical expression adapter factory will be used unless a custom
433+ /// `SchemaAdapterFactory` is set, in which case only the `SchemaAdapterFactory` will be used.
434+ ///
435+ /// See <https://github.com/apache/datafusion/issues/16800> for details on this transition.
436+ pub fn with_physical_expr_adapter_factory (
437+ self ,
438+ physical_expr_adapter_factory : Arc < dyn PhysicalExprAdapterFactory > ,
439+ ) -> Self {
440+ Self {
441+ physical_expr_adapter_factory : Some ( physical_expr_adapter_factory) ,
442+ ..self
443+ }
444+ }
418445}
419446
420447/// Options for creating a [`ListingTable`]
@@ -911,6 +938,8 @@ pub struct ListingTable {
911938 column_defaults : HashMap < String , Expr > ,
912939 /// Optional [`SchemaAdapterFactory`] for creating schema adapters
913940 schema_adapter_factory : Option < Arc < dyn SchemaAdapterFactory > > ,
941+ /// Optional [`PhysicalExprAdapterFactory`] for creating physical expression adapters
942+ expr_adapter_factory : Option < Arc < dyn PhysicalExprAdapterFactory > > ,
914943}
915944
916945impl ListingTable {
@@ -952,6 +981,7 @@ impl ListingTable {
952981 constraints : Constraints :: default ( ) ,
953982 column_defaults : HashMap :: new ( ) ,
954983 schema_adapter_factory : config. schema_adapter_factory ,
984+ expr_adapter_factory : config. physical_expr_adapter_factory ,
955985 } ;
956986
957987 Ok ( table)
@@ -1196,6 +1226,7 @@ impl TableProvider for ListingTable {
11961226 . with_limit ( limit)
11971227 . with_output_ordering ( output_ordering)
11981228 . with_table_partition_cols ( table_partition_cols)
1229+ . with_expr_adapter ( self . expr_adapter_factory . clone ( ) )
11991230 . build ( ) ,
12001231 )
12011232 . await
0 commit comments