Skip to main content

rudb_vector/
vector.rs

1//! The vector itself.
2//!
3//! `spec/07-execution.md` section 7.1 calls this the widest interface in the system, says every
4//! operator depends on it, and says changing it after twenty operators exist is expensive. So it
5//! is written before the first operator rather than after the fifth.
6//!
7//! A vector is a type, a length of at most [`VECTOR_SIZE`], a physical form, a validity
8//! representation and some data. Four of the forms are the ones in `spec/04-architecture.md`
9//! section 4.3: flat, constant, sequence and dictionary. Run length, bit packed and string view come
10//! after them, one at a time with the kernels that read them rather than all at once ahead of
11//! anything that can use them.
12//!
13//! Dictionary and run length are the pair worth understanding together, because they answer
14//! different questions about the same column. A dictionary says which distinct values there are, so
15//! it wins on low cardinality however the rows are ordered. Run length says where the values stop,
16//! so it wins on a clustered column however many distinct values it has. A column can want either
17//! one without wanting the other, and `hits` has columns of both kinds.
18//!
19//! String view is the odd one out, because it is not about making a column smaller. It is about who
20//! owns the bytes: the views are the vector's and the arena is shared, so cutting a chunk out of a
21//! page of strings moves sixteen bytes a row and copies none of the payload. Every other form here
22//! trades a little work per row for less memory, and that one trades nothing at all.
23//!
24//! The nested forms are the odd ones out in a different direction. The forms above are all ways of
25//! writing a column of scalars down more cheaply, and a nested value is not a scalar at all, so
26//! [`Form::List`] and [`Form::Struct`] are each the only form their column has rather than one of
27//! several it could be in. A list is a child vector of every element plus a start and a length per
28//! row. A struct is one child per field with no entries at all, because a struct row holds one value
29//! per field rather than a run of them. Either way the children are ordinary vectors and can be in any
30//! of the forms above, which is where a nested column gets made smaller.
31//!
32//! **What is not here yet.** Buffers are owned. Section 7.1 says a vector borrowed from a buffer
33//! managed page carries a pin, and there is no buffer manager until M2, so there is nothing to pin
34//! and pretending otherwise would be an interface built against an imaginary caller. `ARRAY` is not
35//! stored yet either, and it is a composition of what is here rather than a new shape: it is a list
36//! whose length is the type's rather than the row's, the way a `MAP` is a list whose child is a two
37//! field struct of keys and values. `UNION` is the one that is genuinely different, since it is one
38//! child per member plus a tag saying which member each row is in.
39
40use std::borrow::Cow;
41use std::cmp::Ordering;
42use std::sync::Arc;
43
44use rudb_common::{Cause, Error, Field, LogicalType, Result, Value, slow};
45
46use crate::buffer::Buffer;
47use crate::fsst::SymbolTable;
48use crate::string::{StringColumn, StringView};
49use crate::validity::Validity;
50
51/// How many values are in a full vector.
52///
53/// 8192, which is four times DuckDB's 2048 and eight times what this was. It started at 1024 for
54/// three reasons: the FastLanes unit is 1024, a validity mask comes out at exactly 16 `u64` words,
55/// and a vector of 16 byte string views is 16 KiB, which is small enough that several of them sit
56/// in L1 at once. The first two are still true of any multiple of 1024. The third was the argument
57/// and it was an argument about the wrong level, because it was also deciding how much of a table
58/// one zone map covered and how much work one call into the pipeline did, and those wanted a much
59/// larger number than L1 did.
60///
61/// #984 separated them: a table in memory is stored in row groups of 122,880 rows now and a chunk
62/// is a window into one, so the vector size is only the execution unit and is free to be chosen for
63/// what an operator costs per call. #480 measured it. On twenty million rows in memory, one thread,
64/// going from 1024 to 8192 takes `count(*)` with a filter from 14.0 milliseconds to 1.9, `sum(v)`
65/// with the same filter from 39.6 to 29.6 and `sum(k + v)` from 66.8 to 52.6. On ClickBench over
66/// Parquet, where the time is decode and hash aggregation rather than per call overhead, the same
67/// move is worth about eight percent on the total of the twenty nine queries that run.
68///
69/// 32768 was measured too and is not better: it wins another few percent on the full scans and
70/// loses on the load, on a needle that the chunk zone maps would otherwise prune, and on anything
71/// with a string column, where a vector of views is half a megabyte. 8192 is where the per call
72/// overhead has stopped mattering and the working set has not started to.
73pub const VECTOR_SIZE: usize = 8192;
74
75/// What the key field of a map's child struct is called.
76///
77/// A map is stored as a list of two field structs, and these are the two names. They are DuckDB's, and
78/// they are also the names the Parquet specification gives a map's repeated group, so a reader that
79/// builds one of these from a file finds the names already agreed rather than translated.
80pub const MAP_KEY: &str = "key";
81
82/// What the value field of a map's child struct is called. See [`MAP_KEY`].
83pub const MAP_VALUE: &str = "value";
84
85/// What [`Vector::map_parts`] hands back: one entry per row, then the keys and then the values.
86///
87/// A name rather than the triple written out, because the triple written out is over the complexity
88/// clippy allows and because a kernel that takes these as an argument should be able to say so in one
89/// word.
90pub type MapParts<'a> = (&'a [(u32, u32)], &'a Vector, &'a Vector);
91
92/// Which physical form a vector is in.
93///
94/// An operator asks this once per vector and then takes the path it wants, which is the one branch
95/// per vector that the whole design is willing to spend.
96///
97/// Not exhaustive, and that is a decision rather than an oversight. `Encoded` is the fifth form
98/// and it arrives at layer three with the specialization contract. If this enum were exhaustive,
99/// the day it lands is the day every kernel in the workspace stops compiling, and the pressure at
100/// that moment would be to add an arm to each of them in a hurry rather than to think about what
101/// each one should do with an encoded vector. A required fallback arm means each kernel already
102/// has a correct answer for a form it has never seen, and specializing it is then a change that
103/// can be made one kernel at a time with a benchmark next to it.
104#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
105#[non_exhaustive]
106pub enum Form {
107    /// One value per position.
108    Flat,
109    /// One value, repeated.
110    Constant,
111    /// A start and a step, computed rather than stored.
112    Sequence,
113    /// Codes into a smaller vector of distinct values.
114    Dictionary,
115    /// Integers stored in as many bits as the range of the column needs, offset from a base.
116    ///
117    /// The form a narrow integer column is in. A ClickBench `ResolutionWidth` is a `SMALLINT` whose
118    /// values live between 0 and 2560, which is twelve bits, so the column is three quarters of the
119    /// size it was and the pages behind it are three quarters of the reads. What it costs is a shift
120    /// and a mask per value, which is why this is worth it at storage and at rest and is not a form
121    /// anything should be building in the middle of a pipeline.
122    BitPacked,
123    /// Sixteen byte views over an arena the vector shares rather than owns.
124    ///
125    /// The form a varchar column is in once more than one vector is looking at the same page. A flat
126    /// varchar vector owns its arena, so cutting a chunk out of it copies every byte of every long
127    /// string in the range, and on ClickBench that is most of what reading `URL` costs. Sharing the
128    /// arena makes the cut the views and nothing else, the way a dictionary cut is the codes and
129    /// nothing else.
130    StringView,
131    /// Strings compressed against one symbol table, each row on its own.
132    ///
133    /// The form a text column is in at rest. FSST is about half the bytes on the ClickBench `URL`
134    /// and `Title` columns, and unlike a block compressor it keeps random access, so reading row
135    /// four million does not decompress the four million before it. What it costs is a decompression
136    /// per row read, which is why an equality filter over it is worth writing in code space: the
137    /// literal compresses once and the rows never decompress at all.
138    Fsst,
139    /// One value per run, with the row each run ends at.
140    ///
141    /// The form a clustered column is in. `hits` is written in time order, so `EventDate` is a few
142    /// hundred runs over a hundred million rows, and a sum over it is a few hundred multiplications
143    /// rather than a hundred million additions. Dictionary says which distinct values there are and
144    /// this says where they stop, and a column can want either one without wanting the other.
145    Rle,
146    /// A child vector of every element, and a start and a length per row.
147    ///
148    /// The form a `LIST` column is in, and the only form it has. The others are all ways of writing
149    /// down a column of scalars more cheaply and this is the shape a nested value has at all, so a
150    /// list vector reports this whether or not anything has tried to make it smaller. Making it
151    /// smaller happens in the child, which is an ordinary vector and can be any of the forms above.
152    ///
153    /// A `MAP` column reports this too, because a map is a list whose child is a two field struct and
154    /// the bytes really are a list's. This enum is about the physical layout, and the logical type is
155    /// what remembers the difference, which is the same division `LogicalType::physical` already makes.
156    List,
157    /// One child vector per field, each as long as the vector itself.
158    ///
159    /// The form a `STRUCT` column is in, and the only form it has, for the reason [`Form::List`] is
160    /// the only form a list has. A struct holds exactly one value per field per row rather than a run
161    /// of them, so there are no entries here and the children line up with the rows one to one, which
162    /// makes a cut a cut of every child and a gather a gather of every child. Each child is an
163    /// ordinary vector and can be in any of the forms above, so that is where a struct column gets
164    /// made smaller.
165    Struct,
166    /// One row id per row, into a source vector that is far longer than this one.
167    ///
168    /// The form a link join's parent columns are in, per `spec/graph/08-vector-engine.md` section
169    /// 8.2. Physically it is [`Form::Dictionary`] and logically it is the opposite of one, which is
170    /// why it is a form of its own rather than a dictionary with a note on it. A dictionary promises
171    /// that the values are few and distinct, and every kernel that has a dictionary arm takes that
172    /// promise by folding the operation over the values once and then indexing. A gather's source is
173    /// a whole parent table, so folding over it to answer two thousand rows reads fifteen million
174    /// values for nothing. Both forms want the same code and they want it under opposite conditions,
175    /// so the condition is [`Vector::fold_over_source`] and the form is what makes a kernel ask.
176    Gathered,
177}
178
179/// The values of a flat vector, one Rust vector per physical type.
180///
181/// The variants are physical rather than logical, which is what lets `DATE` and `INTEGER` share
182/// storage and share a kernel. What a run of `i32` means is the vector's logical type's business.
183#[derive(Debug, Clone, PartialEq)]
184#[non_exhaustive]
185pub enum Data {
186    /// No values, for the type of an untyped `NULL`.
187    Empty,
188    /// One byte per value.
189    Bool(Buffer<bool>),
190    /// 8 bit signed.
191    Int8(Buffer<i8>),
192    /// 16 bit signed.
193    Int16(Buffer<i16>),
194    /// 32 bit signed.
195    Int32(Buffer<i32>),
196    /// 64 bit signed.
197    Int64(Buffer<i64>),
198    /// 128 bit signed.
199    Int128(Buffer<i128>),
200    /// 8 bit unsigned.
201    UInt8(Buffer<u8>),
202    /// 16 bit unsigned.
203    UInt16(Buffer<u16>),
204    /// 32 bit unsigned.
205    UInt32(Buffer<u32>),
206    /// 64 bit unsigned.
207    UInt64(Buffer<u64>),
208    /// 128 bit unsigned.
209    UInt128(Buffer<u128>),
210    /// IEEE 754 binary32.
211    Float32(Buffer<f32>),
212    /// IEEE 754 binary64.
213    Float64(Buffer<f64>),
214    /// The months, days and microseconds triple.
215    Interval(Buffer<(i32, i32, i64)>),
216    /// Strings, as 16 byte views plus the arena the long ones live in.
217    Varlen(StringColumn),
218}
219
220impl Data {
221    /// How many values are stored.
222    ///
223    /// The match below has no wildcard arm, and that is what makes this function the check that
224    /// keeps [`for_each_layout`](crate::for_each_layout) honest. A variant added to this enum
225    /// without being added to the `all` group fails to compile here, which is a line in a build log
226    /// rather than a layout quietly missing from six kernels.
227    #[must_use]
228    pub fn len(&self) -> usize {
229        macro_rules! lengths {
230            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
231                match self {
232                    Self::Empty => 0,
233                    $(Self::$variant(values) => values.len(),)+
234                }
235            };
236        }
237        crate::for_each_layout!(all, lengths)
238    }
239
240    /// Whether there are no values.
241    #[must_use]
242    pub fn is_empty(&self) -> bool {
243        self.len() == 0
244    }
245
246    /// How many bytes of memory these values are holding.
247    ///
248    /// One arm per layout through the same macro as [`Data::len`], for the same reason: a layout
249    /// added without a size here is a layout the memory limit would charge nothing for, and a
250    /// buffer that is free is a buffer that can be grown until the process dies.
251    #[must_use]
252    pub fn footprint(&self) -> usize {
253        macro_rules! sizes {
254            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
255                match self {
256                    Self::Empty => 0,
257                    $(Self::$variant(values) => values.footprint(),)+
258                }
259            };
260        }
261        crate::for_each_layout!(all, sizes)
262    }
263
264    /// These values held as a page, so that copying or cutting them does not copy the values.
265    ///
266    /// For a producer that is going to hand the same values out many times, which is what a stored
267    /// column is. It costs one `Arc` per layout and moves the run into it without touching a value,
268    /// and after it a write through any reader copies out rather than writing the page, which is
269    /// [`Buffer::to_mut`]. A run that is already a page comes back as it was.
270    #[must_use]
271    pub fn into_pages(self) -> Self {
272        macro_rules! paged {
273            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
274                match self {
275                    Self::Empty => Self::Empty,
276                    $(Self::$variant(values) => Self::$variant(values.into_page()),)+
277                }
278            };
279        }
280        crate::for_each_layout!(all, paged)
281    }
282
283    /// An integer at `index`, widened, for any of the signed integer layouts.
284    ///
285    /// Used by the decimal path, which needs the unscaled value out of whichever width the width
286    /// and scale picked, and by anything else that would otherwise repeat the same five arms.
287    #[must_use]
288    pub fn signed_at(&self, index: usize) -> Option<i128> {
289        macro_rules! widened {
290            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
291                match self {
292                    $(Self::$variant(v) => v.get(index).map(|&x| i128::from(x)),)+
293                    _ => None,
294                }
295            };
296        }
297        crate::for_each_layout!(signed, widened)
298    }
299
300    /// The first `len` signed integers, widened to `i64`, appended to `out`.
301    ///
302    /// The bulk form of [`Self::signed_at`]. Four of the five signed layouts, because the fifth is
303    /// 128 bits wide and does not fit what this hands back. `Int64` is a copy of the run and the
304    /// three narrower ones are a sign extension the compiler turns into one instruction per lane.
305    ///
306    /// `false`, leaving `out` as it found it, for the wide layout, for a run shorter than `len` and
307    /// for every layout that is not a signed integer.
308    #[must_use]
309    pub fn signed_block(&self, len: usize, out: &mut Vec<i64>) -> bool {
310        match self {
311            Self::Int8(v) => widen(v.as_slice(), len, out),
312            Self::Int16(v) => widen(v.as_slice(), len, out),
313            Self::Int32(v) => widen(v.as_slice(), len, out),
314            Self::Int64(v) => match v.as_slice().get(..len) {
315                Some(run) => {
316                    out.extend_from_slice(run);
317                    true
318                }
319                None => false,
320            },
321            _ => false,
322        }
323    }
324
325    /// An unsigned integer at `index`, widened.
326    #[must_use]
327    pub fn unsigned_at(&self, index: usize) -> Option<u128> {
328        macro_rules! widened {
329            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
330                match self {
331                    $(Self::$variant(v) => v.get(index).map(|&x| u128::from(x)),)+
332                    _ => None,
333                }
334            };
335        }
336        crate::for_each_layout!(unsigned, widened)
337    }
338
339    /// The string at `index`, for a `Varlen`.
340    #[must_use]
341    pub fn str_at(&self, index: usize) -> Option<&str> {
342        match self {
343            Self::Varlen(column) => column.get(index),
344            _ => None,
345        }
346    }
347
348    /// The bytes at `index`, for a `Varlen`, whatever they are.
349    ///
350    /// What a `BLOB` reads through, since the bytes of one are not required to be text and
351    /// [`Self::str_at`] answers `None` for the ones that are not.
352    #[must_use]
353    pub fn bytes_at(&self, index: usize) -> Option<&[u8]> {
354        match self {
355            Self::Varlen(column) => column.bytes(index),
356            _ => None,
357        }
358    }
359}
360
361/// A type, a length, a validity representation and some data.
362#[derive(Debug, Clone, PartialEq)]
363pub struct Vector {
364    ty: LogicalType,
365    len: usize,
366    validity: Validity,
367    body: Body,
368}
369
370/// What the vector holds, which is what its form is decided by.
371#[derive(Debug, Clone, PartialEq)]
372enum Body {
373    Flat(Data),
374    Constant(Box<Value>),
375    Sequence {
376        start: i64,
377        step: i64,
378    },
379    /// The values are behind an `Arc` rather than a `Box` because slicing shares them.
380    ///
381    /// A dictionary vector is cut once per chunk and the dictionary itself is the same dictionary
382    /// every time, so a `Box` meant a copy of every value in it per cut. On the ClickBench columns
383    /// that are dictionary encoded the dictionary is larger than the chunk of codes pointing into
384    /// it, and copying it was ten percent of the cycles of reading the file.
385    ///
386    /// Nothing here mutates a dictionary in place, so sharing one is only ever a read, and the one
387    /// place that wants an owned copy of the values is [`compose`], which asks for one.
388    Dictionary {
389        codes: Vec<u32>,
390        values: Arc<Vector>,
391        stable: bool,
392    },
393    /// Integer codes of `width` bits each, packed end to end, each one an offset from `base`.
394    ///
395    /// Row `r` is the `width` bits starting at bit `(offset + r) * width`, read little end first, so
396    /// a code that straddles a word boundary has its low bits in the earlier word. `offset` is what
397    /// lets a cut of a packed column be free: the bits are not byte aligned, so a slice either
398    /// repacks or remembers where it starts, and remembering is one addition per read.
399    ///
400    /// The words are behind an `Arc` for the reason the dictionary's values are. A page is packed
401    /// once and cut into chunk sized pieces, and copying the words per cut would undo most of what
402    /// the packing saved.
403    Packed {
404        words: Arc<Vec<u64>>,
405        width: u32,
406        base: i128,
407        offset: usize,
408    },
409    /// The views of a string column, over an arena that other vectors are reading at the same time.
410    ///
411    /// The views are owned because a cut is a different run of views, and the arena is shared
412    /// because a cut is the same bytes. That split is the whole form: sixteen bytes a row move and
413    /// the payload does not, however many cuts a page is taken in.
414    ///
415    /// A row's bytes are found the same way [`StringColumn`] finds them, through
416    /// [`StringView::bytes_in`], so a short string never reads the arena at all and the two ways of
417    /// holding strings cannot answer a row differently.
418    Views {
419        views: Vec<StringView>,
420        arena: Arc<Buffer<u8>>,
421    },
422    /// Text owned by a storage source and fetched by position.
423    ExternalText {
424        source: Arc<dyn TextSource>,
425    },
426    /// The FSST codes of every row, end to end, with one symbol table over all of them.
427    ///
428    /// A span rather than a run of offsets, because a gather keeps this form and a gather puts the
429    /// rows in an order the codes are not in. Eight bytes a row either way, and the span is the one
430    /// that survives being permuted.
431    ///
432    /// The codes and the table are shared for the reason a dictionary's values are: one table is
433    /// trained per page and every chunk cut out of it points at the same one. A table is sixty five
434    /// thousand hash slots, so a table per chunk would cost more than the compression saves.
435    Coded {
436        codes: Arc<Vec<u8>>,
437        spans: Vec<(u32, u32)>,
438        table: Arc<SymbolTable>,
439    },
440    /// One value per run, with the row each run ends at, exclusive and increasing.
441    ///
442    /// Ends rather than lengths, because every reader of this wants to know which run holds a row
443    /// and ends answer that with a binary search while lengths answer it with a running total. The
444    /// two are the same information and only one of them is the one that gets asked for.
445    ///
446    /// The values are behind an `Arc` for the reason the dictionary's are: a page is cut into chunk
447    /// sized pieces and the values are the same values every time.
448    Runs {
449        ends: Vec<u32>,
450        values: Arc<Vector>,
451    },
452    /// One child vector holding every element of every row, and a start and a length per row.
453    ///
454    /// Start and length rather than the run of offsets Arrow carries, because offsets say where a
455    /// row ends by saying where the next one begins, and that is only true while the rows are in
456    /// order and none is skipped. A gather permutes the rows and a filter drops them, both of which
457    /// this form has to survive without copying the child, so each row says where its own elements
458    /// are and nothing is implied about its neighbour.
459    ///
460    /// The child is behind an `Arc` for the reason a dictionary's values are. A cut of a list column
461    /// is the entries and nothing else, so a page of lists taken in chunk sized pieces holds one
462    /// child however many pieces it is read in, and the elements outside the cut stay reachable but
463    /// unreferenced rather than being copied out.
464    ///
465    /// A null list and an empty list are different rows and this is where the difference lives. A
466    /// null is the validity mask at this level being false, the same as for any other type, and its
467    /// entry is `(start, 0)` and never read. An empty list is a valid row whose entry is `(start, 0)`
468    /// as well. So the entry alone does not say which one a row is, the mask does, which is the same
469    /// division of labour every other form here uses.
470    ///
471    /// A `MAP` is stored here too, with a [`Body::Fields`] child of `key` and `value`. Everything above
472    /// is true of it unchanged, which is the point of storing it this way: the cut, the gather and the
473    /// null rule are written once and a map inherits all three.
474    Nested {
475        entries: Vec<(u32, u32)>,
476        child: Arc<Vector>,
477    },
478    /// One child vector per field, in the order the type names them, each as long as this vector.
479    ///
480    /// No entries, which is the whole difference from [`Body::Nested`]. A list row is a run of
481    /// elements so it needs to say where its run is, and a struct row is one value per field so row
482    /// `r` of field `f` is position `r` of child `f` and there is nothing to record. That makes a cut
483    /// a cut of every child and a gather a gather of every child, both at the same positions, rather
484    /// than a rewrite of an index.
485    ///
486    /// The children are behind an `Arc` for the reason a dictionary's values are, and it pays off less
487    /// often here. A cut of a list column shares its child untouched because the entries carry the
488    /// range, and a cut of a struct column has to cut each child, so the sharing only survives the
489    /// cases where nothing moves. It is still worth having, because a struct of a hundred fields
490    /// handed between operators is a hundred pointers rather than a hundred columns.
491    ///
492    /// A null struct is the validity mask at this level being false and says nothing about the
493    /// children, which still hold whatever was put in them at that row. That is DuckDB's behaviour and
494    /// it is the reason this form cannot decide a row is null by looking down: the mask is the answer,
495    /// the same as it is for a list.
496    Fields {
497        children: Vec<Arc<Vector>>,
498    },
499    /// Row `r` is row `rids[offset + r]` of `source`, and is null where that is [`NO_ROW`].
500    ///
501    /// Late materialization written into the type system. A link join emits one of these per
502    /// projected parent column and reads nothing out of the parent at all, so a column that is
503    /// projected but never inspected is read once at the end for the rows that reached the end, and
504    /// a column used in a filter is filtered in this form over the distinct parent rows that were
505    /// actually reached rather than once per child row.
506    ///
507    /// The `rids` are shared and carry an `offset` for the reason [`Body::Packed`] carries one: a
508    /// link join fills one buffer of parent rows per child chunk and then the pipeline cuts it, and
509    /// a cut that copied the ids would spend more moving them than the gather it is describing
510    /// costs. Sharing makes a cut two words.
511    ///
512    /// [`NO_ROW`] is the whole of the outer join story here. Section 5.2 says a left link join keeps
513    /// the child rows whose link is the no parent sentinel and gathers null for them, and an inner
514    /// one drops them, so the operator decides which rows exist and this decides only what they
515    /// hold. That keeps the validity of a gather derivable rather than stored: a row is null when
516    /// its id is [`NO_ROW`] or when the source row it names is null, which is two loads and no
517    /// allocation, and the bitmap is materialized only when a kernel asks for one.
518    Gathered {
519        source: Arc<Vector>,
520        rids: Arc<Vec<u32>>,
521        offset: usize,
522    },
523}
524
525/// Random access to immutable text kept by a storage reader.
526pub trait TextSource: std::fmt::Debug + Send + Sync {
527    /// Number of values available.
528    fn len(&self) -> usize;
529    /// Whether this source has no values.
530    fn is_empty(&self) -> bool {
531        self.len() == 0
532    }
533    /// Bytes at one position, or no value when the position is outside the source.
534    fn bytes_at(&self, index: usize) -> Result<Option<&[u8]>>;
535    /// Byte length at one position without requiring the payload when the source has an index.
536    fn bytes_len_at(&self, index: usize) -> Result<Option<usize>> {
537        Ok(self.bytes_at(index)?.map(<[u8]>::len))
538    }
539    /// The byte length at each of `indices`, into the same place of `into`, and zero for a position
540    /// the source does not have.
541    ///
542    /// The same answers as [`bytes_len_at`](Self::bytes_len_at) a position at a time, which is what
543    /// the default does. A source overrides it when it can answer a run of positions for less than
544    /// the run of calls: a length asked once per row goes through a dispatch here, a dispatch in the
545    /// vector and a `Result` at each, and on a column whose lengths are one load each that was most
546    /// of what `STRLEN` cost.
547    fn bytes_lens_at(&self, indices: &[u32], into: &mut [i64]) -> Result<()> {
548        for (slot, &index) in into.iter_mut().zip(indices) {
549            let len = self.bytes_len_at(index as usize)?.unwrap_or_default();
550            *slot = i64::try_from(len).unwrap_or(i64::MAX);
551        }
552        Ok(())
553    }
554    /// Hands `body` the values from `first` up to at most `limit`, and answers where it stopped.
555    ///
556    /// The point of it is what it does not do, which is keep what it read.
557    /// [`bytes_at`](Self::bytes_at) hands back a borrow, so a source that decodes a block to answer
558    /// it has to hold that block for as long as the source lives, and a reader that walks the whole
559    /// source therefore ends up holding the whole thing decoded. On the ClickBench `URL` dictionary
560    /// that is 4.2 GB resident to answer one `LIKE`, and none of it is read twice.
561    ///
562    /// A caller that means to walk a stretch of values once calls this instead and gets the bytes
563    /// on loan for the length of the call. The source decides how much it hands over at a time,
564    /// which for a blocked payload is the rest of the block it had to decode anyway, and answers
565    /// with one past the last value it visited so the caller can come back for the next stretch.
566    /// The answer is always above `first` where `first` is a value this source has, so a loop on it
567    /// finishes.
568    ///
569    /// The default hands over one value through `bytes_at` and is correct for every source. It is
570    /// also pointless for a source that keeps everything anyway, which is every source built in
571    /// memory, and that is the right default for exactly that reason.
572    fn sweep(
573        &self,
574        first: usize,
575        limit: usize,
576        body: &mut dyn FnMut(usize, &[u8]) -> Result<()>,
577    ) -> Result<usize> {
578        if first >= limit.min(self.len()) {
579            return Ok(first);
580        }
581        body(first, self.bytes_at(first)?.unwrap_or_default())?;
582        Ok(first + 1)
583    }
584    /// Whether the payload block holding `first` might contain `literal` in any value.
585    ///
586    /// A false answer is a proof that every value in the block misses. A source without a stored
587    /// substring signature answers true, which keeps the ordinary exact comparison authoritative.
588    fn might_contain(&self, first: usize, literal: &[u8]) -> Result<bool> {
589        let _ = (first, literal);
590        Ok(true)
591    }
592    /// Hands over the values at `indices`, which rise, without keeping what reading them decoded.
593    ///
594    /// The scattered twin of [`sweep`](Self::sweep). A caller that wants a few hundred values spread
595    /// over the whole source once, which is what turning a frequency synopsis's codes into values
596    /// is, would otherwise leave every block it touched decoded and held for the rest of the
597    /// source's life. On ClickBench `SearchPhrase` that is a hundred and twenty five blocks, the
598    /// larger part of what a query answered out of the synopsis was holding.
599    ///
600    /// `body` is told the position in `indices` and the bytes. The default reads through
601    /// `bytes_at`, which is right for every source that keeps everything anyway.
602    fn visit(
603        &self,
604        indices: &[usize],
605        body: &mut dyn FnMut(usize, &[u8]) -> Result<()>,
606    ) -> Result<()> {
607        for (at, &index) in indices.iter().enumerate() {
608            body(at, self.bytes_at(index)?.unwrap_or_default())?;
609        }
610        Ok(())
611    }
612    /// Resident bytes retained by this source.
613    fn footprint(&self) -> usize;
614    /// How many ranks this source's sorted value order has, when it has one.
615    ///
616    /// A rank is a position in the values sorted by their bytes, so rank zero is the smallest value
617    /// and rank `ranks() - 1` is the largest. A storage format that keeps a dictionary for a whole
618    /// column can afford to sort the distinct values once when it writes the file, and what that
619    /// buys is a binary search where a reader that only knows the values are distinct has to ask
620    /// every one of them whether it matches.
621    ///
622    /// `None` means the source does not know its order, which is the honest answer for anything
623    /// built in memory and for a file written before its format stored one. Nothing is allowed to
624    /// depend on this for correctness, only for speed.
625    ///
626    /// A source that answers with `Some` promises the ranks cover every value it has, and that
627    /// [`compare_rank`](Self::compare_rank) is consistent with an ordering in which the values are
628    /// strictly increasing. Strictly, which is to say the values are distinct, because what reads
629    /// this searches it, and a search of a run of equal values finds one of them rather than all of
630    /// them. A source that holds the same value twice must answer `None` here even though it could
631    /// sort itself perfectly well.
632    fn ranks(&self) -> Option<usize> {
633        None
634    }
635    /// How the value at `rank` compares against `wanted`.
636    ///
637    /// This is a method rather than a slice of positions the caller indexes because the answer is
638    /// the only thing a search wants, and a source that knows that can answer most probes without
639    /// reading a value at all. A file that stores the first few bytes of each value in rank order
640    /// settles every probe from those bytes except the ones where two values start the same way,
641    /// and the payload stays untouched. A caller handed positions instead would have to read a
642    /// value per probe, which for a dictionary of half a million entries spread over thirty
643    /// megabytes is a fresh block of the file every time.
644    ///
645    /// Only called for a rank below [`ranks`](Self::ranks), so the default is the error a source
646    /// that has no order should never be asked to produce.
647    fn compare_rank(&self, rank: usize, wanted: &[u8]) -> Result<Ordering> {
648        let _ = (rank, wanted);
649        Err(Error::internal("a text source without a sorted order was asked to compare a rank"))
650    }
651    /// How many values sort before `wanted`, and whether one of them is `wanted`.
652    ///
653    /// The whole search rather than a probe of it, so that a source which can answer the same
654    /// question twice without repeating the work is allowed to. The default runs the search through
655    /// [`compare_rank`](Self::compare_rank) and remembers nothing, which is right for a source whose
656    /// probes are cheap.
657    ///
658    /// The reason it is on the trait at all is the top N. `ORDER BY <varchar> LIMIT 10` asks once a
659    /// chunk whether anything left can beat the worst candidate, and the worst candidate stops
660    /// changing long before the chunks run out, so nearly every one of those searches is the one
661    /// before it asked again. A probe of a file backed dictionary is not cheap: it settles on the
662    /// stored head where it can and reads a value where it cannot, and reading a value means
663    /// decoding the payload block it sits in. On ClickBench 25 that search was 29 percent of the
664    /// query's instructions and the block decoding under it another 40.
665    ///
666    /// Only called when [`ranks`](Self::ranks) is `Some`, and `ranks` is what it answered.
667    fn below(&self, ranks: usize, wanted: &[u8]) -> Result<(usize, bool)> {
668        search_below(self, ranks, wanted)
669    }
670    /// The position of the value at `rank`, which is what a search returns once it has found one.
671    ///
672    /// Called about once per search rather than once per probe, so unlike
673    /// [`compare_rank`](Self::compare_rank) it is free to be the expensive one.
674    fn code_at_rank(&self, rank: usize) -> Result<u32> {
675        let _ = rank;
676        Err(Error::internal("a text source without a sorted order was asked for a rank"))
677    }
678    /// The rank of every value, in position order, when the source can hand the whole map over.
679    ///
680    /// This is [`code_at_rank`](Self::code_at_rank) turned round, and it is a separate method
681    /// because the two are wanted by opposite kinds of reader. A search wants one code out of a
682    /// rank and probes a handful of times, so it reads the order a block at a time and leaves the
683    /// rest alone. A min or a max over a grouped column wants a rank out of a code once per row,
684    /// and a walk of the order per row costs far more than reading the order once and turning it
685    /// round. What that buys is a comparison of two integers where the alternative is a fetch of
686    /// two strings out of a payload the size of the column.
687    ///
688    /// The slice is indexed by position and is as long as [`len`](Self::len), so a caller holding a
689    /// dictionary code indexes it directly.
690    ///
691    /// `None` from a source with no order, and from one with an order it would rather not invert.
692    /// Nothing depends on this for correctness, only for speed.
693    fn code_ranks(&self) -> Option<&[u32]> {
694        None
695    }
696    /// Whether another source presents the same values.
697    fn equal(&self, other: &dyn TextSource) -> bool {
698        self.len() == other.len()
699            && (0..self.len()).all(|index| {
700                matches!(
701                    (self.bytes_at(index), other.bytes_at(index)),
702                    (Ok(left), Ok(right)) if left == right
703                )
704            })
705    }
706}
707
708impl PartialEq for dyn TextSource {
709    fn eq(&self, other: &Self) -> bool {
710        self.equal(other)
711    }
712}
713
714/// The binary search behind [`TextSource::below`], written once so an override can still use it.
715///
716/// A source that remembers its answers overrides `below` to look in what it remembers first, and
717/// then it still has to do the search when it does not find one. This is that search. It carries on
718/// past an equal probe to the first rank holding the value, so what it returns is a boundary rather
719/// than wherever the halving happened to touch down, and the values are distinct so there is exactly
720/// one such rank.
721///
722/// # Errors
723///
724/// Whatever [`TextSource::compare_rank`] gives for a probe.
725pub fn search_below<S>(source: &S, ranks: usize, wanted: &[u8]) -> Result<(usize, bool)>
726where
727    S: TextSource + ?Sized,
728{
729    let mut low = 0;
730    let mut high = ranks;
731    let mut equal = false;
732    while low < high {
733        let middle = low + (high - low) / 2;
734        match source.compare_rank(middle, wanted)? {
735            Ordering::Less => low = middle + 1,
736            Ordering::Greater => high = middle,
737            Ordering::Equal => {
738                equal = true;
739                high = middle;
740            }
741        }
742    }
743    Ok((low, equal))
744}
745
746impl Vector {
747    /// A flat vector of `data`, all valid.
748    ///
749    /// # Errors
750    ///
751    /// If the data's physical layout is not the one the type calls for. That check is here rather
752    /// than left to the caller because a vector whose type and layout disagree is a wrong answer
753    /// waiting to be read out, and it costs one comparison at construction to prevent.
754    pub fn flat(ty: LogicalType, data: Data) -> Result<Self> {
755        let len = data.len();
756        if !matches!(data, Data::Empty) && layout_of(&data) != ty.physical() {
757            return Err(Error::internal(format!(
758                "a {ty} vector cannot hold {:?} data",
759                layout_of(&data)
760            )));
761        }
762        Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Flat(data) })
763    }
764
765    /// A flat vector built from single values, with the nulls among them turning into validity.
766    ///
767    /// The slow way in, and the only way in that anything outside this crate has. It is what an
768    /// `INSERT`, a `VALUES` clause and a test build a column with, all of which arrive holding
769    /// values rather than a run of `i32`. Nothing on a scan path calls it: a scan produces a run of
770    /// data directly and hands it to [`Self::flat`].
771    ///
772    /// # Errors
773    ///
774    /// If a value is not one the type can hold, or if the type is one there is no vector for yet,
775    /// which today means `ARRAY` and `UNION`. A `LIST`, a `STRUCT` and a `MAP` are routed to their own
776    /// builders and come back built.
777    pub fn from_values(ty: LogicalType, values: &[Value]) -> Result<Self> {
778        match &ty {
779            LogicalType::List(element) => {
780                return Self::list_from_values(element.as_ref().clone(), values);
781            }
782            LogicalType::Struct(fields) => return Self::struct_from_values(fields, values),
783            LogicalType::Map(key, value) => {
784                return Self::map_from_values(key.as_ref().clone(), value.as_ref().clone(), values);
785            }
786            _ => {}
787        }
788        let mut data = empty_data_for(&ty)?;
789        for value in values {
790            push_value(&mut data, value)?;
791        }
792        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
793        Ok(Self { ty, len: values.len(), validity, body: Body::Flat(data) })
794    }
795
796    /// A list vector of `element`, built from one [`Value::List`] per row.
797    ///
798    /// The elements of every row go into one child vector end to end, so a row's elements are a
799    /// contiguous range of it and a row is a start and a length into it. That is what makes a cut of
800    /// this form the entries and nothing else.
801    ///
802    /// A null row contributes no elements and gets an entry of length zero, which is the same entry
803    /// an empty list gets. The two are told apart by the validity mask rather than by the entry, for
804    /// the reason written on [`Body::Nested`].
805    fn list_from_values(element: LogicalType, values: &[Value]) -> Result<Self> {
806        let mut flat = Vec::new();
807        let mut entries = Vec::with_capacity(values.len());
808        for value in values {
809            let start = u32::try_from(flat.len())
810                .map_err(|_| Error::internal("a list column with more than u32 elements in it"))?;
811            match value {
812                Value::Null => entries.push((start, 0)),
813                Value::List { values: held, .. } => {
814                    let len = u32::try_from(held.len())
815                        .map_err(|_| Error::internal("a list longer than u32"))?;
816                    flat.extend_from_slice(held);
817                    entries.push((start, len));
818                }
819                other => {
820                    return Err(Error::internal(format!(
821                        "{other:?} does not belong in a list vector"
822                    )));
823                }
824            }
825        }
826        // The element type is the column's rather than any one value's. A `Value::List` carries what
827        // it thinks it is empty of, and a column built from a row of `INTEGER[]` and a row of
828        // `[]::NULL[]` would otherwise take its type from whichever row came first.
829        let child = Self::from_values(element, &flat)?;
830        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
831        Ok(Self {
832            ty: LogicalType::list(child.ty.clone()),
833            len: values.len(),
834            validity,
835            body: Body::Nested { entries, child: Arc::new(child) },
836        })
837    }
838
839    /// A list vector over a child that already exists, one entry per row.
840    ///
841    /// What a scan and a list returning kernel build, both of which produce the elements in bulk and
842    /// then say which row each range belongs to. Every row is valid, since a caller with nulls to
843    /// record adds them with [`Self::with_validity`].
844    ///
845    /// # Errors
846    ///
847    /// If an entry runs past the end of the child, which would be a row that reads elements belonging
848    /// to nobody and is the one mistake this form makes easy.
849    pub fn list(entries: Vec<(u32, u32)>, child: Vector) -> Result<Self> {
850        let reach = child.len();
851        for &(start, len) in &entries {
852            if start as usize + len as usize > reach {
853                return Err(Error::internal(format!(
854                    "a list entry of {len} at {start} in a child of {reach}"
855                )));
856            }
857        }
858        Ok(Self {
859            ty: LogicalType::list(child.ty.clone()),
860            len: entries.len(),
861            validity: Validity::AllValid,
862            body: Body::Nested { entries, child: Arc::new(child) },
863        })
864    }
865
866    /// A struct vector of `fields`, built from one [`Value::Struct`] per row.
867    ///
868    /// One pass per field rather than one pass per row, because each field becomes its own child
869    /// vector and a child is built from a run of values of one type. So a struct of three fields over
870    /// a thousand rows is three calls to [`Self::from_values`] and not a thousand.
871    ///
872    /// The fields are matched by name and not by position. A `Value::Struct` carries its names, and a
873    /// caller that built one in a different order from the type's would otherwise get the values
874    /// silently transposed into the wrong columns, which is the kind of wrong answer that reads as
875    /// right. A row missing a field the type names is an error rather than a null for the same reason.
876    ///
877    /// A null row is a null in every child as well as a false bit in the mask here. [`Body::Fields`]
878    /// says a null struct is allowed to have readable children and that is about a struct built out of
879    /// children that already exist, where whatever is underneath is the caller's. Built from values
880    /// there is nothing underneath to keep, so the children get the null.
881    fn struct_from_values(fields: &[Field], values: &[Value]) -> Result<Self> {
882        let mut children = Vec::with_capacity(fields.len());
883        for field in fields {
884            let mut column = Vec::with_capacity(values.len());
885            for value in values {
886                column.push(match value {
887                    Value::Null => Value::Null,
888                    Value::Struct(held) => held
889                        .iter()
890                        .find(|(name, _)| *name == field.name)
891                        .map(|(_, held)| held.clone())
892                        .ok_or_else(|| {
893                            Error::internal(format!(
894                                "a struct row with no {} field in it",
895                                field.name
896                            ))
897                        })?,
898                    other => {
899                        return Err(Error::internal(format!(
900                            "{other:?} does not belong in a struct vector"
901                        )));
902                    }
903                });
904            }
905            children.push(Arc::new(Self::from_values(field.ty.clone(), &column)?));
906        }
907        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
908        Ok(Self {
909            ty: LogicalType::Struct(fields.to_vec()),
910            len: values.len(),
911            validity,
912            body: Body::Fields { children },
913        })
914    }
915
916    /// A struct vector over children that already exist, one per field.
917    ///
918    /// What a scan and a struct returning kernel build, both of which produce each field as a column
919    /// and then put them side by side. Every row is valid, since a caller with nulls to record adds
920    /// them with [`Self::with_validity`].
921    ///
922    /// # Errors
923    ///
924    /// If there are no fields, or if the children are not all the same length. The first is not a
925    /// fussy restriction: a struct vector with no children has no child to take its length from, so a
926    /// zero field struct column would be a length with nothing to check it against, and a caller that
927    /// wants a column of empty structs wants a constant vector of one.
928    pub fn structure(children: Vec<(String, Vector)>) -> Result<Self> {
929        let Some((_, first)) = children.first() else {
930            return Err(Error::internal("a struct vector of no fields, which has no length"));
931        };
932        let len = first.len();
933        for (name, child) in &children {
934            if child.len() != len {
935                return Err(Error::internal(format!(
936                    "a {} field of {} rows beside a struct of {len}",
937                    name,
938                    child.len()
939                )));
940            }
941        }
942        let fields = children
943            .iter()
944            .map(|(name, child)| Field::new(name.clone(), child.ty.clone()))
945            .collect();
946        let children = children.into_iter().map(|(_, child)| Arc::new(child)).collect();
947        Ok(Self {
948            ty: LogicalType::Struct(fields),
949            len,
950            validity: Validity::AllValid,
951            body: Body::Fields { children },
952        })
953    }
954
955    /// The children, for a struct vector, and `None` for any other form.
956    ///
957    /// The accessor a kernel over a struct column reads, and the reason field extraction is free:
958    /// picking one field out of a struct is picking one of these, so a projection of `s.a` hands back
959    /// a vector that already exists rather than reading a row at a time and rebuilding a column.
960    #[must_use]
961    pub fn struct_parts(&self) -> Option<&[Arc<Self>]> {
962        match &self.body {
963            Body::Fields { children } => Some(children),
964            _ => None,
965        }
966    }
967
968    /// A map vector, built from one [`Value::Map`] per row.
969    ///
970    /// A map is a list whose child is a two field struct of keys and values, which is what DuckDB
971    /// stores and what Arrow and Parquet store, so this is the list builder and the struct builder
972    /// composed rather than a third layout. The keys of every row go into one column end to end, the
973    /// values into another beside it, and a row is a start and a length into the pair.
974    ///
975    /// The field names are [`MAP_KEY`] and [`MAP_VALUE`] because those are the names DuckDB gives them
976    /// and the names anything reading a Parquet map field will expect to find.
977    ///
978    /// A null row and an empty map are both an entry of length zero, told apart by the validity mask,
979    /// for the reason written on [`Body::Nested`].
980    fn map_from_values(key: LogicalType, value: LogicalType, values: &[Value]) -> Result<Self> {
981        let mut keys = Vec::new();
982        let mut held = Vec::new();
983        let mut entries = Vec::with_capacity(values.len());
984        for row in values {
985            let start = u32::try_from(keys.len())
986                .map_err(|_| Error::internal("a map column with more than u32 entries in it"))?;
987            match row {
988                Value::Null => entries.push((start, 0)),
989                Value::Map { entries: pairs, .. } => {
990                    let len = u32::try_from(pairs.len())
991                        .map_err(|_| Error::internal("a map with more than u32 entries"))?;
992                    for (one, other) in pairs {
993                        keys.push(one.clone());
994                        held.push(other.clone());
995                    }
996                    entries.push((start, len));
997                }
998                other => {
999                    return Err(Error::internal(format!(
1000                        "{other:?} does not belong in a map vector"
1001                    )));
1002                }
1003            }
1004        }
1005        // The two types are the column's rather than any one row's, for the reason the list builder
1006        // takes the element type from the column: a row that is the empty map carries whatever it was
1007        // built as being empty of, and the column is not entitled to take its type from that.
1008        let child = Self::structure(vec![
1009            (MAP_KEY.to_string(), Self::from_values(key, &keys)?),
1010            (MAP_VALUE.to_string(), Self::from_values(value, &held)?),
1011        ])?;
1012        let ty = LogicalType::map(
1013            fields_of(&child.ty)[0].ty.clone(),
1014            fields_of(&child.ty)[1].ty.clone(),
1015        );
1016        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
1017        Ok(Self {
1018            ty,
1019            len: values.len(),
1020            validity,
1021            body: Body::Nested { entries, child: Arc::new(child) },
1022        })
1023    }
1024
1025    /// A map vector over a pair of columns that already exist, one entry per row.
1026    ///
1027    /// What a scan and a map returning kernel build. The keys and the values are two columns of the
1028    /// same length, and each row of the map is the same range of both. Every row is valid, since a
1029    /// caller with nulls to record adds them with [`Self::with_validity`].
1030    ///
1031    /// # Errors
1032    ///
1033    /// If the two columns are different lengths, or if an entry runs past the end of them.
1034    pub fn map(entries: Vec<(u32, u32)>, keys: Vector, values: Vector) -> Result<Self> {
1035        let key = keys.ty.clone();
1036        let value = values.ty.clone();
1037        let child =
1038            Self::structure(vec![(MAP_KEY.to_string(), keys), (MAP_VALUE.to_string(), values)])?;
1039        let mut vector = Self::list(entries, child)?;
1040        vector.ty = LogicalType::map(key, value);
1041        Ok(vector)
1042    }
1043
1044    /// The entries and the two columns, for a map vector, and `None` for anything else.
1045    ///
1046    /// Reaches through the struct child that a map is stored as, so that a kernel over a map column
1047    /// reads the keys and the values as the two columns they are rather than having to know that the
1048    /// pair is spelled as a struct underneath.
1049    #[must_use]
1050    pub fn map_parts(&self) -> Option<MapParts<'_>> {
1051        if !matches!(self.ty, LogicalType::Map(_, _)) {
1052            return None;
1053        }
1054        let (entries, child) = self.list_parts()?;
1055        let [keys, values] = child.struct_parts()? else { return None };
1056        Some((entries, keys, values))
1057    }
1058
1059    /// The entries and the child, for a list vector, and `None` for any other form.
1060    ///
1061    /// The accessor a kernel over a list column reads, for the reason
1062    /// [`Self::dictionary_parts`] exists: `unnest` over 1024 rows wants the child once and the
1063    /// entries once, and reading it through [`Self::value_at`] would build a `Value::List` per row
1064    /// and then throw every one of them away.
1065    ///
1066    /// A map answers here as well, with the struct child it is stored as, because this is a question
1067    /// about the layout and a map's layout is a list's. A caller that wants the keys and the values as
1068    /// two columns wants [`Self::map_parts`], which reaches through that child.
1069    #[must_use]
1070    pub fn list_parts(&self) -> Option<(&[(u32, u32)], &Self)> {
1071        match &self.body {
1072            Body::Nested { entries, child } => Some((entries, child)),
1073            _ => None,
1074        }
1075    }
1076
1077    /// A vector of `len` copies of one value.
1078    ///
1079    /// Costs one value regardless of the length, which is what makes a literal in a predicate free
1080    /// and what makes a projection of a constant free.
1081    #[must_use]
1082    pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
1083        let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
1084        Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
1085    }
1086
1087    /// A vector of `len` values starting at `start` and stepping by `step`.
1088    ///
1089    /// This is what a row identifier column is, and it costs sixteen bytes rather than eight
1090    /// kilobytes. A scan that produces row ids for a later fetch produces one of these.
1091    #[must_use]
1092    pub fn sequence(start: i64, step: i64, len: usize) -> Self {
1093        Self {
1094            ty: LogicalType::BigInt,
1095            len,
1096            validity: Validity::AllValid,
1097            body: Body::Sequence { start, step },
1098        }
1099    }
1100
1101    /// A vector of codes into a smaller vector of distinct values.
1102    ///
1103    /// The form the whole M3 thesis rests on. A dictionary vector handed to a group by is an
1104    /// integer column, and an aggregate over one is an aggregate over integers no matter what the
1105    /// logical type says.
1106    ///
1107    /// A dictionary over a dictionary is composed into one level here rather than left as two, so
1108    /// the form has a depth of one always and a kernel that reads [`Self::dictionary_parts`] is
1109    /// reading the values rather than another layer of codes. Two filters over the same chunk build
1110    /// the second case and four conjuncts pushed down separately build four of it.
1111    ///
1112    /// The cost of leaving them stacked turned out to be a cliff rather than a slope. Every loop in
1113    /// `rudb-kernels` reaches for the values behind the codes with [`Self::data`], a dictionary
1114    /// pointing at a dictionary has no data to hand back, so the second level does not make the
1115    /// kernels slower, it turns them off and drops the work onto the row at a time path that exists
1116    /// to be correct rather than fast. Measured on server3 over a chunk of two numeric columns and a
1117    /// consumer of two vectorized passes, one level reads at 3.5 nanoseconds a row and two levels at
1118    /// 104, and the third and fourth levels cost almost nothing more because the first one had
1119    /// already given up everything there was to give. Composing is one pass over the outer codes,
1120    /// which the range check above is already making.
1121    ///
1122    /// The one dictionary that is not composed past is one carrying a validity of its own. A
1123    /// dictionary is built all valid and only [`Self::with_validity`] can change that, so such a
1124    /// vector is saying that its nulls are at this level rather than in the values it points at, and
1125    /// composing past it would drop them.
1126    ///
1127    /// # Errors
1128    ///
1129    /// If any code is past the end of the value vector.
1130    pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
1131        Self::dictionary_over(codes, Arc::new(values))
1132    }
1133
1134    /// The same, over a set of values somebody else is holding too.
1135    ///
1136    /// The body holds its values in an `Arc` either way, so a caller that already has one has
1137    /// nothing to hand over but a pointer. The caller this is for is a Parquet chunk: one dictionary
1138    /// page serves every data page of the chunk, and going through [`Self::dictionary`] meant
1139    /// copying the whole dictionary into each page's vector on the way to putting it in an `Arc`
1140    /// that then had a single holder. On a ClickBench scan that copy was sixteen percent of the
1141    /// instructions the query ran.
1142    ///
1143    /// Composing a dictionary over a dictionary keeps the handle too. The leaf of the stack is what
1144    /// the composed dictionary points at and neither its values nor anything about it changes, so
1145    /// there is nothing to own and the new dictionary shares the same leaf the old one did.
1146    ///
1147    /// The range check takes the highest code rather than stopping at the first bad one. Stopping
1148    /// early sounds cheaper and is not, because a loop that can exit anywhere cannot be vectorized
1149    /// and a running maximum can, and the only run that would have exited early is the one about to
1150    /// fail the query anyway. Every other run reads the whole of `codes` either way. It was 5.2
1151    /// percent of a ClickBench scan as a `find`.
1152    ///
1153    /// # Errors
1154    ///
1155    /// If any code is past the end of the value vector.
1156    pub fn dictionary_over(codes: Vec<u32>, values: Arc<Vector>) -> Result<Self> {
1157        let highest = codes.iter().copied().fold(0, u32::max);
1158        if !codes.is_empty() && highest as usize >= values.len() {
1159            return Err(Error::internal(format!(
1160                "dictionary code {highest} is past the end of a {} value dictionary",
1161                values.len()
1162            )));
1163        }
1164        let (codes, values) = compose(codes, values);
1165        Ok(Self {
1166            ty: values.ty.clone(),
1167            len: codes.len(),
1168            validity: Validity::AllValid,
1169            body: Body::Dictionary { codes, values, stable: false },
1170        })
1171    }
1172
1173    /// A dictionary whose codes keep the same meaning across every page of its source.
1174    pub fn stable_dictionary(codes: Vec<u32>, values: Arc<Vector>) -> Result<Self> {
1175        let mut vector = Self::dictionary_over(codes, values)?;
1176        if let Body::Dictionary { stable, .. } = &mut vector.body {
1177            *stable = true;
1178        }
1179        Ok(vector)
1180    }
1181
1182    /// A stable dictionary whose caller already found the largest code while decoding it.
1183    pub fn stable_dictionary_validated(
1184        codes: Vec<u32>,
1185        values: Arc<Vector>,
1186        highest: Option<u32>,
1187    ) -> Result<Self> {
1188        if highest.is_some_and(|code| code as usize >= values.len()) {
1189            return Err(Error::internal("a stable dictionary code is past its value dictionary"));
1190        }
1191        Ok(Self {
1192            ty: values.ty.clone(),
1193            len: codes.len(),
1194            validity: Validity::AllValid,
1195            body: Body::Dictionary { codes, values, stable: true },
1196        })
1197    }
1198
1199    /// One row of `source` per id, without reading any of them.
1200    ///
1201    /// What a link join emits for each of its parent columns, per `spec/graph/08-vector-engine.md`
1202    /// section 8.2. Row `r` is row `rids[r]` of `source`, and is null where that is [`NO_ROW`].
1203    ///
1204    /// The ids are taken by `Arc` rather than by value because one link join fills one buffer of
1205    /// parent rows per child chunk and then hands the same buffer to every projected parent column,
1206    /// so a gather of eight columns is eight pointers and one buffer. [`Self::gathered_from`] is the
1207    /// same thing starting part way in, which is what a cut of one produces.
1208    ///
1209    /// # Errors
1210    ///
1211    /// If an id is past the end of the source and is not [`NO_ROW`]. That check is a pass over the
1212    /// ids and it is the only thing standing between a link built against the wrong parent and a
1213    /// read of whatever happens to be at that offset, so it is not optional and it is not deferred:
1214    /// `spec/graph/03-the-file-format.md` section 3.1 says a stale section is ignored rather than
1215    /// repaired, and this is where a stale one stops being ignorable.
1216    pub fn gathered(source: Arc<Vector>, rids: Arc<Vec<u32>>) -> Result<Self> {
1217        let len = rids.len();
1218        Self::gathered_from(source, rids, 0, len)
1219    }
1220
1221    /// The same, reading `len` ids starting at `offset`.
1222    ///
1223    /// # Errors
1224    ///
1225    /// If the range runs past the end of the ids, or if an id in it is past the end of the source.
1226    pub fn gathered_from(
1227        source: Arc<Vector>,
1228        rids: Arc<Vec<u32>>,
1229        offset: usize,
1230        len: usize,
1231    ) -> Result<Self> {
1232        let end = offset.checked_add(len).ok_or_else(|| Error::internal("a gather that wraps"))?;
1233        let Some(taken) = rids.get(offset..end) else {
1234            return Err(Error::internal(format!(
1235                "rows {offset} to {end} of a gather over {} ids",
1236                rids.len()
1237            )));
1238        };
1239        let rows = source.len();
1240        if taken.iter().any(|&rid| rid != NO_ROW && rid as usize >= rows) {
1241            return Err(Error::internal(format!(
1242                "a gathered row id is past the {rows} rows of its source"
1243            )));
1244        }
1245        Ok(Self {
1246            ty: source.ty.clone(),
1247            len,
1248            // The mask is all valid and the nulls are real, which is the same split a dictionary
1249            // makes: this level says every row exists and the body says what each one holds, and
1250            // `is_null_at` reads through to answer. A mask here would be a second copy of what the
1251            // ids already say and the two could disagree.
1252            validity: Validity::AllValid,
1253            body: Body::Gathered { source, rids, offset },
1254        })
1255    }
1256
1257    /// The source and the ids of a gathered vector, and `None` for any other form.
1258    #[must_use]
1259    pub fn gathered_parts(&self) -> Option<(&Arc<Self>, &[u32])> {
1260        match &self.body {
1261            Body::Gathered { source, rids, offset } => {
1262                Some((source, rids.get(*offset..offset + self.len)?))
1263            }
1264            _ => None,
1265        }
1266    }
1267
1268    /// Whether a kernel over this vector should fold over the source once and then index.
1269    ///
1270    /// Section 8.2's dispatch rule, which is one comparison and is the whole difference between a
1271    /// gather and a dictionary. Every kernel with a dictionary arm already folds over the values
1272    /// once and indexes, and that arm is right for a gather exactly when the source is shorter than
1273    /// the rows being answered. A dictionary always is, by construction. A gather off a parent
1274    /// table almost never is, and a kernel that took the dictionary arm anyway would read fifteen
1275    /// million parent rows to answer two thousand child ones.
1276    ///
1277    /// `false` for every other form, so a kernel can ask this without first asking what it has.
1278    #[must_use]
1279    pub fn fold_over_source(&self) -> bool {
1280        match &self.body {
1281            Body::Gathered { source, .. } => source.len() < self.len,
1282            _ => false,
1283        }
1284    }
1285
1286    /// A vector of runs, one value each, with the row each run ends at.
1287    ///
1288    /// `ends` is exclusive and strictly increasing, so run `i` covers the rows from `ends[i - 1]` to
1289    /// `ends[i]` and run zero starts at nothing. The length of the vector is the last end.
1290    ///
1291    /// The depth is one, the same way a dictionary's is, and for a sharper reason. Every kernel that
1292    /// wants runs wants the value of a run without another search, and a run length vector over a
1293    /// run length vector turns one search into two and then into three. Rather than compose, this
1294    /// refuses: nothing in the engine builds a stacked one, because [`Self::run_encoded`] only ever
1295    /// reads a flat body, so a stacked one is a caller doing something by hand and the useful answer
1296    /// is to say so rather than to quietly do a pass of work they did not ask for.
1297    ///
1298    /// A run over a dictionary is fine and is not that case. The two forms answer different
1299    /// questions and a column that is both clustered and low cardinality genuinely wants both.
1300    ///
1301    /// # Errors
1302    ///
1303    /// If there is not exactly one value per run, if the ends do not increase, or if the values are
1304    /// themselves run length encoded.
1305    pub fn runs(ends: Vec<u32>, values: Vector) -> Result<Self> {
1306        if matches!(values.body, Body::Runs { .. }) {
1307            return Err(Error::internal("runs of runs, which is two searches to read one row"));
1308        }
1309        if ends.len() != values.len() {
1310            return Err(Error::internal(format!(
1311                "{} runs and {} values to put in them",
1312                ends.len(),
1313                values.len()
1314            )));
1315        }
1316        if ends.windows(2).any(|pair| pair[0] >= pair[1]) || ends.first() == Some(&0) {
1317            return Err(Error::internal("run ends that do not increase"));
1318        }
1319        let len = ends.last().copied().unwrap_or(0) as usize;
1320        Ok(Self {
1321            ty: values.ty.clone(),
1322            len,
1323            validity: Validity::AllValid,
1324            body: Body::Runs { ends, values: Arc::new(values) },
1325        })
1326    }
1327
1328    /// The same values as runs, when there are few enough runs for that to be smaller.
1329    ///
1330    /// Costs one pass over the column to find out, which is why this is a call somebody makes rather
1331    /// than something a constructor does. The decision is the same arithmetic every time: a row in
1332    /// flat form costs one value, a run costs one value plus the four bytes of its end, so runs are
1333    /// smaller once there are fewer than about half as many runs as rows, and the narrower the
1334    /// column the more runs it takes. `RUNS_PAY_AT` is that ratio, written down rather than spelt
1335    /// into an `if`, because it is the number a sweep will want to move.
1336    ///
1337    /// Only a flat body is looked at. A constant and a sequence are already one value and two
1338    /// numbers, so there is nothing to win, and a dictionary that is also clustered is a real case
1339    /// that wants its codes run length encoded rather than its values, which is a different function
1340    /// and not this one.
1341    ///
1342    /// Two adjacent nulls are one run. Two adjacent equal values with a null between them are three,
1343    /// because the null is a value of the column as far as anything reading it is concerned.
1344    ///
1345    /// # Errors
1346    ///
1347    /// From the gather this does at the end, and nowhere else. A body that is not flat comes back
1348    /// unchanged rather than as an error, so a nested vector never reaches the part that can fail.
1349    pub fn run_encoded(&self) -> Result<Self> {
1350        let Body::Flat(data) = &self.body else {
1351            return Ok(self.clone());
1352        };
1353        let ends = boundaries(data, &self.validity, self.len);
1354        if ends.len().saturating_mul(RUNS_PAY_AT) >= self.len {
1355            return Ok(self.clone());
1356        }
1357        let starts: Vec<u32> =
1358            std::iter::once(0).chain(ends.iter().copied()).take(ends.len()).collect();
1359        Self::runs(ends, self.gather(&starts)?)
1360    }
1361
1362    /// A vector of `len` integers packed `width` bits each, every one an offset from `base`.
1363    ///
1364    /// The way in for a reader that already has the packed bits, which is what a column file holds
1365    /// and what a network frame carries. Nothing unpacks on the way in, so a scan of a packed column
1366    /// hands the bits straight to the chunk and the cost of the form is paid by whoever reads a
1367    /// value rather than by the scan.
1368    ///
1369    /// The range check is on the two ends rather than on every code, which is the whole check. A
1370    /// code is between zero and `2^width - 1` by construction, so if `base` and `base + 2^width - 1`
1371    /// both fit the column's layout then every value does, and that is two comparisons instead of
1372    /// one per row.
1373    ///
1374    /// # Errors
1375    ///
1376    /// If the type is not one of the integer layouts, if the width is not between one and
1377    /// [`PACKED_WIDTH_MAX`], if there are not enough words for the length, or if either end of the
1378    /// range would not fit the type.
1379    pub fn packed(
1380        ty: LogicalType,
1381        words: Vec<u64>,
1382        width: u32,
1383        base: i128,
1384        len: usize,
1385    ) -> Result<Self> {
1386        let Some((low, high)) = layout_range(&ty) else {
1387            return Err(Error::internal(format!("a {ty} vector has no integer layout to pack")));
1388        };
1389        if width == 0 || width > PACKED_WIDTH_MAX {
1390            return Err(Error::internal(format!(
1391                "a packed width of {width}, which is outside 1 to {PACKED_WIDTH_MAX}"
1392            )));
1393        }
1394        let needed = words_for(len, width);
1395        if words.len() < needed {
1396            return Err(Error::internal(format!(
1397                "{} words for {len} values of {width} bits, which needs {needed}",
1398                words.len()
1399            )));
1400        }
1401        let top = base + i128::from(u64::MAX >> (64 - width));
1402        if base < low || top > high {
1403            return Err(Error::internal(format!(
1404                "packed values from {base} to {top}, which a {ty} cannot hold"
1405            )));
1406        }
1407        Ok(Self {
1408            ty,
1409            len,
1410            validity: Validity::AllValid,
1411            body: Body::Packed { words: Arc::new(words), width, base, offset: 0 },
1412        })
1413    }
1414
1415    /// The same values bit packed, when the range of the column makes that smaller.
1416    ///
1417    /// Costs one pass to find the range and one to write the bits, which is why this is a call
1418    /// somebody makes rather than something a constructor does. It is the counterpart of
1419    /// [`Self::run_encoded`] and the decision has the same shape: a row flat costs the width of its
1420    /// layout, a row packed costs the bits the column's range needs, and the form is worth having
1421    /// only when the second is a good deal smaller than the first. [`PACKING_PAYS_AT`] is that
1422    /// ratio, written down rather than spelt into an `if`, because it is the number a sweep will
1423    /// want to move.
1424    ///
1425    /// Only a flat integer body is looked at. A constant and a sequence are already smaller than any
1426    /// packing of them, a dictionary's codes are the thing that would want packing rather than its
1427    /// values, and a float has no range to pack into since the bits of an `f64` are not an integer
1428    /// that arithmetic on the column agrees with.
1429    ///
1430    /// The range is taken over every slot including the null ones, which hold a zero. A column of
1431    /// large values with one null in it therefore packs a range that reaches down to zero and comes
1432    /// out wider than it needed to be. The alternative is a pass that consults the validity per slot
1433    /// to find the range and a second rule for what to write into a null slot, and this form exists
1434    /// to make reads cheap rather than to squeeze the last bit out of a sparse column.
1435    ///
1436    /// A column whose values are all the same packs to nothing at all, and rather than invent a zero
1437    /// bit code this declines and leaves it to [`Self::run_encoded`], which turns that column into
1438    /// one run and is smaller than any packing of it.
1439    ///
1440    /// # Errors
1441    ///
1442    /// If the packed bits and the length disagree, which would be a bug here rather than a caller
1443    /// doing something wrong.
1444    pub fn bit_packed(&self) -> Result<Self> {
1445        let Body::Flat(data) = &self.body else {
1446            return Ok(self.clone());
1447        };
1448        let Some((low, high)) = span_of(data, self.len) else {
1449            return Ok(self.clone());
1450        };
1451        let Some(range) = high.checked_sub(low).and_then(|range| u64::try_from(range).ok()) else {
1452            return Ok(self.clone());
1453        };
1454        let width = u64::BITS - range.leading_zeros();
1455        if width == 0 || width > PACKED_WIDTH_MAX {
1456            return Ok(self.clone());
1457        }
1458        if words_for(self.len, width) * size_of::<u64>() * PACKING_PAYS_AT > data.footprint() {
1459            return Ok(self.clone());
1460        }
1461        let words = pack(data, self.len, low, width);
1462        let packed = Self::packed(self.ty.clone(), words, width, low, self.len)?;
1463        Ok(packed.with_validity(self.validity.clone()))
1464    }
1465
1466    /// A vector of string views over an arena somebody else is holding too.
1467    ///
1468    /// The way in for a scan that has a page of strings and wants several chunks over it. Each chunk
1469    /// gets its own run of views and they all share the one arena, so the bytes are read where the
1470    /// page put them and nothing copies them.
1471    ///
1472    /// Every view is checked against the arena here rather than when a row is read. That is a pass
1473    /// over the views at construction, which is the same pass the caller just did to build them, and
1474    /// what it buys is that a row of this form cannot resolve to bytes that are not there. The check
1475    /// is on the offsets and not on the bytes, so it says nothing about whether the payload is text,
1476    /// which is the same promise a `BLOB` column makes.
1477    ///
1478    /// # Errors
1479    ///
1480    /// If the type is not one stored as views, or if a view points past the end of the arena.
1481    pub fn string_views(
1482        ty: LogicalType,
1483        views: Vec<StringView>,
1484        arena: Arc<Buffer<u8>>,
1485    ) -> Result<Self> {
1486        if ty.physical() != rudb_common::PhysicalType::Varlen {
1487            return Err(Error::internal(format!("a {ty} vector cannot hold string views")));
1488        }
1489        if views.iter().any(|view| view.bytes_in(&arena).is_none()) {
1490            return Err(Error::internal("a string view points past the end of its arena"));
1491        }
1492        let len = views.len();
1493        Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Views { views, arena } })
1494    }
1495
1496    /// A text vector whose values remain in a storage source until they are read.
1497    pub fn external_text(ty: LogicalType, source: Arc<dyn TextSource>) -> Result<Self> {
1498        if ty.physical() != rudb_common::PhysicalType::Varlen {
1499            return Err(Error::internal(format!(
1500                "a {ty} vector cannot use an external text source"
1501            )));
1502        }
1503        let len = source.len();
1504        Ok(Self { ty, len, validity: Validity::AllValid, body: Body::ExternalText { source } })
1505    }
1506
1507    /// The same strings, in a form where a cut of them does not copy the bytes.
1508    ///
1509    /// The counterpart of [`Self::run_encoded`] and [`Self::bit_packed`] for a string column, and
1510    /// the only one of the three that takes `self` by value. It has to: what it does is move the
1511    /// arena into an `Arc` so nothing copies it again, and a version taking `&self` would start by
1512    /// copying the arena once to have one to move.
1513    ///
1514    /// Anything that is not a flat string column comes back as it was, which includes a column that
1515    /// is already in this form.
1516    ///
1517    /// # Errors
1518    ///
1519    /// Nothing here fails today. The result is a `Result` because the check inside
1520    /// [`Self::string_views`] is worth running on the views this builds rather than trusting that
1521    /// this function built them right.
1522    pub fn shared_text(self) -> Result<Self> {
1523        let Body::Flat(Data::Varlen(column)) = self.body else {
1524            return Ok(self);
1525        };
1526        let (views, arena) = column.into_parts();
1527        let shared = Self::string_views(self.ty, views, Arc::new(arena))?;
1528        Ok(shared.with_validity(self.validity))
1529    }
1530
1531    /// A vector of FSST codes against a table somebody else trained.
1532    ///
1533    /// The way in for a reader that has a page of compressed strings and the table that goes with
1534    /// it. The codes are not copied and the table is not retrained, so laying several chunks over
1535    /// one page costs the spans and nothing else.
1536    ///
1537    /// # Errors
1538    ///
1539    /// If the type is not one stored as text, or if a span runs past the end of the codes.
1540    pub fn coded(
1541        ty: LogicalType,
1542        codes: Arc<Vec<u8>>,
1543        spans: Vec<(u32, u32)>,
1544        table: Arc<SymbolTable>,
1545    ) -> Result<Self> {
1546        if ty.physical() != rudb_common::PhysicalType::Varlen {
1547            return Err(Error::internal(format!("a {ty} vector cannot hold FSST codes")));
1548        }
1549        let end = u32::try_from(codes.len()).unwrap_or(u32::MAX);
1550        if spans.iter().any(|&(from, to)| from > to || to > end) {
1551            return Err(Error::internal("an FSST span runs past the end of the codes"));
1552        }
1553        let len = spans.len();
1554        Ok(Self {
1555            ty,
1556            len,
1557            validity: Validity::AllValid,
1558            body: Body::Coded { codes, spans, table },
1559        })
1560    }
1561
1562    /// The same strings, compressed against a table trained on them.
1563    ///
1564    /// The counterpart of [`Self::run_encoded`] and [`Self::bit_packed`] for a text column, and it
1565    /// takes `self` by value for the reason [`Self::shared_text`] does.
1566    ///
1567    /// The table is trained on every row rather than on a sample. A vector is at most 1024 rows, so
1568    /// the sample would be most of the column anyway, and the systematic sampling
1569    /// `spec/06-compression.md` section 6.3 asks for is a decision about a page and belongs to
1570    /// whoever is holding one.
1571    ///
1572    /// It declines unless the codes are at most half the bytes the strings are. FSST gets about that
1573    /// on text and rather less on anything already short or already random, and below that the
1574    /// decompression per row read is not bought back. A column it declines on comes back as it was.
1575    ///
1576    /// # Errors
1577    ///
1578    /// Nothing here fails today. The result is a `Result` because the checks inside [`Self::coded`]
1579    /// are worth running on what this builds rather than trusting that this built it right.
1580    pub fn compressed(self) -> Result<Self> {
1581        let Body::Flat(Data::Varlen(column)) = &self.body else {
1582            return Ok(self);
1583        };
1584        let rows: Vec<&[u8]> = (0..self.len).filter_map(|row| column.bytes(row)).collect();
1585        if rows.len() != self.len {
1586            return Ok(self);
1587        }
1588        let plain: usize = rows.iter().map(|row| row.len()).sum();
1589        let table = SymbolTable::train(&rows);
1590        let mut codes = Vec::with_capacity(plain);
1591        let mut spans = Vec::with_capacity(self.len);
1592        for row in &rows {
1593            let from = u32::try_from(codes.len()).unwrap_or(u32::MAX);
1594            table.compress(row, &mut codes);
1595            spans.push((from, u32::try_from(codes.len()).unwrap_or(u32::MAX)));
1596        }
1597        if codes.len() * FSST_PAYS_AT > plain {
1598            return Ok(self);
1599        }
1600        let coded = Self::coded(self.ty.clone(), Arc::new(codes), spans, Arc::new(table))?;
1601        Ok(coded.with_validity(self.validity.clone()))
1602    }
1603
1604    /// The same values under a wider decimal type that stores them the same way.
1605    ///
1606    /// A decimal is kept as its unscaled integer, so two decimal types with one scale and one
1607    /// storage width describe the same bits, and going from the narrower of them to the wider is a
1608    /// relabelling rather than a conversion. The binder writes three of those into
1609    /// `l_extendedprice * (1 - l_discount)`, because a product's operands are given the answer's
1610    /// width and the answer's width is eighteen while both columns are fifteen, and each one was a
1611    /// pass over six million rows that wrote back the bytes it had just read.
1612    ///
1613    /// A flat run only, and deliberately. The general cast flattens whatever it is given, so a
1614    /// dictionary column came out of a width change as a run of values, and a relabelling that kept
1615    /// the dictionary would hand the arithmetic above two columns it has to read through a code per
1616    /// row instead of two it can read end to end. That was measured and it is the worse of the two:
1617    /// on `sum(l_extendedprice * l_discount)` under the filter q6 puts on it, where the rows left
1618    /// are few and scattered and the indirection is a cache miss each, keeping the dictionary cost
1619    /// half again as much as the flattening it saved. The flat case has no such question, since
1620    /// what it hands on is exactly what the pass would have built.
1621    ///
1622    /// Only widening, because a narrower width is a range every value has to be checked against and
1623    /// checking it is the pass this exists to avoid. `None` for anything else, including a narrower
1624    /// width, a changed scale, a changed storage width and any form but the flat one.
1625    #[must_use]
1626    pub fn as_wider_decimal(&self, target: &LogicalType) -> Option<Self> {
1627        let (
1628            LogicalType::Decimal { width: from, scale: held },
1629            LogicalType::Decimal { width: into, scale },
1630        ) = (&self.ty, target)
1631        else {
1632            return None;
1633        };
1634        if held != scale || from > into || self.ty.decimal_storage() != target.decimal_storage() {
1635            return None;
1636        }
1637        // Nothing in a flat run says what its numbers mean, so the relabelling is the type and
1638        // nothing else, and the buffer underneath is shared rather than copied.
1639        if !matches!(self.body, Body::Flat(_)) {
1640            return None;
1641        }
1642        Some(Self {
1643            ty: target.clone(),
1644            len: self.len,
1645            validity: self.validity.clone(),
1646            body: self.body.clone(),
1647        })
1648    }
1649
1650    /// The same vector with a different validity.
1651    #[must_use]
1652    pub fn with_validity(mut self, validity: Validity) -> Self {
1653        self.validity = validity;
1654        self
1655    }
1656
1657    /// What kind of values these are.
1658    #[must_use]
1659    pub fn logical_type(&self) -> &LogicalType {
1660        &self.ty
1661    }
1662
1663    /// How many values there are.
1664    #[must_use]
1665    pub fn len(&self) -> usize {
1666        self.len
1667    }
1668
1669    /// Whether there are no values.
1670    #[must_use]
1671    pub fn is_empty(&self) -> bool {
1672        self.len == 0
1673    }
1674
1675    /// How many bytes of memory this vector is holding.
1676    ///
1677    /// What the memory limit charges for it. A constant and a sequence hold one value and two
1678    /// numbers however long they are, which is the point of both forms, so the number here is the
1679    /// form's cost and not the column's width times its length.
1680    ///
1681    /// A part that is behind an `Arc` counts as one holder's share of it, which is
1682    /// [`Buffer::footprint`]'s rule for a shared page applied to the other shared parts. A
1683    /// dictionary counted in full in every vector sharing it is not a conservative over count, it is
1684    /// a number with the chunk count in it: an aggregate that emits nineteen thousand chunks of
1685    /// groups out of one stable dictionary reported that dictionary nineteen thousand times and
1686    /// refused itself a budget of twenty five gigabytes while the process held one. Dividing by the
1687    /// holders makes the sum over everything sharing the part come to about the part, which is what
1688    /// the number is supposed to mean, and it errs high rather than low whenever the holders arrive
1689    /// one after another, because each of them counts what it sees at the time it asks.
1690    #[must_use]
1691    pub fn footprint(&self) -> usize {
1692        let body = match &self.body {
1693            Body::Flat(data) => data.footprint(),
1694            Body::Constant(value) => value.footprint(),
1695            Body::Sequence { .. } => 0,
1696            Body::Dictionary { codes, values, .. } => {
1697                codes.capacity() * size_of::<u32>() + share(values.footprint(), values)
1698            }
1699            Body::Packed { words, .. } => share(words.capacity() * size_of::<u64>(), words),
1700            Body::Views { views, arena } => {
1701                views.capacity() * size_of::<StringView>() + share(arena.footprint(), arena)
1702            }
1703            Body::ExternalText { source } => share(source.footprint(), source),
1704            Body::Coded { codes, spans, table } => {
1705                share(codes.capacity(), codes)
1706                    + spans.capacity() * size_of::<(u32, u32)>()
1707                    + share(table.footprint(), table)
1708            }
1709            Body::Runs { ends, values } => {
1710                ends.capacity() * size_of::<u32>() + share(values.footprint(), values)
1711            }
1712            // The ids are shared between every cut of one link join's output, and the source is
1713            // shared with every other column gathered off the same parent, so both are divided by
1714            // their holders for the reason the dictionary above is. A gather whose source counted in
1715            // full would report a parent table per projected column per chunk.
1716            Body::Gathered { source, rids, .. } => {
1717                share(rids.capacity() * size_of::<u32>(), rids) + share(source.footprint(), source)
1718            }
1719            Body::Nested { entries, child } => {
1720                entries.capacity() * size_of::<(u32, u32)>() + share(child.footprint(), child)
1721            }
1722            // A struct is as wide as its fields are, so this is the one body whose cost is a sum
1723            // over children rather than one number, and a struct of a hundred narrow fields costs
1724            // what the hundred columns cost.
1725            Body::Fields { children } => {
1726                children.capacity() * size_of::<Arc<Self>>()
1727                    + children.iter().map(|child| share(child.footprint(), child)).sum::<usize>()
1728            }
1729        };
1730        size_of::<Self>() + self.validity.footprint() + body
1731    }
1732
1733    /// Which of the values are not null, at this level and no deeper.
1734    ///
1735    /// This is not the same question as [`Self::is_null_at`] and the difference has already cost
1736    /// one wrong answer. A dictionary and a run length vector keep their nulls in the values they
1737    /// point at rather than in a mask of their own, so both are built with every row marked present
1738    /// here and a row whose value is null reads as valid. A caller that wants to know whether a row
1739    /// is null wants the other one. A caller that wants the mask of a flat column, to copy it or to
1740    /// count it, wants this one.
1741    #[must_use]
1742    pub fn validity(&self) -> &Validity {
1743        &self.validity
1744    }
1745
1746    /// Whether the row at `index` is null, in whichever form the vector is in.
1747    ///
1748    /// Reads through a dictionary or a run to the value it stands for, which is where those two
1749    /// forms keep their nulls, and answers from the mask for every other form. A row past the end
1750    /// is null, the same answer [`Self::value_at`] gives it.
1751    #[must_use]
1752    pub fn is_null_at(&self, index: usize) -> bool {
1753        if index >= self.len || !self.validity.is_valid(index) {
1754            return true;
1755        }
1756        match &self.body {
1757            Body::Dictionary { codes, values, .. } => match codes.get(index) {
1758                Some(&code) => values.is_null_at(code as usize),
1759                None => true,
1760            },
1761            Body::Runs { ends, values } => match run_holding(ends, index) {
1762                Some(run) => values.is_null_at(run),
1763                None => true,
1764            },
1765            // Section 8.2's lazy validity, which is this line. A gather has no mask of its own and
1766            // does not need one: the id says whether there is a row and the source says whether that
1767            // row is null, and both of those are already in memory.
1768            Body::Gathered { source, rids, offset } => match rids.get(offset + index) {
1769                Some(&NO_ROW) | None => true,
1770                Some(&rid) => source.is_null_at(rid as usize),
1771            },
1772            _ => false,
1773        }
1774    }
1775
1776    /// Whether no row in range is null, answered without reading a row.
1777    ///
1778    /// This is the cheap side of [`Self::is_null_at`] and has to follow it exactly. A dictionary and
1779    /// a run keep their nulls in the values they stand for, so both levels have to say they have
1780    /// none. Every other form answers from its own mask. A false means only that the cheap answer
1781    /// was not available, so a caller that gets one still has to ask row by row.
1782    ///
1783    /// Public because the alternative a caller has is a pass over the values, and on a dictionary
1784    /// that is the size of a Parquet column chunk's that pass is the thing it was trying to avoid.
1785    #[must_use]
1786    pub fn never_null(&self) -> bool {
1787        if self.validity.has_nulls(self.len) {
1788            return false;
1789        }
1790        match &self.body {
1791            Body::Dictionary { values, .. } | Body::Runs { values, .. } => values.never_null(),
1792            // A gather is never null when no id is the sentinel and the source holds no nulls. The
1793            // first of those is a pass over the ids rather than a constant, which is the one place
1794            // this question is not free, and it is worth paying: the ids are four bytes a row and
1795            // contiguous, and the alternative is reading through to the source once per row for the
1796            // whole vector, which is the random access this form exists to postpone.
1797            Body::Gathered { source, rids, offset } => {
1798                source.never_null()
1799                    && !rids[*offset..].iter().take(self.len).any(|&rid| rid == NO_ROW)
1800            }
1801            _ => true,
1802        }
1803    }
1804
1805    /// Which physical form this vector is in.
1806    #[must_use]
1807    pub fn form(&self) -> Form {
1808        match self.body {
1809            Body::Flat(_) => Form::Flat,
1810            Body::Constant(_) => Form::Constant,
1811            Body::Sequence { .. } => Form::Sequence,
1812            Body::Dictionary { .. } => Form::Dictionary,
1813            Body::Packed { .. } => Form::BitPacked,
1814            Body::Views { .. } => Form::StringView,
1815            Body::ExternalText { .. } => Form::StringView,
1816            Body::Coded { .. } => Form::Fsst,
1817            Body::Runs { .. } => Form::Rle,
1818            Body::Nested { .. } => Form::List,
1819            Body::Fields { .. } => Form::Struct,
1820            Body::Gathered { .. } => Form::Gathered,
1821        }
1822    }
1823
1824    /// The data, for a flat vector, and `None` for any other form.
1825    ///
1826    /// A kernel that wants a slice asks for it and takes the flat path if it gets one. A kernel
1827    /// that can do better on a constant or a dictionary checks [`Self::form`] first.
1828    #[must_use]
1829    pub fn data(&self) -> Option<&Data> {
1830        match &self.body {
1831            Body::Flat(data) => Some(data),
1832            _ => None,
1833        }
1834    }
1835
1836    /// The one value, for a constant vector, and `None` for any other form.
1837    ///
1838    /// A kernel comparing a column against a literal wants the literal once rather than 1024
1839    /// times, and [`Self::value_at`] on a constant clones it on every call because it has to be
1840    /// able to hand back a `Value` for any form. This is the accessor that lets the specialized
1841    /// path hoist the clone out of the loop.
1842    #[must_use]
1843    pub fn constant_value(&self) -> Option<&Value> {
1844        match &self.body {
1845            Body::Constant(value) => Some(value.as_ref()),
1846            _ => None,
1847        }
1848    }
1849
1850    /// The codes and the values, for a dictionary vector, and `None` for any other form.
1851    ///
1852    /// The reason a kernel needs this rather than reading the dictionary through
1853    /// [`Self::value_at`] is the entire argument for the form existing. A filter against a
1854    /// dictionary column of 1024 rows and 40 distinct values is 40 comparisons and 1024 lookups,
1855    /// not 1024 comparisons, and there is no way to write that loop without seeing the codes.
1856    ///
1857    /// Note what the validity of the returned vector means. A dictionary keeps its nulls in the
1858    /// vector it points at, and the dictionary's own validity says nothing about them, so a caller
1859    /// deciding whether row `i` is null has to ask the value vector about `codes[i]` rather than
1860    /// asking this vector about `i`. [`Self::flatten`] has the same note on it for the same
1861    /// reason, because getting this wrong is a null that survives being selected and comes out as
1862    /// a zero.
1863    #[must_use]
1864    pub fn dictionary_parts(&self) -> Option<(&[u32], &Self)> {
1865        match &self.body {
1866            Body::Dictionary { codes, values, .. } => Some((codes, values.as_ref())),
1867            _ => None,
1868        }
1869    }
1870
1871    /// The codes and the shared dictionary handle for a dictionary vector.
1872    ///
1873    /// Storage readers use the identity of this handle to prove that codes from separate pages
1874    /// belong to one table-wide dictionary. Kernels that only read values should continue to use
1875    /// [`Self::dictionary_parts`].
1876    #[must_use]
1877    pub fn shared_dictionary_parts(&self) -> Option<(&[u32], &Arc<Self>)> {
1878        match &self.body {
1879            Body::Dictionary { codes, values, .. } => Some((codes, values)),
1880            _ => None,
1881        }
1882    }
1883
1884    /// Stable codes and their shared values, when storage guarantees one code space across pages.
1885    #[must_use]
1886    pub fn stable_dictionary_parts(&self) -> Option<(&[u32], &Arc<Self>)> {
1887        match &self.body {
1888            Body::Dictionary { codes, values, stable: true } => Some((codes, values)),
1889            _ => None,
1890        }
1891    }
1892
1893    /// The run ends and the run values, for a run length vector, and `None` for any other form.
1894    ///
1895    /// The ends are exclusive and increasing, and there is exactly one value per run, so a kernel
1896    /// that wants to walk this walks the pairs and never asks which run a row is in. That is the
1897    /// whole argument for the form: an aggregate over a clustered column is one multiply per run
1898    /// instead of one add per row, and there is no way to write that loop without seeing the ends.
1899    ///
1900    /// The nulls are in the values, the way a dictionary's are, so a caller deciding whether row `i`
1901    /// is null asks the value vector about the run rather than asking this vector about `i`.
1902    #[must_use]
1903    pub fn run_parts(&self) -> Option<(&[u32], &Self)> {
1904        match &self.body {
1905            Body::Runs { ends, values } => Some((ends, values.as_ref())),
1906            _ => None,
1907        }
1908    }
1909
1910    /// Where each row's value is, for the two forms that keep their values somewhere else.
1911    ///
1912    /// A dictionary and a run length vector are the same shape seen from a kernel: a run of
1913    /// positions and a vector to read them out of. The difference is that a dictionary stores the
1914    /// positions and a run length vector works them out, and a kernel writing `values[at[row]]` does
1915    /// not care which. So every specialization written against [`Self::dictionary_parts`] covers
1916    /// both forms by asking this instead, and the day a third form with an indirection arrives it
1917    /// covers that one too without any of those kernels being reopened.
1918    ///
1919    /// The run length side costs an allocation of one position per row and a pass to fill it, which
1920    /// is the same four bytes a row a dictionary was already carrying and is paid once per kernel
1921    /// call rather than once per row. That is the price of this being one accessor rather than a
1922    /// second arm in eighteen kernels, and it is not the last word: a kernel that wants a run at a
1923    /// time reads [`Self::run_parts`] and pays nothing, which is the specialization this makes it
1924    /// possible to skip writing until a sweep says it is worth it.
1925    #[must_use]
1926    pub fn positions(&self) -> Option<(Cow<'_, [u32]>, &Self)> {
1927        match &self.body {
1928            Body::Dictionary { codes, values, .. } => Some((Cow::Borrowed(codes), values.as_ref())),
1929            Body::Runs { ends, values } => {
1930                let mut at = Vec::with_capacity(self.len);
1931                for (run, &stop) in ends.iter().enumerate() {
1932                    let run = u32::try_from(run).unwrap_or(u32::MAX);
1933                    at.resize(stop as usize, run);
1934                }
1935                Some((Cow::Owned(at), values.as_ref()))
1936            }
1937            _ => None,
1938        }
1939    }
1940
1941    /// The bits and what they mean, for a bit packed vector, and `None` for any other form.
1942    ///
1943    /// What a kernel needs to stay in code space. A comparison against a literal is the case that
1944    /// pays: `column > 900` over a column packed from a base of 40 is `code > 860`, which is the
1945    /// same shift and mask the read was going to do anyway and no unpacking at all, and a literal
1946    /// outside the packed range answers the whole vector without reading a bit of it. None of that
1947    /// can be written without seeing the width and the base.
1948    #[must_use]
1949    pub fn packed_parts(&self) -> Option<Packed<'_>> {
1950        match &self.body {
1951            Body::Packed { words, width, base, offset } => {
1952                Some(Packed { words, width: *width, base: *base, offset: *offset })
1953            }
1954            _ => None,
1955        }
1956    }
1957
1958    /// The views and the arena, for either form that stores strings, and `None` for the rest.
1959    ///
1960    /// This is to the two string forms what [`Self::positions`] is to the two forms that point
1961    /// somewhere else. A flat varchar column owns its arena and a string view column shares one, and
1962    /// a kernel reading a row wants the view and the bytes either way, so every specialization
1963    /// written against this covers both forms and neither has to be reopened when a third way of
1964    /// holding an arena arrives.
1965    ///
1966    /// The arena is whatever the long strings live in, which for a column over a page is the page,
1967    /// including the parts of it no view points at. Only the views say which bytes are a row.
1968    #[must_use]
1969    pub fn text_parts(&self) -> Option<(&[StringView], &[u8])> {
1970        match &self.body {
1971            Body::Flat(Data::Varlen(column)) => Some((column.views(), column.arena())),
1972            Body::Views { views, arena } => Some((views, arena)),
1973            _ => None,
1974        }
1975    }
1976
1977    /// The codes and the table, for an FSST vector, and `None` for any other form.
1978    ///
1979    /// What a kernel needs to stay in code space. An equality filter is the case that pays, and it
1980    /// pays completely: the literal is compressed once against the same table and after that a row
1981    /// matches exactly when its code bytes match, because compressing is a function and so is
1982    /// decompressing. No row is decompressed at all. An ordering comparison cannot do that, since a
1983    /// symbol code says nothing about where its symbol sorts, so those decompress and say so.
1984    #[must_use]
1985    pub fn coded_parts(&self) -> Option<Coded<'_>> {
1986        match &self.body {
1987            Body::Coded { codes, spans, table } => Some(Coded { codes, spans, table }),
1988            _ => None,
1989        }
1990    }
1991
1992    /// The start and the step, for a sequence vector, and `None` for any other form.
1993    #[must_use]
1994    pub fn sequence_parts(&self) -> Option<(i64, i64)> {
1995        match self.body {
1996            Body::Sequence { start, step } => Some((start, step)),
1997            _ => None,
1998        }
1999    }
2000
2001    /// The value at `index`, as a single value.
2002    ///
2003    /// This is the slow path on purpose. It is what a result set is read out with and what a test
2004    /// asserts on, and an operator that calls it per row is an operator that has already lost the
2005    /// argument the vector interface exists to win.
2006    #[must_use]
2007    pub fn value_at(&self, index: usize) -> Value {
2008        if index >= self.len || !self.validity.is_valid(index) {
2009            return Value::Null;
2010        }
2011        match &self.body {
2012            Body::Constant(value) => value.as_ref().clone(),
2013            Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
2014            Body::Dictionary { codes, values, .. } => match codes.get(index) {
2015                Some(&code) => values.value_at(code as usize),
2016                None => Value::Null,
2017            },
2018            Body::Runs { ends, values } => match run_holding(ends, index) {
2019                Some(run) => values.value_at(run),
2020                None => Value::Null,
2021            },
2022            // The one read every other reader of this form is: follow the id, and answer null when
2023            // there is no row to follow. Written out once per reader rather than through a helper
2024            // because each of them returns a different kind of nothing.
2025            Body::Gathered { source, rids, offset } => match rids.get(offset + index) {
2026                Some(&NO_ROW) | None => Value::Null,
2027                Some(&rid) => source.value_at(rid as usize),
2028            },
2029            // One value unpacked into a run of one, so that what a packed value means is decided in
2030            // the same place a flat one is rather than in a second copy of the type mapping that
2031            // could drift from it. It allocates, which this path is allowed to do and the typed
2032            // unpack in `copied` is not, and it is the reason anything about to read a packed
2033            // column a row at a time should flatten it once instead.
2034            Body::Packed { words, width, base, offset } => {
2035                unpack(&self.ty, words, *offset, *width, *base, &[index])
2036                    .map_or(Value::Null, |data| value_from(&self.ty, &data, 0))
2037            }
2038            // The bytes are where the arena has them, and what they are read as is the logical
2039            // type's business, so this hands the row to the same reader a flat column goes through
2040            // rather than deciding here that a `BLOB` is a string.
2041            Body::Views { views, arena } => {
2042                match views.get(index).and_then(|v| v.bytes_in(arena)) {
2043                    Some(bytes) => bytes_as(&self.ty, bytes),
2044                    None => Value::Null,
2045                }
2046            }
2047            Body::ExternalText { source } => source
2048                .bytes_at(index)
2049                .ok()
2050                .flatten()
2051                .map_or(Value::Null, |bytes| bytes_as(&self.ty, bytes)),
2052            // One row decompressed on its own, which is the property the form is chosen for. It
2053            // allocates, which this path is allowed to do, and it is the reason anything about to
2054            // read a compressed column a row at a time should flatten it once instead.
2055            Body::Coded { codes, spans, table } => {
2056                match spans.get(index).and_then(|&(from, to)| {
2057                    let mut out = Vec::new();
2058                    table.decompress(codes.get(from as usize..to as usize)?, &mut out).ok()?;
2059                    Some(out)
2060                }) {
2061                    Some(bytes) => bytes_as(&self.ty, &bytes),
2062                    None => Value::Null,
2063                }
2064            }
2065            // A row's elements are read out of the child one at a time, which is the slow path this
2066            // whole function is and is why a kernel over a list column reads `list_parts` instead.
2067            // The element type comes from the child rather than from this vector's type, so a list
2068            // whose child was built narrower than the column claims still hands back what is in it.
2069            //
2070            // A map is stored in this body too, so which value comes out is decided by the logical
2071            // type rather than by the body. That is the one place the composition shows: the bytes of
2072            // a map really are the bytes of a list of two field structs, and the only thing that
2073            // remembers it is a map is the type.
2074            Body::Nested { entries, child } => match (entries.get(index), &self.ty) {
2075                (Some(&(start, len)), LogicalType::Map(key, value)) => {
2076                    let pairs = child.struct_parts().unwrap_or_default();
2077                    Value::map(
2078                        key.as_ref().clone(),
2079                        value.as_ref().clone(),
2080                        (start..start + len)
2081                            .filter_map(|at| {
2082                                let [keys, values] = pairs else { return None };
2083                                Some((keys.value_at(at as usize), values.value_at(at as usize)))
2084                            })
2085                            .collect(),
2086                    )
2087                }
2088                (Some(&(start, len)), _) => Value::List {
2089                    element: child.ty.clone(),
2090                    values: (start..start + len).map(|at| child.value_at(at as usize)).collect(),
2091                },
2092                (None, _) => Value::Null,
2093            },
2094            // One value read out of each child at the same position, which is the slow path this whole
2095            // function is and is why a kernel over a struct column reads `struct_parts` instead. The
2096            // names come from this vector's type rather than from the children, because a child is a
2097            // vector and a vector has no name, and the type is where the field order is written down.
2098            Body::Fields { children } => Value::Struct(
2099                fields_of(&self.ty)
2100                    .iter()
2101                    .zip(children)
2102                    .map(|(field, child)| (field.name.clone(), child.value_at(index)))
2103                    .collect(),
2104            ),
2105            Body::Flat(data) => value_from(&self.ty, data, index),
2106        }
2107    }
2108
2109    /// One value of this vector's type, built out of bytes the caller already holds.
2110    ///
2111    /// [`try_value_at`](Self::try_value_at) finds the bytes itself, which over a dictionary that
2112    /// keeps its payload in a file means a read. A caller that swept the values out has the bytes in
2113    /// hand already and wants nothing from here but the type.
2114    pub fn value_of(&self, bytes: &[u8]) -> Value {
2115        bytes_as(&self.ty, bytes)
2116    }
2117
2118    /// The value at `index`, preserving storage read and validation failures.
2119    pub fn try_value_at(&self, index: usize) -> Result<Value> {
2120        if index >= self.len || !self.validity.is_valid(index) {
2121            return Ok(Value::Null);
2122        }
2123        match &self.body {
2124            Body::ExternalText { source } => {
2125                Ok(source.bytes_at(index)?.map_or(Value::Null, |bytes| bytes_as(&self.ty, bytes)))
2126            }
2127            Body::Dictionary { codes, values, .. } => match codes.get(index) {
2128                Some(&code) => values.try_value_at(code as usize),
2129                None => Ok(Value::Null),
2130            },
2131            Body::Runs { ends, values } => match run_holding(ends, index) {
2132                Some(run) => values.try_value_at(run),
2133                None => Ok(Value::Null),
2134            },
2135            Body::Nested { entries, child } => match (entries.get(index), &self.ty) {
2136                (Some(&(start, len)), LogicalType::Map(key, value)) => {
2137                    let pairs = child.struct_parts().unwrap_or_default();
2138                    let [keys, values] = pairs else { return Ok(Value::Null) };
2139                    let mut entries = Vec::with_capacity(len as usize);
2140                    for at in start..start + len {
2141                        entries.push((
2142                            keys.try_value_at(at as usize)?,
2143                            values.try_value_at(at as usize)?,
2144                        ));
2145                    }
2146                    Ok(Value::map(key.as_ref().clone(), value.as_ref().clone(), entries))
2147                }
2148                (Some(&(start, len)), _) => {
2149                    let mut values = Vec::with_capacity(len as usize);
2150                    for at in start..start + len {
2151                        values.push(child.try_value_at(at as usize)?);
2152                    }
2153                    Ok(Value::List { element: child.ty.clone(), values })
2154                }
2155                (None, _) => Ok(Value::Null),
2156            },
2157            Body::Fields { children } => {
2158                let mut values = Vec::with_capacity(children.len());
2159                for (field, child) in fields_of(&self.ty).iter().zip(children) {
2160                    values.push((field.name.clone(), child.try_value_at(index)?));
2161                }
2162                Ok(Value::Struct(values))
2163            }
2164            _ => Ok(self.value_at(index)),
2165        }
2166    }
2167
2168    /// The text at `index`, borrowed rather than copied.
2169    ///
2170    /// [`Self::value_at`] on a `VARCHAR` column allocates a `String` per call, and a group by that
2171    /// reads a string column keys on one string per input row. This hands back the bytes where they
2172    /// already are, so a caller with somewhere to put them does not go to the allocator at all.
2173    ///
2174    /// `None` for a null, for an index past the end, for a column that is not `VARCHAR`, and for the
2175    /// constant and sequence forms, whose values are not stored per position. A caller that gets
2176    /// `None` has to fall back to [`Self::value_at`], which is correct for all of those.
2177    #[must_use]
2178    pub fn text_at(&self, index: usize) -> Option<&str> {
2179        if self.ty != LogicalType::Varchar || index >= self.len || !self.validity.is_valid(index) {
2180            return None;
2181        }
2182        match &self.body {
2183            Body::Flat(data) => data.str_at(index),
2184            Body::Dictionary { codes, values, .. } => {
2185                values.text_at(usize::try_from(*codes.get(index)?).ok()?)
2186            }
2187            Body::Runs { ends, values } => values.text_at(run_holding(ends, index)?),
2188            Body::Gathered { source, rids, offset } => {
2189                source.text_at(row_of(rids, *offset, index)?)
2190            }
2191            Body::Views { views, arena } => {
2192                std::str::from_utf8(views.get(index)?.bytes_in(arena)?).ok()
2193            }
2194            Body::ExternalText { source } => {
2195                std::str::from_utf8(source.bytes_at(index).ok().flatten()?).ok()
2196            }
2197            _ => None,
2198        }
2199    }
2200
2201    /// The variable length bytes at `index`, borrowed without validating or copying them.
2202    ///
2203    /// String data is validated when it enters a vector. Hashing and equality only need its bytes,
2204    /// so those kernels should not pay for UTF-8 validation again on every read.
2205    #[must_use]
2206    pub fn bytes_at(&self, index: usize) -> Option<&[u8]> {
2207        if index >= self.len || !self.validity.is_valid(index) {
2208            return None;
2209        }
2210        match &self.body {
2211            Body::Constant(value) => match value.as_ref() {
2212                Value::Varchar(text) => Some(text.as_bytes()),
2213                Value::Blob(bytes) => Some(bytes),
2214                _ => None,
2215            },
2216            Body::Dictionary { codes, values, .. } => {
2217                values.bytes_at(usize::try_from(*codes.get(index)?).ok()?)
2218            }
2219            Body::Runs { ends, values } => values.bytes_at(run_holding(ends, index)?),
2220            Body::Gathered { source, rids, offset } => {
2221                source.bytes_at(row_of(rids, *offset, index)?)
2222            }
2223            Body::Views { views, arena } => views.get(index)?.bytes_in(arena),
2224            Body::ExternalText { source } => source.bytes_at(index).ok().flatten(),
2225            Body::Flat(data) => data.bytes_at(index),
2226            // The same `None` [`Self::text_at`] gives, for the same reason. A compressed row is not
2227            // anywhere in its plain bytes, so there is nothing here to hand back a borrow of, and a
2228            // caller that gets `None` goes to `value_at` and gets the row decompressed into a value.
2229            // A list row is `None` for a nearer reason: it is not bytes at all, and a caller wanting
2230            // its elements wants [`Self::list_parts`] rather than a borrow of one row.
2231            Body::Coded { .. }
2232            | Body::Sequence { .. }
2233            | Body::Packed { .. }
2234            | Body::Nested { .. }
2235            | Body::Fields { .. } => None,
2236        }
2237    }
2238
2239    /// Variable length bytes at `index`, preserving storage read and validation failures.
2240    pub fn try_bytes_at(&self, index: usize) -> Result<Option<&[u8]>> {
2241        if index >= self.len || !self.validity.is_valid(index) {
2242            return Ok(None);
2243        }
2244        match &self.body {
2245            Body::Constant(value) => Ok(match value.as_ref() {
2246                Value::Varchar(text) => Some(text.as_bytes()),
2247                Value::Blob(bytes) => Some(bytes.as_slice()),
2248                _ => None,
2249            }),
2250            Body::Dictionary { codes, values, .. } => match codes.get(index) {
2251                Some(&code) => values.try_bytes_at(code as usize),
2252                None => Ok(None),
2253            },
2254            Body::Runs { ends, values } => match run_holding(ends, index) {
2255                Some(run) => values.try_bytes_at(run),
2256                None => Ok(None),
2257            },
2258            Body::Gathered { source, rids, offset } => match row_of(rids, *offset, index) {
2259                Some(row) => source.try_bytes_at(row),
2260                None => Ok(None),
2261            },
2262            Body::Views { views, arena } => {
2263                Ok(views.get(index).and_then(|view| view.bytes_in(arena)))
2264            }
2265            Body::ExternalText { source } => source.bytes_at(index),
2266            Body::Flat(data) => Ok(data.bytes_at(index)),
2267            Body::Coded { .. }
2268            | Body::Sequence { .. }
2269            | Body::Packed { .. }
2270            | Body::Nested { .. }
2271            | Body::Fields { .. } => Ok(None),
2272        }
2273    }
2274
2275    /// Walks the values from `first` up to at most `limit`, without keeping what it read.
2276    ///
2277    /// [`TextSource::sweep`] is what this is for and what the doc on it explains. Everything else
2278    /// here is the honest fallback: a vector that is not reading text out of a file has its values
2279    /// already, so there is nothing to avoid keeping, and it hands over one value and lets the
2280    /// caller come back. The answer is one past the last value visited either way, so the loop that
2281    /// calls this is the same loop whichever form it got.
2282    ///
2283    /// Nulls go the slow way. A source that reads a file holds no validity of its own, so the
2284    /// vector's own mask is the only thing that knows, and rather than teach the sweep about it the
2285    /// one form that can have both hands over a value at a time through the reader that checks.
2286    ///
2287    /// # Errors
2288    ///
2289    /// Whatever reading a value raises, and whatever `body` raises.
2290    pub fn sweep_text(
2291        &self,
2292        first: usize,
2293        limit: usize,
2294        body: &mut dyn FnMut(usize, &[u8]) -> Result<()>,
2295    ) -> Result<usize> {
2296        let limit = limit.min(self.len);
2297        if first >= limit {
2298            return Ok(first);
2299        }
2300        if let Body::ExternalText { source } = &self.body {
2301            if matches!(self.validity, Validity::AllValid) {
2302                return source.sweep(first, limit, body);
2303            }
2304        }
2305        body(first, self.try_bytes_at(first)?.unwrap_or_default())?;
2306        Ok(first + 1)
2307    }
2308
2309    /// A conservative substring test for the payload block holding `first`.
2310    ///
2311    /// Only a file-backed string source with all-valid values can skip a whole block. Every other
2312    /// form returns true and lets the ordinary sweep decide its values.
2313    pub fn text_block_might_contain(&self, first: usize, literal: &[u8]) -> Result<bool> {
2314        match &self.body {
2315            Body::ExternalText { source } if matches!(self.validity, Validity::AllValid) => {
2316                source.might_contain(first, literal)
2317            }
2318            _ => Ok(true),
2319        }
2320    }
2321
2322    /// The values at `indices`, which rise, without keeping what reading them decoded.
2323    ///
2324    /// [`TextSource::visit`] is what this is for. A vector that is not reading text out of a file, or
2325    /// that has nulls of its own, reads a value at a time through the reader that checks.
2326    ///
2327    /// # Errors
2328    ///
2329    /// Whatever reading a value raises.
2330    pub fn try_values_visited(&self, indices: &[usize]) -> Result<Vec<Value>> {
2331        if let Body::ExternalText { source } = &self.body {
2332            if matches!(self.validity, Validity::AllValid) {
2333                let mut out = vec![Value::Null; indices.len()];
2334                let mut own = |at: usize, bytes: &[u8]| {
2335                    if indices[at] < self.len {
2336                        out[at] = bytes_as(&self.ty, bytes);
2337                    }
2338                    Ok(())
2339                };
2340                source.visit(indices, &mut own)?;
2341                return Ok(out);
2342            }
2343        }
2344        indices.iter().map(|&index| self.try_value_at(index)).collect()
2345    }
2346
2347    /// Variable length byte count at `index`, preserving storage failures.
2348    pub fn try_bytes_len_at(&self, index: usize) -> Result<Option<usize>> {
2349        if index >= self.len || !self.validity.is_valid(index) {
2350            return Ok(None);
2351        }
2352        match &self.body {
2353            Body::Dictionary { codes, values, .. } => match codes.get(index) {
2354                Some(&code) => values.try_bytes_len_at(code as usize),
2355                None => Ok(None),
2356            },
2357            Body::Runs { ends, values } => match run_holding(ends, index) {
2358                Some(run) => values.try_bytes_len_at(run),
2359                None => Ok(None),
2360            },
2361            Body::ExternalText { source } => source.bytes_len_at(index),
2362            _ => Ok(self.bytes_at(index).map(<[u8]>::len)),
2363        }
2364    }
2365
2366    /// The byte length of every row, in one call to whatever holds the text, when that is possible.
2367    ///
2368    /// `into` is one slot per row. The answer is whether it was filled: a vector with nulls in it,
2369    /// or one whose text is not read from a [`TextSource`], answers `false` and leaves the caller to
2370    /// ask a row at a time through [`Self::try_bytes_len_at`], which is right for every shape. The
2371    /// two shapes taken here are the two a scan of a stored string column hands out, the text itself
2372    /// and a dictionary of codes over it, and each is one call to the source for the whole vector
2373    /// rather than a call per row down through this type.
2374    ///
2375    /// # Errors
2376    ///
2377    /// Whatever reading the lengths out of storage raises.
2378    pub fn try_bytes_lens(&self, into: &mut [i64]) -> Result<bool> {
2379        if into.len() != self.len || !matches!(self.validity, Validity::AllValid) {
2380            return Ok(false);
2381        }
2382        match &self.body {
2383            Body::ExternalText { source } => {
2384                let Ok(rows) = u32::try_from(self.len) else { return Ok(false) };
2385                let indices = (0..rows).collect::<Vec<_>>();
2386                source.bytes_lens_at(&indices, into)?;
2387                Ok(true)
2388            }
2389            Body::Dictionary { codes, values, .. } => match &values.body {
2390                Body::ExternalText { source } if matches!(values.validity, Validity::AllValid) => {
2391                    source.bytes_lens_at(codes, into)?;
2392                    Ok(true)
2393                }
2394                _ => Ok(false),
2395            },
2396            _ => Ok(false),
2397        }
2398    }
2399
2400    /// How many ranks this vector's values have in sorted order, when whatever holds them knows.
2401    ///
2402    /// See [`TextSource::ranks`] for what a rank is and what a source promises by answering with
2403    /// one. Only a vector whose values come from storage can answer, because only storage is in a
2404    /// position to have sorted them once and written the answer down.
2405    #[must_use]
2406    pub fn ranks(&self) -> Option<usize> {
2407        match &self.body {
2408            Body::ExternalText { source } => source.ranks(),
2409            _ => None,
2410        }
2411    }
2412
2413    /// How the value at `rank` compares against `wanted`. See [`TextSource::compare_rank`].
2414    pub fn compare_rank(&self, rank: usize, wanted: &[u8]) -> Result<Ordering> {
2415        match &self.body {
2416            Body::ExternalText { source } => source.compare_rank(rank, wanted),
2417            _ => {
2418                Err(Error::internal("a vector without a sorted order was asked to compare a rank"))
2419            }
2420        }
2421    }
2422
2423    /// Where `wanted` would go in the sorted order. See [`TextSource::below`].
2424    ///
2425    /// # Errors
2426    ///
2427    /// If this vector has no sorted order, or if a probe of it fails.
2428    pub fn below(&self, ranks: usize, wanted: &[u8]) -> Result<(usize, bool)> {
2429        match &self.body {
2430            Body::ExternalText { source } => source.below(ranks, wanted),
2431            _ => Err(Error::internal("a vector without a sorted order was asked for a boundary")),
2432        }
2433    }
2434
2435    /// The position of the value at `rank`. See [`TextSource::code_at_rank`].
2436    pub fn code_at_rank(&self, rank: usize) -> Result<u32> {
2437        match &self.body {
2438            Body::ExternalText { source } => source.code_at_rank(rank),
2439            _ => Err(Error::internal("a vector without a sorted order was asked for a rank")),
2440        }
2441    }
2442
2443    /// The rank of every value, indexed by position. See [`TextSource::code_ranks`].
2444    #[must_use]
2445    pub fn code_ranks(&self) -> Option<&[u32]> {
2446        match &self.body {
2447            Body::ExternalText { source } => source.code_ranks(),
2448            _ => None,
2449        }
2450    }
2451
2452    /// Text at `index`, preserving storage read, validation and UTF-8 failures.
2453    pub fn try_text_at(&self, index: usize) -> Result<Option<&str>> {
2454        if self.ty != LogicalType::Varchar {
2455            return Ok(None);
2456        }
2457        self.try_bytes_at(index)?
2458            .map(|bytes| {
2459                std::str::from_utf8(bytes).map_err(|error| {
2460                    Error::conversion(format!("invalid UTF-8 in VARCHAR: {error}"))
2461                })
2462            })
2463            .transpose()
2464    }
2465
2466    /// Read every storage-backed value reachable through this vector.
2467    pub fn validate_external(&self) -> Result<()> {
2468        match &self.body {
2469            Body::ExternalText { source } => {
2470                for index in 0..source.len() {
2471                    source.bytes_at(index)?;
2472                }
2473            }
2474            Body::Dictionary { codes, values, .. } => {
2475                for &code in codes {
2476                    values.try_bytes_at(code as usize)?;
2477                }
2478            }
2479            Body::Runs { values, .. } | Body::Gathered { source: values, .. } => {
2480                values.validate_external()?;
2481            }
2482            Body::Nested { child, .. } => child.validate_external()?,
2483            Body::Fields { children } => {
2484                for child in children {
2485                    child.validate_external()?;
2486                }
2487            }
2488            _ => {}
2489        }
2490        Ok(())
2491    }
2492
2493    /// The signed integer at `index`, widened, read without building a [`Value`].
2494    ///
2495    /// The integer sibling of [`Self::bytes_at`], and it is here for the same caller. A group by on
2496    /// an integer column compares one key per input row against the group it probed, and doing that
2497    /// through [`Self::value_at`] built and dropped a sixty four byte value a row at a time for a
2498    /// number that was already sitting in the column.
2499    ///
2500    /// Widened to `i128` because that is what [`Data::signed_at`] hands back underneath, and one
2501    /// method that covers every signed width is worth more than five that do not. A caller that
2502    /// wants a narrower type narrows it, which is a range check against a value in a register.
2503    ///
2504    /// The types this answers for are the ones whose flat data is read through `signed_at`, so the
2505    /// five signed integer widths and the decimal, date, time and timestamp types that are stored
2506    /// in them. A decimal answers with its unscaled value, which is the number the column holds.
2507    ///
2508    /// `None` for a null, for an index past the end, for a column of any other type, and for the
2509    /// compressed form. Packed integers stay in code space and answer `base + code` directly. A
2510    /// caller that gets `None` falls back to [`Self::value_at`], which is correct for the remaining
2511    /// forms.
2512    #[must_use]
2513    pub fn signed_at(&self, index: usize) -> Option<i128> {
2514        if index >= self.len || !self.validity.is_valid(index) {
2515            return None;
2516        }
2517        match &self.body {
2518            Body::Flat(data) => data.signed_at(index),
2519            Body::Constant(value) => match value.as_ref() {
2520                Value::TinyInt(x) => Some(i128::from(*x)),
2521                Value::SmallInt(x) => Some(i128::from(*x)),
2522                Value::Integer(x) | Value::Date(x) => Some(i128::from(*x)),
2523                Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => Some(i128::from(*x)),
2524                Value::HugeInt(x) | Value::Decimal { unscaled: x, .. } => Some(*x),
2525                _ => None,
2526            },
2527            // The same arithmetic [`Self::value_at`] does on a sequence, so the two agree about a
2528            // sequence that runs off the end of the width it is stored in.
2529            Body::Sequence { start, step } => {
2530                Some(i128::from(start.wrapping_add(step.wrapping_mul(index as i64))))
2531            }
2532            Body::Dictionary { codes, values, .. } => {
2533                values.signed_at(usize::try_from(*codes.get(index)?).ok()?)
2534            }
2535            Body::Runs { ends, values } => values.signed_at(run_holding(ends, index)?),
2536            Body::Gathered { source, rids, offset } => {
2537                source.signed_at(row_of(rids, *offset, index)?)
2538            }
2539            Body::Packed { words, width, base, offset } => Some(
2540                *base + i128::from(code_at(words, (*offset + index) * *width as usize, *width)),
2541            ),
2542            // The same `None` [`Self::bytes_at`] gives, for the same reason. A compressed row is not
2543            // an integer anywhere until it has been unpacked, and a caller that gets
2544            // `None` goes to `value_at` and gets the row unpacked into a value. A list row is not an
2545            // integer in any form, however many integers are in it, and a struct row is not one even
2546            // when it has exactly one integer field, since the row is the struct and not the field.
2547            Body::Coded { .. }
2548            | Body::Views { .. }
2549            | Body::ExternalText { .. }
2550            | Body::Nested { .. }
2551            | Body::Fields { .. } => None,
2552        }
2553    }
2554
2555    /// Every signed value in order, widened to `i64`, written into `out`.
2556    ///
2557    /// The bulk form of [`Self::signed_at`], for a caller that is going to read the whole vector
2558    /// anyway. A group by on two integer columns called `signed_at` once per column per row, and
2559    /// every one of those matched on the body, called into the data and matched again on the
2560    /// layout, which is about sixty five instructions to read a number that was already sitting in
2561    /// a slice. It was a fifth of ClickBench 32 on its own.
2562    ///
2563    /// A null writes whatever the body holds under it, which is the zero a flat column keeps behind
2564    /// its mask. Nulls are a separate question and the caller asks it separately, from
2565    /// [`Self::none_null`] once for the vector when that answers and a row at a time when it does
2566    /// not.
2567    ///
2568    /// `false`, with `out` left empty, for a vector this cannot hand over as a block: `HUGEINT` and
2569    /// the wide decimals, whose values do not fit an `i64`, the string and nested forms, the
2570    /// compressed form, and the dictionary and run forms, which are a gather rather than a copy and
2571    /// are left until something wants them. A caller that gets `false` reads the vector the way it
2572    /// read it before, with [`Self::signed_at`].
2573    #[must_use]
2574    pub fn signed_block(&self, out: &mut Vec<i64>) -> bool {
2575        out.clear();
2576        match &self.body {
2577            Body::Flat(data) => data.signed_block(self.len, out),
2578            Body::Constant(value) => {
2579                let held = match value.as_ref() {
2580                    Value::TinyInt(x) => i64::from(*x),
2581                    Value::SmallInt(x) => i64::from(*x),
2582                    Value::Integer(x) | Value::Date(x) => i64::from(*x),
2583                    Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => *x,
2584                    _ => return false,
2585                };
2586                out.resize(self.len, held);
2587                true
2588            }
2589            // The same arithmetic [`Self::signed_at`] does on a sequence, once per row rather than
2590            // once per call, and it wraps where that one wraps.
2591            Body::Sequence { start, step } => {
2592                out.extend(
2593                    (0..self.len).map(|index| start.wrapping_add(step.wrapping_mul(index as i64))),
2594                );
2595                true
2596            }
2597            Body::Packed { words, width, base, offset } => match i64::try_from(*base) {
2598                Ok(base) => {
2599                    out.extend((0..self.len).map(|index| {
2600                        base.wrapping_add(code_at(
2601                            words,
2602                            (*offset + index) * *width as usize,
2603                            *width,
2604                        ) as i64)
2605                    }));
2606                    true
2607                }
2608                Err(_) => false,
2609            },
2610            Body::Dictionary { .. }
2611            | Body::Runs { .. }
2612            | Body::Gathered { .. }
2613            | Body::Coded { .. }
2614            | Body::Views { .. }
2615            | Body::ExternalText { .. }
2616            | Body::Nested { .. }
2617            | Body::Fields { .. } => false,
2618        }
2619    }
2620
2621    /// Whether the vector holds no nulls at all, asked once rather than a row at a time.
2622    ///
2623    /// The bulk form of [`Self::is_null_at`], and it answers the same question that one does, so a
2624    /// dictionary and a run are read through to the values behind them where those two keep their
2625    /// nulls. A dictionary that holds a null no code points at answers `false` here and `false` at
2626    /// every row, which is the safe direction and is the only place the two can differ.
2627    ///
2628    /// A caller that gets `false` goes back to asking a row at a time.
2629    #[must_use]
2630    pub fn none_null(&self) -> bool {
2631        if self.validity.has_nulls(self.len) {
2632            return false;
2633        }
2634        match &self.body {
2635            Body::Dictionary { values, .. } | Body::Runs { values, .. } => values.none_null(),
2636            Body::Gathered { source, rids, offset } => {
2637                source.none_null()
2638                    && !rids[*offset..].iter().take(self.len).any(|&rid| rid == NO_ROW)
2639            }
2640            _ => true,
2641        }
2642    }
2643
2644    /// Every value in order, as single values.
2645    pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
2646        (0..self.len).map(|index| self.value_at(index))
2647    }
2648
2649    /// This vector with its payload held as a page, so that copying or cutting it is free.
2650    ///
2651    /// For a producer that means to hand the same values out many times, which is what a stored
2652    /// column is. A flat body is the form this changes, because it is the only one that owns a run
2653    /// of values a copy would have to copy. Every other form already shares what is expensive and
2654    /// owns only what a cut has to rewrite, so it comes back as it was: a dictionary shares its
2655    /// values, a packed body shares its words, a string body shares its arena, an FSST body shares
2656    /// its codes and its table, and a constant and a sequence have nothing to share.
2657    ///
2658    /// Not recursive into a nested column's children, because a `LIST` or a `STRUCT` holds its
2659    /// children behind an `Arc` already.
2660    #[must_use]
2661    pub fn into_pages(self) -> Self {
2662        let body = match self.body {
2663            Body::Flat(data) => Body::Flat(data.into_pages()),
2664            other => other,
2665        };
2666        Self { body, ..self }
2667    }
2668
2669    /// A contiguous run of the values, in the form they are already in.
2670    ///
2671    /// This is the cut [`Self::gather`] cannot do. A gather walks a dictionary to its leaf and
2672    /// copies, so gathering a piece of a dictionary encoded column hands back a flat one, and a
2673    /// caller that only wanted the first thousand rows of a page has silently paid for a copy and
2674    /// thrown the dictionary away. A group by over a dictionary encoded column is the case that
2675    /// cares, and it is most of ClickBench.
2676    ///
2677    /// So each form is cut as itself. A dictionary keeps its dictionary and slices its codes, a
2678    /// sequence stays arithmetic with its start moved along, a constant stays a shorter constant,
2679    /// and a flat body is a window into its page when it has one and a copy of its range when it
2680    /// does not, which [`Self::into_pages`] is how a producer decides.
2681    ///
2682    /// The dictionary itself is shared rather than copied, so a cut is the codes and nothing else.
2683    /// It used to be copied, and on a read of a ClickBench partition that copy was ten percent of
2684    /// the cycles: a page holds one dictionary and is cut into chunk sized pieces, so the whole
2685    /// dictionary was copied once per chunk to be read the same way each time.
2686    ///
2687    /// # Errors
2688    ///
2689    /// If the range runs past the end of the vector, or if the type has no flat layout and the
2690    /// body is one that has to be copied.
2691    pub fn slice(&self, at: usize, len: usize) -> Result<Self> {
2692        let end = at.checked_add(len).ok_or_else(|| Error::internal("a slice that wraps"))?;
2693        if end > self.len {
2694            return Err(Error::internal(format!("rows {at} to {end} of a vector of {}", self.len)));
2695        }
2696        if at == 0 && len == self.len {
2697            return Ok(self.clone());
2698        }
2699        let validity = self.validity.slice(at, len);
2700        let body = match &self.body {
2701            Body::Constant(value) => Body::Constant(value.clone()),
2702            Body::Sequence { start, step } => {
2703                Body::Sequence { start: start + step * at as i64, step: *step }
2704            }
2705            Body::Dictionary { codes, values, stable } => Body::Dictionary {
2706                codes: codes[at..end].to_vec(),
2707                values: Arc::clone(values),
2708                stable: *stable,
2709            },
2710            // The same cut [`Body::Packed`] below takes and for the same reason, and here it is free
2711            // rather than merely cheap: a link join fills one buffer of parent rows per child chunk
2712            // and the pipeline cuts it, so moving the starting row is what keeps the ids from being
2713            // copied once per cut. Both ends of the gather stay shared, the ids and the source.
2714            Body::Gathered { source, rids, offset } => Body::Gathered {
2715                source: Arc::clone(source),
2716                rids: Arc::clone(rids),
2717                offset: offset + at,
2718            },
2719            // The bits are not byte aligned, so a cut either repacks them or moves the row the
2720            // reading starts at. Moving it is one addition and repacking is a pass, and a page is
2721            // cut into chunk sized pieces often enough that the difference is the form.
2722            Body::Packed { words, width, base, offset } => Body::Packed {
2723                words: Arc::clone(words),
2724                width: *width,
2725                base: *base,
2726                offset: offset + at,
2727            },
2728            // The cut a flat string column cannot do. Sixteen bytes a row move and the payload stays
2729            // where the page put it, so taking a chunk out of a column of long strings costs the
2730            // same as taking one out of a column of integers. A flat varchar body copies every byte
2731            // of every long string in the range instead, which is the measurement written down in
2732            // `Chunk::compact`: compaction loses on a varchar column, and this is the half of the
2733            // reason that is about cutting rather than about selecting.
2734            Body::Views { views, arena } => {
2735                Body::Views { views: views[at..end].to_vec(), arena: Arc::clone(arena) }
2736            }
2737            // The spans are absolute positions in the shared codes, so a cut is a run of them and
2738            // nothing has to be rebased. One page of compressed strings, one table, and as many
2739            // chunks over it as the reader wants.
2740            Body::Coded { codes, spans, table } => Body::Coded {
2741                codes: Arc::clone(codes),
2742                spans: spans[at..end].to_vec(),
2743                table: Arc::clone(table),
2744            },
2745            // Only the runs the range touches survive, the first and last of them cut back to where
2746            // the range starts and stops, and every end moved to be relative to the new row zero. A
2747            // cut of a hundred rows out of a column of a hundred million is a handful of runs, which
2748            // is the reason this form is worth cutting as itself rather than copying out.
2749            Body::Runs { ends, values } if len > 0 => {
2750                let first = run_holding(ends, at).unwrap_or(0);
2751                let last = run_holding(ends, end - 1).unwrap_or(first);
2752                let cut: Vec<u32> = ends[first..=last]
2753                    .iter()
2754                    .map(|&stop| stop.min(end as u32) - at as u32)
2755                    .collect();
2756                let values = values.slice(first, last - first + 1)?;
2757                Body::Runs { ends: cut, values: Arc::new(values) }
2758            }
2759            // An empty cut has no run to point at and an empty run length body would be a vector of
2760            // no runs claiming a length, so it comes back as the empty flat vector instead.
2761            Body::Runs { .. } => return self.gather(&[]),
2762            // The entries are absolute positions in the shared child, so a cut is a run of them and
2763            // nothing has to be rebased, the same as a cut of FSST spans. The elements outside the
2764            // range stay in the child unreferenced, which is the trade this form makes: a chunk cut
2765            // out of a page of lists moves eight bytes a row and copies no elements at all.
2766            Body::Nested { entries, child } => {
2767                Body::Nested { entries: entries[at..end].to_vec(), child: Arc::clone(child) }
2768            }
2769            // Every child cut at the same place, because a struct row is one value per field at the
2770            // same position in each and there is no entry standing between the row and the child to
2771            // rewrite instead. So this is the one nested form whose cut is not free, and what it costs
2772            // is whatever cutting each field costs, which for a field of string views is sixteen bytes
2773            // a row and for a field of packed integers is one addition.
2774            Body::Fields { children } => Body::Fields {
2775                children: children
2776                    .iter()
2777                    .map(|child| child.slice(at, len).map(Arc::new))
2778                    .collect::<Result<Vec<_>>>()?,
2779            },
2780            Body::ExternalText { source } => {
2781                let mut out = StringColumn::with_capacity(len);
2782                for index in at..end {
2783                    out.push_bytes(source.bytes_at(index)?.unwrap_or_default());
2784                }
2785                Body::Flat(Data::Varlen(out))
2786            }
2787            // The one form with nowhere to point, so its range is copied out. A run and not a
2788            // gather: this used to build a vector of the positions `at..end` and hand it to
2789            // `gather`, which then built a vector of `usize` from it, a vector of `bool` beside
2790            // that, and read the values back one bounds checked index at a time. That is five
2791            // passes and three allocations to say `memcpy`, and on a scan it was the largest thing
2792            // in the program after the aggregation itself, because every chunk of every column of
2793            // every page comes through here.
2794            Body::Flat(data) => Body::Flat(run_of(data, at, end)),
2795        };
2796        Ok(Self { ty: self.ty.clone(), len, validity, body })
2797    }
2798
2799    /// The same values in flat form.
2800    ///
2801    /// Flattening a vector that is already flat is free. Flattening any other form costs a copy,
2802    /// which is exactly why the other forms exist and why nothing on the hot path should call
2803    /// this. It is here for the operators that genuinely cannot do better and for the tests that
2804    /// check the other forms against it.
2805    ///
2806    /// A call that copies counts itself against [`Cause::Flatten`], because a flatten on a hot path
2807    /// is the most expensive thing in this crate and the only way to find one is to have the number.
2808    /// A call on a vector that is already flat does not count, since it neither copies nor gives
2809    /// anything up.
2810    ///
2811    /// # Errors
2812    ///
2813    /// If the type is one there is no vector for yet, which today means `ARRAY` and `UNION`. A `LIST`
2814    /// and a `MAP` flatten to themselves and a `STRUCT` to a struct of flattened fields, since none of
2815    /// the three has a data slice in any form and there is nothing flatter to become.
2816    pub fn flatten(&self) -> Result<Self> {
2817        if let Body::Flat(_) = self.body {
2818            return Ok(self.clone());
2819        }
2820        slow::took(Cause::Flatten);
2821        self.copied((0..self.len).collect(), false)
2822    }
2823
2824    /// The same values in flat form, taking the vector rather than borrowing it.
2825    ///
2826    /// A vector that is already flat comes back as itself, which is the whole reason this exists
2827    /// beside [`Self::flatten`]. Flattening through a borrow has to clone that vector, and a clone
2828    /// of a flat vector that owns its values copies every one of them to produce a vector that is
2829    /// identical to the one it was handed. Anything not already flat goes the same way it does
2830    /// through [`Self::flatten`], since the copy is real work there rather than work for nothing.
2831    ///
2832    /// # Errors
2833    ///
2834    /// The same as [`Self::flatten`].
2835    pub fn into_flat(self) -> Result<Self> {
2836        if let Body::Flat(_) = self.body {
2837            return Ok(self);
2838        }
2839        // flatten: the caller asked for flat, and the form that is already flat took the branch
2840        // above, so this is the one case where the copy is what was wanted rather than a shortcut
2841        // somebody took instead of reading the column where it lies.
2842        self.flatten()
2843    }
2844
2845    /// The values at the given positions, copied, in a form that does not point back at this vector.
2846    ///
2847    /// This is the copying counterpart to [`Self::dictionary`], and the two are the two halves of
2848    /// the decision `spec/07-execution.md` section 7.1 describes. Which half is right is measured
2849    /// rather than argued, and [`Chunk::compact`](crate::Chunk::compact) is where the measurement
2850    /// is written down.
2851    ///
2852    /// A dictionary chain is walked to its leaf first and the codes composed on the way down, so the
2853    /// copy runs once over the data rather than once per level, and a position that is null at any
2854    /// level comes out null here. The copy is a typed loop per physical layout rather than a `Value`
2855    /// per row, which is the whole point of it and is what [`Self::flatten`] now goes through too.
2856    ///
2857    /// # Errors
2858    ///
2859    /// If the type is one there is no vector for yet, which today means `ARRAY` and `UNION`. A `LIST`
2860    /// and a `MAP` gather by permuting their entries and a `STRUCT` by gathering every field.
2861    pub fn gather(&self, indices: &[u32]) -> Result<Self> {
2862        self.copied(indices.iter().map(|&index| index as usize).collect(), true)
2863    }
2864
2865    /// The copy both [`Self::gather`] and [`Self::flatten`] are.
2866    ///
2867    /// `forms_stay` is the one thing the two want differently. A gather of a constant is a shorter
2868    /// constant and copying it out would be a thousand writes of the same value for nothing, and a
2869    /// gather of string views is a shorter run of views over the same arena rather than a copy of
2870    /// the bytes. Flattening promises flat form to a caller that is about to read the data slice, so
2871    /// for that one both of them have to be written out.
2872    fn copied(&self, at: Vec<usize>, forms_stay: bool) -> Result<Self> {
2873        let rows = at.len();
2874        if forms_stay {
2875            if let Body::Dictionary { codes, values, stable: true } = &self.body {
2876                // A gather off a column with no nulls in it is all valid as long as every index it
2877                // was handed is in range, and both of those are answered by a word at a time rather
2878                // than by asking each row whether it is null. That per row question reads through
2879                // the dictionary to the value it stands for, which made it the single line a
2880                // filtered scan of a dictionary column spent most of its copy in.
2881                let validity = if self.never_null() && at.iter().all(|&index| index < self.len) {
2882                    Validity::AllValid
2883                } else {
2884                    Validity::from_iter(rows, |row| {
2885                        at.get(row)
2886                            .is_some_and(|&index| index < self.len && !self.is_null_at(index))
2887                    })
2888                };
2889                let gathered: Vec<u32> =
2890                    at.iter().map(|&index| codes.get(index).copied().unwrap_or(0)).collect();
2891                // Every code here is one this vector already held, which was checked against the
2892                // same values on the way in, or the zero a row past the end is written as. So the
2893                // only code that can be out of range is that zero over no values at all, and the
2894                // pass that looks for the largest code is not needed to find it. On ClickBench 28
2895                // that pass was four percent of the query, because every filtered chunk of `URL`
2896                // came through here.
2897                // Values that are themselves a dictionary are composed through by the constructor,
2898                // and this skips the constructor, so that shape still goes the checked way.
2899                if matches!(values.body, Body::Dictionary { .. }) {
2900                    return Ok(Self::stable_dictionary(gathered, Arc::clone(values))?
2901                        .with_validity(validity));
2902                }
2903                let highest = (values.is_empty() && !gathered.is_empty()).then_some(0);
2904                return Ok(Self::stable_dictionary_validated(
2905                    gathered,
2906                    Arc::clone(values),
2907                    highest,
2908                )?
2909                .with_validity(validity));
2910            }
2911        }
2912        let (at, leaf) = self.resolve(at);
2913        let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
2914        let validity = Validity::from_run(&live);
2915        let body = match &leaf.body {
2916            // The same gather the arm below is, for a type that has no flat layout to be written out
2917            // into. It goes through the nested builders rather than through a run of data, because they
2918            // are the one place that knows a row of a list column is a range of a child and a row of a
2919            // struct column is one position in each of several, and a second copy of that here would
2920            // be a second thing to keep in step with them.
2921            Body::Constant(value)
2922                if matches!(
2923                    self.ty,
2924                    LogicalType::List(_) | LogicalType::Struct(_) | LogicalType::Map(_, _)
2925                ) =>
2926            {
2927                if forms_stay && matches!(validity, Validity::AllValid) {
2928                    return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
2929                }
2930                let rows: Vec<Value> = at
2931                    .iter()
2932                    .map(
2933                        |&index| {
2934                            if index == NOWHERE { Value::Null } else { value.as_ref().clone() }
2935                        },
2936                    )
2937                    .collect();
2938                return Self::from_values(self.ty.clone(), &rows);
2939            }
2940            // Every position holds the same value, so the only thing the gather can change is the
2941            // length and which positions are null. A gather with no null in it is still a constant.
2942            Body::Constant(value) => {
2943                if forms_stay && matches!(validity, Validity::AllValid) {
2944                    return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
2945                }
2946                let mut data = empty_data_for(&self.ty)?;
2947                for &index in &at {
2948                    push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
2949                }
2950                Body::Flat(data)
2951            }
2952            // A sequence is arithmetic rather than storage, so the gather is the arithmetic done at
2953            // the positions asked for, and a null writes the zero every other layout writes.
2954            Body::Sequence { start, step } => Body::Flat(Data::Int64(
2955                at.iter()
2956                    .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
2957                    .collect(),
2958            )),
2959            // A flat body with no values is the untyped null, so every position asked for is null
2960            // whatever was asked for. Going through the copy would build a run of no values and
2961            // call it `rows` long, which is a vector whose length and data disagree.
2962            Body::Flat(Data::Empty) => {
2963                return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
2964            }
2965            Body::Flat(data) => Body::Flat(copy_of(data, &at)),
2966            // The one form whose copy is arithmetic rather than a move of bytes. It goes through a
2967            // typed loop per layout the way the flat copy does, because the alternative is a `Value`
2968            // per row and this is the path a flatten of a scanned column takes.
2969            Body::Packed { words, width, base, offset } => {
2970                Body::Flat(unpack(&self.ty, words, *offset, *width, *base, &at)?)
2971            }
2972            // A gather keeps the form, which is what makes selecting rows out of a string column
2973            // cost sixteen bytes a row instead of the bytes of the strings. The arena it shares is
2974            // the whole arena and not the part the kept rows point at, so a selection that throws
2975            // most of a page away goes on holding the page. That is the trade the form is: a cut and
2976            // a filter are cheap and the memory comes back when the last vector over the page goes,
2977            // and a caller that wants the bytes narrowed asks for a flatten.
2978            Body::Views { views, arena } if forms_stay => Body::Views {
2979                views: at
2980                    .iter()
2981                    .map(|&index| views.get(index).copied().unwrap_or_else(StringView::empty))
2982                    .collect(),
2983                arena: Arc::clone(arena),
2984            },
2985            // Flattening promises a data slice, and a flat string column is views over an arena
2986            // just as this form is, so when the arena is a page the flatten is the views and
2987            // nothing else. The form is given up, which is what was asked for, and not the sharing,
2988            // which nobody asked to have given up: a result set of six million strings used to copy
2989            // every byte of them out of the pages they were already sitting in.
2990            Body::Views { views, arena } if arena.is_shared() => {
2991                Body::Flat(Data::Varlen(StringColumn::from_parts(
2992                    at.iter()
2993                        .map(|&index| views.get(index).copied().unwrap_or_else(StringView::empty))
2994                        .collect(),
2995                    (**arena).clone(),
2996                )))
2997            }
2998            // The arena is this vector's own, so there is nothing to share and the bytes are copied
2999            // out into an arena of their own. The total is known before any of it is copied, the
3000            // way the flat copy works it out, so the new arena is one allocation.
3001            Body::Views { views, arena } => {
3002                let mut out = StringColumn::with_capacity(at.len());
3003                out.reserve_bytes(
3004                    at.iter()
3005                        .filter_map(|&index| views.get(index))
3006                        .filter(|view| !view.is_inline())
3007                        .map(StringView::len)
3008                        .sum(),
3009                );
3010                for &index in &at {
3011                    let bytes = views.get(index).and_then(|view| view.bytes_in(arena));
3012                    out.push_bytes(bytes.unwrap_or_default());
3013                }
3014                Body::Flat(Data::Varlen(out))
3015            }
3016            Body::ExternalText { source } => {
3017                let mut out = StringColumn::with_capacity(at.len());
3018                for &index in &at {
3019                    out.push_bytes(source.bytes_at(index)?.unwrap_or_default());
3020                }
3021                Body::Flat(Data::Varlen(out))
3022            }
3023            // A gather keeps the form, because the codes do not move and a span survives being put
3024            // in an order the codes are not in. A position that resolved to nowhere gets the empty
3025            // span, which decompresses to no bytes, which is the zero every other layout writes.
3026            Body::Coded { codes, spans, table } if forms_stay => Body::Coded {
3027                codes: Arc::clone(codes),
3028                spans: at
3029                    .iter()
3030                    .map(|&index| spans.get(index).copied().unwrap_or((0, 0)))
3031                    .collect(),
3032                table: Arc::clone(table),
3033            },
3034            // Flattening decompresses, which is the price of the data slice it promises. The scratch
3035            // buffer is reused across rows, so this is one allocation for the whole column rather
3036            // than one per row the way reading it a value at a time would be.
3037            Body::Coded { codes, spans, table } => {
3038                let mut out = StringColumn::with_capacity(at.len());
3039                let mut scratch = Vec::new();
3040                for &index in &at {
3041                    scratch.clear();
3042                    let span = spans
3043                        .get(index)
3044                        .and_then(|&(from, to)| codes.get(from as usize..to as usize));
3045                    if let Some(span) = span {
3046                        table.decompress(span, &mut scratch)?;
3047                    }
3048                    out.push_bytes(&scratch);
3049                }
3050                Body::Flat(Data::Varlen(out))
3051            }
3052            // The entries move and the child does not, which is the same trade the string forms
3053            // make and is why a gather of a list column costs eight bytes a row however long the
3054            // lists are. A position that resolved to nowhere gets a zero length entry, and the mask
3055            // already says it is null, so the entry is never read.
3056            //
3057            // This arm ignores `forms_stay`, unlike every arm above it, because there is nothing
3058            // flatter for a list to become. The other forms are all cheaper ways of writing down a
3059            // column of scalars and flattening gives up the saving to hand back a data slice, and a
3060            // list has no data slice in any form, so a flatten of one is this and a caller reading it
3061            // goes through `list_parts` either way.
3062            Body::Nested { entries, child } => Body::Nested {
3063                entries: at
3064                    .iter()
3065                    .map(|&index| entries.get(index).copied().unwrap_or((0, 0)))
3066                    .collect(),
3067                child: Arc::clone(child),
3068            },
3069            // Every child gathered at the same positions, for the reason the cut cuts every child:
3070            // there are no entries to permute instead, so the permutation happens once per field. The
3071            // positions handed down are the resolved ones, sentinel and all, so a row that resolved to
3072            // nowhere comes back null in each field as well as null here.
3073            //
3074            // `forms_stay` is passed straight through rather than ignored, which is the opposite of
3075            // what the list arm does, and the difference is real. There is nothing flatter for a list
3076            // to become, and a struct is only as flat as its fields are, so a flatten of a struct
3077            // column is a flatten of each field and a caller that asked for data slices gets them.
3078            Body::Fields { children } => Body::Fields {
3079                children: children
3080                    .iter()
3081                    .map(|child| child.copied(at.clone(), forms_stay).map(Arc::new))
3082                    .collect::<Result<Vec<_>>>()?,
3083            },
3084            // Unreachable, because `resolve` walks past every form that points at another vector
3085            // and stops at the first body that does not.
3086            Body::Dictionary { .. } | Body::Runs { .. } | Body::Gathered { .. } => {
3087                return Err(Error::internal(
3088                    "a form that points somewhere survived being resolved",
3089                ));
3090            }
3091        };
3092        Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
3093    }
3094
3095    /// Where each wanted position lives in the first body that points nowhere else, and that body.
3096    ///
3097    /// A position that is null anywhere on the way down, or past the end of anything on the way
3098    /// down, comes back as [`NOWHERE`]. That single sentinel is what keeps the copy loop from
3099    /// carrying a validity mask alongside the positions it is already walking.
3100    fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
3101        let mut source = self;
3102        loop {
3103            for slot in &mut at {
3104                if *slot >= source.len || !source.validity.is_valid(*slot) {
3105                    *slot = NOWHERE;
3106                }
3107            }
3108            source = match &source.body {
3109                Body::Dictionary { codes, values, .. } => {
3110                    for slot in &mut at {
3111                        *slot = match codes.get(*slot) {
3112                            Some(&code) => code as usize,
3113                            None => NOWHERE,
3114                        };
3115                    }
3116                    values.as_ref()
3117                }
3118                // A run length body is a dictionary whose code is worked out from the position
3119                // rather than stored, so the walk down is the same walk with a search where the
3120                // lookup was. `NOWHERE` searches for nothing and stays `NOWHERE`.
3121                Body::Runs { ends, values } => {
3122                    for slot in &mut at {
3123                        *slot = run_holding(ends, *slot).unwrap_or(NOWHERE);
3124                    }
3125                    values.as_ref()
3126                }
3127                // The same walk the dictionary above takes, with the sentinel folded into the one
3128                // this loop already has. That composition is the whole reason a gather is a body
3129                // rather than an operator: a filter over the output of a link join selects into the
3130                // ids and copies nothing, and a gather off a gather is one walk down to whatever is
3131                // at the bottom rather than two passes over the parent.
3132                Body::Gathered { source: below, rids, offset } => {
3133                    for slot in &mut at {
3134                        *slot = if *slot == NOWHERE {
3135                            NOWHERE
3136                        } else {
3137                            row_of(rids, *offset, *slot).unwrap_or(NOWHERE)
3138                        };
3139                    }
3140                    below.as_ref()
3141                }
3142                _ => return (at, source),
3143            };
3144        }
3145    }
3146}
3147
3148/// So that a kernel can take its operands as either a list of vectors or a list of references.
3149///
3150/// A caller that built a `Vec<Vector>` and a caller whose operands are already somewhere else, in a
3151/// chunk or in an evaluator's scratch, want the same kernel. Without this the second kind has to
3152/// clone every operand into a `Vec` to satisfy the signature, and a clone of a vector is a copy of
3153/// the whole column, so the type would be charging real memory traffic for nothing.
3154impl AsRef<Vector> for Vector {
3155    fn as_ref(&self) -> &Vector {
3156        self
3157    }
3158}
3159
3160/// The bits of a packed vector and what they mean, for a kernel that wants to stay in code space.
3161///
3162/// Borrowed from the vector rather than owning anything, so getting one costs nothing and a kernel
3163/// that finds it cannot use them has given up nothing by asking.
3164#[derive(Debug, Clone, Copy)]
3165pub struct Packed<'a> {
3166    words: &'a [u64],
3167    width: u32,
3168    base: i128,
3169    offset: usize,
3170}
3171
3172impl Packed<'_> {
3173    /// Packed words. A persisted vector also records [`Self::offset`].
3174    #[must_use]
3175    pub fn words(&self) -> &[u64] {
3176        self.words
3177    }
3178
3179    /// Bit offset, in rows, of the first value.
3180    #[must_use]
3181    pub fn offset(&self) -> usize {
3182        self.offset
3183    }
3184
3185    /// How many bits one code takes, between one and [`PACKED_WIDTH_MAX`].
3186    #[must_use]
3187    pub fn width(&self) -> u32 {
3188        self.width
3189    }
3190
3191    /// What zero means, so that the value of a row is the base plus its code.
3192    #[must_use]
3193    pub fn base(&self) -> i128 {
3194        self.base
3195    }
3196
3197    /// The largest value this vector can be holding, whatever it is actually holding.
3198    ///
3199    /// With [`Self::base`] this is the pair a comparison kernel wants first. A literal outside the
3200    /// two answers every row of the vector the same way, which is a whole chunk decided without a
3201    /// bit being read, and that is the case a zone map would have caught if there were one here.
3202    #[must_use]
3203    pub fn ceiling(&self) -> i128 {
3204        self.base + i128::from(u64::MAX >> (u64::BITS - self.width))
3205    }
3206
3207    /// The code of row `row`, which is its value minus [`Self::base`].
3208    ///
3209    /// Out of range rows read as zero rather than panicking, the way every other accessor in this
3210    /// file answers for a row that is not there.
3211    ///
3212    /// Marked inline because every caller that matters is a kernel in another crate reading one code
3213    /// per row, and thin LTO was leaving it as a call there. On TPC-H SF1 that call was 1.5 percent of
3214    /// the suite and a tenth of q12.
3215    #[must_use]
3216    #[inline]
3217    pub fn code(&self, row: usize) -> u64 {
3218        code_at(self.words, (self.offset + row) * self.width as usize, self.width)
3219    }
3220
3221    /// Which code a value would have, and `None` for a value this vector cannot be holding.
3222    ///
3223    /// The translation a comparison does once per vector so that it does not have to unpack once per
3224    /// row. `None` is the useful answer rather than a failure: it says the literal is outside the
3225    /// packed range, so every row compares against it the same way.
3226    #[must_use]
3227    pub fn code_of(&self, value: i128) -> Option<u64> {
3228        u64::try_from(value.checked_sub(self.base)?).ok().filter(|&code| code <= self.mask())
3229    }
3230
3231    /// The largest code the width allows.
3232    fn mask(&self) -> u64 {
3233        u64::MAX >> (u64::BITS - self.width)
3234    }
3235}
3236
3237/// The widest a packed code is allowed to be.
3238///
3239/// Sixty three rather than sixty four so that a mask is `u64::MAX >> (64 - width)` with no shift of
3240/// a whole word in it, and reading a code is one branch on whether it straddles rather than two. A
3241/// sixty four bit code saves nothing anyway, since it is the layout it came from.
3242pub const PACKED_WIDTH_MAX: u32 = 63;
3243
3244/// How much smaller packing has to be before it is worth the shift and the mask on every read.
3245///
3246/// Two, so a column packs when the bits come to half the flat size or less. A column that would save
3247/// a tenth stays flat, because a tenth of a column is not worth turning every read of it into
3248/// arithmetic, and the whole argument for the form is that a narrow column saves most of itself.
3249pub const PACKING_PAYS_AT: usize = 2;
3250
3251/// How much smaller compressing has to be before it is worth a decompression on every read.
3252///
3253/// Two, the same rule packing follows and for the same reason. FSST gets about that on text, so a
3254/// column of English or of URLs compresses and a column of short codes or of random bytes does not,
3255/// which is the right answer for both.
3256pub const FSST_PAYS_AT: usize = 2;
3257
3258/// The codes of a compressed column and the table they are against.
3259///
3260/// Handed out by [`Vector::coded_parts`] so a kernel can work in code space. Nothing here
3261/// decompresses, which is the point: [`Self::encode`] puts the literal into the same space the rows
3262/// are already in, and after that an equality test is a byte slice comparison.
3263#[derive(Debug, Clone, Copy)]
3264pub struct Coded<'a> {
3265    codes: &'a [u8],
3266    spans: &'a [(u32, u32)],
3267    table: &'a SymbolTable,
3268}
3269
3270impl Coded<'_> {
3271    /// The table every row in this vector is compressed against.
3272    #[must_use]
3273    pub fn table(&self) -> &SymbolTable {
3274        self.table
3275    }
3276
3277    /// The code bytes of one row, still compressed.
3278    #[must_use]
3279    pub fn row(&self, row: usize) -> Option<&[u8]> {
3280        let &(from, to) = self.spans.get(row)?;
3281        self.codes.get(from as usize..to as usize)
3282    }
3283
3284    /// Some bytes in the code space this vector is in.
3285    ///
3286    /// The literal side of an equality filter. Compressing is a function of the table and the bytes,
3287    /// so two strings compress to the same codes exactly when they are the same string, and an
3288    /// equality test on the codes is an equality test on the strings with no decompression in it.
3289    #[must_use]
3290    pub fn encode(&self, bytes: &[u8]) -> Vec<u8> {
3291        let mut out = Vec::with_capacity(bytes.len());
3292        self.table.compress(bytes, &mut out);
3293        out
3294    }
3295}
3296
3297/// The first `len` of a run of some narrower signed width, sign extended into `out`.
3298///
3299/// Written once and called from the three narrow arms of [`Data::signed_block`], so that the sign
3300/// extension is one loop the compiler can widen rather than three written out by hand.
3301fn widen<T: Copy + Into<i64>>(run: &[T], len: usize, out: &mut Vec<i64>) -> bool {
3302    match run.get(..len) {
3303        Some(run) => {
3304            out.extend(run.iter().map(|&x| x.into()));
3305            true
3306        }
3307        None => false,
3308    }
3309}
3310
3311/// One holder's share of a part that several vectors are reading at the same time.
3312///
3313/// The rule [`Buffer::footprint`] already uses for a shared page. Everything holding the part asks
3314/// this, so what they say between them comes to about what the part costs rather than to the part
3315/// times the number of them, and the answer is never zero for a part that costs anything, because a
3316/// caller with a reference is at least one holder.
3317fn share<T: ?Sized>(bytes: usize, held: &Arc<T>) -> usize {
3318    bytes / Arc::strong_count(held).max(1)
3319}
3320
3321/// How many words hold `len` codes of `width` bits.
3322fn words_for(len: usize, width: u32) -> usize {
3323    (len * width as usize).div_ceil(u64::BITS as usize)
3324}
3325
3326/// The lowest and highest value a type's layout can hold, and `None` for a type with no integer one.
3327///
3328/// This is also the test of whether a type can be packed at all, and it is the only one, so the
3329/// layouts listed here and the layouts [`pack`] and [`unpack`] know how to walk are the same list
3330/// from the same macro and cannot drift apart.
3331fn layout_range(ty: &LogicalType) -> Option<(i128, i128)> {
3332    use rudb_common::PhysicalType as P;
3333    macro_rules! ranges {
3334        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3335            match ty.physical() {
3336                $(P::$variant => Some((i128::from(<$native>::MIN), i128::from(<$native>::MAX))),)+
3337                _ => None,
3338            }
3339        };
3340    }
3341    crate::for_each_layout!(exact, ranges)
3342}
3343
3344/// The lowest and highest value in the first `len` slots of a run of integer data.
3345///
3346/// `None` for data that is not integers, which is what says a column cannot be packed. The null
3347/// slots are in the span, holding whatever zero was written into them, which
3348/// [`Vector::bit_packed`] says more about.
3349fn span_of(data: &Data, len: usize) -> Option<(i128, i128)> {
3350    macro_rules! spans {
3351        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3352            match data {
3353                $(Data::$variant(values) => {
3354                    let mut low = i128::MAX;
3355                    let mut high = i128::MIN;
3356                    for &value in values.as_slice().iter().take(len) {
3357                        let value = i128::from(value);
3358                        low = low.min(value);
3359                        high = high.max(value);
3360                    }
3361                    (low <= high).then_some((low, high))
3362                })+
3363                _ => None,
3364            }
3365        };
3366    }
3367    crate::for_each_layout!(exact, spans)
3368}
3369
3370/// The first `len` values of a run of integer data, written out as codes of `width` bits from `base`.
3371fn pack(data: &Data, len: usize, base: i128, width: u32) -> Vec<u64> {
3372    let mut words = vec![0u64; words_for(len, width)];
3373    macro_rules! packing {
3374        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3375            match data {
3376                $(Data::$variant(values) => {
3377                    for (row, &value) in values.as_slice().iter().take(len).enumerate() {
3378                        // In range because `base` and `width` came from the span of this same run.
3379                        let code = u64::try_from(i128::from(value) - base).unwrap_or(0);
3380                        write_code(&mut words, row * width as usize, width, code);
3381                    }
3382                })+
3383                _ => {}
3384            }
3385        };
3386    }
3387    crate::for_each_layout!(exact, packing);
3388    words
3389}
3390
3391/// The codes at the given rows, unpacked into the flat layout the type calls for.
3392///
3393/// A row of [`NOWHERE`] writes the layout's zero, which is the rule [`copy_of`] follows for the same
3394/// reason: every layout here is a parallel array to a validity mask, so a null takes a slot.
3395///
3396/// # Errors
3397///
3398/// If the type has no flat layout, which a packed vector cannot have and which is checked when one
3399/// is built, so an error here is a bug rather than a caller mistake.
3400fn unpack(
3401    ty: &LogicalType,
3402    words: &[u64],
3403    offset: usize,
3404    width: u32,
3405    base: i128,
3406    at: &[usize],
3407) -> Result<Data> {
3408    let mut out = empty_data_for(ty)?;
3409    let value_of = |row: usize| {
3410        if row == NOWHERE {
3411            return None;
3412        }
3413        Some(base + i128::from(code_at(words, (offset + row) * width as usize, width)))
3414    };
3415    macro_rules! unpacking {
3416        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3417            match &mut out {
3418                $(Data::$variant(values) => {
3419                    values.reserve(at.len());
3420                    for &row in at {
3421                        // In range because both ends of it were checked when the vector was built.
3422                        let value = value_of(row)
3423                            .and_then(|value| <$native>::try_from(value).ok())
3424                            .unwrap_or($zero);
3425                        values.push(value);
3426                    }
3427                })+
3428                _ => {
3429                    return Err(Error::internal(format!(
3430                        "a {ty} vector was packed, which no integer layout allows"
3431                    )));
3432                }
3433            }
3434        };
3435    }
3436    crate::for_each_layout!(exact, unpacking);
3437    Ok(out)
3438}
3439
3440/// The `width` bits starting at `bit`, low end first.
3441///
3442/// Zero for bits past the end of the words, which keeps a read of a row that is not there from
3443/// panicking and matches what every other accessor here does with one.
3444#[inline]
3445fn code_at(words: &[u64], bit: usize, width: u32) -> u64 {
3446    let word = bit / u64::BITS as usize;
3447    let shift = (bit % u64::BITS as usize) as u32;
3448    let mask = u64::MAX >> (u64::BITS - width);
3449    let low = words.get(word).copied().unwrap_or(0) >> shift;
3450    let taken = u64::BITS - shift;
3451    if taken >= width {
3452        return low & mask;
3453    }
3454    // The code straddles two words, and `taken` is under the width here so it is under sixty four,
3455    // which is what makes the shift below one the hardware will do rather than one it refuses.
3456    let high = words.get(word + 1).copied().unwrap_or(0) << taken;
3457    (low | high) & mask
3458}
3459
3460/// Writes `width` bits of `code` starting at `bit`, over words that started out zero.
3461fn write_code(words: &mut [u64], bit: usize, width: u32, code: u64) {
3462    let word = bit / u64::BITS as usize;
3463    let shift = (bit % u64::BITS as usize) as u32;
3464    words[word] |= code << shift;
3465    let taken = u64::BITS - shift;
3466    if taken < width {
3467        words[word + 1] |= code >> taken;
3468    }
3469}
3470
3471/// One level of dictionary out of however many levels were handed to [`Vector::dictionary`].
3472///
3473/// Every dictionary in the system is built through that constructor and every one of them comes
3474/// through here first, so the invariant this maintains is that the vector a dictionary points at is
3475/// never itself a dictionary that could have been composed away. That makes the work a single `if`
3476/// rather than a loop: the inner vector was already composed when it was built, so composing the
3477/// outer codes through it leaves the result no deeper than the inner vector already was.
3478///
3479/// The codes are indexed rather than fetched with `get`, because the caller has already walked the
3480/// whole outer array to check that every code is in range and the inner array is exactly as long as
3481/// the vector those codes were checked against.
3482fn compose(codes: Vec<u32>, values: Arc<Vector>) -> (Vec<u32>, Arc<Vector>) {
3483    // A dictionary carrying a validity of its own is one whose nulls live at this level rather than
3484    // in the values, which is the one thing composition cannot carry down with it.
3485    if !matches!(values.validity, Validity::AllValid) {
3486        return (codes, values);
3487    }
3488    let Body::Dictionary { codes: inner, values: leaf, .. } = &values.body else {
3489        return (codes, values);
3490    };
3491    debug_assert!(
3492        !matches!(leaf.body, Body::Dictionary { .. })
3493            || !matches!(leaf.validity, Validity::AllValid),
3494        "a dictionary was stacked on a dictionary without going through the constructor"
3495    );
3496    // The leaf is handed on as the handle it already is. Nothing here reads it and nothing here
3497    // changes it, so the composed dictionary points at the same values the stacked one did and
3498    // whoever else is holding them keeps holding them. This used to take them out of the `Arc`,
3499    // which copied the whole leaf whenever anybody else was still reading it, and a scan selecting
3500    // rows out of a chunk whose column came from a shared page dictionary is exactly that: the page
3501    // holds the leaf, every chunk cut from the page composes through it, and every one of those
3502    // cuts copied the page's dictionary. TPC-H q21 does it once per thousand rows of `lineitem`.
3503    let composed = codes.iter().map(|&code| inner[code as usize]).collect();
3504    (composed, Arc::clone(leaf))
3505}
3506
3507/// How many rows a run has to cover on average before run length encoding is smaller.
3508///
3509/// A run costs its value plus the four bytes of its end, so on a four byte column a run of two rows
3510/// breaks even and a run of three wins. Wider columns win sooner and narrower ones later, and this
3511/// is the one ratio for all of them because a threshold per width is a table that has to be right
3512/// nine times rather than once. It is a constant with a name so that the sweep that eventually moves
3513/// it has something to move.
3514const RUNS_PAY_AT: usize = 2;
3515
3516/// Which run holds `row`, given ends that are exclusive and increasing.
3517///
3518/// A binary search rather than a scan, because the callers that ask this are the ones that are not
3519/// walking the runs in order: a single value read out of a result set, or a gather at scattered
3520/// positions. Anything walking in order should be reading [`Vector::run_parts`] instead, which is
3521/// what the form is for.
3522fn run_holding(ends: &[u32], row: usize) -> Option<usize> {
3523    let row = u32::try_from(row).ok()?;
3524    let run = match ends.binary_search(&row) {
3525        // The ends are exclusive, so landing exactly on one means the row is the first of the next.
3526        Ok(at) => at + 1,
3527        Err(at) => at,
3528    };
3529    (run < ends.len()).then_some(run)
3530}
3531
3532/// The row each run ends at, for a flat body read alongside the validity that goes with it.
3533///
3534/// Two adjacent nulls are one run, because a reader of either gets a null and cannot tell them
3535/// apart. A null between two equal values is three runs for the same reason, since the null is a
3536/// value of the column as far as anything reading it is concerned.
3537///
3538/// The comparison is per layout rather than per `Value`, which is the whole reason this is a macro.
3539/// A `Value` a row would allocate a string per row on a `VARCHAR` column and would be the exact
3540/// defect `cargo xtask rowloop` exists to fail the build on.
3541fn boundaries(data: &Data, validity: &Validity, len: usize) -> Vec<u32> {
3542    if len == 0 {
3543        return Vec::new();
3544    }
3545    let breaks = |ends: &mut Vec<u32>, mut differs: Box<dyn FnMut(usize, usize) -> bool + '_>| {
3546        for row in 1..len {
3547            let same = match (validity.is_valid(row), validity.is_valid(row - 1)) {
3548                (false, false) => true,
3549                (true, true) => !differs(row, row - 1),
3550                _ => false,
3551            };
3552            if !same {
3553                ends.push(u32::try_from(row).unwrap_or(u32::MAX));
3554            }
3555        }
3556        ends.push(u32::try_from(len).unwrap_or(u32::MAX));
3557    };
3558    let mut ends = Vec::new();
3559    macro_rules! walked {
3560        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3561            match data {
3562                // No values at all, so every row is the same null and the column is one run.
3563                Data::Empty => ends.push(u32::try_from(len).unwrap_or(u32::MAX)),
3564                $(Data::$variant(values) => {
3565                    breaks(&mut ends, Box::new(|a, b| values.get(a) != values.get(b)));
3566                })+
3567                Data::Varlen(values) => {
3568                    breaks(&mut ends, Box::new(|a, b| values.bytes(a) != values.bytes(b)));
3569                }
3570            }
3571        };
3572    }
3573    crate::for_each_layout!(fixed, walked);
3574    ends
3575}
3576
3577/// The position of a value that is not anywhere, because it is null or out of range.
3578///
3579/// `usize::MAX` rather than an `Option<usize>`, because the copy loop's bounds check rejects it for
3580/// free and an `Option` would put a second branch next to the one already there.
3581pub(crate) const NOWHERE: usize = usize::MAX;
3582
3583/// The row id of a row that is not in the source, which reads as null.
3584///
3585/// Public because whoever builds a [`Form::Gathered`] vector has to write it, and it is `u32::MAX`
3586/// for the reason the crate's own offset sentinel is `usize::MAX`: a bounds check the reader is
3587/// doing anyway rejects it, where an `Option<u32>` would be eight bytes a row instead of four and a
3588/// second branch beside the one already there. It costs the last row of a four billion row source,
3589/// which is a source no column in this engine has.
3590pub const NO_ROW: u32 = u32::MAX;
3591
3592/// Which source row a gathered row names, and `None` when it names none.
3593///
3594/// The `Option` is what every reader of [`Body::Gathered`] that returns an `Option` wants, so the
3595/// three cases that are all *there is nothing here*, past the end of the ids, the sentinel, and an
3596/// id that does not fit a `usize`, are collapsed once here rather than three times each.
3597fn row_of(rids: &[u32], offset: usize, index: usize) -> Option<usize> {
3598    match rids.get(offset + index) {
3599        Some(&NO_ROW) | None => None,
3600        Some(&rid) => Some(rid as usize),
3601    }
3602}
3603
3604/// A run of data copied at the given positions, with a zero wherever the position is [`NOWHERE`].
3605///
3606/// A zero and not a skip, because every layout here is a parallel array to a validity mask and a
3607/// short one would put every value after the first null at the wrong index. It is the same rule
3608/// [`push_value`] follows for a null.
3609/// A contiguous run of a flat body, copied out.
3610///
3611/// The counterpart to [`copy_of`] for the one case that is a range rather than a set of positions,
3612/// which is what [`Vector::slice`] asks for. Every fixed width layout is one `memcpy` and the
3613/// string layout is a run of views and their bytes, where `copy_of` is a bounds checked index and a
3614/// null test per row.
3615///
3616/// The caller has already checked that `end` is inside the vector, and a body whose data is shorter
3617/// than its vector claims is a bug elsewhere, so a short run is clamped rather than reported.
3618///
3619/// A fixed width run over a buffer that is a window into a page does not copy anything, because
3620/// [`Buffer::slice`] moves the offset instead. That is the case a scan over stored memory is in, and
3621/// it is why the flat body is no longer the one form of a vector whose cut costs an allocation.
3622fn run_of(data: &Data, at: usize, end: usize) -> Data {
3623    macro_rules! run {
3624        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3625            match data {
3626                Data::Empty => Data::Empty,
3627                $(Data::$variant(values) => {
3628                    let held = values.len();
3629                    let from = at.min(held);
3630                    let to = end.max(from).min(held);
3631                    if to == end {
3632                        // The whole run is there, so this is a window on a shared page and a copy on
3633                        // an owned one, decided inside the buffer rather than here.
3634                        Data::$variant(values.slice(from, end - from))
3635                    } else {
3636                        let values = values.as_slice();
3637                        let mut out = Buffer::with_capacity(end - at);
3638                        out.extend_from_slice(&values[from..to]);
3639                        // A body shorter than the rows asked for pads with the zero every layout
3640                        // uses for a null, which is the answer `copy_of` gives for a position past
3641                        // the end.
3642                        // row at a time: never runs on a vector whose data matches its length.
3643                        for _ in to..end {
3644                            out.push($zero);
3645                        }
3646                        Data::$variant(out)
3647                    }
3648                })+
3649                // A view says where its bytes are, so a run of rows is not a run of bytes and this
3650                // is the one layout whose cut is still a loop. The total is known before any of it
3651                // is copied, so the arena is one allocation.
3652                //
3653                // Unless the payload is a page, in which case the cut points at the same page the
3654                // column does and no byte of it moves. That is the case a scan of a stored column
3655                // is in, and it is the whole of why a producer pages its payload: a page cut into
3656                // chunk sized pieces used to copy every byte of every long string once per piece.
3657                Data::Varlen(values) => {
3658                    if let Some(shared) = values.viewing(at..end) {
3659                        return Data::Varlen(shared);
3660                    }
3661                    let views = values.views();
3662                    let mut out = StringColumn::with_capacity(end - at);
3663                    out.reserve_bytes(
3664                        views
3665                            .get(at.min(views.len())..end.min(views.len()))
3666                            .unwrap_or(&[])
3667                            .iter()
3668                            .filter(|view| !view.is_inline())
3669                            .map(StringView::len)
3670                            .sum(),
3671                    );
3672                    // row at a time: see above, the bytes of consecutive rows need not be next to
3673                    // each other.
3674                    for index in at..end {
3675                        out.push_from(values, index);
3676                    }
3677                    Data::Varlen(out)
3678                }
3679            }
3680        };
3681    }
3682    crate::for_each_layout!(fixed, run)
3683}
3684
3685/// The values of `data` written to the places `inverse` gives them, the other way round from
3686/// [`copy_of`]: value `n` lands at `inverse[n]`.
3687///
3688/// `inverse` is a permutation of the positions of `data` and the answer is as long as it. A place
3689/// past the end is dropped rather than trusted, and a place nobody wrote keeps the zero, the same
3690/// zero a gather writes for a position that resolved to nowhere. Strings are turned back into
3691/// positions and gathered, because their one caller moves the views itself and never sends them.
3692pub(crate) fn placed_of(data: &Data, inverse: &[u32]) -> Data {
3693    macro_rules! placed {
3694        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3695            match data {
3696                $(Data::$variant(values) => {
3697                    let mut out: Vec<$native> = vec![$zero; inverse.len()];
3698                    for (value, &to) in values.as_slice().iter().zip(inverse) {
3699                        if let Some(slot) = out.get_mut(to as usize) {
3700                            *slot = *value;
3701                        }
3702                    }
3703                    Data::$variant(Buffer::from_vec(out))
3704                })+
3705                Data::Empty => Data::Empty,
3706                // Turned back round into positions and gathered, so a caller that does hand this
3707                // strings gets the right answer rather than a missing arm.
3708                Data::Varlen(_) => {
3709                    let mut at = vec![NOWHERE; inverse.len()];
3710                    for (row, &to) in inverse.iter().enumerate() {
3711                        if let Some(slot) = at.get_mut(to as usize) {
3712                            *slot = row;
3713                        }
3714                    }
3715                    copy_of(data, &at)
3716                }
3717            }
3718        };
3719    }
3720    crate::for_each_layout!(fixed, placed)
3721}
3722
3723pub(crate) fn copy_of(data: &Data, at: &[usize]) -> Data {
3724    macro_rules! copied {
3725        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3726            match data {
3727                Data::Empty => Data::Empty,
3728                $(Data::$variant(values) => {
3729                    let values = values.as_slice();
3730                    // Into a `Vec` and then into a buffer, rather than pushing at the buffer. A
3731                    // push asks the buffer whether it owns its run and copies the page out if it
3732                    // does not, which is the copy on write point and is the right answer for a
3733                    // caller writing one value. This caller is writing `at.len()` of them into a
3734                    // run it made itself one line earlier, so the question has one answer and it
3735                    // is asked once by not being asked at all. The map is exact sized, so the
3736                    // extend reserves once and writes without a capacity check per value.
3737                    let mut out: Vec<$native> = Vec::with_capacity(at.len());
3738                    // One bounds check rather than a null test and a bounds check, because
3739                    // `NOWHERE` is past the end of every slice there can be.
3740                    out.extend(at.iter().map(|&index| values.get(index).copied().unwrap_or($zero)));
3741                    Data::$variant(Buffer::from_vec(out))
3742                })+
3743                // The one layout where a gather is a copy of bytes rather than a copy of fixed
3744                // width slots, and the reason compaction is a decision rather than a default on a
3745                // string column. A payload that is a page is the exception: the gathered views
3746                // point at the page the column already points at, so the gather is sixteen bytes a
3747                // row and the bytes stay where the page put them.
3748                Data::Varlen(values) => {
3749                    if let Some(shared) = values.viewing(at.iter().copied()) {
3750                        return Data::Varlen(shared);
3751                    }
3752                    let mut out = StringColumn::with_capacity(at.len());
3753                    // The bytes are known before any of them are copied, because a view carries its
3754                    // length and the wanted positions are already in hand, so the arena is one
3755                    // allocation rather than a run of doublings that each copy what the last one
3756                    // copied.
3757                    let views = values.views();
3758                    out.reserve_bytes(
3759                        at.iter()
3760                            .filter_map(|&index| views.get(index))
3761                            .filter(|view| !view.is_inline())
3762                            .map(StringView::len)
3763                            .sum(),
3764                    );
3765                    for &index in at {
3766                        out.push_from(values, index);
3767                    }
3768                    Data::Varlen(out)
3769                }
3770            }
3771        };
3772    }
3773    crate::for_each_layout!(fixed, copied)
3774}
3775
3776/// The physical layout a run of data is in, for the check that it matches its type.
3777///
3778/// The two enums name their variants the same way on purpose, so this is one generated arm rather
3779/// than sixteen chances to pair the wrong two up.
3780pub(crate) fn layout_of(data: &Data) -> rudb_common::PhysicalType {
3781    use rudb_common::PhysicalType as P;
3782    macro_rules! layouts {
3783        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3784            match data {
3785                Data::Empty => P::Empty,
3786                $(Data::$variant(_) => P::$variant,)+
3787            }
3788        };
3789    }
3790    crate::for_each_layout!(all, layouts)
3791}
3792
3793/// One value out of a run of data, given what the run means.
3794///
3795/// The match is on the logical type rather than on the data, because the data cannot tell a `DATE`
3796/// from an `INTEGER` and that is the whole reason the two are kept apart.
3797fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
3798    let signed = || data.signed_at(index);
3799    let unsigned = || data.unsigned_at(index);
3800    let value = match ty {
3801        LogicalType::Boolean => match data {
3802            Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
3803            _ => None,
3804        },
3805        LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
3806        LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
3807        LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
3808        LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
3809        LogicalType::HugeInt => signed().map(Value::HugeInt),
3810        LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
3811        LogicalType::USmallInt => {
3812            unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
3813        }
3814        LogicalType::UInteger => {
3815            unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
3816        }
3817        LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
3818        LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
3819        LogicalType::Float => match data {
3820            Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
3821            _ => None,
3822        },
3823        LogicalType::Double => match data {
3824            Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
3825            _ => None,
3826        },
3827        LogicalType::Decimal { width, scale } => {
3828            signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
3829        }
3830        LogicalType::Varchar | LogicalType::Blob | LogicalType::Bit => {
3831            data.bytes_at(index).map(|bytes| bytes_as(ty, bytes))
3832        }
3833        LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
3834        LogicalType::Time => signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time),
3835        LogicalType::TimeTz => signed().and_then(|x| i64::try_from(x).ok()).map(Value::TimeTz),
3836        LogicalType::Timestamp
3837        | LogicalType::TimestampS
3838        | LogicalType::TimestampMs
3839        | LogicalType::TimestampNs => {
3840            signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
3841        }
3842        LogicalType::TimestampTz => {
3843            signed().and_then(|x| i64::try_from(x).ok()).map(Value::TimestampTz)
3844        }
3845        LogicalType::Interval => match data {
3846            Data::Interval(v) => {
3847                v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
3848            }
3849            _ => None,
3850        },
3851        _ => None,
3852    };
3853    value.unwrap_or(Value::Null)
3854}
3855
3856/// The fields a struct type names, and nothing for any other type.
3857///
3858/// Only a `STRUCT` vector has a [`Body::Fields`] body, and the two are built together, so in practice
3859/// the empty slice is unreachable and is here so that reading a field name is not a panic if that ever
3860/// stops being true. A struct vector whose type has fewer fields than it has children answers about
3861/// the fields it can name, because the zip stops at the shorter of the two.
3862fn fields_of(ty: &LogicalType) -> &[Field] {
3863    match ty {
3864        LogicalType::Struct(fields) => fields,
3865        _ => &[],
3866    }
3867}
3868
3869/// One row of a string column as a value, given what its bytes are meant to be read as.
3870///
3871/// Both forms that hold strings come through here, so a row that is a `BLOB` in a flat column is a
3872/// `BLOB` in a string view column too. Bytes that are not text in a `VARCHAR` column are a null
3873/// rather than a panic, since everything that got in went in as a string and a column that has
3874/// something else in it is a bug somewhere earlier that a read should not turn into a crash.
3875fn bytes_as(ty: &LogicalType, bytes: &[u8]) -> Value {
3876    match ty {
3877        LogicalType::Varchar => {
3878            std::str::from_utf8(bytes).map_or(Value::Null, |text| Value::Varchar(text.to_owned()))
3879        }
3880        LogicalType::Blob | LogicalType::Bit => Value::Blob(bytes.to_vec()),
3881        _ => Value::Null,
3882    }
3883}
3884
3885/// An empty run of data of the right layout for a type.
3886pub(crate) fn empty_data_for(ty: &LogicalType) -> Result<Data> {
3887    use rudb_common::PhysicalType as P;
3888    macro_rules! empties {
3889        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3890            match ty.physical() {
3891                P::Empty => Data::Empty,
3892                $(P::$variant => Data::$variant(Buffer::new()),)+
3893                P::Varlen => Data::Varlen(StringColumn::new()),
3894                other => {
3895                    return Err(Error::not_implemented(format!(
3896                        "a flat vector of {other:?} data, which arrives with the storage layer"
3897                    )));
3898                }
3899            }
3900        };
3901    }
3902    Ok(crate::for_each_layout!(fixed, empties))
3903}
3904
3905/// An empty run of the type's layout with room for `rows` values already taken.
3906///
3907/// For a caller that knows how many values are going in before the first one does, which is a
3908/// producer laying pieces end to end. Growing from empty instead reallocates once per doubling and
3909/// finishes holding a run rounded up to the next power of two, and on a row group of 122,880 values
3910/// that rounding is the last 8,192 of them carried for the life of the table.
3911///
3912/// Bytes are not reserved for a varlen run, because how many of them there are is not the number of
3913/// rows and the caller appending them is the one that can work it out.
3914///
3915/// # Errors
3916///
3917/// If the type has no flat layout, the same as [`empty_data_for`].
3918pub(crate) fn data_for(ty: &LogicalType, rows: usize) -> Result<Data> {
3919    let mut data = empty_data_for(ty)?;
3920    macro_rules! reserved {
3921        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3922            match &mut data {
3923                Data::Empty => {}
3924                $(Data::$variant(values) => values.reserve(rows),)+
3925                Data::Varlen(values) => values.reserve_views(rows),
3926            }
3927        };
3928    }
3929    crate::for_each_layout!(fixed, reserved);
3930    Ok(data)
3931}
3932
3933/// Appends one value to a run of data, or a zero of the right shape when it is null.
3934///
3935/// The zero matters. A null still occupies a position, the validity mask is what says it is null,
3936/// and a run of data with a hole in it would put every value after the hole in the wrong place.
3937fn push_value(data: &mut Data, value: &Value) -> Result<()> {
3938    macro_rules! push {
3939        ($vec:expr, $variant:path, $zero:expr) => {
3940            match value {
3941                Value::Null => $vec.push($zero),
3942                $variant(x) => $vec.push(*x),
3943                other => {
3944                    return Err(Error::internal(format!(
3945                        "{other:?} does not belong in this vector"
3946                    )));
3947                }
3948            }
3949        };
3950    }
3951    // A decimal is stored as its unscaled integer in whatever width its precision needs, which
3952    // `LogicalType::physical` decides and which is why the same `Value::Decimal` is at home in four
3953    // different runs. The narrowing cannot fail for a value the binder produced, because the width
3954    // that chose the run is the width in the value, but it is checked rather than assumed because
3955    // an unchecked cast here would silently store a different number.
3956    macro_rules! decimal {
3957        ($vec:expr, $ty:ty, $unscaled:expr) => {
3958            match <$ty>::try_from(*$unscaled) {
3959                Ok(x) => $vec.push(x),
3960                Err(_) => {
3961                    return Err(Error::internal(format!(
3962                        "an unscaled decimal of {} does not fit the run its precision chose",
3963                        $unscaled
3964                    )));
3965                }
3966            }
3967        };
3968    }
3969    match data {
3970        Data::Empty => {}
3971        Data::Bool(v) => push!(v, Value::Boolean, false),
3972        Data::Int8(v) => push!(v, Value::TinyInt, 0),
3973        Data::Int16(v) => match value {
3974            Value::Null => v.push(0),
3975            Value::SmallInt(x) => v.push(*x),
3976            Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
3977            other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
3978        },
3979        Data::Int32(v) => match value {
3980            Value::Null => v.push(0),
3981            Value::Integer(x) | Value::Date(x) => v.push(*x),
3982            Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
3983            other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
3984        },
3985        Data::Int64(v) => match value {
3986            Value::Null => v.push(0),
3987            Value::BigInt(x)
3988            | Value::Time(x)
3989            | Value::TimeTz(x)
3990            | Value::Timestamp(x)
3991            | Value::TimestampTz(x) => v.push(*x),
3992            Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
3993            other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
3994        },
3995        Data::Int128(v) => match value {
3996            Value::Null => v.push(0),
3997            Value::HugeInt(x) => v.push(*x),
3998            Value::Decimal { unscaled, .. } => v.push(*unscaled),
3999            other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
4000        },
4001        Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
4002        Data::UInt16(v) => push!(v, Value::USmallInt, 0),
4003        Data::UInt32(v) => push!(v, Value::UInteger, 0),
4004        Data::UInt64(v) => push!(v, Value::UBigInt, 0),
4005        Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
4006        Data::Float32(v) => push!(v, Value::Float, 0.0),
4007        Data::Float64(v) => push!(v, Value::Double, 0.0),
4008        Data::Interval(v) => match value {
4009            Value::Null => v.push((0, 0, 0)),
4010            Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
4011            other => return Err(Error::internal(format!("{other:?} is not an interval"))),
4012        },
4013        Data::Varlen(column) => match value {
4014            Value::Null => {
4015                column.push("");
4016            }
4017            Value::Varchar(text) => {
4018                column.push(text);
4019            }
4020            // A blob goes in as the bytes it is. The column stores a length and some bytes either
4021            // way, so text is the reading of one rather than a different column, and a blob that
4022            // is not UTF-8 is stored exactly like one that happens to be.
4023            Value::Blob(bytes) => {
4024                column.push_bytes(bytes);
4025            }
4026            other => return Err(Error::internal(format!("{other:?} is not a string"))),
4027        },
4028    }
4029    Ok(())
4030}
4031
4032#[cfg(test)]
4033mod tests {
4034    use std::sync::Arc;
4035
4036    use rudb_common::{Field, LogicalType, Value};
4037
4038    use super::{Body, Data, FSST_PAYS_AT, Form, MAP_KEY, MAP_VALUE, NO_ROW, VECTOR_SIZE, Vector};
4039    use crate::buffer::Buffer;
4040    use crate::fsst::SymbolTable;
4041    use crate::string::{StringColumn, StringView};
4042    use crate::validity::Validity;
4043
4044    fn integers(values: &[i32]) -> Vector {
4045        Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec().into())).unwrap()
4046    }
4047
4048    /// A `Value::List` of integers, which is what a row of a list column arrives as.
4049    fn list(values: &[i32]) -> Value {
4050        Value::List {
4051            element: LogicalType::Integer,
4052            values: values.iter().map(|&v| Value::Integer(v)).collect(),
4053        }
4054    }
4055
4056    fn list_column(rows: &[Value]) -> Vector {
4057        Vector::from_values(LogicalType::list(LogicalType::Integer), rows).unwrap()
4058    }
4059
4060    #[test]
4061    fn a_list_column_is_one_child_and_a_range_per_row() {
4062        let rows = vec![list(&[1, 2, 3]), list(&[]), Value::Null, list(&[4])];
4063        let column = list_column(&rows);
4064        assert_eq!(column.form(), Form::List);
4065        assert_eq!(column.len(), 4);
4066        assert_eq!(column.logical_type(), &LogicalType::list(LogicalType::Integer));
4067        // Four rows and four elements, because a null and an empty list both contribute none.
4068        let (entries, child) = column.list_parts().expect("a list");
4069        assert_eq!(entries, [(0, 3), (3, 0), (3, 0), (3, 1)]);
4070        assert_eq!(child.len(), 4);
4071        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
4072    }
4073
4074    /// The one thing the entries cannot say on their own, so it has to be checked that the mask says
4075    /// it. An empty list is a row that is there and holds nothing, a null is a row that is not there,
4076    /// and both of them have an entry of length zero.
4077    #[test]
4078    fn an_empty_list_and_a_null_list_have_the_same_entry_and_are_different_rows() {
4079        let column = list_column(&[list(&[]), Value::Null]);
4080        let (entries, _) = column.list_parts().expect("a list");
4081        assert_eq!(entries[0].1, entries[1].1, "both entries are empty");
4082        assert!(!column.is_null_at(0), "an empty list is not null");
4083        assert!(column.is_null_at(1), "a null list is null");
4084        assert_eq!(column.value_at(0), list(&[]));
4085        assert_eq!(column.value_at(1), Value::Null);
4086    }
4087
4088    #[test]
4089    fn slicing_a_list_column_shares_the_child_rather_than_copying_it() {
4090        let rows: Vec<Value> = (0..64).map(|row| list(&[row, row + 1, row + 2])).collect();
4091        let column = list_column(&rows);
4092        let cut = column.slice(8, 4).unwrap();
4093        assert_eq!(cut.form(), Form::List);
4094        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[8..12]);
4095        // The entries are absolute positions in a child that was not cut, which is what makes the
4096        // cut eight bytes a row however long the lists are. The elements outside the range are still
4097        // there and nothing points at them.
4098        let (entries, child) = cut.list_parts().expect("a list");
4099        assert_eq!(entries[0], (24, 3));
4100        assert_eq!(child.len(), 192);
4101    }
4102
4103    #[test]
4104    fn gathering_a_list_column_permutes_the_entries_and_leaves_the_child_alone() {
4105        let rows = vec![list(&[1]), list(&[2, 2]), list(&[3, 3, 3])];
4106        let column = list_column(&rows);
4107        let picked = column.gather(&[2, 0, 2]).unwrap();
4108        assert_eq!(
4109            picked.iter().collect::<Vec<_>>(),
4110            [list(&[3, 3, 3]), list(&[1]), list(&[3, 3, 3])]
4111        );
4112        // Two of the three rows are the same row, which is the case a run of offsets cannot write
4113        // down and a start and a length can. That is the whole reason this form carries both.
4114        assert_eq!(picked.list_parts().expect("a list").1.len(), 6);
4115    }
4116
4117    #[test]
4118    fn a_gather_past_the_end_of_a_list_column_is_null_rather_than_somebody_elses_elements() {
4119        let column = list_column(&[list(&[1, 2]), list(&[3])]);
4120        let picked = column.gather(&[1, 9]).unwrap();
4121        assert_eq!(picked.value_at(0), list(&[3]));
4122        assert_eq!(picked.value_at(1), Value::Null);
4123    }
4124
4125    #[test]
4126    fn a_list_of_lists_nests_as_far_as_it_is_written() {
4127        let outer = Value::List {
4128            element: LogicalType::list(LogicalType::Integer),
4129            values: vec![list(&[1, 2]), list(&[3])],
4130        };
4131        let column = Vector::from_values(
4132            LogicalType::list(LogicalType::list(LogicalType::Integer)),
4133            std::slice::from_ref(&outer),
4134        )
4135        .unwrap();
4136        assert_eq!(column.value_at(0), outer);
4137        assert_eq!(column.list_parts().expect("a list").1.form(), Form::List);
4138    }
4139
4140    /// A list row is not bytes and not an integer, and a caller that asks for either gets nothing
4141    /// rather than the first element or a length. Both of those would be a wrong answer that a
4142    /// group by or a hash would read without complaining.
4143    #[test]
4144    fn the_scalar_readers_decline_a_list_instead_of_answering_about_its_elements() {
4145        let column = list_column(&[list(&[7])]);
4146        assert_eq!(column.signed_at(0), None);
4147        assert_eq!(column.bytes_at(0), None);
4148        assert_eq!(column.data(), None);
4149    }
4150
4151    fn pair(a: i32, b: &str) -> Value {
4152        Value::Struct(vec![
4153            ("a".to_string(), Value::Integer(a)),
4154            ("b".to_string(), Value::Varchar(b.to_string())),
4155        ])
4156    }
4157
4158    fn pair_type() -> LogicalType {
4159        LogicalType::Struct(vec![
4160            Field::new("a", LogicalType::Integer),
4161            Field::new("b", LogicalType::Varchar),
4162        ])
4163    }
4164
4165    fn pair_column(rows: &[Value]) -> Vector {
4166        Vector::from_values(pair_type(), rows).unwrap()
4167    }
4168
4169    #[test]
4170    fn a_struct_column_is_one_child_per_field_as_long_as_the_column() {
4171        let rows = vec![pair(1, "x"), pair(2, "y"), pair(3, "z")];
4172        let column = pair_column(&rows);
4173        assert_eq!(column.form(), Form::Struct);
4174        assert_eq!(column.len(), 3);
4175        assert_eq!(column.logical_type(), &pair_type());
4176        // Two children rather than two entries and a child, and both of them as long as the column,
4177        // which is the whole difference between this form and the list one.
4178        let children = column.struct_parts().expect("a struct");
4179        assert_eq!(children.len(), 2);
4180        assert_eq!(children[0].len(), 3);
4181        assert_eq!(children[1].len(), 3);
4182        assert_eq!(children[0].logical_type(), &LogicalType::Integer);
4183        assert_eq!(children[1].logical_type(), &LogicalType::Varchar);
4184        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
4185    }
4186
4187    /// Picking one field out of a struct is picking one child, which is the reason this accessor is
4188    /// public. A projection of `s.a` hands back a vector that already exists, so it costs a pointer
4189    /// rather than a pass over the rows, and that is only true while the children are full length.
4190    #[test]
4191    fn one_field_of_a_struct_column_is_a_column_that_is_already_there() {
4192        let column = pair_column(&[pair(10, "x"), pair(20, "y")]);
4193        let field = &column.struct_parts().expect("a struct")[0];
4194        assert_eq!(field.iter().collect::<Vec<_>>(), [Value::Integer(10), Value::Integer(20)]);
4195        assert_eq!(field.signed_at(1), Some(20), "the field is a scalar column and reads like one");
4196    }
4197
4198    /// A null struct is a bit in the mask at the top and nothing deeper, which is how every other type
4199    /// records a null and is what DuckDB does. The row reads as a single null rather than as a struct of
4200    /// nulls, and the fields underneath are still their own columns.
4201    #[test]
4202    fn a_null_struct_is_the_mask_at_the_top_and_not_a_struct_full_of_nulls() {
4203        let column = pair_column(&[pair(1, "x"), Value::Null]);
4204        assert!(!column.is_null_at(0));
4205        assert!(column.is_null_at(1));
4206        assert_eq!(column.value_at(1), Value::Null);
4207        // A struct row whose every field happens to be null is a different row, and it is not null.
4208        let all_null = pair_column(&[Value::Struct(vec![
4209            ("a".to_string(), Value::Null),
4210            ("b".to_string(), Value::Null),
4211        ])]);
4212        assert!(!all_null.is_null_at(0), "a struct of nulls is a row that is there");
4213        assert_ne!(all_null.value_at(0), Value::Null);
4214    }
4215
4216    #[test]
4217    fn slicing_a_struct_column_cuts_every_field_at_the_same_place() {
4218        let rows: Vec<Value> = (0..64).map(|row| pair(row, "s")).collect();
4219        let column = pair_column(&rows);
4220        let cut = column.slice(8, 4).unwrap();
4221        assert_eq!(cut.form(), Form::Struct);
4222        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[8..12]);
4223        // The cut a list column does not have to do. A list shares its child untouched because the
4224        // entries carry the range, and a struct has no entry standing between the row and the child,
4225        // so every child is four rows long here rather than sixty four.
4226        for child in cut.struct_parts().expect("a struct") {
4227            assert_eq!(child.len(), 4);
4228        }
4229    }
4230
4231    #[test]
4232    fn gathering_a_struct_column_gathers_every_field_at_the_same_positions() {
4233        let column = pair_column(&[pair(1, "x"), pair(2, "y"), pair(3, "z")]);
4234        let picked = column.gather(&[2, 0, 2]).unwrap();
4235        assert_eq!(picked.iter().collect::<Vec<_>>(), [pair(3, "z"), pair(1, "x"), pair(3, "z")]);
4236        for child in picked.struct_parts().expect("a struct") {
4237            assert_eq!(child.len(), 3, "a field is as long as the gather, not as the source");
4238        }
4239    }
4240
4241    #[test]
4242    fn a_gather_past_the_end_of_a_struct_column_is_null_in_every_field_and_at_the_top() {
4243        let column = pair_column(&[pair(1, "x"), pair(2, "y")]);
4244        let picked = column.gather(&[1, 9]).unwrap();
4245        assert_eq!(picked.value_at(0), pair(2, "y"));
4246        assert_eq!(picked.value_at(1), Value::Null);
4247        for child in picked.struct_parts().expect("a struct") {
4248            assert!(child.is_null_at(1), "a row that came from nowhere has no field value either");
4249        }
4250    }
4251
4252    /// The names are matched and not counted, because a caller holding a struct value built in a
4253    /// different order from the type's would otherwise get its columns transposed, and that is a wrong
4254    /// answer that reads as a right one.
4255    #[test]
4256    fn the_fields_of_a_struct_value_go_in_by_name_rather_than_by_position() {
4257        let swapped = Value::Struct(vec![
4258            ("b".to_string(), Value::Varchar("x".to_string())),
4259            ("a".to_string(), Value::Integer(1)),
4260        ]);
4261        let column = pair_column(&[swapped]);
4262        assert_eq!(column.value_at(0), pair(1, "x"));
4263        let wrong = Value::Struct(vec![
4264            ("a".to_string(), Value::Integer(1)),
4265            ("c".to_string(), Value::Varchar("x".to_string())),
4266        ]);
4267        let failed = Vector::from_values(pair_type(), &[wrong]);
4268        assert!(failed.is_err(), "a row with no b field is an error rather than a null b");
4269    }
4270
4271    #[test]
4272    fn a_struct_built_from_children_takes_its_field_names_from_the_caller() {
4273        let column = Vector::structure(vec![
4274            ("a".to_string(), integers(&[1, 2, 3])),
4275            ("b".to_string(), integers(&[4, 5, 6])),
4276        ])
4277        .expect("two columns of three");
4278        assert_eq!(column.len(), 3);
4279        assert_eq!(
4280            column.logical_type(),
4281            &LogicalType::Struct(vec![
4282                Field::new("a", LogicalType::Integer),
4283                Field::new("b", LogicalType::Integer),
4284            ])
4285        );
4286        assert_eq!(
4287            column.value_at(1),
4288            Value::Struct(vec![
4289                ("a".to_string(), Value::Integer(2)),
4290                ("b".to_string(), Value::Integer(5)),
4291            ])
4292        );
4293    }
4294
4295    /// The two mistakes this constructor makes easy, both refused rather than stored. A short field is
4296    /// the one that matters: it would be a struct that reads past the end of one of its own children,
4297    /// which is the same mistake `Vector::list` checks for at the other end.
4298    #[test]
4299    fn a_struct_of_uneven_children_or_of_no_children_is_refused() {
4300        let uneven = Vector::structure(vec![
4301            ("a".to_string(), integers(&[1, 2, 3])),
4302            ("b".to_string(), integers(&[4, 5])),
4303        ]);
4304        assert!(uneven.is_err(), "a field shorter than the struct");
4305        assert!(Vector::structure(vec![]).is_err(), "no field to take a length from");
4306    }
4307
4308    #[test]
4309    fn a_struct_of_lists_and_a_list_of_structs_both_nest() {
4310        let ty =
4311            LogicalType::Struct(vec![Field::new("a", LogicalType::list(LogicalType::Integer))]);
4312        let row = Value::Struct(vec![("a".to_string(), list(&[1, 2]))]);
4313        let column = Vector::from_values(ty, std::slice::from_ref(&row)).unwrap();
4314        assert_eq!(column.value_at(0), row);
4315        assert_eq!(column.struct_parts().expect("a struct")[0].form(), Form::List);
4316
4317        let outer = Value::List { element: pair_type(), values: vec![pair(1, "x"), pair(2, "y")] };
4318        let lists =
4319            Vector::from_values(LogicalType::list(pair_type()), std::slice::from_ref(&outer))
4320                .unwrap();
4321        assert_eq!(lists.value_at(0), outer);
4322        assert_eq!(lists.list_parts().expect("a list").1.form(), Form::Struct);
4323    }
4324
4325    fn tags(pairs: &[(&str, &str)]) -> Value {
4326        Value::map(
4327            LogicalType::Varchar,
4328            LogicalType::Varchar,
4329            pairs
4330                .iter()
4331                .map(|&(key, value)| {
4332                    (Value::Varchar(key.to_string()), Value::Varchar(value.to_string()))
4333                })
4334                .collect(),
4335        )
4336    }
4337
4338    fn tag_column(rows: &[Value]) -> Vector {
4339        Vector::from_values(LogicalType::map(LogicalType::Varchar, LogicalType::Varchar), rows)
4340            .unwrap()
4341    }
4342
4343    /// A map is a list of two field structs, which is the whole design, so the test that says so is
4344    /// the one that reaches through both layers and finds the pieces where each of them puts them.
4345    #[test]
4346    fn a_map_column_is_a_list_whose_child_is_a_struct_of_keys_and_values() {
4347        let rows =
4348            vec![tags(&[("a", "b"), ("c", "d")]), tags(&[]), Value::Null, tags(&[("e", "f")])];
4349        let column = tag_column(&rows);
4350        assert_eq!(column.len(), 4);
4351        assert_eq!(
4352            column.logical_type(),
4353            &LogicalType::map(LogicalType::Varchar, LogicalType::Varchar)
4354        );
4355        // The physical form is a list's, because the bytes are a list's. The logical type is what
4356        // remembers it is a map, which is the same split `LogicalType::physical` already makes.
4357        assert_eq!(column.form(), Form::List);
4358        let (entries, child) = column.list_parts().expect("the layout of a list");
4359        assert_eq!(entries, [(0, 2), (2, 0), (2, 0), (2, 1)]);
4360        assert_eq!(child.form(), Form::Struct);
4361        assert_eq!(
4362            child.logical_type(),
4363            &LogicalType::Struct(vec![
4364                Field::new(MAP_KEY, LogicalType::Varchar),
4365                Field::new(MAP_VALUE, LogicalType::Varchar),
4366            ])
4367        );
4368        // And the accessor that reaches through it hands back the two columns rather than the struct.
4369        let (entries, keys, values) = column.map_parts().expect("a map");
4370        assert_eq!(entries.len(), 4);
4371        assert_eq!(keys.text_at(0), Some("a"));
4372        assert_eq!(values.text_at(0), Some("b"));
4373        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
4374    }
4375
4376    /// The same distinction a list has, checked again here rather than assumed from the composition,
4377    /// because the empty map is the one every catalog table in D2 is full of and a null map is what a
4378    /// column with no tags at all would be.
4379    #[test]
4380    fn an_empty_map_and_a_null_map_are_different_rows() {
4381        let column = tag_column(&[tags(&[]), Value::Null]);
4382        assert!(!column.is_null_at(0), "an empty map is a row that is there");
4383        assert!(column.is_null_at(1));
4384        assert_eq!(column.value_at(0), tags(&[]));
4385        assert_eq!(column.value_at(1), Value::Null);
4386        assert_eq!(column.value_at(0).to_string(), "{}");
4387        assert_eq!(column.value_at(1).to_string(), "NULL");
4388    }
4389
4390    /// A map prints `{a=b}` and a struct prints `{'a': b}`, both measured off the pin. They share a
4391    /// layout and they cannot share a printer, which is the one thing about this composition that does
4392    /// not fall out of it.
4393    #[test]
4394    fn a_map_prints_with_equals_signs_and_a_struct_prints_with_quoted_names() {
4395        assert_eq!(tags(&[("a", "b"), ("c", "d")]).to_string(), "{a=b, c=d}");
4396        assert_eq!(pair(1, "x").to_string(), "{'a': 1, 'b': x}");
4397        let numbers = Value::map(
4398            LogicalType::Integer,
4399            LogicalType::Integer,
4400            vec![(Value::Integer(1), Value::Integer(3)), (Value::Integer(2), Value::Integer(4))],
4401        );
4402        assert_eq!(numbers.to_string(), "{1=3, 2=4}");
4403        let null_value = Value::map(
4404            LogicalType::Varchar,
4405            LogicalType::Varchar,
4406            vec![(Value::Varchar("x".to_string()), Value::Null)],
4407        );
4408        assert_eq!(null_value.to_string(), "{x=NULL}");
4409    }
4410
4411    /// A map inherits the list's cut and the list's gather, which is the payoff for storing it as one.
4412    /// Neither of these is code written for maps and both of them are worth a test that says the
4413    /// inheritance works, since the type is rewritten on the way through and a form that came back as a
4414    /// list would still read.
4415    #[test]
4416    fn cutting_and_gathering_a_map_keeps_it_a_map() {
4417        let rows: Vec<Value> =
4418            (0..16).map(|row| tags(&[("k", if row % 2 == 0 { "e" } else { "o" })])).collect();
4419        let column = tag_column(&rows);
4420
4421        let cut = column.slice(4, 3).unwrap();
4422        assert!(matches!(cut.logical_type(), LogicalType::Map(_, _)), "still a map after a cut");
4423        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[4..7]);
4424        // The child was not cut, the same as for a list, which is what makes the cut eight bytes a row.
4425        assert_eq!(cut.map_parts().expect("a map").1.len(), 16);
4426
4427        let picked = column.gather(&[3, 0, 3]).unwrap();
4428        assert!(matches!(picked.logical_type(), LogicalType::Map(_, _)));
4429        assert_eq!(
4430            picked.iter().collect::<Vec<_>>(),
4431            [rows[3].clone(), rows[0].clone(), rows[3].clone()]
4432        );
4433        let past = column.gather(&[0, 99]).unwrap();
4434        assert_eq!(past.value_at(1), Value::Null);
4435    }
4436
4437    #[test]
4438    fn a_map_built_from_two_columns_pairs_them_by_position() {
4439        let keys = Vector::from_values(
4440            LogicalType::Varchar,
4441            &[Value::Varchar("a".to_string()), Value::Varchar("c".to_string())],
4442        )
4443        .unwrap();
4444        let values = Vector::from_values(
4445            LogicalType::Varchar,
4446            &[Value::Varchar("b".to_string()), Value::Varchar("d".to_string())],
4447        )
4448        .unwrap();
4449        let column = Vector::map(vec![(0, 2), (2, 0)], keys, values).expect("two rows");
4450        assert_eq!(column.len(), 2);
4451        assert_eq!(
4452            column.logical_type(),
4453            &LogicalType::map(LogicalType::Varchar, LogicalType::Varchar)
4454        );
4455        assert_eq!(column.value_at(0), tags(&[("a", "b"), ("c", "d")]));
4456        assert_eq!(column.value_at(1), tags(&[]));
4457        // The entry check the list constructor does is the one a map gets, so an entry past the end of
4458        // the pair of columns is refused here too rather than read as somebody else's keys.
4459        let short =
4460            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("a".to_string())]).unwrap();
4461        let other =
4462            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("b".to_string())]).unwrap();
4463        assert!(Vector::map(vec![(0, 9)], short, other).is_err(), "an entry past the end");
4464    }
4465
4466    /// `map_parts` is about the logical type and `list_parts` is about the layout, so a list has to
4467    /// decline the first and a map has to answer the second. Getting that backwards would let a kernel
4468    /// written for maps read a list of two field structs as if it were one.
4469    #[test]
4470    fn a_list_is_not_a_map_however_much_its_child_looks_like_one() {
4471        let pairs = Value::List { element: pair_type(), values: vec![pair(1, "x")] };
4472        let column =
4473            Vector::from_values(LogicalType::list(pair_type()), std::slice::from_ref(&pairs))
4474                .unwrap();
4475        assert!(column.map_parts().is_none(), "a list of structs is a list");
4476        assert!(column.list_parts().is_some());
4477        let map = tag_column(&[tags(&[("a", "b")])]);
4478        assert!(map.map_parts().is_some());
4479        assert!(map.list_parts().is_some(), "a map has a list's layout and says so");
4480    }
4481
4482    /// A struct row is not bytes and not an integer, and it stays that way when it has exactly one
4483    /// integer field, which is the case where answering about the field would look reasonable and would
4484    /// be a hash keyed on the wrong thing.
4485    #[test]
4486    fn the_scalar_readers_decline_a_struct_of_one_integer_field() {
4487        let ty = LogicalType::Struct(vec![Field::new("a", LogicalType::Integer)]);
4488        let row = Value::Struct(vec![("a".to_string(), Value::Integer(7))]);
4489        let column = Vector::from_values(ty, &[row]).unwrap();
4490        assert_eq!(column.signed_at(0), None);
4491        assert_eq!(column.bytes_at(0), None);
4492        assert_eq!(column.data(), None);
4493    }
4494
4495    #[test]
4496    fn a_clustered_column_becomes_runs_and_reads_back_the_same() {
4497        let mut values = Vec::new();
4498        for (value, times) in [(7, 400), (8, 300), (7, 324)] {
4499            values.extend(std::iter::repeat_n(value, times));
4500        }
4501        let flat = integers(&values);
4502        let runs = flat.run_encoded().unwrap();
4503        assert_eq!(runs.form(), Form::Rle);
4504        assert_eq!(runs.run_parts().expect("runs").0, [400, 700, 1024]);
4505        assert_eq!(runs.len(), flat.len());
4506        assert_eq!(runs.iter().collect::<Vec<_>>(), flat.iter().collect::<Vec<_>>());
4507        assert!(
4508            runs.footprint() * 10 < flat.footprint(),
4509            "three runs against a thousand rows: {} against {}",
4510            runs.footprint(),
4511            flat.footprint()
4512        );
4513    }
4514
4515    /// The check is worth having in both directions. A form that is only ever bigger than what it
4516    /// replaced is a form that costs a pass over the column to decide not to use.
4517    #[test]
4518    fn a_column_that_does_not_repeat_is_left_flat() {
4519        let flat = integers(&(0..1024).collect::<Vec<i32>>());
4520        assert_eq!(flat.run_encoded().unwrap().form(), Form::Flat);
4521        // Two runs over four rows is exactly break even on a four byte column, and break even is
4522        // not a reason to change form.
4523        assert_eq!(integers(&[1, 1, 2, 2]).run_encoded().unwrap().form(), Form::Flat);
4524        assert_eq!(integers(&[1, 1, 1, 2, 2]).run_encoded().unwrap().form(), Form::Rle);
4525    }
4526
4527    #[test]
4528    fn two_nulls_beside_each_other_are_one_run_and_a_null_between_two_equals_is_a_break() {
4529        let mut values = vec![Value::Integer(4), Value::Integer(4)];
4530        values.extend([Value::Null, Value::Null, Value::Null]);
4531        values.extend(std::iter::repeat_n(Value::Integer(4), 5));
4532        let flat = Vector::from_values(LogicalType::Integer, &values).unwrap();
4533        let runs = flat.run_encoded().unwrap();
4534        assert_eq!(runs.run_parts().expect("runs").0, [2, 5, 10]);
4535        assert_eq!(runs.iter().collect::<Vec<_>>(), values);
4536    }
4537
4538    #[test]
4539    fn slicing_runs_keeps_them_runs_and_cuts_the_first_and_last_one_back() {
4540        let flat = integers(&[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]);
4541        let runs = flat.run_encoded().unwrap();
4542        let piece = runs.slice(3, 6).unwrap();
4543        assert_eq!(piece.form(), Form::Rle, "the form is the whole point");
4544        assert_eq!(piece.run_parts().expect("runs").0, [1, 5, 6]);
4545        assert_eq!(
4546            piece.iter().collect::<Vec<_>>(),
4547            flat.slice(3, 6).unwrap().iter().collect::<Vec<_>>()
4548        );
4549        assert_eq!(runs.slice(0, 0).unwrap().len(), 0);
4550        assert_eq!(runs.slice(0, 12).unwrap().form(), Form::Rle);
4551    }
4552
4553    #[test]
4554    fn gathering_out_of_runs_walks_to_the_values_the_way_it_walks_a_dictionary() {
4555        let mut values = vec![Value::Varchar("red".into()); 4];
4556        values.extend([Value::Null, Value::Null, Value::Null]);
4557        values.extend(vec![Value::Varchar("blue".into()); 4]);
4558        let runs =
4559            Vector::from_values(LogicalType::Varchar, &values).unwrap().run_encoded().unwrap();
4560        assert_eq!(runs.form(), Form::Rle);
4561        let picked = runs.gather(&[8, 0, 5, 2]).unwrap();
4562        assert_eq!(picked.form(), Form::Flat, "a gather copies, whatever it gathered from");
4563        assert_eq!(
4564            picked.iter().collect::<Vec<_>>(),
4565            [values[8].clone(), values[0].clone(), Value::Null, values[2].clone()]
4566        );
4567        assert_eq!(runs.text_at(1), Some("red"));
4568        assert_eq!(runs.text_at(5), None, "a null has no text");
4569        assert_eq!(runs.flatten().unwrap().iter().collect::<Vec<_>>(), values);
4570    }
4571
4572    /// A run length vector over a run length vector turns one search per row into two, and there is
4573    /// nothing in the engine that builds one, so it is refused rather than composed.
4574    #[test]
4575    fn runs_of_runs_are_refused_and_runs_of_a_dictionary_are_not() {
4576        let inner = integers(&[1, 1, 1, 1, 2]).run_encoded().unwrap();
4577        assert_eq!(inner.form(), Form::Rle);
4578        let error = Vector::runs(vec![2, 8], inner).unwrap_err();
4579        assert!(error.to_string().contains("runs of runs"), "{error}");
4580
4581        let words = Vector::from_values(
4582            LogicalType::Varchar,
4583            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
4584        )
4585        .unwrap();
4586        let dictionary = Vector::dictionary(vec![1, 0], words).unwrap();
4587        let stacked = Vector::runs(vec![4, 9], dictionary).unwrap();
4588        assert_eq!(stacked.len(), 9);
4589        assert_eq!(stacked.value_at(3), Value::Varchar("blue".into()));
4590        assert_eq!(stacked.value_at(4), Value::Varchar("red".into()));
4591    }
4592
4593    #[test]
4594    fn run_ends_have_to_increase_and_there_is_one_value_for_each_of_them() {
4595        let values = integers(&[1, 2]);
4596        assert!(Vector::runs(vec![4], values.clone()).is_err(), "two values and one run");
4597        assert!(Vector::runs(vec![4, 4], values.clone()).is_err(), "an end that repeats");
4598        assert!(Vector::runs(vec![4, 2], values.clone()).is_err(), "an end that goes backwards");
4599        assert!(Vector::runs(vec![0, 2], values.clone()).is_err(), "a first run holding no rows");
4600        assert_eq!(Vector::runs(vec![4, 9], values).unwrap().len(), 9);
4601    }
4602
4603    #[test]
4604    fn a_form_that_is_already_compact_is_left_where_it_is() {
4605        let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1000);
4606        assert_eq!(constant.run_encoded().unwrap().form(), Form::Constant);
4607        assert_eq!(Vector::sequence(0, 1, 1000).run_encoded().unwrap().form(), Form::Sequence);
4608    }
4609
4610    /// What makes one accessor cover both forms. A dictionary hands back the codes it stores and a
4611    /// run length vector works the same numbers out, and a kernel writing `values[at[row]]` reads
4612    /// the same rows out of either.
4613    #[test]
4614    fn both_forms_that_point_somewhere_hand_back_a_position_per_row() {
4615        let words = Vector::from_values(
4616            LogicalType::Varchar,
4617            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
4618        )
4619        .unwrap();
4620        let runs = Vector::runs(vec![3, 5], words.clone()).unwrap();
4621        let (at, values) = runs.positions().expect("runs point somewhere");
4622        assert_eq!(at.as_ref(), [0, 0, 0, 1, 1]);
4623        assert_eq!(values.value_at(at[3] as usize), runs.value_at(3));
4624
4625        let dictionary = Vector::dictionary(vec![1, 0, 1], words).unwrap();
4626        let (at, values) = dictionary.positions().expect("a dictionary points somewhere");
4627        assert_eq!(at.as_ref(), [1, 0, 1]);
4628        assert_eq!(values.value_at(at[0] as usize), dictionary.value_at(0));
4629
4630        assert!(integers(&[1, 2, 3]).positions().is_none(), "a flat vector points at itself");
4631        assert!(Vector::sequence(0, 1, 4).positions().is_none(), "a sequence stores nothing");
4632    }
4633
4634    #[test]
4635    fn slicing_a_dictionary_keeps_it_a_dictionary_where_gathering_would_not() {
4636        let values = Vector::from_values(
4637            LogicalType::Varchar,
4638            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
4639        )
4640        .unwrap();
4641        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
4642
4643        let piece = vector.slice(1, 3).unwrap();
4644        assert_eq!(piece.form(), Form::Dictionary, "the form is the whole point");
4645        assert_eq!(piece.len(), 3);
4646        assert_eq!(
4647            piece.iter().collect::<Vec<_>>(),
4648            [
4649                Value::Varchar("blue".into()),
4650                Value::Varchar("blue".into()),
4651                Value::Varchar("red".into())
4652            ]
4653        );
4654        assert_eq!(vector.gather(&[1, 2, 3]).unwrap().form(), Form::Flat, "which a gather loses");
4655    }
4656
4657    #[test]
4658    fn slicing_a_dictionary_shares_the_dictionary_rather_than_copying_it() {
4659        // The assertion is about the address and not about the values, because the values were
4660        // right when the dictionary was copied too. A page holds one dictionary and is cut into a
4661        // chunk of codes at a time, so copying the dictionary here is a copy of every string in it
4662        // per chunk, and on a read of a ClickBench partition it was ten percent of the cycles.
4663        let values = Vector::from_values(
4664            LogicalType::Varchar,
4665            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
4666        )
4667        .unwrap();
4668        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
4669        let Body::Dictionary { values: whole, .. } = &vector.body else {
4670            panic!("a dictionary vector holds a dictionary");
4671        };
4672
4673        let piece = vector.slice(1, 3).unwrap();
4674        let Body::Dictionary { codes, values: cut, .. } = &piece.body else {
4675            panic!("a slice of a dictionary is a dictionary");
4676        };
4677        assert!(Arc::ptr_eq(whole, cut), "the cut copied the dictionary");
4678        assert_eq!(codes, &[1, 1, 0], "the codes are the part that is cut");
4679
4680        // And a cut of a cut shares it too, since that is what a scan does to a page it reads twice.
4681        let again = piece.slice(1, 2).unwrap();
4682        let Body::Dictionary { values: cut, .. } = &again.body else {
4683            panic!("a slice of a slice of a dictionary is a dictionary");
4684        };
4685        assert!(Arc::ptr_eq(whole, cut), "the second cut copied the dictionary");
4686        assert_eq!(
4687            again.iter().collect::<Vec<_>>(),
4688            [Value::Varchar("blue".into()), Value::Varchar("red".into())]
4689        );
4690    }
4691
4692    #[test]
4693    fn a_slice_carries_the_nulls_that_were_in_its_range_and_not_the_others() {
4694        let vector =
4695            integers(&[1, 2, 3, 4]).with_validity(Validity::from_run(&[false, true, false, true]));
4696        let piece = vector.slice(1, 2).unwrap();
4697        assert!(piece.validity().is_valid(0));
4698        assert!(!piece.validity().is_valid(1));
4699        assert_eq!(piece.value_at(1), Value::Null);
4700    }
4701
4702    #[test]
4703    fn slicing_a_sequence_moves_its_start_rather_than_writing_the_values_out() {
4704        let vector = Vector::sequence(100, 5, 10);
4705        let piece = vector.slice(3, 4).unwrap();
4706        assert_eq!(piece.form(), Form::Sequence);
4707        assert_eq!(
4708            piece.iter().collect::<Vec<_>>(),
4709            [Value::BigInt(115), Value::BigInt(120), Value::BigInt(125), Value::BigInt(130)]
4710        );
4711    }
4712
4713    #[test]
4714    fn slicing_a_constant_is_a_shorter_constant() {
4715        let vector = Vector::constant(LogicalType::Integer, Value::Integer(9), 8);
4716        let piece = vector.slice(2, 3).unwrap();
4717        assert_eq!(piece.form(), Form::Constant);
4718        assert_eq!(piece.len(), 3);
4719        assert_eq!(piece.value_at(2), Value::Integer(9));
4720    }
4721
4722    #[test]
4723    fn slicing_the_whole_vector_hands_it_back_as_it_was() {
4724        let vector = integers(&[1, 2, 3]);
4725        assert_eq!(
4726            vector.slice(0, 3).unwrap().iter().collect::<Vec<_>>(),
4727            [Value::Integer(1), Value::Integer(2), Value::Integer(3)]
4728        );
4729    }
4730
4731    #[test]
4732    fn cutting_a_flat_body_answers_what_gathering_the_same_rows_answers() {
4733        // The cut of a flat body used to be written as a gather over the positions in the range,
4734        // and it is now a run copied out, so the two have to keep saying the same thing. Every
4735        // start and every length, with nulls in the range and out of it, since the validity is the
4736        // half of this that changed shape.
4737        let rows: Vec<i32> = (0..70).collect();
4738        let valid: Vec<bool> = (0..70).map(|row| row % 7 != 0 && row % 11 != 3).collect();
4739        let vector = integers(&rows).with_validity(Validity::from_run(&valid));
4740        for at in 0..70usize {
4741            for len in 0..=(70 - at) {
4742                let cut = vector.slice(at, len).unwrap();
4743                let positions: Vec<u32> = (at..at + len).map(|row| row as u32).collect();
4744                let gathered = vector.gather(&positions).unwrap();
4745                assert_eq!(cut.len(), len, "rows {at} to {}", at + len);
4746                assert_eq!(
4747                    cut.iter().collect::<Vec<_>>(),
4748                    gathered.iter().collect::<Vec<_>>(),
4749                    "rows {at} to {}",
4750                    at + len
4751                );
4752            }
4753        }
4754    }
4755
4756    /// The flat body used to be the one form of a vector whose cut cost an allocation and a copy,
4757    /// and it is not any more when its buffer is a run inside a page. Asserted on the address,
4758    /// because the values are the same either way and the address is the whole claim.
4759    #[test]
4760    fn cutting_a_flat_body_over_a_page_does_not_copy_it() {
4761        let page = Arc::new((0i64..64).collect::<Vec<_>>());
4762        let address = page.as_ptr() as usize;
4763        let data = Data::Int64(Buffer::from_arc(Arc::clone(&page)));
4764        let vector = Vector::flat(LogicalType::BigInt, data).unwrap();
4765        let cut = vector.slice(16, 8).unwrap();
4766        assert_eq!(cut.form(), Form::Flat);
4767        assert_eq!(cut.len(), 8);
4768        let Some(Data::Int64(run)) = cut.data() else {
4769            panic!("the layout changed under the test")
4770        };
4771        assert!(run.is_shared(), "the cut copied the run out of the page");
4772        assert_eq!(run.as_slice().as_ptr() as usize, address + 16 * 8);
4773        assert_eq!(run.as_slice(), &(16i64..24).collect::<Vec<_>>()[..]);
4774        assert_eq!(cut.value_at(0), Value::BigInt(16));
4775        // And the same cut of an owned run says the same thing, by copying it.
4776        let owned = Vector::flat(LogicalType::BigInt, Data::Int64((0i64..64).collect())).unwrap();
4777        let copied = owned.slice(16, 8).unwrap();
4778        let Some(Data::Int64(run)) = copied.data() else {
4779            panic!("the layout changed under the test")
4780        };
4781        assert!(!run.is_shared());
4782        assert_eq!(run.as_slice(), &(16i64..24).collect::<Vec<_>>()[..]);
4783    }
4784
4785    /// `into_pages` is how a producer says its values will be handed out many times. A flat body is
4786    /// the form it changes, and after it a copy of the vector is a reference count bump.
4787    #[test]
4788    fn a_vector_over_pages_is_copied_and_cut_without_its_values_moving() {
4789        let vector = integers(&[1, 2, 3, 4, 5, 6, 7, 8]).into_pages();
4790        let address = |vector: &Vector| match vector.data() {
4791            Some(Data::Int32(values)) => values.as_slice().as_ptr() as usize,
4792            _ => panic!("the layout changed under the test"),
4793        };
4794        let stored = address(&vector);
4795        assert_eq!(address(&vector.clone()), stored, "a copy moved the values");
4796        assert_eq!(address(&vector.slice(2, 4).unwrap()), stored + 2 * 4, "a cut moved the values");
4797        assert_eq!(
4798            vector.slice(2, 4).unwrap().iter().collect::<Vec<_>>(),
4799            [Value::Integer(3), Value::Integer(4), Value::Integer(5), Value::Integer(6)]
4800        );
4801        // Twice is not two pages.
4802        assert_eq!(address(&vector.clone().into_pages()), stored);
4803    }
4804
4805    /// A cut, a gather and a flatten of a string column over a page all move views and no bytes.
4806    ///
4807    /// This is the string half of the paging that `a_vector_over_pages_is_copied_and_cut_without_
4808    /// its_values_moving` checks for a fixed width column, and it is worth its own test because a
4809    /// string column is two allocations rather than one: the cut that matters is the payload
4810    /// staying where it is while the views move.
4811    #[test]
4812    fn a_string_column_over_a_page_is_cut_and_gathered_without_its_payload_moving() {
4813        let long = ["the first of the long strings", "the second one", "and a third long one here"];
4814        let mut built = StringColumn::with_capacity(long.len());
4815        for text in long {
4816            built.push(text);
4817        }
4818        let vector = Vector::flat(LogicalType::Varchar, Data::Varlen(built.into_page())).unwrap();
4819        let payload = |vector: &Vector| match vector.data() {
4820            Some(Data::Varlen(column)) => column.arena().as_ptr() as usize,
4821            _ => panic!("the layout changed under the test"),
4822        };
4823        let stored = payload(&vector);
4824        let cut = vector.slice(1, 2).unwrap();
4825        assert_eq!(payload(&cut), stored, "a cut moved the payload");
4826        assert_eq!(cut.text_at(0), Some(long[1]));
4827        assert_eq!(cut.text_at(1), Some(long[2]));
4828        let gathered = vector.gather(&[2, 0]).unwrap();
4829        assert_eq!(payload(&gathered), stored, "a gather moved the payload");
4830        assert_eq!(gathered.text_at(0), Some(long[2]));
4831        assert_eq!(gathered.text_at(1), Some(long[0]));
4832        // And the same column with its own arena still copies, because sharing an owned arena
4833        // means cloning every byte of it including the bytes nobody asked for.
4834        let mut owned = StringColumn::with_capacity(long.len());
4835        for text in long {
4836            owned.push(text);
4837        }
4838        let held = Vector::flat(LogicalType::Varchar, Data::Varlen(owned)).unwrap();
4839        let copied = held.slice(1, 2).unwrap();
4840        assert_ne!(payload(&copied), payload(&held), "an owned payload was shared");
4841        assert_eq!(copied.text_at(0), Some(long[1]));
4842    }
4843
4844    /// A flatten gives up the form and not the sharing. The views form is already views over an
4845    /// arena, so flattening one over a page is the views and nothing else, and the flat column
4846    /// that comes out reads the same strings out of the same bytes.
4847    #[test]
4848    fn flattening_string_views_over_a_page_keeps_the_page() {
4849        let mut built = StringColumn::with_capacity(2);
4850        built.push("a string too long to sit inside a view");
4851        built.push("another string that is also too long");
4852        let (views, arena) = built.into_page().into_parts();
4853        let stored = arena.as_slice().as_ptr() as usize;
4854        let vector = Vector::string_views(LogicalType::Varchar, views, Arc::new(arena)).unwrap();
4855        assert_eq!(vector.form(), Form::StringView);
4856        let flat = vector.flatten().unwrap();
4857        assert_eq!(flat.form(), Form::Flat);
4858        let Some(Data::Varlen(column)) = flat.data() else {
4859            panic!("the layout changed under the test")
4860        };
4861        assert_eq!(column.arena().as_ptr() as usize, stored, "the flatten moved the payload");
4862        assert_eq!(flat.text_at(0), Some("a string too long to sit inside a view"));
4863        assert_eq!(flat.text_at(1), Some("another string that is also too long"));
4864    }
4865
4866    /// Every form that is not flat already shares what is expensive, so this is a no op on them and
4867    /// in particular does not flatten anything. A form that came back flat would be a column that
4868    /// lost its encoding on the way into a table.
4869    #[test]
4870    fn putting_a_vector_on_pages_does_not_change_any_other_form() {
4871        let dictionary = Vector::dictionary(
4872            vec![0, 1, 0, 1],
4873            Vector::from_values(
4874                LogicalType::Varchar,
4875                &[Value::Varchar("a".into()), Value::Varchar("b".into())],
4876            )
4877            .unwrap(),
4878        )
4879        .unwrap();
4880        let cases = [
4881            Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
4882            Vector::sequence(4, 0, 1),
4883            dictionary,
4884        ];
4885        for vector in cases {
4886            let form = vector.form();
4887            let paged = vector.clone().into_pages();
4888            assert_eq!(paged.form(), form, "{form:?} changed form");
4889            assert_eq!(paged.iter().collect::<Vec<_>>(), vector.iter().collect::<Vec<_>>());
4890        }
4891    }
4892
4893    #[test]
4894    fn cutting_a_flat_string_column_answers_what_gathering_it_answers() {
4895        // The string layout is the one whose cut is still a loop, and it is also the one where a
4896        // row is a view into an arena rather than a slot, so it gets the same treatment separately.
4897        // Both inline and out of line strings, since they are copied by different paths.
4898        let rows: Vec<String> =
4899            (0..40).map(|row| "x".repeat(row % 30) + &row.to_string()).collect();
4900        let values: Vec<Value> = rows.iter().map(|row| Value::Varchar(row.clone())).collect();
4901        let vector = Vector::from_values(LogicalType::Varchar, &values).unwrap().flatten().unwrap();
4902        assert_eq!(vector.form(), Form::Flat, "the cut under test is the flat one");
4903        for at in 0..40usize {
4904            for len in 0..=(40 - at) {
4905                let cut = vector.slice(at, len).unwrap();
4906                let positions: Vec<u32> = (at..at + len).map(|row| row as u32).collect();
4907                let gathered = vector.gather(&positions).unwrap();
4908                assert_eq!(
4909                    cut.iter().collect::<Vec<_>>(),
4910                    gathered.iter().collect::<Vec<_>>(),
4911                    "rows {at} to {}",
4912                    at + len
4913                );
4914            }
4915        }
4916    }
4917
4918    #[test]
4919    fn a_slice_past_the_end_is_an_error_rather_than_a_short_vector() {
4920        let error = integers(&[1, 2, 3]).slice(2, 2).unwrap_err();
4921        assert!(error.to_string().contains("of a vector of 3"), "{error}");
4922    }
4923
4924    #[test]
4925    fn the_vector_size_is_the_one_the_design_is_built_around() {
4926        // 8192, which is four times DuckDB's 2048, measured in #480 against 1024, 2048, 4096 and
4927        // 32768. What the rest of the code assumes about it is not the value but the shape: a
4928        // multiple of 1024, which is the FastLanes unit and is what makes a validity mask a whole
4929        // number of u64 words with none of them half used.
4930        assert_eq!(VECTOR_SIZE, 8192);
4931        assert_eq!(VECTOR_SIZE % 1024, 0);
4932        assert_eq!(VECTOR_SIZE % 64, 0);
4933        assert_eq!(VECTOR_SIZE / 64, 128, "the words in a validity mask");
4934    }
4935
4936    #[test]
4937    fn a_flat_vector_reads_back_what_was_put_in_it() {
4938        let vector = integers(&[1, 2, 3]);
4939        assert_eq!(vector.form(), Form::Flat);
4940        assert_eq!(vector.len(), 3);
4941        assert_eq!(vector.value_at(1), Value::Integer(2));
4942        assert_eq!(
4943            vector.iter().collect::<Vec<_>>(),
4944            vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
4945        );
4946    }
4947
4948    #[test]
4949    fn a_vector_built_from_values_reads_the_same_values_back() {
4950        let vector = Vector::from_values(
4951            LogicalType::Varchar,
4952            &[
4953                Value::Varchar("a".to_string()),
4954                Value::Null,
4955                Value::Varchar("a string too long to sit inside a view".to_string()),
4956            ],
4957        )
4958        .expect("strings and a null");
4959        assert_eq!(vector.len(), 3);
4960        assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
4961        assert_eq!(vector.value_at(1), Value::Null);
4962        assert_eq!(
4963            vector.value_at(2),
4964            Value::Varchar("a string too long to sit inside a view".to_string())
4965        );
4966    }
4967
4968    /// A null still occupies a position. If it did not then every value after it would read back
4969    /// one place to the left, which is the kind of bug that looks like a storage bug for a week.
4970    #[test]
4971    fn a_null_in_the_middle_does_not_move_the_values_after_it() {
4972        let vector = Vector::from_values(
4973            LogicalType::Integer,
4974            &[Value::Integer(1), Value::Null, Value::Integer(3)],
4975        )
4976        .expect("integers and a null");
4977        assert_eq!(vector.value_at(2), Value::Integer(3));
4978        assert!(vector.validity().has_nulls(3), "the middle one is null");
4979    }
4980
4981    #[test]
4982    fn a_value_the_type_cannot_hold_is_refused() {
4983        let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
4984        assert!(wrong.is_err(), "a string is not an integer");
4985    }
4986
4987    #[test]
4988    fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
4989        // One comparison here against a wrong answer read out three layers later.
4990        let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1].into()));
4991        assert!(wrong.is_err());
4992        let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1].into()));
4993        assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
4994    }
4995
4996    #[test]
4997    fn a_constant_vector_costs_one_value_whatever_its_length() {
4998        let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
4999        assert_eq!(vector.form(), Form::Constant);
5000        assert_eq!(vector.len(), VECTOR_SIZE);
5001        assert_eq!(vector.value_at(0), Value::Integer(7));
5002        assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
5003        assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
5004    }
5005
5006    #[test]
5007    fn a_constant_null_is_all_invalid_without_being_told() {
5008        let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
5009        assert_eq!(vector.validity(), &Validity::AllInvalid);
5010        assert_eq!(vector.value_at(3), Value::Null);
5011    }
5012
5013    #[test]
5014    fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
5015        let vector = Vector::sequence(100, 1, VECTOR_SIZE);
5016        assert_eq!(vector.form(), Form::Sequence);
5017        assert_eq!(vector.value_at(0), Value::BigInt(100));
5018        assert_eq!(vector.value_at(923), Value::BigInt(1023));
5019        let stepped = Vector::sequence(0, 5, 4);
5020        assert_eq!(
5021            stepped.iter().collect::<Vec<_>>(),
5022            vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
5023        );
5024    }
5025
5026    #[test]
5027    fn a_dictionary_vector_reads_through_its_codes() {
5028        let mut column = StringColumn::new();
5029        column.push("red");
5030        column.push("green");
5031        let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
5032        let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
5033        assert_eq!(vector.form(), Form::Dictionary);
5034        assert_eq!(vector.logical_type(), &LogicalType::Varchar);
5035        assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
5036        assert_eq!(vector.len(), 4);
5037    }
5038
5039    /// The accessor a group by keys a string column through, which has to agree with `value_at` on
5040    /// every position or two rows holding one string end up in two groups.
5041    #[test]
5042    fn text_is_read_where_it_already_is_for_the_forms_that_store_it() {
5043        let mut column = StringColumn::new();
5044        column.push("red");
5045        column.push("green");
5046        column.push("");
5047        let flat = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
5048        for index in 0..flat.len() {
5049            assert_eq!(flat.text_at(index).map(str::to_string), text_of(&flat.value_at(index)));
5050        }
5051        let dictionary = Vector::dictionary(vec![1, 0, 1, 2], flat).unwrap();
5052        for index in 0..dictionary.len() {
5053            assert_eq!(
5054                dictionary.text_at(index).map(str::to_string),
5055                text_of(&dictionary.value_at(index))
5056            );
5057        }
5058        assert_eq!(dictionary.text_at(4), None, "past the end");
5059    }
5060
5061    /// The forms and types that have no text to hand back, which a caller answers by falling back
5062    /// to `value_at`. A blob is the one that would be a correctness bug rather than a slow path,
5063    /// since its bytes are not required to be text and it is not a `VARCHAR` either way.
5064    #[test]
5065    fn text_is_refused_where_it_is_not_stored_as_itself() {
5066        let nulls =
5067            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into()), Value::Null])
5068                .unwrap();
5069        assert_eq!(nulls.text_at(0), Some("red"));
5070        assert_eq!(nulls.text_at(1), None, "a null has no text");
5071        let constant = Vector::constant(LogicalType::Varchar, Value::Varchar("red".into()), 3);
5072        assert_eq!(constant.text_at(0), None, "a constant is not stored per position");
5073        assert_eq!(integers(&[1, 2]).text_at(0), None, "an integer is not text");
5074        let mut bytes = StringColumn::new();
5075        bytes.push("red");
5076        let blob = Vector::flat(LogicalType::Blob, Data::Varlen(bytes)).unwrap();
5077        assert_eq!(blob.text_at(0), None, "a blob is not a varchar");
5078    }
5079
5080    /// The accessor a group by keys an integer column through, which has to agree with `value_at`
5081    /// on every position or two rows holding one number end up in two groups.
5082    #[test]
5083    fn a_signed_integer_is_read_where_it_already_is_for_the_forms_that_store_it() {
5084        let flat = integers(&[7, -3, 0, 2]);
5085        for index in 0..flat.len() {
5086            assert_eq!(flat.signed_at(index), signed_of(&flat.value_at(index)), "flat {index}");
5087        }
5088        let dictionary = Vector::dictionary(vec![1, 0, 3, 2], flat).unwrap();
5089        for index in 0..dictionary.len() {
5090            assert_eq!(
5091                dictionary.signed_at(index),
5092                signed_of(&dictionary.value_at(index)),
5093                "dictionary {index}"
5094            );
5095        }
5096        assert_eq!(dictionary.signed_at(4), None, "past the end");
5097
5098        let runs = Vector::runs(vec![2, 5], integers(&[4, 9])).unwrap();
5099        for index in 0..runs.len() {
5100            assert_eq!(runs.signed_at(index), signed_of(&runs.value_at(index)), "run {index}");
5101        }
5102        let constant = Vector::constant(LogicalType::BigInt, Value::BigInt(11), 3);
5103        assert_eq!(constant.signed_at(2), Some(11));
5104        let sequence = Vector::sequence(100, 5, 4);
5105        for index in 0..sequence.len() {
5106            assert_eq!(
5107                sequence.signed_at(index),
5108                signed_of(&sequence.value_at(index)),
5109                "sequence {index}"
5110            );
5111        }
5112    }
5113
5114    /// The forms and types that have no integer to hand back, which a caller answers by falling
5115    /// back to `value_at`.
5116    #[test]
5117    fn a_signed_integer_is_refused_where_it_is_not_stored_as_itself() {
5118        let nulls =
5119            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
5120        assert_eq!(nulls.signed_at(0), Some(4));
5121        assert_eq!(nulls.signed_at(1), None, "a null is not a number");
5122        let packed = integers(&[1, 2, 3, 1]).bit_packed().unwrap();
5123        assert_eq!(packed.signed_at(0), Some(1), "a packed integer is read in code space");
5124        let mut bytes = StringColumn::new();
5125        bytes.push("red");
5126        let text = Vector::flat(LogicalType::Varchar, Data::Varlen(bytes)).unwrap();
5127        assert_eq!(text.signed_at(0), None, "a string is not a number");
5128        let double = Vector::flat(LogicalType::Double, Data::Float64(vec![1.5].into())).unwrap();
5129        assert_eq!(double.signed_at(0), None, "a double is not a signed integer");
5130    }
5131
5132    /// The block form has to agree with the row at a time form on every position of every shape it
5133    /// answers for, because a caller picks one of the two and a group by that read two different
5134    /// numbers for one row would put that row in two groups.
5135    #[test]
5136    fn a_block_of_signed_integers_holds_what_the_row_at_a_time_accessor_hands_back() {
5137        let mut out = Vec::new();
5138        let shapes = [
5139            integers(&[7, -3, 0, 2]),
5140            Vector::flat(LogicalType::Integer, Data::Int32(vec![5, -6, 7].into())).unwrap(),
5141            Vector::flat(LogicalType::SmallInt, Data::Int16(vec![1, -2].into())).unwrap(),
5142            Vector::flat(LogicalType::TinyInt, Data::Int8(vec![-128, 127].into())).unwrap(),
5143            Vector::constant(LogicalType::BigInt, Value::BigInt(11), 3),
5144            Vector::sequence(100, 5, 4),
5145            integers(&[1, 2, 3, 1]).bit_packed().unwrap(),
5146        ];
5147        for column in &shapes {
5148            assert!(column.signed_block(&mut out), "{:?} hands over a block", column.form());
5149            assert_eq!(out.len(), column.len(), "{:?} filled the whole chunk", column.form());
5150            for (index, &held) in out.iter().enumerate() {
5151                assert_eq!(
5152                    Some(i128::from(held)),
5153                    column.signed_at(index),
5154                    "{:?} at {index}",
5155                    column.form()
5156                );
5157            }
5158        }
5159    }
5160
5161    /// What the block form will not answer for, where the caller reads the vector a row at a time
5162    /// instead. A null is not one of them: it writes whatever sits under it and the caller reads the
5163    /// null from the column.
5164    #[test]
5165    fn a_block_is_refused_for_the_shapes_it_would_have_to_gather_or_widen() {
5166        let mut out = Vec::new();
5167        let flat = integers(&[7, -3, 0, 2]);
5168        assert!(!Vector::dictionary(vec![1, 0], flat.clone()).unwrap().signed_block(&mut out));
5169        assert!(!Vector::runs(vec![2, 5], integers(&[4, 9])).unwrap().signed_block(&mut out));
5170        let wide = Vector::flat(LogicalType::HugeInt, Data::Int128(vec![1, 2].into())).unwrap();
5171        assert!(!wide.signed_block(&mut out), "a hugeint does not fit sixty four bits");
5172        let double = Vector::flat(LogicalType::Double, Data::Float64(vec![1.5].into())).unwrap();
5173        assert!(!double.signed_block(&mut out), "a double is not a signed integer");
5174        assert!(out.is_empty(), "a refusal leaves the buffer empty");
5175
5176        let nulls =
5177            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
5178        assert!(nulls.signed_block(&mut out), "a flat column with nulls still hands over");
5179        assert_eq!(out[0], 4);
5180    }
5181
5182    /// Asked once for a chunk, and it has to agree with `is_null_at` asked for every row of it.
5183    #[test]
5184    fn a_vector_says_whether_it_holds_any_null_at_all() {
5185        let flat = integers(&[7, -3, 0, 2]);
5186        assert!(flat.none_null());
5187        let nulls =
5188            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
5189        assert!(!nulls.none_null());
5190        assert!(Vector::dictionary(vec![1, 0], flat.clone()).unwrap().none_null());
5191        // The null is in the dictionary rather than in the mask, which is the case the row at a time
5192        // form reads through for and the reason this one does too.
5193        let holed = Vector::dictionary(vec![0, 0], nulls.clone()).unwrap();
5194        assert!(!holed.none_null(), "a dictionary is read through to its values");
5195        assert!(!holed.is_null_at(0), "and no code points at the null it holds");
5196        assert!(Vector::runs(vec![2, 5], integers(&[4, 9])).unwrap().none_null());
5197        assert!(!Vector::runs(vec![1, 2], nulls).unwrap().none_null());
5198        assert!(Vector::constant(LogicalType::BigInt, Value::BigInt(11), 3).none_null());
5199        assert!(!Vector::constant(LogicalType::BigInt, Value::Null, 3).none_null());
5200    }
5201
5202    /// The integer of a value, for comparing `signed_at` against `value_at` position by position.
5203    fn signed_of(value: &Value) -> Option<i128> {
5204        match value {
5205            Value::TinyInt(x) => Some(i128::from(*x)),
5206            Value::SmallInt(x) => Some(i128::from(*x)),
5207            Value::Integer(x) | Value::Date(x) => Some(i128::from(*x)),
5208            Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => Some(i128::from(*x)),
5209            Value::HugeInt(x) | Value::Decimal { unscaled: x, .. } => Some(*x),
5210            _ => None,
5211        }
5212    }
5213
5214    /// The text of a value, for comparing `text_at` against `value_at` position by position.
5215    fn text_of(value: &Value) -> Option<String> {
5216        match value {
5217            Value::Varchar(text) => Some(text.clone()),
5218            _ => None,
5219        }
5220    }
5221
5222    #[test]
5223    fn a_dictionary_code_past_the_end_is_refused() {
5224        // The alternative is a silent read of the wrong value, which is the failure mode the
5225        // entire M3 design has to be careful about.
5226        let values = integers(&[1, 2]);
5227        assert!(Vector::dictionary(vec![0, 2], values).is_err());
5228        // The check runs on the highest code rather than the first bad one, so it has to say that
5229        // no codes at all is fine even when there are no values for them to point at either.
5230        let empty = Vector::dictionary(Vec::new(), integers(&[])).expect("no codes, no values");
5231        assert_eq!(empty.len(), 0);
5232        // And a code of zero against an empty dictionary is still past the end.
5233        assert!(Vector::dictionary(vec![0], integers(&[])).is_err());
5234    }
5235
5236    #[test]
5237    fn every_form_flattens_to_the_same_values_it_reads_out() {
5238        // This is the shape of the equivalence testing in spec/16-testing.md section 16.2, in
5239        // miniature and long before there is an encoded kernel to point it at. A form that reads
5240        // out one way and flattens another is the exact bug that testing exists to catch.
5241        let mut column = StringColumn::new();
5242        column.push("alpha");
5243        column.push("beta");
5244        let dictionary = Vector::dictionary(
5245            vec![1, 0, 1],
5246            Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
5247        )
5248        .unwrap();
5249        let cases = [
5250            Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
5251            Vector::sequence(7, -2, 5),
5252            dictionary,
5253        ];
5254        for vector in cases {
5255            let flat = vector.flatten().unwrap();
5256            assert_eq!(flat.form(), Form::Flat);
5257            assert_eq!(flat.len(), vector.len());
5258            for index in 0..vector.len() {
5259                assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
5260            }
5261        }
5262    }
5263
5264    #[test]
5265    fn a_null_still_occupies_a_position_after_flattening() {
5266        // The reason push_value writes a zero for a null rather than skipping it. A run of data
5267        // with a hole in it puts every value after the hole in the wrong place, and the validity
5268        // mask is what says the position is null.
5269        let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
5270        let flat = vector.flatten().unwrap();
5271        assert_eq!(flat.value_at(0), Value::BigInt(0));
5272        assert_eq!(flat.value_at(1), Value::Null);
5273        assert_eq!(flat.value_at(2), Value::BigInt(2));
5274        assert_eq!(flat.value_at(3), Value::BigInt(3));
5275    }
5276
5277    /// A dictionary holds its nulls in the vector it points at, so its own validity is all valid
5278    /// and reading that instead of the values turns a null into whatever zero means for the type.
5279    /// A filter over a nullable column produces exactly this vector, so the bug reaches a result
5280    /// set as `LEFT JOIN` padding that comes back as zeros.
5281    #[test]
5282    fn a_null_behind_a_dictionary_survives_flattening() {
5283        let values =
5284            Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
5285        let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
5286        let flat = dictionary.flatten().unwrap();
5287        assert_eq!(flat.value_at(0), Value::Null);
5288        assert_eq!(flat.value_at(1), Value::Integer(3));
5289        assert_eq!(flat.value_at(2), Value::Null);
5290    }
5291
5292    /// The property that makes `gather` usable at all: it has to be the same function as reading the
5293    /// wanted positions one at a time, over every form, or compaction changes answers.
5294    #[test]
5295    fn gathering_reads_what_reading_one_position_at_a_time_reads() {
5296        let mut column = StringColumn::new();
5297        column.push("alpha");
5298        column.push("beta");
5299        column.push("gamma");
5300        let cases = [
5301            integers(&[10, 20, 30, 40]),
5302            integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
5303            Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
5304            Vector::sequence(100, -7, 4),
5305            Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
5306            Vector::dictionary(
5307                vec![2, 0, 1, 2],
5308                Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
5309            )
5310            .unwrap(),
5311            Vector::dictionary(
5312                vec![1, 0, 1, 0],
5313                Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
5314                    .unwrap(),
5315            )
5316            .unwrap(),
5317        ];
5318        let wanted = [3_u32, 0, 2, 2, 1];
5319        for vector in cases {
5320            let gathered = vector.gather(&wanted).unwrap();
5321            assert_eq!(gathered.len(), wanted.len());
5322            assert_eq!(gathered.logical_type(), vector.logical_type());
5323            for (slot, &index) in wanted.iter().enumerate() {
5324                assert_eq!(
5325                    gathered.value_at(slot),
5326                    vector.value_at(index as usize),
5327                    "slot {slot} of {:?}",
5328                    vector.form()
5329                );
5330            }
5331        }
5332    }
5333
5334    /// A gather past the end is not an error, because the selection that produced the indices is
5335    /// checked by its caller and the one thing that must not happen here is a read of the wrong
5336    /// value. An index nothing answers is null, which is what an outer join pad needs anyway.
5337    #[test]
5338    fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
5339        let vector = integers(&[1, 2, 3]);
5340        let gathered = vector.gather(&[2, 9]).unwrap();
5341        assert_eq!(gathered.value_at(0), Value::Integer(3));
5342        assert_eq!(gathered.value_at(1), Value::Null);
5343    }
5344
5345    /// The vector with nothing in it at all, which is what an untyped `NULL` is stored as. Every
5346    /// position asked for is past its end, so the answer is nulls and the length has to be the
5347    /// length that was asked for rather than the length that was there.
5348    #[test]
5349    fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
5350        let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
5351        let gathered = vector.gather(&[0, 1, 2]).unwrap();
5352        assert_eq!(gathered.len(), 3);
5353        assert_eq!(gathered.value_at(0), Value::Null);
5354        assert_eq!(gathered.value_at(2), Value::Null);
5355    }
5356
5357    /// Every position holds the same value, so a gather with no hole in it has nothing to copy and
5358    /// the result is the constant again rather than a run of a thousand copies of it.
5359    #[test]
5360    fn gathering_a_constant_stays_a_constant() {
5361        let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
5362        let gathered = vector.gather(&[7, 7, 99]).unwrap();
5363        assert_eq!(gathered.form(), Form::Constant);
5364        assert_eq!(gathered.len(), 3);
5365        assert_eq!(gathered.value_at(2), Value::Integer(4));
5366    }
5367
5368    /// A dictionary over a dictionary is what a second filter over an already filtered chunk builds,
5369    /// and the gather has to walk to the bottom of that chain rather than one step down it. The
5370    /// constructor composes the ordinary chain away, so the one built here is the kind it cannot,
5371    /// which is a level holding nulls of its own.
5372    #[test]
5373    fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
5374        let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
5375            .unwrap()
5376            .with_validity(Validity::from_iter(3, |index| index != 2));
5377        let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
5378        let gathered = outer.gather(&[0, 1]).unwrap();
5379        assert_eq!(gathered.form(), Form::Flat);
5380        assert_eq!(gathered.value_at(0), Value::Integer(8));
5381        assert_eq!(gathered.value_at(1), Value::Null);
5382    }
5383
5384    /// Two filters over one chunk build a dictionary over a dictionary, four conjuncts pushed down
5385    /// separately build four levels of it, and every level is a dependent load on every later read
5386    /// of every row plus a code array that cannot be freed. Composing at construction is one pass
5387    /// over the codes the range check was walking anyway.
5388    #[test]
5389    fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
5390        let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
5391        let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
5392        let (codes, values) = outer.dictionary_parts().unwrap();
5393        assert_eq!(codes, [1, 0]);
5394        assert_eq!(values.form(), Form::Flat);
5395        assert_eq!(outer.value_at(0), Value::Integer(8));
5396        assert_eq!(outer.value_at(1), Value::Integer(7));
5397    }
5398
5399    /// The invariant stated as the thing it is there for, which is that the depth does not grow with
5400    /// the number of filters. Four levels stacked one at a time are one level at the end of it.
5401    #[test]
5402    fn stacking_dictionaries_does_not_make_them_deeper() {
5403        let mut vector = integers(&[10, 20, 30, 40]);
5404        for _ in 0..4 {
5405            vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
5406        }
5407        let (codes, values) = vector.dictionary_parts().unwrap();
5408        assert_eq!(values.form(), Form::Flat);
5409        assert_eq!(codes, [0, 1, 2, 3]);
5410        assert_eq!(
5411            vector.iter().collect::<Vec<_>>(),
5412            integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
5413        );
5414    }
5415
5416    /// Composing has to carry the nulls down with it. The values hold them, the codes point at them,
5417    /// and a composed code that lands on a null position is still a null.
5418    #[test]
5419    fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
5420        let values =
5421            Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
5422        let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
5423        let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
5424        assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
5425        assert_eq!(outer.value_at(0), Value::Null);
5426        assert_eq!(outer.value_at(1), Value::Integer(3));
5427    }
5428
5429    /// The one level composition cannot go past. A dictionary that was given a validity of its own is
5430    /// saying its nulls are at that level rather than in the values, and pointing the outer codes
5431    /// straight at the values would read through the holes instead of stopping at them.
5432    #[test]
5433    fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
5434        let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
5435            .unwrap()
5436            .with_validity(Validity::from_iter(3, |index| index != 1));
5437        let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
5438        assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
5439        assert_eq!(outer.value_at(0), Value::Null);
5440        assert_eq!(outer.value_at(1), Value::Integer(3));
5441        assert_eq!(outer.value_at(2), Value::Integer(1));
5442    }
5443
5444    /// The difference between the two questions about nulls, which a group by got wrong. A filtered
5445    /// chunk is dictionary vectors, those are built with every row marked present at their own
5446    /// level, and the nulls are down in the values. So the mask says the row has a value and the
5447    /// row does not.
5448    #[test]
5449    fn a_null_behind_a_dictionary_reads_as_null_even_though_the_mask_says_otherwise() {
5450        let values = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
5451            .unwrap()
5452            .with_validity(Validity::from_iter(2, |index| index != 0));
5453        let vector = Vector::dictionary(vec![0, 1, 0], values).unwrap();
5454        assert!(vector.validity().is_valid(0), "the mask at this level says present");
5455        assert!(vector.is_null_at(0));
5456        assert!(!vector.is_null_at(1));
5457        assert!(vector.is_null_at(2));
5458        assert!(vector.is_null_at(3), "a row past the end is null");
5459    }
5460
5461    /// The same for runs, which are built the same way and keep their nulls in the same place.
5462    #[test]
5463    fn a_null_inside_a_run_reads_as_null_even_though_the_mask_says_otherwise() {
5464        let values = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
5465            .unwrap()
5466            .with_validity(Validity::from_iter(2, |index| index != 0));
5467        let vector = Vector::runs(vec![2, 3], values).unwrap();
5468        assert!(vector.validity().is_valid(0));
5469        assert!(vector.is_null_at(0));
5470        assert!(vector.is_null_at(1));
5471        assert!(!vector.is_null_at(2));
5472    }
5473
5474    /// Every other form keeps its nulls in its own mask, so the two answers agree there.
5475    #[test]
5476    fn the_forms_that_hold_their_own_nulls_answer_the_same_either_way() {
5477        let flat = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
5478            .unwrap()
5479            .with_validity(Validity::from_iter(2, |index| index != 0));
5480        let constant = Vector::constant(LogicalType::Integer, Value::Null, 2);
5481        let sequence = Vector::sequence(10, 2, 2);
5482        for vector in [flat, constant, sequence] {
5483            for row in 0..vector.len() {
5484                assert_eq!(vector.is_null_at(row), !vector.validity().is_valid(row));
5485            }
5486        }
5487    }
5488
5489    #[test]
5490    fn flattening_a_flat_vector_is_the_same_vector() {
5491        let vector = integers(&[1, 2, 3]);
5492        assert_eq!(vector.flatten().unwrap(), vector);
5493    }
5494
5495    /// The same answer as `flatten` and, for the vector that is already flat and owns its values,
5496    /// the same allocation. Asserted on the address because that is the whole claim: the values
5497    /// come back where they were rather than in a copy of themselves. A flatten through a borrow
5498    /// cannot do that, and at the top of a query it copied every column of every chunk of the
5499    /// result to hand back the bytes it was given.
5500    #[test]
5501    fn flattening_a_vector_that_owns_its_values_moves_them_rather_than_copying_them() {
5502        let vector = integers(&[1, 2, 3, 4]);
5503        let address = |vector: &Vector| match vector.data() {
5504            Some(Data::Int32(values)) => values.as_slice().as_ptr() as usize,
5505            _ => panic!("the layout changed under the test"),
5506        };
5507        let stored = address(&vector);
5508        let flat = vector.into_flat().unwrap();
5509        assert_eq!(address(&flat), stored, "the values moved");
5510        assert_eq!(
5511            flat.iter().collect::<Vec<_>>(),
5512            (1..=4).map(Value::Integer).collect::<Vec<_>>()
5513        );
5514        // And a form that is not flat is flattened, which is the case the copy is deserved in.
5515        let dictionary = Vector::dictionary(vec![1, 0, 1], integers(&[7, 8])).unwrap();
5516        let flat = dictionary.clone().into_flat().unwrap();
5517        assert_eq!(flat.form(), Form::Flat);
5518        assert_eq!(flat.iter().collect::<Vec<_>>(), dictionary.iter().collect::<Vec<_>>());
5519    }
5520
5521    #[test]
5522    fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
5523        let ty = LogicalType::decimal(9, 2).unwrap();
5524        let vector = Vector::flat(ty, Data::Int32(vec![1234].into())).unwrap();
5525        assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
5526        assert_eq!(vector.value_at(0).to_string(), "12.34");
5527    }
5528
5529    #[test]
5530    fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
5531        // The read path worked at every width and the write path only accepted the 128 bit run, so
5532        // `SELECT 2.5` produced a value nothing could store. All four widths round trip now.
5533        for (width, scale, unscaled) in
5534            [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
5535        {
5536            let ty = LogicalType::decimal(width, scale).unwrap();
5537            let value = Value::Decimal { unscaled, width, scale };
5538            let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
5539            assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
5540            assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
5541        }
5542    }
5543
5544    /// The bytes a blob holds are not required to be text, and a vector of them used to refuse the
5545    /// ones that were not. A byte array column in a Parquet file that nothing annotated is a blob,
5546    /// which is what ClickHouse writes and what ten of the ClickBench queries compare against, so
5547    /// this is the path those take rather than a corner of the type system.
5548    #[test]
5549    fn a_blob_holds_bytes_that_are_not_text() {
5550        let bytes = |raw: &[u8]| Value::Blob(raw.to_vec());
5551        let values = [
5552            bytes(b"a\xffb"),
5553            bytes(b"\x00\x01\x02"),
5554            Value::Null,
5555            bytes(b"\xed\xa0\x80 and long enough to leave the view"),
5556            bytes(b""),
5557        ];
5558        let vector = Vector::from_values(LogicalType::Blob, &values).unwrap();
5559        for (index, value) in values.iter().enumerate() {
5560            assert_eq!(&vector.value_at(index), value, "row {index}");
5561        }
5562    }
5563
5564    #[test]
5565    fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
5566        // Only reachable by hand, since a value's width is what picked the run. Truncating here
5567        // would store a different number and say nothing about it.
5568        let ty = LogicalType::decimal(4, 1).unwrap();
5569        let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
5570        let error = Vector::from_values(ty, &[value]).unwrap_err();
5571        assert!(error.to_string().contains("does not fit"), "{error}");
5572    }
5573
5574    #[test]
5575    fn a_flat_vector_costs_its_values_and_a_constant_costs_one() {
5576        let flat = integers(&[1; 1000]);
5577        assert!(
5578            flat.footprint() >= 4000,
5579            "a thousand i32 are four thousand bytes: {}",
5580            flat.footprint()
5581        );
5582        // The forms that compute their values rather than storing them cost nothing per value,
5583        // which is the point of having them and is what the memory limit should see.
5584        let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1_000_000);
5585        assert!(constant.footprint() < 200, "a constant is one value: {}", constant.footprint());
5586        let sequence = Vector::sequence(0, 1, 1_000_000);
5587        assert!(sequence.footprint() < 200, "a sequence is two numbers: {}", sequence.footprint());
5588    }
5589
5590    #[test]
5591    fn a_gather_off_a_dictionary_answers_the_same_nulls_either_way_round() {
5592        let words = [Value::Varchar("north".into()), Value::Null, Value::Varchar("south".into())];
5593        let plain: Vec<Value> =
5594            ["north", "east", "south"].iter().map(|word| Value::Varchar((*word).into())).collect();
5595        let clean = Arc::new(Vector::from_values(LogicalType::Varchar, &plain).unwrap());
5596        let dirty = Arc::new(Vector::from_values(LogicalType::Varchar, &words).unwrap());
5597        let codes = vec![0, 1, 2, 0, 1, 2];
5598        let sources = [
5599            Vector::stable_dictionary(codes.clone(), Arc::clone(&clean)).unwrap(),
5600            Vector::stable_dictionary(codes.clone(), Arc::clone(&dirty)).unwrap(),
5601            Vector::stable_dictionary(codes, Arc::clone(&clean))
5602                .unwrap()
5603                .with_validity(Validity::from_run(&[true, true, false, true, true, true])),
5604        ];
5605        // What a gather says about a row has to be what the column it came out of says about the
5606        // row it was taken from, whichever of the two ways the nulls are reached: the mask over the
5607        // codes, or the value a code stands for. The fast answer is only allowed when neither has
5608        // any, and an index past the end is null in both readings.
5609        for source in &sources {
5610            let picks: Vec<u32> = vec![5, 0, 3, 2, 1, 99, 4];
5611            let taken = source.gather(&picks).unwrap();
5612            for (row, &pick) in picks.iter().enumerate() {
5613                assert_eq!(
5614                    taken.is_null_at(row),
5615                    source.is_null_at(pick as usize),
5616                    "row {row} of a gather of {picks:?}"
5617                );
5618            }
5619        }
5620    }
5621
5622    #[test]
5623    fn a_dictionary_read_by_many_cuts_is_counted_about_once_between_them() {
5624        let strings: Vec<Value> = (0..2000)
5625            .map(|at| Value::Varchar(format!("a value well past the inline limit, number {at}")))
5626            .collect();
5627        let values = Arc::new(Vector::from_values(LogicalType::Varchar, &strings).unwrap());
5628        let dictionary = values.footprint();
5629        let cuts: Vec<Vector> = (0..500)
5630            .map(|_| Vector::stable_dictionary(vec![0; 8], Arc::clone(&values)).unwrap())
5631            .collect();
5632        let together: usize = cuts.iter().map(Vector::footprint).sum();
5633        // Five hundred chunks cut out of one page hold one dictionary, and what they say they hold
5634        // has to be about one dictionary. Before this it was five hundred of them, which is a
5635        // reading that grows with the answer and refuses a query holding a gigabyte a budget of
5636        // twenty five.
5637        assert!(
5638            together < dictionary * 2,
5639            "five hundred cuts are not five hundred dictionaries: {together} against {dictionary}"
5640        );
5641        assert!(
5642            together > dictionary / 2,
5643            "the dictionary is still counted: {together} against {dictionary}"
5644        );
5645    }
5646
5647    #[test]
5648    fn a_string_vector_costs_the_bytes_of_its_long_strings() {
5649        let short =
5650            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into())]).unwrap();
5651        let long = "a string well past the sixteen bytes a view holds inline".to_string();
5652        let spilled =
5653            Vector::from_values(LogicalType::Varchar, &[Value::Varchar(long.clone())]).unwrap();
5654        assert!(
5655            spilled.footprint() >= short.footprint() + long.len(),
5656            "the arena is counted: {} against {}",
5657            spilled.footprint(),
5658            short.footprint()
5659        );
5660    }
5661
5662    /// The cases worth checking are the widths where a code straddles a word boundary, which is
5663    /// every width that does not divide sixty four, and the two ends of the range.
5664    #[test]
5665    fn a_narrow_column_packs_and_reads_back_the_same_at_every_width() {
5666        for width in 1..=20u32 {
5667            let span = (1i64 << width) - 1;
5668            let values: Vec<i64> =
5669                (0..1000).map(|row| 1_000_000 + (row * 7919) % (span + 1)).collect();
5670            let flat =
5671                Vector::flat(LogicalType::BigInt, Data::Int64(values.clone().into())).unwrap();
5672            let packed = flat.bit_packed().unwrap();
5673            assert_eq!(packed.len(), flat.len());
5674            assert_eq!(
5675                packed.iter().collect::<Vec<_>>(),
5676                flat.iter().collect::<Vec<_>>(),
5677                "width {width} read back differently"
5678            );
5679        }
5680    }
5681
5682    #[test]
5683    fn the_width_is_the_bits_the_range_needs_and_not_the_bits_the_type_has() {
5684        let values: Vec<i32> = (0..1024).map(|row| 40 + (row * 2560) / 1023).collect();
5685        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
5686        let packed = flat.bit_packed().unwrap();
5687        assert_eq!(packed.form(), Form::BitPacked);
5688        let parts = packed.packed_parts().expect("packed");
5689        assert_eq!(parts.width(), 12, "0 to 2560 is twelve bits");
5690        assert_eq!(parts.base(), 40);
5691        assert!(
5692            packed.footprint() * 2 < flat.footprint(),
5693            "twelve bits against thirty two: {} against {}",
5694            packed.footprint(),
5695            flat.footprint()
5696        );
5697    }
5698
5699    /// The check is worth having in both directions, the way the run length one is. A form that is
5700    /// only ever bigger than what it replaced costs a pass over the column to decide not to use.
5701    #[test]
5702    fn a_column_that_uses_its_whole_type_is_left_flat() {
5703        let values: Vec<i32> = (0..1024).map(|row| row * 2_000_000 - 1_000_000_000).collect();
5704        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
5705        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
5706    }
5707
5708    /// A column of one value would pack to no bits at all, and one run is smaller than any packing
5709    /// of it, so the two forms do not fight over that column.
5710    #[test]
5711    fn a_column_of_one_value_is_left_to_the_run_length_form() {
5712        let flat = integers(&[9; 1024]);
5713        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
5714        assert_eq!(flat.run_encoded().unwrap().form(), Form::Rle);
5715    }
5716
5717    #[test]
5718    fn a_string_column_has_no_range_to_pack() {
5719        let text = Vector::from_values(
5720            LogicalType::Varchar,
5721            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
5722        )
5723        .unwrap();
5724        assert_eq!(text.bit_packed().unwrap().form(), Form::Flat);
5725    }
5726
5727    /// The cut is the reason the form carries a row to start reading at. It stays packed, it shares
5728    /// the same words, and it reads the rows the range asked for.
5729    #[test]
5730    fn a_cut_of_a_packed_column_stays_packed_and_shares_its_bits() {
5731        let values: Vec<i32> = (0..1024).map(|row| 100 + row % 300).collect();
5732        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
5733        let packed = flat.bit_packed().unwrap();
5734        let cut = packed.slice(500, 24).unwrap();
5735        assert_eq!(cut.form(), Form::BitPacked);
5736        assert_eq!(cut.len(), 24);
5737        assert_eq!(
5738            cut.iter().collect::<Vec<_>>(),
5739            flat.slice(500, 24).unwrap().iter().collect::<Vec<_>>()
5740        );
5741        assert!(
5742            cut.footprint() >= packed.footprint(),
5743            "a cut shares the words rather than copying a piece of them"
5744        );
5745    }
5746
5747    #[test]
5748    fn a_gather_of_a_packed_column_comes_out_flat_and_keeps_the_nulls() {
5749        let values: Vec<i32> = (0..64).map(|row| 10 + row).collect();
5750        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
5751        let packed =
5752            flat.bit_packed().unwrap().with_validity(Validity::from_iter(64, |row| row % 3 != 0));
5753        let taken = packed.gather(&[0, 1, 2, 3, 62]).unwrap();
5754        assert_eq!(taken.form(), Form::Flat);
5755        assert_eq!(
5756            taken.iter().collect::<Vec<_>>(),
5757            vec![
5758                Value::Null,
5759                Value::Integer(11),
5760                Value::Integer(12),
5761                Value::Null,
5762                Value::Integer(72)
5763            ]
5764        );
5765    }
5766
5767    /// The pair a comparison kernel asks for before it reads a bit. A literal inside the range has a
5768    /// code and a literal outside it does not, which answers the whole vector at once.
5769    #[test]
5770    fn a_literal_outside_the_packed_range_has_no_code() {
5771        let values: Vec<i32> = (0..256).map(|row| 1000 + row).collect();
5772        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
5773        let packed = flat.bit_packed().unwrap();
5774        let parts = packed.packed_parts().expect("packed");
5775        assert_eq!(parts.code_of(1000), Some(0));
5776        assert_eq!(parts.code_of(1100), Some(100));
5777        assert_eq!(parts.code_of(999), None);
5778        assert!(parts.ceiling() >= 1255);
5779        assert_eq!(parts.code_of(parts.ceiling() + 1), None);
5780    }
5781
5782    /// The bits arriving from a file rather than from a flat vector, which is what the form is for.
5783    #[test]
5784    fn packed_bits_can_be_handed_in_without_a_flat_vector_to_start_from() {
5785        let packed = Vector::packed(LogicalType::SmallInt, vec![0x0000_0000_0000_4321], 4, 7, 4)
5786            .expect("four codes of four bits");
5787        assert_eq!(
5788            packed.iter().collect::<Vec<_>>(),
5789            vec![Value::SmallInt(8), Value::SmallInt(9), Value::SmallInt(10), Value::SmallInt(11)]
5790        );
5791    }
5792
5793    #[test]
5794    fn packed_bits_that_could_not_hold_what_they_claim_are_refused() {
5795        assert!(Vector::packed(LogicalType::Varchar, vec![0], 4, 0, 4).is_err(), "not an integer");
5796        assert!(Vector::packed(LogicalType::Integer, vec![0], 0, 0, 4).is_err(), "no width");
5797        assert!(Vector::packed(LogicalType::Integer, vec![0], 64, 0, 4).is_err(), "too wide");
5798        assert!(Vector::packed(LogicalType::Integer, vec![0], 8, 0, 9).is_err(), "too few words");
5799        assert!(Vector::packed(LogicalType::TinyInt, vec![0], 8, 100, 8).is_err(), "would not fit");
5800    }
5801
5802    /// A column of strings long enough that the payload is in the arena rather than in the views.
5803    fn long_strings(count: usize) -> Vector {
5804        let values: Vec<Value> = (0..count)
5805            .map(|row| {
5806                Value::Varchar(format!("a string too long to sit inside a view, number {row}"))
5807            })
5808            .collect();
5809        Vector::from_values(LogicalType::Varchar, &values).unwrap()
5810    }
5811
5812    #[test]
5813    fn a_string_column_in_view_form_reads_back_the_same_strings() {
5814        let flat = long_strings(40);
5815        let shared = flat.clone().shared_text().unwrap();
5816        assert_eq!(shared.form(), Form::StringView);
5817        assert_eq!(shared.len(), 40);
5818        for row in 0..40 {
5819            assert_eq!(shared.value_at(row), flat.value_at(row), "row {row}");
5820            assert_eq!(shared.text_at(row), flat.text_at(row), "row {row}");
5821        }
5822    }
5823
5824    #[test]
5825    fn a_short_string_is_read_out_of_its_view_and_never_out_of_the_arena() {
5826        let flat = Vector::from_values(
5827            LogicalType::Varchar,
5828            &[Value::Varchar("red".into()), Value::Varchar("green".into()), Value::Null],
5829        )
5830        .unwrap();
5831        let shared = flat.shared_text().unwrap();
5832        // Nothing went to the arena, so the whole column resolves with an empty one.
5833        let (views, arena) = shared.text_parts().unwrap();
5834        assert!(arena.is_empty(), "three short strings need no arena");
5835        assert_eq!(views[0].bytes_in(arena), Some(&b"red"[..]));
5836        assert_eq!(shared.value_at(1), Value::Varchar("green".into()));
5837        assert_eq!(shared.value_at(2), Value::Null, "the validity came across");
5838    }
5839
5840    #[test]
5841    fn a_cut_of_a_view_column_shares_the_arena_rather_than_copying_the_bytes() {
5842        let shared = long_strings(64).shared_text().unwrap();
5843        let cut = shared.slice(16, 8).unwrap();
5844        assert_eq!(cut.form(), Form::StringView, "a cut of views is views");
5845        assert_eq!(cut.len(), 8);
5846        assert_eq!(cut.value_at(0), shared.value_at(16));
5847        assert_eq!(cut.value_at(7), shared.value_at(23));
5848        // The arena is the same bytes at the same address, which is the whole point of the form.
5849        let (_, whole) = shared.text_parts().unwrap();
5850        let (_, piece) = cut.text_parts().unwrap();
5851        assert_eq!(piece.as_ptr(), whole.as_ptr(), "the cut shares the page");
5852        assert_eq!(piece.len(), whole.len());
5853    }
5854
5855    #[test]
5856    fn a_flat_string_column_has_to_copy_the_bytes_its_cut_keeps() {
5857        let flat = long_strings(64);
5858        let cut = flat.slice(16, 8).unwrap();
5859        assert_eq!(cut.form(), Form::Flat);
5860        let (_, whole) = flat.text_parts().unwrap();
5861        let (_, piece) = cut.text_parts().unwrap();
5862        assert!(piece.len() < whole.len(), "the flat cut carries only what it kept");
5863    }
5864
5865    #[test]
5866    fn a_gather_of_a_view_column_keeps_the_form_and_a_flatten_copies_out_of_it() {
5867        let shared = long_strings(32).shared_text().unwrap();
5868        let picked: Vec<u32> = (0..32).step_by(3).collect();
5869        let gathered = shared.gather(&picked).unwrap();
5870        assert_eq!(gathered.form(), Form::StringView, "selecting rows moves views, not bytes");
5871        assert_eq!(gathered.len(), picked.len());
5872        for (row, &from) in picked.iter().enumerate() {
5873            assert_eq!(gathered.value_at(row), shared.value_at(from as usize), "row {row}");
5874        }
5875        let flattened = gathered.flatten().unwrap();
5876        assert_eq!(flattened.form(), Form::Flat);
5877        assert_eq!(flattened.iter().collect::<Vec<_>>(), gathered.iter().collect::<Vec<_>>());
5878        // The flatten is what narrows the bytes, so the arena it built holds only the rows it kept.
5879        let (_, narrowed) = flattened.text_parts().unwrap();
5880        let (_, whole) = shared.text_parts().unwrap();
5881        assert!(narrowed.len() < whole.len(), "flattening lets the page go");
5882    }
5883
5884    #[test]
5885    fn a_null_in_a_view_column_survives_being_gathered_and_flattened() {
5886        let shared = long_strings(8)
5887            .with_validity(Validity::from_iter(8, |row| row % 3 != 0))
5888            .shared_text()
5889            .unwrap();
5890        let gathered = shared.gather(&[0, 1, 2, 3, 4]).unwrap();
5891        let expected =
5892            [Value::Null, shared.value_at(1), shared.value_at(2), Value::Null, shared.value_at(4)];
5893        assert_eq!(gathered.iter().collect::<Vec<_>>(), expected);
5894        assert_eq!(gathered.flatten().unwrap().iter().collect::<Vec<_>>(), expected);
5895    }
5896
5897    #[test]
5898    fn both_string_forms_hand_a_kernel_the_same_views_and_the_same_bytes() {
5899        let flat = long_strings(6);
5900        let shared = flat.clone().shared_text().unwrap();
5901        let (flat_views, flat_arena) = flat.text_parts().unwrap();
5902        let (shared_views, shared_arena) = shared.text_parts().unwrap();
5903        assert_eq!(flat_views.len(), shared_views.len());
5904        for row in 0..6 {
5905            assert_eq!(
5906                flat_views[row].bytes_in(flat_arena),
5907                shared_views[row].bytes_in(shared_arena),
5908                "row {row}"
5909            );
5910        }
5911        // Nothing else answers this, which is what keeps a kernel from taking it for a string column.
5912        assert!(Vector::sequence(0, 1, 4).text_parts().is_none());
5913        assert!(integers(&[1, 2, 3]).text_parts().is_none());
5914    }
5915
5916    #[test]
5917    fn a_column_that_is_not_strings_cannot_be_held_as_views() {
5918        let views = vec![StringView::inline("red")];
5919        let arena = Arc::new(Buffer::new());
5920        let wrong = Vector::string_views(LogicalType::Integer, views, arena);
5921        assert!(wrong.is_err(), "an integer column has no views");
5922        assert_eq!(integers(&[1, 2]).shared_text().unwrap().form(), Form::Flat, "left alone");
5923    }
5924
5925    /// A column with enough repeated structure for a symbol table to find something, which is what
5926    /// a real text column has and a column of random bytes does not.
5927    fn sentences(count: usize) -> Vector {
5928        let values: Vec<Value> = (0..count)
5929            .map(|row| {
5930                Value::Varchar(format!(
5931                    "http://example.test/catalogue/section/{}/item/{row}",
5932                    row % 7
5933                ))
5934            })
5935            .collect();
5936        Vector::from_values(LogicalType::Varchar, &values).unwrap()
5937    }
5938
5939    #[test]
5940    fn a_compressed_column_reads_back_the_strings_that_went_into_it() {
5941        let flat = sentences(64);
5942        let coded = flat.clone().compressed().unwrap();
5943        assert_eq!(coded.form(), Form::Fsst, "a text column compresses");
5944        assert_eq!(coded.len(), 64);
5945        for row in 0..64 {
5946            assert_eq!(coded.value_at(row), flat.value_at(row), "row {row}");
5947        }
5948        assert_eq!(coded.flatten().unwrap(), flat, "flattening is the column it came from");
5949    }
5950
5951    #[test]
5952    fn compressing_halves_the_bytes_or_the_column_is_left_flat() {
5953        let flat = sentences(200);
5954        let coded = flat.clone().compressed().unwrap();
5955        let parts = coded.coded_parts().expect("compressed");
5956        // Read through the flat column, because the compressed one has no bytes to hand back where
5957        // they are and answers `None` to `text_at` rather than decompressing into a borrow.
5958        assert_eq!(coded.text_at(0), None, "nothing to borrow until it is flattened");
5959        let plain: usize = (0..200).map(|row| flat.text_at(row).map_or(0, str::len)).sum();
5960        let codes: usize = (0..200).map(|row| parts.row(row).map_or(0, <[u8]>::len)).sum();
5961        assert!(codes * FSST_PAYS_AT <= plain, "{codes} codes against {plain} bytes");
5962        // Text with no repeated structure in it gives a table nothing longer than a byte to find,
5963        // so the codes are the bytes and the column stays where it is rather than paying a
5964        // decompression per read to save nothing.
5965        let mut seed = 0x2545_f491_4f6c_dd1du64;
5966        let values: Vec<Value> = (0..256)
5967            .map(|_| {
5968                let mut text = String::new();
5969                while text.len() < 12 {
5970                    seed = seed.wrapping_mul(6_364_136_223_846_793_005).wrapping_add(1);
5971                    text.push(char::from(b'!' + ((seed >> 33) % 90) as u8));
5972                }
5973                Value::Varchar(text)
5974            })
5975            .collect();
5976        let noise = Vector::from_values(LogicalType::Varchar, &values).unwrap();
5977        assert_eq!(noise.compressed().unwrap().form(), Form::Flat);
5978    }
5979
5980    #[test]
5981    fn a_cut_of_a_compressed_column_shares_the_codes_and_the_table() {
5982        let coded = sentences(64).compressed().unwrap();
5983        let cut = coded.slice(8, 16).unwrap();
5984        assert_eq!(cut.form(), Form::Fsst);
5985        assert_eq!(cut.len(), 16);
5986        for row in 0..16 {
5987            assert_eq!(cut.value_at(row), coded.value_at(8 + row), "row {row}");
5988        }
5989        let (whole, piece) = (coded.coded_parts().unwrap(), cut.coded_parts().unwrap());
5990        assert_eq!(piece.row(0), whole.row(8), "the spans point into the same codes");
5991    }
5992
5993    #[test]
5994    fn a_gather_of_a_compressed_column_stays_compressed_and_keeps_the_nulls() {
5995        let coded = sentences(32)
5996            .with_validity(Validity::from_iter(32, |row| row % 5 != 2))
5997            .compressed()
5998            .unwrap();
5999        let picked: Vec<u32> = (0..32).step_by(2).collect();
6000        let gathered = coded.gather(&picked).unwrap();
6001        assert_eq!(gathered.form(), Form::Fsst, "selecting rows moves spans, not bytes");
6002        for (row, &from) in picked.iter().enumerate() {
6003            assert_eq!(gathered.value_at(row), coded.value_at(from as usize), "row {row}");
6004        }
6005        assert_eq!(
6006            gathered.flatten().unwrap().iter().collect::<Vec<_>>(),
6007            gathered.iter().collect::<Vec<_>>()
6008        );
6009    }
6010
6011    #[test]
6012    fn a_literal_lands_in_the_same_codes_the_row_holding_it_does() {
6013        let coded = sentences(40).compressed().unwrap();
6014        let parts = coded.coded_parts().expect("compressed");
6015        let text = coded.value_at(11);
6016        let Value::Varchar(text) = text else { panic!("a string column reads back strings") };
6017        assert_eq!(parts.encode(text.as_bytes()), parts.row(11).expect("row 11"));
6018        assert_ne!(parts.encode(b"something else entirely"), parts.row(11).unwrap());
6019    }
6020
6021    #[test]
6022    fn codes_that_run_past_what_is_there_are_refused() {
6023        let table = Arc::new(SymbolTable::empty());
6024        let codes = Arc::new(vec![1u8, 2, 3, 4]);
6025        let good = vec![(0u32, 2u32), (2, 4)];
6026        assert!(
6027            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), good, Arc::clone(&table))
6028                .is_ok()
6029        );
6030        let past = vec![(0u32, 9u32)];
6031        assert!(
6032            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), past, Arc::clone(&table))
6033                .is_err(),
6034            "a span past the end of the codes"
6035        );
6036        let backwards = vec![(3u32, 1u32)];
6037        assert!(
6038            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), backwards, Arc::clone(&table))
6039                .is_err(),
6040            "a span that ends before it starts"
6041        );
6042        let wrong = vec![(0u32, 2u32)];
6043        assert!(
6044            Vector::coded(LogicalType::Integer, codes, wrong, table).is_err(),
6045            "an integer column has no codes"
6046        );
6047    }
6048
6049    #[test]
6050    fn a_view_pointing_past_its_arena_is_refused_at_construction() {
6051        let long = "a string too long to sit inside a view";
6052        let arena: Arc<Buffer<u8>> = Arc::new(long.as_bytes().to_vec().into());
6053        let good = vec![StringView::over(long.as_bytes(), 0)];
6054        assert!(Vector::string_views(LogicalType::Varchar, good, Arc::clone(&arena)).is_ok());
6055        let bad = vec![StringView::over(long.as_bytes(), 4)];
6056        assert!(
6057            Vector::string_views(LogicalType::Varchar, bad, arena).is_err(),
6058            "four bytes short of what the view claims"
6059        );
6060    }
6061
6062    /// The form at its simplest: an id per row, and the row it names.
6063    #[test]
6064    fn a_gathered_vector_reads_the_source_row_its_id_names() {
6065        let source = Arc::new(integers(&[10, 20, 30, 40]));
6066        let vector = Vector::gathered(source, Arc::new(vec![3, 0, 3, 1])).unwrap();
6067        assert_eq!(vector.form(), Form::Gathered);
6068        assert_eq!(vector.len(), 4);
6069        assert_eq!(
6070            vector.iter().collect::<Vec<_>>(),
6071            vec![Value::Integer(40), Value::Integer(10), Value::Integer(40), Value::Integer(20)]
6072        );
6073    }
6074
6075    /// Section 8.2's lazy validity. The sentinel is a null and it is not in a mask anywhere, which is
6076    /// what lets a left link join gather null for an unmatched child row without allocating one.
6077    #[test]
6078    fn a_gathered_row_with_no_source_row_is_null_without_a_mask() {
6079        let source = Arc::new(integers(&[10, 20]));
6080        let vector = Vector::gathered(source, Arc::new(vec![1, NO_ROW, 0])).unwrap();
6081        assert!(!vector.validity().has_nulls(vector.len()), "the mask at this level says nothing");
6082        assert!(vector.is_null_at(1));
6083        assert!(!vector.is_null_at(0) && !vector.is_null_at(2));
6084        assert_eq!(
6085            vector.iter().collect::<Vec<_>>(),
6086            vec![Value::Integer(20), Value::Null, Value::Integer(10)]
6087        );
6088        assert!(!vector.none_null(), "a sentinel is a null and the bulk answer has to agree");
6089    }
6090
6091    /// The other half of the same rule: a null in the source is a null here, the way a dictionary's
6092    /// nulls live in its values. Two ways for a row to be null and one answer from `is_null_at`.
6093    #[test]
6094    fn a_gather_of_a_null_source_row_is_null() {
6095        let source = Arc::new(
6096            Vector::from_values(LogicalType::Integer, &[Value::Integer(7), Value::Null]).unwrap(),
6097        );
6098        let vector = Vector::gathered(source, Arc::new(vec![1, 0, 1])).unwrap();
6099        assert!(vector.is_null_at(0) && vector.is_null_at(2));
6100        assert_eq!(vector.value_at(1), Value::Integer(7));
6101        assert!(!vector.none_null());
6102    }
6103
6104    /// An id past the end of the source is the one failure in this form that reads whatever happens
6105    /// to be at that offset rather than failing, so it is refused where the vector is built.
6106    #[test]
6107    fn a_gathered_id_past_the_end_of_its_source_is_refused() {
6108        let source = Arc::new(integers(&[1, 2, 3]));
6109        assert!(Vector::gathered(Arc::clone(&source), Arc::new(vec![0, 3])).is_err());
6110        assert!(
6111            Vector::gathered(source, Arc::new(vec![0, NO_ROW])).is_ok(),
6112            "the sentinel is not an id past the end, it is the absence of one"
6113        );
6114    }
6115
6116    /// A cut is the offset and nothing else, which is what keeps a pipeline from copying the ids once
6117    /// per operator. Both ends stay shared and the rows answer the same.
6118    #[test]
6119    fn cutting_a_gather_moves_where_it_starts_and_copies_nothing() {
6120        let source = Arc::new(integers(&[10, 20, 30, 40, 50]));
6121        let rids = Arc::new(vec![4, 3, 2, 1, 0]);
6122        let vector = Vector::gathered(Arc::clone(&source), Arc::clone(&rids)).unwrap();
6123        let held = Arc::strong_count(&rids);
6124        let cut = vector.slice(1, 3).unwrap();
6125        assert_eq!(cut.form(), Form::Gathered);
6126        assert_eq!(
6127            Arc::strong_count(&rids),
6128            held + 1,
6129            "the cut shares the ids rather than copying"
6130        );
6131        assert_eq!(
6132            cut.iter().collect::<Vec<_>>(),
6133            vec![Value::Integer(40), Value::Integer(30), Value::Integer(20)]
6134        );
6135        assert_eq!(cut.gathered_parts().unwrap().1, [3, 2, 1]);
6136    }
6137
6138    /// Composition, which is why this is a body and not an operator. A filter over the output of a
6139    /// link join selects into the ids, and what comes out is one level rather than two.
6140    #[test]
6141    fn a_gather_of_a_gather_resolves_to_one_walk_over_the_source() {
6142        let source = Arc::new(integers(&[10, 20, 30, 40]));
6143        let inner = Vector::gathered(source, Arc::new(vec![3, 2, 1, 0])).unwrap();
6144        let outer = inner.gather(&[0, 3]).unwrap();
6145        assert_eq!(outer.iter().collect::<Vec<_>>(), vec![Value::Integer(40), Value::Integer(10)]);
6146        assert_ne!(outer.form(), Form::Gathered, "the walk stops at what the ids point into");
6147    }
6148
6149    /// The sentinel survives being gathered through, which it has to: a filter over a left link
6150    /// join's output keeps the unmatched rows it kept and they are still null.
6151    #[test]
6152    fn gathering_through_a_sentinel_keeps_it_null() {
6153        let source = Arc::new(integers(&[10, 20]));
6154        let inner = Vector::gathered(source, Arc::new(vec![0, NO_ROW, 1])).unwrap();
6155        let outer = inner.gather(&[1, 2, 1]).unwrap();
6156        assert_eq!(
6157            outer.iter().collect::<Vec<_>>(),
6158            vec![Value::Null, Value::Integer(20), Value::Null]
6159        );
6160    }
6161
6162    /// Section 8.2's dispatch rule, which is the whole difference between this form and a dictionary
6163    /// and is one comparison. A gather off a parent larger than the chunk does not want the
6164    /// dictionary arm of any kernel, and a gather off a source smaller than the chunk does.
6165    #[test]
6166    fn folding_over_the_source_is_worth_it_only_when_the_source_is_the_shorter_one() {
6167        let wide = Arc::new(integers(&(0..64).collect::<Vec<i32>>()));
6168        let narrow = Arc::new(integers(&[1, 2]));
6169        let off_wide = Vector::gathered(wide, Arc::new(vec![0, 1, 2])).unwrap();
6170        let off_narrow = Vector::gathered(narrow, Arc::new(vec![0, 1, 0, 1, 0])).unwrap();
6171        assert!(!off_wide.fold_over_source(), "sixty four source rows to answer three");
6172        assert!(off_narrow.fold_over_source(), "two source rows to answer five");
6173        assert!(!integers(&[1, 2]).fold_over_source(), "and every other form says no");
6174    }
6175
6176    /// Strings, which read their bytes where the source already has them rather than through a value.
6177    /// A gather of a string column is four bytes a row and no arena is touched until something asks.
6178    #[test]
6179    fn a_gathered_string_is_read_where_the_source_put_it() {
6180        let mut column = StringColumn::new();
6181        column.push("red");
6182        column.push("a string too long to sit inside a sixteen byte view");
6183        let source = Arc::new(Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap());
6184        let vector = Vector::gathered(source, Arc::new(vec![1, 0, NO_ROW])).unwrap();
6185        assert_eq!(vector.text_at(0), Some("a string too long to sit inside a sixteen byte view"));
6186        assert_eq!(vector.text_at(1), Some("red"));
6187        assert_eq!(vector.text_at(2), None);
6188        assert_eq!(vector.bytes_at(1), Some(b"red".as_slice()));
6189        assert_eq!(vector.value_at(1), Value::Varchar("red".into()));
6190    }
6191
6192    /// The integer accessor a group by keys through, which has to agree with `value_at` at every
6193    /// row or two rows holding one value land in two groups.
6194    #[test]
6195    fn the_signed_reader_of_a_gather_agrees_with_the_value_reader() {
6196        let source = Arc::new(integers(&[10, 20, 30]));
6197        let vector = Vector::gathered(source, Arc::new(vec![2, NO_ROW, 0, 1])).unwrap();
6198        for row in 0..vector.len() {
6199            let signed = vector.signed_at(row);
6200            match vector.value_at(row) {
6201                Value::Null => assert_eq!(signed, None),
6202                Value::Integer(held) => assert_eq!(signed, Some(i128::from(held))),
6203                other => panic!("an integer column answered {other}"),
6204            }
6205        }
6206    }
6207
6208    /// Flattening gives up the form, which is what it is for, and what comes out holds the values the
6209    /// gather stood for, nulls included.
6210    #[test]
6211    fn flattening_a_gather_writes_out_the_rows_it_pointed_at() {
6212        let source = Arc::new(integers(&[10, 20, 30]));
6213        let vector = Vector::gathered(source, Arc::new(vec![2, NO_ROW, 0])).unwrap();
6214        let flat = vector.flatten().unwrap();
6215        assert_eq!(flat.form(), Form::Flat);
6216        assert_eq!(
6217            flat.iter().collect::<Vec<_>>(),
6218            vec![Value::Integer(30), Value::Null, Value::Integer(10)]
6219        );
6220    }
6221
6222    /// A gather counts a share of what it shares, for the reason a dictionary does. Eight columns
6223    /// gathered off one parent are one parent between them, not eight.
6224    #[test]
6225    fn a_parent_gathered_by_many_columns_is_counted_about_once_between_them() {
6226        let source = Arc::new(integers(&(0..4096).collect::<Vec<i32>>()));
6227        let rids = Arc::new(vec![0; 64]);
6228        let alone = Vector::gathered(Arc::clone(&source), Arc::clone(&rids)).unwrap().footprint();
6229        let many = (0..8)
6230            .map(|_| Vector::gathered(Arc::clone(&source), Arc::clone(&rids)).unwrap())
6231            .collect::<Vec<_>>();
6232        let together = many.iter().map(Vector::footprint).sum::<usize>();
6233        assert!(
6234            together < alone * 2,
6235            "eight gathers off one parent reported {together} against {alone} for one"
6236        );
6237    }
6238}