@@ -520,15 +520,13 @@ impl ExprSchemable for Expr {
520520 metadata,
521521 ..
522522 } ) => {
523- let mut combined_metadata = expr. metadata ( schema) ?;
523+ let field = expr. to_field ( schema) ?. 1 ;
524+ let mut combined_metadata = FieldMetadata :: from ( field. metadata ( ) ) ;
524525 if let Some ( metadata) = metadata {
525526 combined_metadata. extend ( metadata. clone ( ) ) ;
526527 }
527528
528- Ok ( expr
529- . to_field ( schema)
530- . map ( |( _, f) | f) ?
531- . with_field_metadata ( & combined_metadata) )
529+ Ok ( field. with_field_metadata ( & combined_metadata) )
532530 }
533531 Expr :: Negative ( expr) => expr. to_field ( schema) . map ( |( _, f) | f) ,
534532 Expr :: Column ( c) => schema. field_from_column ( c) . map ( Arc :: clone) ,
@@ -1150,6 +1148,54 @@ mod tests {
11501148 assert_eq ! ( expr. metadata( & schema) . unwrap( ) , alias_metadata) ;
11511149 }
11521150
1151+ #[ test]
1152+ fn test_nested_alias_resolves_child_field_once ( ) -> Result < ( ) > {
1153+ #[ derive( Debug ) ]
1154+ struct CountingSchema {
1155+ field : FieldRef ,
1156+ lookups : std:: cell:: Cell < usize > ,
1157+ }
1158+
1159+ impl ExprSchema for CountingSchema {
1160+ fn nullable ( & self , _col : & Column ) -> Result < bool > {
1161+ Ok ( self . field . is_nullable ( ) )
1162+ }
1163+
1164+ fn field_from_column ( & self , _col : & Column ) -> Result < & FieldRef > {
1165+ self . lookups . set ( self . lookups . get ( ) + 1 ) ;
1166+ Ok ( & self . field )
1167+ }
1168+ }
1169+
1170+ let schema = CountingSchema {
1171+ field : Arc :: new ( Field :: new ( "value" , DataType :: Int32 , false ) . with_metadata (
1172+ HashMap :: from ( [
1173+ ( "override" . to_string ( ) , "base" . to_string ( ) ) ,
1174+ ( "keep" . to_string ( ) , "base" . to_string ( ) ) ,
1175+ ] ) ,
1176+ ) ) ,
1177+ lookups : std:: cell:: Cell :: new ( 0 ) ,
1178+ } ;
1179+ let mut expr = col ( "value" ) ;
1180+ for index in 0 ..12 {
1181+ let Expr :: Alias ( alias) = expr. alias ( format ! ( "alias_{index}" ) ) else {
1182+ unreachable ! ( ) ;
1183+ } ;
1184+ expr = Expr :: Alias ( alias. with_metadata ( Some ( FieldMetadata :: from (
1185+ HashMap :: from ( [ ( "override" . to_string ( ) , index. to_string ( ) ) ] ) ,
1186+ ) ) ) ) ;
1187+ }
1188+
1189+ let field = expr. to_field ( & schema) ?. 1 ;
1190+ assert_eq ! ( schema. lookups. get( ) , 1 ) ;
1191+ assert_eq ! ( field. name( ) , "alias_11" ) ;
1192+ assert_eq ! ( field. data_type( ) , & DataType :: Int32 ) ;
1193+ assert ! ( !field. is_nullable( ) ) ;
1194+ assert_eq ! ( field. metadata( ) . get( "override" ) , Some ( & "11" . to_string( ) ) ) ;
1195+ assert_eq ! ( field. metadata( ) . get( "keep" ) , Some ( & "base" . to_string( ) ) ) ;
1196+ Ok ( ( ) )
1197+ }
1198+
11531199 #[ test]
11541200 fn test_expr_placeholder ( ) {
11551201 let schema = MockExprSchema :: new ( ) ;
0 commit comments