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 ;
@@ -18,23 +25,30 @@ use vortex_array::expr::lit;
1825use vortex_array:: expr:: root;
1926use vortex_error:: VortexResult ;
2027use vortex_error:: vortex_err;
28+ use vortex_io:: runtime:: single:: block_on;
29+ use vortex_io:: session:: RuntimeSessionExt ;
2130use vortex_session:: registry:: CachedId ;
2231use vortex_session:: registry:: ReadContext ;
2332
2433use super :: * ;
2534use crate :: LayoutBuildContext ;
2635use crate :: LayoutEncoding ;
2736use crate :: LayoutRef ;
37+ use crate :: LayoutStrategy ;
2838use crate :: OwnedLayoutChildren ;
2939use crate :: layouts:: chunked:: ChunkedLayout ;
3040use crate :: layouts:: dict:: DictLayout ;
3141use crate :: layouts:: flat:: FlatLayout ;
42+ use crate :: layouts:: flat:: writer:: FlatLayoutStrategy ;
3243use crate :: layouts:: foreign:: new_foreign_layout;
3344use crate :: layouts:: row_idx:: row_idx;
3445use crate :: layouts:: struct_:: StructLayout ;
3546use crate :: layouts:: zoned:: LegacyStatsLayoutEncoding ;
3647use crate :: layouts:: zoned:: ZonedLayout ;
3748use crate :: segments:: SegmentId ;
49+ use crate :: segments:: TestSegments ;
50+ use crate :: sequence:: SequenceId ;
51+ use crate :: sequence:: SequentialArrayStreamExt ;
3852
3953fn primitive ( ptype : PType , nullability : Nullability ) -> DType {
4054 DType :: Primitive ( ptype, nullability)
@@ -437,6 +451,71 @@ fn multi_field_struct_expression_pushes_into_each_field() -> VortexResult<()> {
437451 Ok ( ( ) )
438452}
439453
454+ #[ test]
455+ fn multi_field_struct_expression_does_not_read_unused_fields ( ) -> VortexResult < ( ) > {
456+ block_on ( |handle| async move {
457+ let session = crate :: test:: new_session ( ) . with_handle ( handle) ;
458+ let segments = Arc :: new ( TestSegments :: default ( ) ) ;
459+ let strategy = FlatLayoutStrategy :: default ( ) ;
460+
461+ let ( a_sequence, a_eof) = SequenceId :: root ( ) . split ( ) ;
462+ let a = strategy
463+ . write_stream (
464+ ArrayContext :: empty ( ) . into ( ) ,
465+ Arc :: < TestSegments > :: clone ( & segments) ,
466+ PrimitiveArray :: from_iter ( [ 1_i32 , 6 , 8 ] )
467+ . into_array ( )
468+ . to_array_stream ( )
469+ . sequenced ( a_sequence) ,
470+ a_eof,
471+ & session,
472+ )
473+ . await ?;
474+ let ( b_sequence, b_eof) = SequenceId :: root ( ) . split ( ) ;
475+ let b = strategy
476+ . write_stream (
477+ ArrayContext :: empty ( ) . into ( ) ,
478+ Arc :: < TestSegments > :: clone ( & segments) ,
479+ PrimitiveArray :: from_iter ( [ 10_i32 , 8 , 9 ] )
480+ . into_array ( )
481+ . to_array_stream ( )
482+ . sequenced ( b_sequence) ,
483+ b_eof,
484+ & session,
485+ )
486+ . await ?;
487+
488+ let value_dtype = primitive ( PType :: I32 , Nullability :: NonNullable ) ;
489+ let layout = StructLayout :: new (
490+ 3 ,
491+ DType :: Struct (
492+ StructFields :: from_iter ( [
493+ ( "a" , value_dtype. clone ( ) ) ,
494+ ( "b" , value_dtype. clone ( ) ) ,
495+ ( "c" , value_dtype. clone ( ) ) ,
496+ ] ) ,
497+ Nullability :: NonNullable ,
498+ ) ,
499+ vec ! [ a, b, flat( 3 , value_dtype, 2 ) ] ,
500+ )
501+ . into_layout ( ) ;
502+ let expression = and (
503+ gt ( get_item ( "a" , root ( ) ) , lit ( 5_i32 ) ) ,
504+ gt ( get_item ( "b" , root ( ) ) , lit ( 7_i32 ) ) ,
505+ ) ;
506+ let optimized = ExpressionPlan :: try_new ( expression, make_plan ( layout) ?) ?. optimize ( ) ?;
507+ let execution = PlanExecutionContext :: new ( segments, session. clone ( ) ) ;
508+
509+ let actual = optimized
510+ . execute ( & execution, & ( 0 ..3 ) , MaskFuture :: new_true ( 3 ) ) ?
511+ . await ?;
512+ let expected = BoolArray :: from_iter ( [ false , true , true ] ) . into_array ( ) ;
513+
514+ assert_arrays_eq ! ( actual, expected, & mut session. create_execution_ctx( ) ) ;
515+ Ok ( ( ) )
516+ } )
517+ }
518+
440519#[ test]
441520fn multi_field_struct_expression_keeps_cross_field_refinement ( ) -> VortexResult < ( ) > {
442521 let value_dtype = primitive ( PType :: I32 , Nullability :: NonNullable ) ;
0 commit comments