@@ -296,12 +296,26 @@ impl SparkPhysicalExprAdapter {
296296 ) -> DataFusionResult < Arc < dyn PhysicalExpr > > {
297297 expr. transform ( |e| {
298298 if let Some ( column) = e. as_any ( ) . downcast_ref :: < Column > ( ) {
299- let col_idx = column. index ( ) ;
300299 let col_name = column. name ( ) ;
301300
302- let logical_field = self . logical_file_schema . fields ( ) . get ( col_idx) ;
303- // Look up physical field by name instead of index for correctness
304- // when logical and physical schemas have different column orderings
301+ // Resolve fields by name because this is the fallback path
302+ // that runs on the original expression when the default
303+ // adapter fails. The original expression was built against
304+ // the required (pruned) schema, so column indices refer to
305+ // that schema — not the logical or physical file schemas.
306+ // DataFusion's DefaultPhysicalExprAdapter::resolve_physical_column
307+ // also resolves by name for the same reason.
308+ let logical_field = if self . parquet_options . case_sensitive {
309+ self . logical_file_schema
310+ . fields ( )
311+ . iter ( )
312+ . find ( |f| f. name ( ) == col_name)
313+ } else {
314+ self . logical_file_schema
315+ . fields ( )
316+ . iter ( )
317+ . find ( |f| f. name ( ) . eq_ignore_ascii_case ( col_name) )
318+ } ;
305319 let physical_field = if self . parquet_options . case_sensitive {
306320 self . physical_file_schema
307321 . fields ( )
@@ -314,19 +328,40 @@ impl SparkPhysicalExprAdapter {
314328 . find ( |f| f. name ( ) . eq_ignore_ascii_case ( col_name) )
315329 } ;
316330
317- if let ( Some ( logical_field) , Some ( physical_field) ) = ( logical_field, physical_field)
331+ // Remap the column index to the physical file schema so
332+ // downstream evaluation reads the correct column from the
333+ // parquet batch.
334+ let physical_index = if self . parquet_options . case_sensitive {
335+ self . physical_file_schema . index_of ( col_name) . ok ( )
336+ } else {
337+ self . physical_file_schema
338+ . fields ( )
339+ . iter ( )
340+ . position ( |f| f. name ( ) . eq_ignore_ascii_case ( col_name) )
341+ } ;
342+
343+ if let ( Some ( logical_field) , Some ( physical_field) , Some ( phys_idx) ) =
344+ ( logical_field, physical_field, physical_index)
318345 {
346+ let remapped: Arc < dyn PhysicalExpr > = if column. index ( ) != phys_idx {
347+ Arc :: new ( Column :: new ( col_name, phys_idx) )
348+ } else {
349+ Arc :: clone ( & e)
350+ } ;
351+
319352 if logical_field. data_type ( ) != physical_field. data_type ( ) {
320353 let cast_expr: Arc < dyn PhysicalExpr > = Arc :: new (
321354 CometCastColumnExpr :: new (
322- Arc :: clone ( & e ) ,
355+ remapped ,
323356 Arc :: clone ( physical_field) ,
324357 Arc :: clone ( logical_field) ,
325358 None ,
326359 )
327360 . with_parquet_options ( self . parquet_options . clone ( ) ) ,
328361 ) ;
329362 return Ok ( Transformed :: yes ( cast_expr) ) ;
363+ } else if column. index ( ) != phys_idx {
364+ return Ok ( Transformed :: yes ( remapped) ) ;
330365 }
331366 }
332367 }
0 commit comments