@@ -14,6 +14,7 @@ mod reader;
1414pub mod writer;
1515
1616use std:: sync:: Arc ;
17+ use std:: sync:: LazyLock ;
1718use std:: sync:: OnceLock ;
1819
1920use futures:: FutureExt ;
@@ -38,15 +39,17 @@ use vortex_array::dtype::StructFields;
3839use vortex_array:: expr:: root;
3940use vortex_array:: serde:: BUFFER_COLUMNS_DTYPE ;
4041use vortex_array:: serde:: ColumnarArrayTree ;
41- use vortex_array:: serde:: NODES_COLUMNS_DTYPE ;
42+ use vortex_array:: serde:: DEFAULT_STATS ;
4243use vortex_array:: serde:: StatsColumns ;
44+ use vortex_array:: serde:: nodes_columns_dtype;
4345use vortex_error:: SharedVortexResult ;
4446use vortex_error:: VortexExpect ;
4547use vortex_error:: VortexResult ;
4648use vortex_error:: vortex_bail;
4749use vortex_error:: vortex_err;
4850use vortex_error:: vortex_panic;
4951use vortex_session:: VortexSession ;
52+ use vortex_session:: registry:: Id ;
5053use vortex_session:: registry:: ReadContext ;
5154use vortex_utils:: aliases:: hash_map:: HashMap ;
5255
@@ -69,6 +72,17 @@ use crate::vtable;
6972
7073vtable ! ( ArrayTree ) ;
7174
75+ /// Well-known [`LayoutReaderContext`] key under which [`ArrayTreeLayout::derive_reader_ctx`]
76+ /// publishes its [`ArrayTreesSource`].
77+ ///
78+ /// Both the publisher (parent [`ArrayTreeLayout`]) and the consumer
79+ /// ([`ArrayTreeFlatLayout`]'s `new_reader`) hardcode this id, so no metadata persistence is
80+ /// needed to bind them. Two stacked `ArrayTreeLayouts` both publish under this id; the
81+ /// inner one overrides the outer in the descendant's view — exactly the "nearest ancestor
82+ /// wins" semantic each `ArrayTreeFlat` leaf wants.
83+ pub static ARRAY_TREES_SOURCE_ID : LazyLock < Id > =
84+ LazyLock :: new ( || Id :: new_static ( "vortex.array_tree.source" ) ) ;
85+
7286/// Encoding marker for [`ArrayTreeLayout`].
7387#[ derive( Debug ) ]
7488pub struct ArrayTreeLayoutEncoding ;
@@ -109,10 +123,15 @@ impl ArrayTreeLayout {
109123 /// }
110124 /// ```
111125 ///
112- /// The List<> element types are exactly the canonical per-tree schemas defined by
113- /// [`vortex_array::serde::NODES_COLUMNS_DTYPE `] / [`vortex_array::serde::BUFFER_COLUMNS_DTYPE`],
114- /// so slicing one row's nodes (resp. buffers) yields a [`StructArray`] matching the inner
126+ /// The List<> element types are produced by
127+ /// [`vortex_array::serde::nodes_columns_dtype `] / [`vortex_array::serde::BUFFER_COLUMNS_DTYPE`].
128+ /// Slicing one row's nodes (resp. buffers) yields a [`StructArray`] matching the inner
115129 /// shape of a [`ColumnarArrayTree`].
130+ ///
131+ /// The `nodes` schema is parameterized by the stat menu the layout tracks; today this
132+ /// defaults to [`vortex_array::serde::DEFAULT_STATS`] (the historical 11-stat set), but
133+ /// future writers can pick a different menu and the schema field names carry that menu
134+ /// across the wire.
116135 pub fn array_trees_dtype ( ) -> DType {
117136 let nn = Nullability :: NonNullable ;
118137 DType :: Struct (
@@ -125,7 +144,7 @@ impl ArrayTreeLayout {
125144 . into ( ) ,
126145 vec ! [
127146 DType :: Primitive ( PType :: U32 , nn) ,
128- DType :: List ( Arc :: new( NODES_COLUMNS_DTYPE . clone ( ) ) , nn) ,
147+ DType :: List ( Arc :: new( nodes_columns_dtype ( DEFAULT_STATS ) ) , nn) ,
129148 DType :: List ( Arc :: new( BUFFER_COLUMNS_DTYPE . clone( ) ) , nn) ,
130149 ] ,
131150 ) ,
@@ -134,8 +153,9 @@ impl ArrayTreeLayout {
134153 }
135154
136155 /// Derive a [`LayoutReaderContext`] that publishes an [`ArrayTreesSource`] backed by this
137- /// layout's auxiliary `array_trees` child. Descendant [`ArrayTreeFlatLayout`] readers
138- /// pull the source via `ctx.get::<ArrayTreesSource>()` to resolve their compact trees.
156+ /// layout's auxiliary `array_trees` child under [`ARRAY_TREES_SOURCE_ID`]. Descendant
157+ /// [`ArrayTreeFlatLayout`] readers pull the source by the same id to resolve their
158+ /// compact trees.
139159 ///
140160 /// Used by:
141161 /// - The normal [`crate::VTable::new_reader`] dispatch on `ArrayTreeLayout` (production path).
@@ -158,7 +178,7 @@ impl ArrayTreeLayout {
158178 ctx,
159179 ) ?;
160180 let source = Arc :: new ( ArrayTreesSource :: new ( trees_reader, session. clone ( ) ) ) ;
161- Ok ( ctx. with ( source) )
181+ Ok ( ctx. with ( * ARRAY_TREES_SOURCE_ID , source) )
162182 }
163183}
164184
@@ -259,8 +279,8 @@ impl VTable for ArrayTree {
259279/// the cached map.
260280///
261281/// Published by [`ArrayTreeLayout::derive_reader_ctx`] into the [`LayoutReaderContext`]
262- /// passed to descendants; pulled by [`ArrayTreeFlatLayout`]'s reader via
263- /// `ctx.get::<ArrayTreesSource>()` .
282+ /// passed to descendants under [`ARRAY_TREES_SOURCE_ID`]; pulled by
283+ /// [`ArrayTreeFlatLayout`]'s reader by the same id .
264284pub struct ArrayTreesSource {
265285 reader : LayoutReaderRef ,
266286 /// Session used to create execution contexts when canonicalizing the consolidated array
0 commit comments