@@ -24,6 +24,8 @@ use parquet_variant::Variant;
24
24
use std:: any:: Any ;
25
25
use std:: sync:: Arc ;
26
26
27
+ use crate :: shredding:: VariantSchema ;
28
+
27
29
/// An array of Parquet [`Variant`] values
28
30
///
29
31
/// A [`VariantArray`] wraps an Arrow [`StructArray`] that stores the underlying
@@ -60,11 +62,7 @@ pub struct VariantArray {
60
62
/// int8.
61
63
inner : StructArray ,
62
64
63
- /// Reference to the metadata column of inner
64
- metadata_ref : ArrayRef ,
65
-
66
- /// Reference to the value column of inner
67
- value_ref : ArrayRef ,
65
+ variant_schema : VariantSchema ,
68
66
}
69
67
70
68
impl VariantArray {
@@ -94,23 +92,11 @@ impl VariantArray {
94
92
) ) ;
95
93
} ;
96
94
97
- // todo, remove this since we already do it in validate_shredded_schema
98
- let Some ( metadata_field) = VariantArray :: find_metadata_field ( inner) else {
99
- return Err ( ArrowError :: InvalidArgumentError (
100
- "Invalid VariantArray: StructArray must contain a 'metadata' field" . to_string ( ) ,
101
- ) ) ;
102
- } ;
103
-
104
- let Some ( value_field) = VariantArray :: find_value_field ( inner) else {
105
- return Err ( ArrowError :: InvalidArgumentError (
106
- "Invalid VariantArray: StructArray must contain a 'value' field" . to_string ( ) ,
107
- ) ) ;
108
- } ;
95
+ let variant_schema = VariantSchema :: try_new ( inner. fields ( ) . clone ( ) ) ?;
109
96
110
97
Ok ( Self {
111
98
inner : inner. clone ( ) ,
112
- metadata_ref : metadata_field,
113
- value_ref : value_field,
99
+ variant_schema,
114
100
} )
115
101
}
116
102
@@ -126,34 +112,41 @@ impl VariantArray {
126
112
127
113
/// Return the [`Variant`] instance stored at the given row
128
114
///
129
- /// Panics if the index is out of bounds.
115
+ /// Panics if the index is out of bounds or value array does not exist .
130
116
///
131
117
/// Note: Does not do deep validation of the [`Variant`], so it is up to the
132
118
/// caller to ensure that the metadata and value were constructed correctly.
119
+ ///
120
+ /// Todo: reconstruct partially shredded or shredded variants
133
121
pub fn value ( & self , index : usize ) -> Variant {
134
122
let metadata = self . metadata_field ( ) . as_binary_view ( ) . value ( index) ;
135
- let value = self . value_field ( ) . as_binary_view ( ) . value ( index) ;
123
+ let value = self
124
+ . value_field ( )
125
+ . expect ( "value field does not exist" )
126
+ . as_binary_view ( )
127
+ . value ( index) ;
136
128
Variant :: new ( metadata, value)
137
129
}
138
130
139
- fn find_metadata_field ( array : & StructArray ) -> Option < ArrayRef > {
140
- array. column_by_name ( "metadata" ) . cloned ( )
141
- }
142
-
143
- fn find_value_field ( array : & StructArray ) -> Option < ArrayRef > {
144
- array. column_by_name ( "value" ) . cloned ( )
145
- }
146
-
147
131
/// Return a reference to the metadata field of the [`StructArray`]
148
132
pub fn metadata_field ( & self ) -> & ArrayRef {
149
- // spec says fields order is not guaranteed, so we search by name
150
- & self . metadata_ref
133
+ let metadata_idx = self . variant_schema . metadata_idx ( ) ;
134
+
135
+ self . inner . column ( metadata_idx)
151
136
}
152
137
153
138
/// Return a reference to the value field of the `StructArray`
154
- pub fn value_field ( & self ) -> & ArrayRef {
155
- // spec says fields order is not guaranteed, so we search by name
156
- & self . value_ref
139
+ pub fn value_field ( & self ) -> Option < & ArrayRef > {
140
+ self . variant_schema
141
+ . value_idx ( )
142
+ . map ( |i| self . inner . column ( i) )
143
+ }
144
+
145
+ /// Return a reference to the shredded value field of the `StructArray`
146
+ pub fn shredded_value_field ( & self ) -> Option < & ArrayRef > {
147
+ self . variant_schema
148
+ . shredded_value_idx ( )
149
+ . map ( |i| self . inner . column ( i) )
157
150
}
158
151
}
159
152
@@ -176,12 +169,9 @@ impl Array for VariantArray {
176
169
177
170
fn slice ( & self , offset : usize , length : usize ) -> ArrayRef {
178
171
let slice = self . inner . slice ( offset, length) ;
179
- let met = self . metadata_ref . slice ( offset, length) ;
180
- let val = self . value_ref . slice ( offset, length) ;
181
172
Arc :: new ( Self {
182
173
inner : slice,
183
- metadata_ref : met,
184
- value_ref : val,
174
+ variant_schema : self . variant_schema . clone ( ) ,
185
175
} )
186
176
}
187
177
0 commit comments