22// SPDX-FileCopyrightText: Copyright the Vortex contributors
33
44use std:: fmt;
5+ use std:: num:: NonZeroUsize ;
56use std:: sync:: Arc ;
67
8+ use vortex_array:: aggregate_fn:: AggregateFnRef ;
79use vortex_array:: dtype:: DType ;
810use vortex_array:: dtype:: Nullability ;
911use vortex_array:: dtype:: PType ;
@@ -22,6 +24,8 @@ use vortex_session::registry::CachedId;
2224use vortex_session:: registry:: ReadContext ;
2325
2426use super :: * ;
27+ use crate :: LayoutBuildContext ;
28+ use crate :: LayoutEncoding ;
2529use crate :: LayoutRef ;
2630use crate :: OwnedLayoutChildren ;
2731use crate :: layouts:: chunked:: ChunkedLayout ;
@@ -31,6 +35,8 @@ use crate::layouts::foreign::new_foreign_layout;
3135use crate :: layouts:: list:: ListLayout ;
3236use crate :: layouts:: row_idx:: row_idx;
3337use crate :: layouts:: struct_:: StructLayout ;
38+ use crate :: layouts:: zoned:: LegacyStatsLayoutEncoding ;
39+ use crate :: layouts:: zoned:: ZonedLayout ;
3440use crate :: segments:: SegmentId ;
3541
3642fn primitive ( ptype : PType , nullability : Nullability ) -> DType {
@@ -852,3 +858,61 @@ fn nullable_struct_keeps_expression_above_parent_validity() -> VortexResult<()>
852858 assert ! ( eval. child_plan( ) . is:: <Pack >( ) ) ;
853859 Ok ( ( ) )
854860}
861+
862+ #[ test]
863+ fn zoned_plan_exposes_data_and_zones ( ) -> VortexResult < ( ) > {
864+ let dtype = primitive ( PType :: I32 , Nullability :: NonNullable ) ;
865+ let zones_dtype = DType :: Struct ( StructFields :: empty ( ) , Nullability :: NonNullable ) ;
866+ let zone_len = NonZeroUsize :: new ( 3 ) . ok_or_else ( || vortex_err ! ( "zone length is zero" ) ) ?;
867+ let aggregate_fns: Arc < [ AggregateFnRef ] > = Vec :: new ( ) . into ( ) ;
868+ let layout = ZonedLayout :: try_new (
869+ flat ( 5 , dtype, 0 ) ,
870+ flat ( 2 , zones_dtype, 1 ) ,
871+ zone_len,
872+ aggregate_fns,
873+ ) ?
874+ . into_layout ( ) ;
875+
876+ let plan = make_plan ( layout) ?;
877+ assert ! ( plan. is:: <Zoned >( ) ) ;
878+ insta:: assert_snapshot!( plan. display_tree( ) , @"
879+ root: vortex.plan.zoned(i32, rows=5)
880+ data: vortex.plan.segment_scan(i32, rows=5)
881+ zones: vortex.plan.segment_scan({}, rows=2)
882+ " ) ;
883+ Ok ( ( ) )
884+ }
885+
886+ #[ test]
887+ fn legacy_stats_layout_uses_zoned_plan ( ) -> VortexResult < ( ) > {
888+ let dtype = primitive ( PType :: I32 , Nullability :: NonNullable ) ;
889+ let zones_dtype = DType :: Struct ( StructFields :: empty ( ) , Nullability :: NonNullable ) ;
890+ let children = OwnedLayoutChildren :: layout_children ( vec ! [
891+ flat( 5 , dtype. clone( ) , 0 ) ,
892+ flat( 2 , zones_dtype, 1 ) ,
893+ ] ) ;
894+ let session = vortex_array:: array_session ( ) ;
895+ let read_ctx = ReadContext :: new ( [ ] ) ;
896+ let build_ctx = LayoutBuildContext {
897+ session : & session,
898+ array_read_ctx : & read_ctx,
899+ } ;
900+ let layout = LayoutEncoding :: build (
901+ & LegacyStatsLayoutEncoding ,
902+ & dtype,
903+ 5 ,
904+ & 3_u32 . to_le_bytes ( ) ,
905+ Vec :: new ( ) ,
906+ children. as_ref ( ) ,
907+ & build_ctx,
908+ ) ?;
909+
910+ let plan = make_plan ( layout) ?;
911+ assert ! ( plan. is:: <Zoned >( ) ) ;
912+ insta:: assert_snapshot!( plan. display_tree( ) , @"
913+ root: vortex.plan.zoned(i32, rows=5)
914+ data: vortex.plan.segment_scan(i32, rows=5)
915+ zones: vortex.plan.segment_scan({}, rows=2)
916+ " ) ;
917+ Ok ( ( ) )
918+ }
0 commit comments