44use std:: num:: NonZeroUsize ;
55use std:: sync:: Arc ;
66
7+ use vortex_array:: ArrayContext ;
8+ use vortex_array:: IntoArray ;
9+ use vortex_array:: MaskFuture ;
10+ use vortex_array:: VortexSessionExecute ;
711use vortex_array:: aggregate_fn:: AggregateFnRef ;
12+ use vortex_array:: arrays:: BoolArray ;
13+ use vortex_array:: arrays:: PrimitiveArray ;
14+ use vortex_array:: assert_arrays_eq;
815use vortex_array:: dtype:: DType ;
916use vortex_array:: dtype:: Nullability ;
1017use vortex_array:: dtype:: PType ;
@@ -19,23 +26,30 @@ use vortex_array::expr::lit;
1926use vortex_array:: expr:: root;
2027use vortex_error:: VortexResult ;
2128use vortex_error:: vortex_err;
29+ use vortex_io:: runtime:: single:: block_on;
30+ use vortex_io:: session:: RuntimeSessionExt ;
2231use vortex_session:: registry:: CachedId ;
2332use vortex_session:: registry:: ReadContext ;
2433
2534use super :: * ;
2635use crate :: LayoutBuildContext ;
2736use crate :: LayoutEncoding ;
2837use crate :: LayoutRef ;
38+ use crate :: LayoutStrategy ;
2939use crate :: OwnedLayoutChildren ;
3040use crate :: layouts:: chunked:: ChunkedLayout ;
3141use crate :: layouts:: dict:: DictLayout ;
3242use crate :: layouts:: flat:: FlatLayout ;
43+ use crate :: layouts:: flat:: writer:: FlatLayoutStrategy ;
3344use crate :: layouts:: foreign:: new_foreign_layout;
3445use crate :: layouts:: row_idx:: row_idx;
3546use crate :: layouts:: struct_:: StructLayout ;
3647use crate :: layouts:: zoned:: LegacyStatsLayoutEncoding ;
3748use crate :: layouts:: zoned:: ZonedLayout ;
3849use crate :: segments:: SegmentId ;
50+ use crate :: segments:: TestSegments ;
51+ use crate :: sequence:: SequenceId ;
52+ use crate :: sequence:: SequentialArrayStreamExt ;
3953
4054fn primitive ( ptype : PType , nullability : Nullability ) -> DType {
4155 DType :: Primitive ( ptype, nullability)
@@ -447,6 +461,71 @@ fn multi_field_struct_expression_pushes_into_each_field() -> VortexResult<()> {
447461 Ok ( ( ) )
448462}
449463
464+ #[ test]
465+ fn multi_field_struct_expression_does_not_read_unused_fields ( ) -> VortexResult < ( ) > {
466+ block_on ( |handle| async move {
467+ let session = crate :: test:: new_session ( ) . with_handle ( handle) ;
468+ let segments = Arc :: new ( TestSegments :: default ( ) ) ;
469+ let strategy = FlatLayoutStrategy :: default ( ) ;
470+
471+ let ( a_sequence, a_eof) = SequenceId :: root ( ) . split ( ) ;
472+ let a = strategy
473+ . write_stream (
474+ ArrayContext :: empty ( ) . into ( ) ,
475+ Arc :: < TestSegments > :: clone ( & segments) ,
476+ PrimitiveArray :: from_iter ( [ 1_i32 , 6 , 8 ] )
477+ . into_array ( )
478+ . to_array_stream ( )
479+ . sequenced ( a_sequence) ,
480+ a_eof,
481+ & session,
482+ )
483+ . await ?;
484+ let ( b_sequence, b_eof) = SequenceId :: root ( ) . split ( ) ;
485+ let b = strategy
486+ . write_stream (
487+ ArrayContext :: empty ( ) . into ( ) ,
488+ Arc :: < TestSegments > :: clone ( & segments) ,
489+ PrimitiveArray :: from_iter ( [ 10_i32 , 8 , 9 ] )
490+ . into_array ( )
491+ . to_array_stream ( )
492+ . sequenced ( b_sequence) ,
493+ b_eof,
494+ & session,
495+ )
496+ . await ?;
497+
498+ let value_dtype = primitive ( PType :: I32 , Nullability :: NonNullable ) ;
499+ let layout = StructLayout :: new (
500+ 3 ,
501+ DType :: Struct (
502+ StructFields :: from_iter ( [
503+ ( "a" , value_dtype. clone ( ) ) ,
504+ ( "b" , value_dtype. clone ( ) ) ,
505+ ( "c" , value_dtype. clone ( ) ) ,
506+ ] ) ,
507+ Nullability :: NonNullable ,
508+ ) ,
509+ vec ! [ a, b, flat( 3 , value_dtype, 2 ) ] ,
510+ )
511+ . into_layout ( ) ;
512+ let expression = and (
513+ gt ( get_item ( "a" , root ( ) ) , lit ( 5_i32 ) ) ,
514+ gt ( get_item ( "b" , root ( ) ) , lit ( 7_i32 ) ) ,
515+ ) ;
516+ let optimized = make_expression_plan ( expression, make_plan ( layout) ?) ?. optimize ( ) ?;
517+ let execution = PlanExecutionContext :: new ( segments, session. clone ( ) ) ;
518+
519+ let actual = optimized
520+ . execute ( & execution, & ( 0 ..3 ) , MaskFuture :: new_true ( 3 ) ) ?
521+ . await ?;
522+ let expected = BoolArray :: from_iter ( [ false , true , true ] ) . into_array ( ) ;
523+
524+ assert_arrays_eq ! ( actual, expected, & mut session. create_execution_ctx( ) ) ;
525+ Ok ( ( ) )
526+ } )
527+ }
528+
450529#[ test]
451530fn multi_field_struct_expression_keeps_cross_field_refinement ( ) -> VortexResult < ( ) > {
452531 let value_dtype = primitive ( PType :: I32 , Nullability :: NonNullable ) ;
0 commit comments