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