@@ -25,8 +25,6 @@ use crate::{
25
25
apply_file_schema_type_coercions, coerce_int96_to_resolution, row_filter,
26
26
ParquetAccessPlan , ParquetFileMetrics , ParquetFileReaderFactory ,
27
27
} ;
28
- use arrow:: compute:: can_cast_types;
29
- use datafusion_common:: tree_node:: { Transformed , TransformedResult , TreeNode } ;
30
28
use datafusion_datasource:: file_meta:: FileMeta ;
31
29
use datafusion_datasource:: file_stream:: { FileOpenFuture , FileOpener } ;
32
30
use datafusion_datasource:: schema_adapter:: SchemaAdapterFactory ;
@@ -539,7 +537,7 @@ fn should_enable_page_index(
539
537
. unwrap_or ( false )
540
538
}
541
539
542
- use datafusion_physical_expr:: expressions ;
540
+ use datafusion_physical_expr:: PhysicalExprSchemaRewriter ;
543
541
544
542
/// Given a [`PhysicalExpr`] and a [`SchemaRef`], returns a new [`PhysicalExpr`] that
545
543
/// is cast to the specified data type.
@@ -553,68 +551,11 @@ pub fn cast_expr_to_schema(
553
551
partition_values : Vec < ScalarValue > ,
554
552
partition_fields : & [ FieldRef ] ,
555
553
) -> Result < Arc < dyn PhysicalExpr > > {
556
- expr. transform ( |expr| {
557
- if let Some ( column) = expr. as_any ( ) . downcast_ref :: < expressions:: Column > ( ) {
558
- let logical_field = match logical_file_schema. field_with_name ( column. name ( ) ) {
559
- Ok ( field) => field,
560
- Err ( e) => {
561
- // If the column is a partition field, we can use the partition value
562
- for ( partition_field, partition_value) in
563
- partition_fields. iter ( ) . zip ( partition_values. iter ( ) )
564
- {
565
- if partition_field. name ( ) == column. name ( ) {
566
- return Ok ( Transformed :: yes ( expressions:: lit (
567
- partition_value. clone ( ) ,
568
- ) ) ) ;
569
- }
570
- }
571
- // If the column is not found in the logical schema, return an error
572
- // This should probably never be hit unless something upstream broke, but nontheless it's better
573
- // for us to return a handleable error than to panic / do something unexpected.
574
- return Err ( e. into ( ) ) ;
575
- }
576
- } ;
577
- let Ok ( physical_field) = physical_file_schema. field_with_name ( column. name ( ) )
578
- else {
579
- if !logical_field. is_nullable ( ) {
580
- return exec_err ! (
581
- "Non-nullable column '{}' is missing from the physical schema" ,
582
- column. name( )
583
- ) ;
584
- }
585
- // If the column is missing from the physical schema fill it in with nulls as `SchemaAdapter` would do.
586
- // TODO: do we need to sync this with what the `SchemaAdapter` actually does?
587
- // While the default implementation fills in nulls in theory a custom `SchemaAdapter` could do something else!
588
- let value = ScalarValue :: Null . cast_to ( logical_field. data_type ( ) ) ?;
589
- return Ok ( Transformed :: yes ( expressions:: lit ( value) ) ) ;
590
- } ;
591
-
592
- if logical_field. data_type ( ) == physical_field. data_type ( ) {
593
- return Ok ( Transformed :: no ( expr) ) ;
594
- }
595
-
596
- // If the logical field and physical field are different, we need to cast
597
- // the column to the logical field's data type.
598
- // We will try later to move the cast to literal values if possible, which is computationally cheaper.
599
- if !can_cast_types ( logical_field. data_type ( ) , physical_field. data_type ( ) ) {
600
- return exec_err ! (
601
- "Cannot cast column '{}' from '{}' (file data type) to '{}' (table data type)" ,
602
- column. name( ) ,
603
- logical_field. data_type( ) ,
604
- physical_field. data_type( )
605
- ) ;
606
- }
607
- let casted_expr = Arc :: new ( expressions:: CastExpr :: new (
608
- expr,
609
- logical_field. data_type ( ) . clone ( ) ,
610
- None ,
611
- ) ) ;
612
- return Ok ( Transformed :: yes ( casted_expr) ) ;
613
- }
554
+ let rewriter =
555
+ PhysicalExprSchemaRewriter :: new ( physical_file_schema, logical_file_schema)
556
+ . with_partition_columns ( partition_fields. to_vec ( ) , partition_values) ;
614
557
615
- Ok ( Transformed :: no ( expr) )
616
- } )
617
- . data ( )
558
+ rewriter. rewrite ( expr)
618
559
}
619
560
620
561
#[ cfg( test) ]
0 commit comments