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.
102#[must_use]
103pub fn below(codes: &[u32], len: usize) -> bool {
104    let Ok(len) = u32::try_from(len) else { return true };
105    if codes.is_empty() || codes.iter().fold(0, |bits, &code| bits | code) < len {
106        return true;
107    }
108    codes.iter().copied().fold(0, u32::max) < len
109}
110
111/// What the key field of a map's child struct is called.
112///
113/// A map is stored as a list of two field structs, and these are the two names. They are DuckDB's, and
114/// they are also the names the Parquet specification gives a map's repeated group, so a reader that
115/// builds one of these from a file finds the names already agreed rather than translated.
116pub const MAP_KEY: &str = "key";
117
118/// What the value field of a map's child struct is called. See [`MAP_KEY`].
119pub const MAP_VALUE: &str = "value";
120
121/// What [`Vector::map_parts`] hands back: one entry per row, then the keys and then the values.
122///
123/// A name rather than the triple written out, because the triple written out is over the complexity
124/// clippy allows and because a kernel that takes these as an argument should be able to say so in one
125/// word.
126pub type MapParts<'a> = (&'a [(u32, u32)], &'a Vector, &'a Vector);
127
128/// Which physical form a vector is in.
129///
130/// An operator asks this once per vector and then takes the path it wants, which is the one branch
131/// per vector that the whole design is willing to spend.
132///
133/// Not exhaustive, and that is a decision rather than an oversight. `Encoded` is the fifth form
134/// and it arrives at layer three with the specialization contract. If this enum were exhaustive,
135/// the day it lands is the day every kernel in the workspace stops compiling, and the pressure at
136/// that moment would be to add an arm to each of them in a hurry rather than to think about what
137/// each one should do with an encoded vector. A required fallback arm means each kernel already
138/// has a correct answer for a form it has never seen, and specializing it is then a change that
139/// can be made one kernel at a time with a benchmark next to it.
140#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
141#[non_exhaustive]
142pub enum Form {
143    /// One value per position.
144    Flat,
145    /// One value, repeated.
146    Constant,
147    /// A start and a step, computed rather than stored.
148    Sequence,
149    /// Codes into a smaller vector of distinct values.
150    Dictionary,
151    /// Integers stored in as many bits as the range of the column needs, offset from a base.
152    ///
153    /// The form a narrow integer column is in. A ClickBench `ResolutionWidth` is a `SMALLINT` whose
154    /// values live between 0 and 2560, which is twelve bits, so the column is three quarters of the
155    /// size it was and the pages behind it are three quarters of the reads. What it costs is a shift
156    /// and a mask per value, which is why this is worth it at storage and at rest and is not a form
157    /// anything should be building in the middle of a pipeline.
158    BitPacked,
159    /// Sixteen byte views over an arena the vector shares rather than owns.
160    ///
161    /// The form a varchar column is in once more than one vector is looking at the same page. A flat
162    /// varchar vector owns its arena, so cutting a chunk out of it copies every byte of every long
163    /// string in the range, and on ClickBench that is most of what reading `URL` costs. Sharing the
164    /// arena makes the cut the views and nothing else, the way a dictionary cut is the codes and
165    /// nothing else.
166    StringView,
167    /// Strings compressed against one symbol table, each row on its own.
168    ///
169    /// The form a text column is in at rest. FSST is about half the bytes on the ClickBench `URL`
170    /// and `Title` columns, and unlike a block compressor it keeps random access, so reading row
171    /// four million does not decompress the four million before it. What it costs is a decompression
172    /// per row read, which is why an equality filter over it is worth writing in code space: the
173    /// literal compresses once and the rows never decompress at all.
174    Fsst,
175    /// One value per run, with the row each run ends at.
176    ///
177    /// The form a clustered column is in. `hits` is written in time order, so `EventDate` is a few
178    /// hundred runs over a hundred million rows, and a sum over it is a few hundred multiplications
179    /// rather than a hundred million additions. Dictionary says which distinct values there are and
180    /// this says where they stop, and a column can want either one without wanting the other.
181    Rle,
182    /// A child vector of every element, and a start and a length per row.
183    ///
184    /// The form a `LIST` column is in, and the only form it has. The others are all ways of writing
185    /// down a column of scalars more cheaply and this is the shape a nested value has at all, so a
186    /// list vector reports this whether or not anything has tried to make it smaller. Making it
187    /// smaller happens in the child, which is an ordinary vector and can be any of the forms above.
188    ///
189    /// A `MAP` column reports this too, because a map is a list whose child is a two field struct and
190    /// the bytes really are a list's. This enum is about the physical layout, and the logical type is
191    /// what remembers the difference, which is the same division `LogicalType::physical` already makes.
192    List,
193    /// One child vector per field, each as long as the vector itself.
194    ///
195    /// The form a `STRUCT` column is in, and the only form it has, for the reason [`Form::List`] is
196    /// the only form a list has. A struct holds exactly one value per field per row rather than a run
197    /// of them, so there are no entries here and the children line up with the rows one to one, which
198    /// makes a cut a cut of every child and a gather a gather of every child. Each child is an
199    /// ordinary vector and can be in any of the forms above, so that is where a struct column gets
200    /// made smaller.
201    Struct,
202    /// One row id per row, into a source vector that is far longer than this one.
203    ///
204    /// The form a link join's parent columns are in, per `spec/graph/08-vector-engine.md` section
205    /// 8.2. Physically it is [`Form::Dictionary`] and logically it is the opposite of one, which is
206    /// why it is a form of its own rather than a dictionary with a note on it. A dictionary promises
207    /// that the values are few and distinct, and every kernel that has a dictionary arm takes that
208    /// promise by folding the operation over the values once and then indexing. A gather's source is
209    /// a whole parent table, so folding over it to answer two thousand rows reads fifteen million
210    /// values for nothing. Both forms want the same code and they want it under opposite conditions,
211    /// so the condition is [`Vector::fold_over_source`] and the form is what makes a kernel ask.
212    Gathered,
213}
214
215/// The values of a flat vector, one Rust vector per physical type.
216///
217/// The variants are physical rather than logical, which is what lets `DATE` and `INTEGER` share
218/// storage and share a kernel. What a run of `i32` means is the vector's logical type's business.
219#[derive(Debug, Clone, PartialEq)]
220#[non_exhaustive]
221pub enum Data {
222    /// No values, for the type of an untyped `NULL`.
223    Empty,
224    /// One byte per value.
225    Bool(Buffer<bool>),
226    /// 8 bit signed.
227    Int8(Buffer<i8>),
228    /// 16 bit signed.
229    Int16(Buffer<i16>),
230    /// 32 bit signed.
231    Int32(Buffer<i32>),
232    /// 64 bit signed.
233    Int64(Buffer<i64>),
234    /// 128 bit signed.
235    Int128(Buffer<i128>),
236    /// 8 bit unsigned.
237    UInt8(Buffer<u8>),
238    /// 16 bit unsigned.
239    UInt16(Buffer<u16>),
240    /// 32 bit unsigned.
241    UInt32(Buffer<u32>),
242    /// 64 bit unsigned.
243    UInt64(Buffer<u64>),
244    /// 128 bit unsigned.
245    UInt128(Buffer<u128>),
246    /// IEEE 754 binary32.
247    Float32(Buffer<f32>),
248    /// IEEE 754 binary64.
249    Float64(Buffer<f64>),
250    /// The months, days and microseconds triple.
251    Interval(Buffer<(i32, i32, i64)>),
252    /// Strings, as 16 byte views plus the arena the long ones live in.
253    Varlen(StringColumn),
254}
255
256impl Data {
257    /// How many values are stored.
258    ///
259    /// The match below has no wildcard arm, and that is what makes this function the check that
260    /// keeps [`for_each_layout`](crate::for_each_layout) honest. A variant added to this enum
261    /// without being added to the `all` group fails to compile here, which is a line in a build log
262    /// rather than a layout quietly missing from six kernels.
263    #[must_use]
264    pub fn len(&self) -> usize {
265        macro_rules! lengths {
266            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
267                match self {
268                    Self::Empty => 0,
269                    $(Self::$variant(values) => values.len(),)+
270                }
271            };
272        }
273        crate::for_each_layout!(all, lengths)
274    }
275
276    /// Whether there are no values.
277    #[must_use]
278    pub fn is_empty(&self) -> bool {
279        self.len() == 0
280    }
281
282    /// How many bytes of memory these values are holding.
283    ///
284    /// One arm per layout through the same macro as [`Data::len`], for the same reason: a layout
285    /// added without a size here is a layout the memory limit would charge nothing for, and a
286    /// buffer that is free is a buffer that can be grown until the process dies.
287    #[must_use]
288    pub fn footprint(&self) -> usize {
289        macro_rules! sizes {
290            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
291                match self {
292                    Self::Empty => 0,
293                    $(Self::$variant(values) => values.footprint(),)+
294                }
295            };
296        }
297        crate::for_each_layout!(all, sizes)
298    }
299
300    /// These values held as a page, so that copying or cutting them does not copy the values.
301    ///
302    /// For a producer that is going to hand the same values out many times, which is what a stored
303    /// column is. It costs one `Arc` per layout and moves the run into it without touching a value,
304    /// and after it a write through any reader copies out rather than writing the page, which is
305    /// [`Buffer::to_mut`]. A run that is already a page comes back as it was.
306    #[must_use]
307    pub fn into_pages(self) -> Self {
308        macro_rules! paged {
309            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
310                match self {
311                    Self::Empty => Self::Empty,
312                    $(Self::$variant(values) => Self::$variant(values.into_page()),)+
313                }
314            };
315        }
316        crate::for_each_layout!(all, paged)
317    }
318
319    /// An integer at `index`, widened, for any of the signed integer layouts.
320    ///
321    /// Used by the decimal path, which needs the unscaled value out of whichever width the width
322    /// and scale picked, and by anything else that would otherwise repeat the same five arms.
323    #[must_use]
324    pub fn signed_at(&self, index: usize) -> Option<i128> {
325        macro_rules! widened {
326            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
327                match self {
328                    $(Self::$variant(v) => v.get(index).map(|&x| i128::from(x)),)+
329                    _ => None,
330                }
331            };
332        }
333        crate::for_each_layout!(signed, widened)
334    }
335
336    /// The first `len` signed integers, widened to `i64`, appended to `out`.
337    ///
338    /// The bulk form of [`Self::signed_at`]. Four of the five signed layouts, because the fifth is
339    /// 128 bits wide and does not fit what this hands back. `Int64` is a copy of the run and the
340    /// three narrower ones are a sign extension the compiler turns into one instruction per lane.
341    ///
342    /// `false`, leaving `out` as it found it, for the wide layout, for a run shorter than `len` and
343    /// for every layout that is not a signed integer.
344    #[must_use]
345    pub fn signed_block(&self, len: usize, out: &mut Vec<i64>) -> bool {
346        match self {
347            Self::Int8(v) => widen(v.as_slice(), len, out),
348            Self::Int16(v) => widen(v.as_slice(), len, out),
349            Self::Int32(v) => widen(v.as_slice(), len, out),
350            Self::Int64(v) => match v.as_slice().get(..len) {
351                Some(run) => {
352                    out.extend_from_slice(run);
353                    true
354                }
355                None => false,
356            },
357            _ => false,
358        }
359    }
360
361    /// The signed integers at the rows `at` names among the first `len`, widened to `i64`,
362    /// appended to `out`.
363    ///
364    /// The gathered form of [`Self::signed_block`], for the rows a filter kept. Widening the whole
365    /// run and then picking the kept rows out of it is a pass over every row and a second over the
366    /// kept ones, where this is the one pass. `false`, leaving `out` as it found it, where
367    /// [`Self::signed_block`] says `false`, and for a row that is not among the first `len`.
368    #[must_use]
369    pub fn signed_gather(&self, len: usize, at: &[u32], out: &mut Vec<i64>) -> bool {
370        match self {
371            Self::Int8(v) => gather_widened(v.as_slice(), len, at, out),
372            Self::Int16(v) => gather_widened(v.as_slice(), len, at, out),
373            Self::Int32(v) => gather_widened(v.as_slice(), len, at, out),
374            Self::Int64(v) => gather_widened(v.as_slice(), len, at, out),
375            _ => false,
376        }
377    }
378
379    /// The runs of equal signed integers among rows `from..to` of the first `len`, each as its
380    /// value widened to `i64` and the row it ends before, appended to `out`.
381    ///
382    /// `false`, with `out` cleared, where [`Self::signed_block`] says `false`, for rows past `len`,
383    /// and once there are more than one run for every `every` rows read so far, give or take a
384    /// block, so that a column in no order is given up on after its first few blocks.
385    #[must_use]
386    pub fn signed_runs(
387        &self,
388        len: usize,
389        (from, to): (usize, usize),
390        every: usize,
391        out: &mut Vec<(i64, usize)>,
392    ) -> bool {
393        match self {
394            Self::Int8(v) => runs_widened(v.as_slice(), len, (from, to), every, out),
395            Self::Int16(v) => runs_widened(v.as_slice(), len, (from, to), every, out),
396            Self::Int32(v) => runs_widened(v.as_slice(), len, (from, to), every, out),
397            Self::Int64(v) => runs_widened(v.as_slice(), len, (from, to), every, out),
398            _ => false,
399        }
400    }
401
402    /// An unsigned integer at `index`, widened.
403    #[must_use]
404    pub fn unsigned_at(&self, index: usize) -> Option<u128> {
405        macro_rules! widened {
406            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
407                match self {
408                    $(Self::$variant(v) => v.get(index).map(|&x| u128::from(x)),)+
409                    _ => None,
410                }
411            };
412        }
413        crate::for_each_layout!(unsigned, widened)
414    }
415
416    /// The string at `index`, for a `Varlen`.
417    #[must_use]
418    pub fn str_at(&self, index: usize) -> Option<&str> {
419        match self {
420            Self::Varlen(column) => column.get(index),
421            _ => None,
422        }
423    }
424
425    /// The bytes at `index`, for a `Varlen`, whatever they are.
426    ///
427    /// What a `BLOB` reads through, since the bytes of one are not required to be text and
428    /// [`Self::str_at`] answers `None` for the ones that are not.
429    #[must_use]
430    pub fn bytes_at(&self, index: usize) -> Option<&[u8]> {
431        match self {
432            Self::Varlen(column) => column.bytes(index),
433            _ => None,
434        }
435    }
436}
437
438/// A type, a length, a validity representation and some data.
439#[derive(Debug, Clone, PartialEq)]
440pub struct Vector {
441    ty: LogicalType,
442    len: usize,
443    validity: Validity,
444    body: Body,
445}
446
447/// What the vector holds, which is what its form is decided by.
448#[derive(Debug, Clone, PartialEq)]
449enum Body {
450    Flat(Data),
451    Constant(Box<Value>),
452    Sequence {
453        start: i64,
454        step: i64,
455    },
456    /// The values are behind an `Arc` rather than a `Box` because slicing shares them.
457    ///
458    /// A dictionary vector is cut once per chunk and the dictionary itself is the same dictionary
459    /// every time, so a `Box` meant a copy of every value in it per cut. On the ClickBench columns
460    /// that are dictionary encoded the dictionary is larger than the chunk of codes pointing into
461    /// it, and copying it was ten percent of the cycles of reading the file.
462    ///
463    /// Nothing here mutates a dictionary in place, so sharing one is only ever a read, and the one
464    /// place that wants an owned copy of the values is [`compose`], which asks for one.
465    Dictionary {
466        codes: Buffer<u32>,
467        values: Arc<Vector>,
468        stable: bool,
469    },
470    /// Integer codes of `width` bits each, packed end to end, each one an offset from `base`.
471    ///
472    /// Row `r` is the `width` bits starting at bit `(offset + r) * width`, read little end first, so
473    /// a code that straddles a word boundary has its low bits in the earlier word. `offset` is what
474    /// lets a cut of a packed column be free: the bits are not byte aligned, so a slice either
475    /// repacks or remembers where it starts, and remembering is one addition per read.
476    ///
477    /// The words are behind an `Arc` for the reason the dictionary's values are. A page is packed
478    /// once and cut into chunk sized pieces, and copying the words per cut would undo most of what
479    /// the packing saved.
480    Packed {
481        words: Arc<Vec<u64>>,
482        width: u32,
483        base: i128,
484        offset: usize,
485    },
486    /// The views of a string column, over an arena that other vectors are reading at the same time.
487    ///
488    /// The views are owned because a cut is a different run of views, and the arena is shared
489    /// because a cut is the same bytes. That split is the whole form: sixteen bytes a row move and
490    /// the payload does not, however many cuts a page is taken in.
491    ///
492    /// A row's bytes are found the same way [`StringColumn`] finds them, through
493    /// [`StringView::bytes_in`], so a short string never reads the arena at all and the two ways of
494    /// holding strings cannot answer a row differently.
495    Views {
496        views: Vec<StringView>,
497        arena: Arc<Buffer<u8>>,
498    },
499    /// Text owned by a storage source and fetched by position.
500    ExternalText {
501        source: Arc<dyn TextSource>,
502    },
503    /// The FSST codes of every row, end to end, with one symbol table over all of them.
504    ///
505    /// A span rather than a run of offsets, because a gather keeps this form and a gather puts the
506    /// rows in an order the codes are not in. Eight bytes a row either way, and the span is the one
507    /// that survives being permuted.
508    ///
509    /// The codes and the table are shared for the reason a dictionary's values are: one table is
510    /// trained per page and every chunk cut out of it points at the same one. A table is sixty five
511    /// thousand hash slots, so a table per chunk would cost more than the compression saves.
512    Coded {
513        codes: Arc<Vec<u8>>,
514        spans: Vec<(u32, u32)>,
515        table: Arc<SymbolTable>,
516    },
517    /// One value per run, with the row each run ends at, exclusive and increasing.
518    ///
519    /// Ends rather than lengths, because every reader of this wants to know which run holds a row
520    /// and ends answer that with a binary search while lengths answer it with a running total. The
521    /// two are the same information and only one of them is the one that gets asked for.
522    ///
523    /// The values are behind an `Arc` for the reason the dictionary's are: a page is cut into chunk
524    /// sized pieces and the values are the same values every time.
525    Runs {
526        ends: Vec<u32>,
527        values: Arc<Vector>,
528    },
529    /// One child vector holding every element of every row, and a start and a length per row.
530    ///
531    /// Start and length rather than the run of offsets Arrow carries, because offsets say where a
532    /// row ends by saying where the next one begins, and that is only true while the rows are in
533    /// order and none is skipped. A gather permutes the rows and a filter drops them, both of which
534    /// this form has to survive without copying the child, so each row says where its own elements
535    /// are and nothing is implied about its neighbour.
536    ///
537    /// The child is behind an `Arc` for the reason a dictionary's values are. A cut of a list column
538    /// is the entries and nothing else, so a page of lists taken in chunk sized pieces holds one
539    /// child however many pieces it is read in, and the elements outside the cut stay reachable but
540    /// unreferenced rather than being copied out.
541    ///
542    /// A null list and an empty list are different rows and this is where the difference lives. A
543    /// null is the validity mask at this level being false, the same as for any other type, and its
544    /// entry is `(start, 0)` and never read. An empty list is a valid row whose entry is `(start, 0)`
545    /// as well. So the entry alone does not say which one a row is, the mask does, which is the same
546    /// division of labour every other form here uses.
547    ///
548    /// A `MAP` is stored here too, with a [`Body::Fields`] child of `key` and `value`. Everything above
549    /// is true of it unchanged, which is the point of storing it this way: the cut, the gather and the
550    /// null rule are written once and a map inherits all three.
551    Nested {
552        entries: Vec<(u32, u32)>,
553        child: Arc<Vector>,
554    },
555    /// One child vector per field, in the order the type names them, each as long as this vector.
556    ///
557    /// No entries, which is the whole difference from [`Body::Nested`]. A list row is a run of
558    /// elements so it needs to say where its run is, and a struct row is one value per field so row
559    /// `r` of field `f` is position `r` of child `f` and there is nothing to record. That makes a cut
560    /// a cut of every child and a gather a gather of every child, both at the same positions, rather
561    /// than a rewrite of an index.
562    ///
563    /// The children are behind an `Arc` for the reason a dictionary's values are, and it pays off less
564    /// often here. A cut of a list column shares its child untouched because the entries carry the
565    /// range, and a cut of a struct column has to cut each child, so the sharing only survives the
566    /// cases where nothing moves. It is still worth having, because a struct of a hundred fields
567    /// handed between operators is a hundred pointers rather than a hundred columns.
568    ///
569    /// A null struct is the validity mask at this level being false and says nothing about the
570    /// children, which still hold whatever was put in them at that row. That is DuckDB's behaviour and
571    /// it is the reason this form cannot decide a row is null by looking down: the mask is the answer,
572    /// the same as it is for a list.
573    Fields {
574        children: Vec<Arc<Vector>>,
575    },
576    /// Row `r` is row `rids[offset + r]` of `source`, and is null where that is [`NO_ROW`].
577    ///
578    /// Late materialization written into the type system. A link join emits one of these per
579    /// projected parent column and reads nothing out of the parent at all, so a column that is
580    /// projected but never inspected is read once at the end for the rows that reached the end, and
581    /// a column used in a filter is filtered in this form over the distinct parent rows that were
582    /// actually reached rather than once per child row.
583    ///
584    /// The `rids` are shared and carry an `offset` for the reason [`Body::Packed`] carries one: a
585    /// link join fills one buffer of parent rows per child chunk and then the pipeline cuts it, and
586    /// a cut that copied the ids would spend more moving them than the gather it is describing
587    /// costs. Sharing makes a cut two words.
588    ///
589    /// [`NO_ROW`] is the whole of the outer join story here. Section 5.2 says a left link join keeps
590    /// the child rows whose link is the no parent sentinel and gathers null for them, and an inner
591    /// one drops them, so the operator decides which rows exist and this decides only what they
592    /// hold. That keeps the validity of a gather derivable rather than stored: a row is null when
593    /// its id is [`NO_ROW`] or when the source row it names is null, which is two loads and no
594    /// allocation, and the bitmap is materialized only when a kernel asks for one.
595    Gathered {
596        source: Arc<Vector>,
597        rids: Arc<Vec<u32>>,
598        offset: usize,
599    },
600}
601
602/// Random access to immutable text kept by a storage reader.
603pub trait TextSource: std::fmt::Debug + Send + Sync {
604    /// Number of values available.
605    fn len(&self) -> usize;
606    /// Whether this source has no values.
607    fn is_empty(&self) -> bool {
608        self.len() == 0
609    }
610    /// Bytes at one position, or no value when the position is outside the source.
611    fn bytes_at(&self, index: usize) -> Result<Option<&[u8]>>;
612    /// Byte length at one position without requiring the payload when the source has an index.
613    fn bytes_len_at(&self, index: usize) -> Result<Option<usize>> {
614        Ok(self.bytes_at(index)?.map(<[u8]>::len))
615    }
616    /// The byte length at each of `indices`, appended to `into` in the same order, and zero for a
617    /// position the source does not have.
618    ///
619    /// The same answers as [`bytes_len_at`](Self::bytes_len_at) a position at a time, which is what
620    /// the default does. A source overrides it when it can answer a run of positions for less than
621    /// the run of calls: a length asked once per row goes through a dispatch here, a dispatch in the
622    /// vector and a `Result` at each, and on a column whose lengths are one load each that was most
623    /// of what `STRLEN` cost. Appended rather than written into place, so that the caller has no
624    /// zeroed buffer to make first only for every slot of it to be written over.
625    fn bytes_lens_at(&self, indices: &[u32], into: &mut Vec<i64>) -> Result<()> {
626        into.reserve(indices.len());
627        for &index in indices {
628            let len = self.bytes_len_at(index as usize)?.unwrap_or_default();
629            into.push(i64::try_from(len).unwrap_or(i64::MAX));
630        }
631        Ok(())
632    }
633    /// The length in characters at each of `indices`, appended to `into` in the same order, and
634    /// zero for a position the source does not have.
635    ///
636    /// What `length` asks for, where [`bytes_lens_at`](Self::bytes_lens_at) is what `strlen` asks
637    /// for. Counting characters means looking at the bytes, and the default does that through
638    /// [`bytes_at`](Self::bytes_at), which is right for a source that keeps its values anyway. A
639    /// source that decodes a block to answer `bytes_at` keeps that block for as long as it lives,
640    /// so a scan of `length` over a whole column ends up holding the whole column decoded. Such a
641    /// source overrides this and keeps the counts instead of the bytes.
642    fn chars_lens_at(&self, indices: &[u32], into: &mut Vec<i64>) -> Result<()> {
643        into.reserve(indices.len());
644        for &index in indices {
645            let bytes = self.bytes_at(index as usize)?.unwrap_or_default();
646            // A continuation byte of UTF-8 is `0b10xx_xxxx`, and every other byte starts a
647            // character, so counting the bytes that are not continuations counts the characters.
648            let characters = bytes.iter().filter(|byte| (**byte as i8) >= -0x40).count();
649            into.push(i64::try_from(characters).unwrap_or(i64::MAX));
650        }
651        Ok(())
652    }
653    /// Hands `body` the values from `first` up to at most `limit`, and answers where it stopped.
654    ///
655    /// The point of it is what it does not do, which is keep what it read.
656    /// [`bytes_at`](Self::bytes_at) hands back a borrow, so a source that decodes a block to answer
657    /// it has to hold that block for as long as the source lives, and a reader that walks the whole
658    /// source therefore ends up holding the whole thing decoded. On the ClickBench `URL` dictionary
659    /// that is 4.2 GB resident to answer one `LIKE`, and none of it is read twice.
660    ///
661    /// A caller that means to walk a stretch of values once calls this instead and gets the bytes
662    /// on loan for the length of the call. The source decides how much it hands over at a time,
663    /// which for a blocked payload is the rest of the block it had to decode anyway, and answers
664    /// with one past the last value it visited so the caller can come back for the next stretch.
665    /// The answer is always above `first` where `first` is a value this source has, so a loop on it
666    /// finishes.
667    ///
668    /// The default hands over one value through `bytes_at` and is correct for every source. It is
669    /// also pointless for a source that keeps everything anyway, which is every source built in
670    /// memory, and that is the right default for exactly that reason.
671    fn sweep(
672        &self,
673        first: usize,
674        limit: usize,
675        body: &mut dyn FnMut(usize, &[u8]) -> Result<()>,
676    ) -> Result<usize> {
677        if first >= limit.min(self.len()) {
678            return Ok(first);
679        }
680        body(first, self.bytes_at(first)?.unwrap_or_default())?;
681        Ok(first + 1)
682    }
683    /// Hands `body` the value at each of `indices`, in whatever order suits the source, with the
684    /// position in `indices` it belongs to.
685    ///
686    /// The whole vector twin of [`bytes_at`](Self::bytes_at), for a kernel that reads every row of
687    /// a vector once and writes something per row, which is what `lower`, `upper` and `substring`
688    /// do. Read a row at a time, a source that decodes a block to answer `bytes_at` has to keep
689    /// every block a row lands in for as long as the source lives, because the borrow it hands back
690    /// says so. Handed a whole vector of positions at once it can put them in block order, decode
691    /// each block once for the call and decide for itself whether that block is worth keeping.
692    ///
693    /// A position the source does not have gets the empty value, which is what a row at a time
694    /// read turns its missing value into. The default reads through `bytes_at` in the order given,
695    /// which is right for every source that keeps its values anyway.
696    fn visit_at(
697        &self,
698        indices: &[u32],
699        body: &mut dyn FnMut(usize, &[u8]) -> Result<()>,
700    ) -> Result<()> {
701        for (at, &index) in indices.iter().enumerate() {
702            body(at, self.bytes_at(index as usize)?.unwrap_or_default())?;
703        }
704        Ok(())
705    }
706    /// Whether the payload block holding `first` might contain `literal` in any value.
707    ///
708    /// A false answer is a proof that every value in the block misses. A source without a stored
709    /// substring signature answers true, which keeps the ordinary exact comparison authoritative.
710    fn might_contain(&self, first: usize, literal: &[u8]) -> Result<bool> {
711        let _ = (first, literal);
712        Ok(true)
713    }
714    /// Hands over the values at `indices`, which rise, without keeping what reading them decoded.
715    ///
716    /// The scattered twin of [`sweep`](Self::sweep). A caller that wants a few hundred values spread
717    /// over the whole source once, which is what turning a frequency synopsis's codes into values
718    /// is, would otherwise leave every block it touched decoded and held for the rest of the
719    /// source's life. On ClickBench `SearchPhrase` that is a hundred and twenty five blocks, the
720    /// larger part of what a query answered out of the synopsis was holding.
721    ///
722    /// `body` is told the position in `indices` and the bytes. The default reads through
723    /// `bytes_at`, which is right for every source that keeps everything anyway.
724    fn visit(
725        &self,
726        indices: &[usize],
727        body: &mut dyn FnMut(usize, &[u8]) -> Result<()>,
728    ) -> Result<()> {
729        for (at, &index) in indices.iter().enumerate() {
730            body(at, self.bytes_at(index)?.unwrap_or_default())?;
731        }
732        Ok(())
733    }
734    /// Resident bytes retained by this source.
735    fn footprint(&self) -> usize;
736    /// How many ranks this source's sorted value order has, when it has one.
737    ///
738    /// A rank is a position in the values sorted by their bytes, so rank zero is the smallest value
739    /// and rank `ranks() - 1` is the largest. A storage format that keeps a dictionary for a whole
740    /// column can afford to sort the distinct values once when it writes the file, and what that
741    /// buys is a binary search where a reader that only knows the values are distinct has to ask
742    /// every one of them whether it matches.
743    ///
744    /// `None` means the source does not know its order, which is the honest answer for anything
745    /// built in memory and for a file written before its format stored one. Nothing is allowed to
746    /// depend on this for correctness, only for speed.
747    ///
748    /// A source that answers with `Some` promises the ranks cover every value it has, and that
749    /// [`compare_rank`](Self::compare_rank) is consistent with an ordering in which the values are
750    /// strictly increasing. Strictly, which is to say the values are distinct, because what reads
751    /// this searches it, and a search of a run of equal values finds one of them rather than all of
752    /// them. A source that holds the same value twice must answer `None` here even though it could
753    /// sort itself perfectly well.
754    fn ranks(&self) -> Option<usize> {
755        None
756    }
757    /// How the value at `rank` compares against `wanted`.
758    ///
759    /// This is a method rather than a slice of positions the caller indexes because the answer is
760    /// the only thing a search wants, and a source that knows that can answer most probes without
761    /// reading a value at all. A file that stores the first few bytes of each value in rank order
762    /// settles every probe from those bytes except the ones where two values start the same way,
763    /// and the payload stays untouched. A caller handed positions instead would have to read a
764    /// value per probe, which for a dictionary of half a million entries spread over thirty
765    /// megabytes is a fresh block of the file every time.
766    ///
767    /// Only called for a rank below [`ranks`](Self::ranks), so the default is the error a source
768    /// that has no order should never be asked to produce.
769    fn compare_rank(&self, rank: usize, wanted: &[u8]) -> Result<Ordering> {
770        let _ = (rank, wanted);
771        Err(Error::internal("a text source without a sorted order was asked to compare a rank"))
772    }
773    /// How many values sort before `wanted`, and whether one of them is `wanted`.
774    ///
775    /// The whole search rather than a probe of it, so that a source which can answer the same
776    /// question twice without repeating the work is allowed to. The default runs the search through
777    /// [`compare_rank`](Self::compare_rank) and remembers nothing, which is right for a source whose
778    /// probes are cheap.
779    ///
780    /// The reason it is on the trait at all is the top N. `ORDER BY <varchar> LIMIT 10` asks once a
781    /// chunk whether anything left can beat the worst candidate, and the worst candidate stops
782    /// changing long before the chunks run out, so nearly every one of those searches is the one
783    /// before it asked again. A probe of a file backed dictionary is not cheap: it settles on the
784    /// stored head where it can and reads a value where it cannot, and reading a value means
785    /// decoding the payload block it sits in. On ClickBench 25 that search was 29 percent of the
786    /// query's instructions and the block decoding under it another 40.
787    ///
788    /// Only called when [`ranks`](Self::ranks) is `Some`, and `ranks` is what it answered.
789    fn below(&self, ranks: usize, wanted: &[u8]) -> Result<(usize, bool)> {
790        search_below(self, ranks, wanted)
791    }
792    /// The position of the value at `rank`, which is what a search returns once it has found one.
793    ///
794    /// Called about once per search rather than once per probe, so unlike
795    /// [`compare_rank`](Self::compare_rank) it is free to be the expensive one.
796    fn code_at_rank(&self, rank: usize) -> Result<u32> {
797        let _ = rank;
798        Err(Error::internal("a text source without a sorted order was asked for a rank"))
799    }
800    /// The rank of every value, in position order, when the source can hand the whole map over.
801    ///
802    /// This is [`code_at_rank`](Self::code_at_rank) turned round, and it is a separate method
803    /// because the two are wanted by opposite kinds of reader. A search wants one code out of a
804    /// rank and probes a handful of times, so it reads the order a block at a time and leaves the
805    /// rest alone. A min or a max over a grouped column wants a rank out of a code once per row,
806    /// and a walk of the order per row costs far more than reading the order once and turning it
807    /// round. What that buys is a comparison of two integers where the alternative is a fetch of
808    /// two strings out of a payload the size of the column.
809    ///
810    /// The slice is indexed by position and is as long as [`len`](Self::len), so a caller holding a
811    /// dictionary code indexes it directly.
812    ///
813    /// `None` from a source with no order, and from one with an order it would rather not invert.
814    /// Nothing depends on this for correctness, only for speed.
815    fn code_ranks(&self) -> Option<&[u32]> {
816        None
817    }
818    /// Whether another source presents the same values.
819    fn equal(&self, other: &dyn TextSource) -> bool {
820        self.len() == other.len()
821            && (0..self.len()).all(|index| {
822                matches!(
823                    (self.bytes_at(index), other.bytes_at(index)),
824                    (Ok(left), Ok(right)) if left == right
825                )
826            })
827    }
828}
829
830impl PartialEq for dyn TextSource {
831    fn eq(&self, other: &Self) -> bool {
832        self.equal(other)
833    }
834}
835
836/// The binary search behind [`TextSource::below`], written once so an override can still use it.
837///
838/// A source that remembers its answers overrides `below` to look in what it remembers first, and
839/// then it still has to do the search when it does not find one. This is that search. It carries on
840/// past an equal probe to the first rank holding the value, so what it returns is a boundary rather
841/// than wherever the halving happened to touch down, and the values are distinct so there is exactly
842/// one such rank.
843///
844/// # Errors
845///
846/// Whatever [`TextSource::compare_rank`] gives for a probe.
847pub fn search_below<S>(source: &S, ranks: usize, wanted: &[u8]) -> Result<(usize, bool)>
848where
849    S: TextSource + ?Sized,
850{
851    let mut low = 0;
852    let mut high = ranks;
853    let mut equal = false;
854    while low < high {
855        let middle = low + (high - low) / 2;
856        match source.compare_rank(middle, wanted)? {
857            Ordering::Less => low = middle + 1,
858            Ordering::Greater => high = middle,
859            Ordering::Equal => {
860                equal = true;
861                high = middle;
862            }
863        }
864    }
865    Ok((low, equal))
866}
867
868impl Vector {
869    /// A flat vector of `data`, all valid.
870    ///
871    /// # Errors
872    ///
873    /// If the data's physical layout is not the one the type calls for. That check is here rather
874    /// than left to the caller because a vector whose type and layout disagree is a wrong answer
875    /// waiting to be read out, and it costs one comparison at construction to prevent.
876    pub fn flat(ty: LogicalType, data: Data) -> Result<Self> {
877        let len = data.len();
878        if !matches!(data, Data::Empty) && layout_of(&data) != ty.physical() {
879            return Err(Error::internal(format!(
880                "a {ty} vector cannot hold {:?} data",
881                layout_of(&data)
882            )));
883        }
884        Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Flat(data) })
885    }
886
887    /// A flat vector built from single values, with the nulls among them turning into validity.
888    ///
889    /// The slow way in, and the only way in that anything outside this crate has. It is what an
890    /// `INSERT`, a `VALUES` clause and a test build a column with, all of which arrive holding
891    /// values rather than a run of `i32`. Nothing on a scan path calls it: a scan produces a run of
892    /// data directly and hands it to [`Self::flat`].
893    ///
894    /// # Errors
895    ///
896    /// If a value is not one the type can hold, or if the type is one there is no vector for yet,
897    /// which today means `ARRAY` and `UNION`. A `LIST`, a `STRUCT` and a `MAP` are routed to their own
898    /// builders and come back built.
899    pub fn from_values(ty: LogicalType, values: &[Value]) -> Result<Self> {
900        match &ty {
901            LogicalType::List(element) => {
902                return Self::list_from_values(element.as_ref().clone(), values);
903            }
904            LogicalType::Struct(fields) => return Self::struct_from_values(fields, values),
905            LogicalType::Map(key, value) => {
906                return Self::map_from_values(key.as_ref().clone(), value.as_ref().clone(), values);
907            }
908            _ => {}
909        }
910        let mut data = empty_data_for(&ty)?;
911        for value in values {
912            let value = stored(&ty, value)?;
913            push_value(&mut data, &value)?;
914        }
915        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
916        Ok(Self { ty, len: values.len(), validity, body: Body::Flat(data) })
917    }
918
919    /// A list vector of `element`, built from one [`Value::List`] per row.
920    ///
921    /// The elements of every row go into one child vector end to end, so a row's elements are a
922    /// contiguous range of it and a row is a start and a length into it. That is what makes a cut of
923    /// this form the entries and nothing else.
924    ///
925    /// A null row contributes no elements and gets an entry of length zero, which is the same entry
926    /// an empty list gets. The two are told apart by the validity mask rather than by the entry, for
927    /// the reason written on [`Body::Nested`].
928    fn list_from_values(element: LogicalType, values: &[Value]) -> Result<Self> {
929        let mut flat = Vec::new();
930        let mut entries = Vec::with_capacity(values.len());
931        for value in values {
932            let start = u32::try_from(flat.len())
933                .map_err(|_| Error::internal("a list column with more than u32 elements in it"))?;
934            match value {
935                Value::Null => entries.push((start, 0)),
936                Value::List { values: held, .. } => {
937                    let len = u32::try_from(held.len())
938                        .map_err(|_| Error::internal("a list longer than u32"))?;
939                    flat.extend_from_slice(held);
940                    entries.push((start, len));
941                }
942                other => {
943                    return Err(Error::internal(format!(
944                        "{other:?} does not belong in a list vector"
945                    )));
946                }
947            }
948        }
949        // The element type is the column's rather than any one value's. A `Value::List` carries what
950        // it thinks it is empty of, and a column built from a row of `INTEGER[]` and a row of
951        // `[]::NULL[]` would otherwise take its type from whichever row came first.
952        let child = Self::from_values(element, &flat)?;
953        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
954        Ok(Self {
955            ty: LogicalType::list(child.ty.clone()),
956            len: values.len(),
957            validity,
958            body: Body::Nested { entries, child: Arc::new(child) },
959        })
960    }
961
962    /// A list vector over a child that already exists, one entry per row.
963    ///
964    /// What a scan and a list returning kernel build, both of which produce the elements in bulk and
965    /// then say which row each range belongs to. Every row is valid, since a caller with nulls to
966    /// record adds them with [`Self::with_validity`].
967    ///
968    /// # Errors
969    ///
970    /// If an entry runs past the end of the child, which would be a row that reads elements belonging
971    /// to nobody and is the one mistake this form makes easy.
972    pub fn list(entries: Vec<(u32, u32)>, child: Vector) -> Result<Self> {
973        let reach = child.len();
974        for &(start, len) in &entries {
975            if start as usize + len as usize > reach {
976                return Err(Error::internal(format!(
977                    "a list entry of {len} at {start} in a child of {reach}"
978                )));
979            }
980        }
981        Ok(Self {
982            ty: LogicalType::list(child.ty.clone()),
983            len: entries.len(),
984            validity: Validity::AllValid,
985            body: Body::Nested { entries, child: Arc::new(child) },
986        })
987    }
988
989    /// A struct vector of `fields`, built from one [`Value::Struct`] per row.
990    ///
991    /// One pass per field rather than one pass per row, because each field becomes its own child
992    /// vector and a child is built from a run of values of one type. So a struct of three fields over
993    /// a thousand rows is three calls to [`Self::from_values`] and not a thousand.
994    ///
995    /// The fields are matched by name and not by position. A `Value::Struct` carries its names, and a
996    /// caller that built one in a different order from the type's would otherwise get the values
997    /// silently transposed into the wrong columns, which is the kind of wrong answer that reads as
998    /// right. A row missing a field the type names is an error rather than a null for the same reason.
999    ///
1000    /// A null row is a null in every child as well as a false bit in the mask here. [`Body::Fields`]
1001    /// says a null struct is allowed to have readable children and that is about a struct built out of
1002    /// children that already exist, where whatever is underneath is the caller's. Built from values
1003    /// there is nothing underneath to keep, so the children get the null.
1004    fn struct_from_values(fields: &[Field], values: &[Value]) -> Result<Self> {
1005        let mut children = Vec::with_capacity(fields.len());
1006        // An unnamed struct has no names to match on, so its fields are taken by place.
1007        let unnamed = Field::unnamed(fields);
1008        for (at, field) in fields.iter().enumerate() {
1009            let mut column = Vec::with_capacity(values.len());
1010            for value in values {
1011                column.push(match value {
1012                    Value::Null => Value::Null,
1013                    Value::Struct(held) if unnamed => held
1014                        .get(at)
1015                        .map(|(_, held)| held.clone())
1016                        .ok_or_else(|| Error::internal("a tuple row shorter than its type"))?,
1017                    Value::Struct(held) => held
1018                        .iter()
1019                        .find(|(name, _)| *name == field.name)
1020                        .map(|(_, held)| held.clone())
1021                        .ok_or_else(|| {
1022                            Error::internal(format!(
1023                                "a struct row with no {} field in it",
1024                                field.name
1025                            ))
1026                        })?,
1027                    other => {
1028                        return Err(Error::internal(format!(
1029                            "{other:?} does not belong in a struct vector"
1030                        )));
1031                    }
1032                });
1033            }
1034            children.push(Arc::new(Self::from_values(field.ty.clone(), &column)?));
1035        }
1036        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
1037        Ok(Self {
1038            ty: LogicalType::Struct(fields.to_vec()),
1039            len: values.len(),
1040            validity,
1041            body: Body::Fields { children },
1042        })
1043    }
1044
1045    /// A struct vector over children that already exist, one per field.
1046    ///
1047    /// What a scan and a struct returning kernel build, both of which produce each field as a column
1048    /// and then put them side by side. Every row is valid, since a caller with nulls to record adds
1049    /// them with [`Self::with_validity`].
1050    ///
1051    /// # Errors
1052    ///
1053    /// If there are no fields, or if the children are not all the same length. The first is not a
1054    /// fussy restriction: a struct vector with no children has no child to take its length from, so a
1055    /// zero field struct column would be a length with nothing to check it against, and a caller that
1056    /// wants a column of empty structs wants a constant vector of one.
1057    pub fn structure(children: Vec<(String, Vector)>) -> Result<Self> {
1058        let Some((_, first)) = children.first() else {
1059            return Err(Error::internal("a struct vector of no fields, which has no length"));
1060        };
1061        let len = first.len();
1062        for (name, child) in &children {
1063            if child.len() != len {
1064                return Err(Error::internal(format!(
1065                    "a {} field of {} rows beside a struct of {len}",
1066                    name,
1067                    child.len()
1068                )));
1069            }
1070        }
1071        let fields = children
1072            .iter()
1073            .map(|(name, child)| Field::new(name.clone(), child.ty.clone()))
1074            .collect();
1075        let children = children.into_iter().map(|(_, child)| Arc::new(child)).collect();
1076        Ok(Self {
1077            ty: LogicalType::Struct(fields),
1078            len,
1079            validity: Validity::AllValid,
1080            body: Body::Fields { children },
1081        })
1082    }
1083
1084    /// The children, for a struct vector, and `None` for any other form.
1085    ///
1086    /// The accessor a kernel over a struct column reads, and the reason field extraction is free:
1087    /// picking one field out of a struct is picking one of these, so a projection of `s.a` hands back
1088    /// a vector that already exists rather than reading a row at a time and rebuilding a column.
1089    #[must_use]
1090    pub fn struct_parts(&self) -> Option<&[Arc<Self>]> {
1091        match &self.body {
1092            Body::Fields { children } => Some(children),
1093            _ => None,
1094        }
1095    }
1096
1097    /// A map vector, built from one [`Value::Map`] per row.
1098    ///
1099    /// A map is a list whose child is a two field struct of keys and values, which is what DuckDB
1100    /// stores and what Arrow and Parquet store, so this is the list builder and the struct builder
1101    /// composed rather than a third layout. The keys of every row go into one column end to end, the
1102    /// values into another beside it, and a row is a start and a length into the pair.
1103    ///
1104    /// The field names are [`MAP_KEY`] and [`MAP_VALUE`] because those are the names DuckDB gives them
1105    /// and the names anything reading a Parquet map field will expect to find.
1106    ///
1107    /// A null row and an empty map are both an entry of length zero, told apart by the validity mask,
1108    /// for the reason written on [`Body::Nested`].
1109    fn map_from_values(key: LogicalType, value: LogicalType, values: &[Value]) -> Result<Self> {
1110        let mut keys = Vec::new();
1111        let mut held = Vec::new();
1112        let mut entries = Vec::with_capacity(values.len());
1113        for row in values {
1114            let start = u32::try_from(keys.len())
1115                .map_err(|_| Error::internal("a map column with more than u32 entries in it"))?;
1116            match row {
1117                Value::Null => entries.push((start, 0)),
1118                Value::Map { entries: pairs, .. } => {
1119                    let len = u32::try_from(pairs.len())
1120                        .map_err(|_| Error::internal("a map with more than u32 entries"))?;
1121                    for (one, other) in pairs {
1122                        keys.push(one.clone());
1123                        held.push(other.clone());
1124                    }
1125                    entries.push((start, len));
1126                }
1127                other => {
1128                    return Err(Error::internal(format!(
1129                        "{other:?} does not belong in a map vector"
1130                    )));
1131                }
1132            }
1133        }
1134        // The two types are the column's rather than any one row's, for the reason the list builder
1135        // takes the element type from the column: a row that is the empty map carries whatever it was
1136        // built as being empty of, and the column is not entitled to take its type from that.
1137        let child = Self::structure(vec![
1138            (MAP_KEY.to_string(), Self::from_values(key, &keys)?),
1139            (MAP_VALUE.to_string(), Self::from_values(value, &held)?),
1140        ])?;
1141        let ty = LogicalType::map(
1142            fields_of(&child.ty)[0].ty.clone(),
1143            fields_of(&child.ty)[1].ty.clone(),
1144        );
1145        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
1146        Ok(Self {
1147            ty,
1148            len: values.len(),
1149            validity,
1150            body: Body::Nested { entries, child: Arc::new(child) },
1151        })
1152    }
1153
1154    /// A map vector over a pair of columns that already exist, one entry per row.
1155    ///
1156    /// What a scan and a map returning kernel build. The keys and the values are two columns of the
1157    /// same length, and each row of the map is the same range of both. Every row is valid, since a
1158    /// caller with nulls to record adds them with [`Self::with_validity`].
1159    ///
1160    /// # Errors
1161    ///
1162    /// If the two columns are different lengths, or if an entry runs past the end of them.
1163    pub fn map(entries: Vec<(u32, u32)>, keys: Vector, values: Vector) -> Result<Self> {
1164        let key = keys.ty.clone();
1165        let value = values.ty.clone();
1166        let child =
1167            Self::structure(vec![(MAP_KEY.to_string(), keys), (MAP_VALUE.to_string(), values)])?;
1168        let mut vector = Self::list(entries, child)?;
1169        vector.ty = LogicalType::map(key, value);
1170        Ok(vector)
1171    }
1172
1173    /// The entries and the two columns, for a map vector, and `None` for anything else.
1174    ///
1175    /// Reaches through the struct child that a map is stored as, so that a kernel over a map column
1176    /// reads the keys and the values as the two columns they are rather than having to know that the
1177    /// pair is spelled as a struct underneath.
1178    #[must_use]
1179    pub fn map_parts(&self) -> Option<MapParts<'_>> {
1180        if !matches!(self.ty, LogicalType::Map(_, _)) {
1181            return None;
1182        }
1183        let (entries, child) = self.list_parts()?;
1184        let [keys, values] = child.struct_parts()? else { return None };
1185        Some((entries, keys, values))
1186    }
1187
1188    /// The entries and the child, for a list vector, and `None` for any other form.
1189    ///
1190    /// The accessor a kernel over a list column reads, for the reason
1191    /// [`Self::dictionary_parts`] exists: `unnest` over 1024 rows wants the child once and the
1192    /// entries once, and reading it through [`Self::value_at`] would build a `Value::List` per row
1193    /// and then throw every one of them away.
1194    ///
1195    /// A map answers here as well, with the struct child it is stored as, because this is a question
1196    /// about the layout and a map's layout is a list's. A caller that wants the keys and the values as
1197    /// two columns wants [`Self::map_parts`], which reaches through that child.
1198    #[must_use]
1199    pub fn list_parts(&self) -> Option<(&[(u32, u32)], &Self)> {
1200        match &self.body {
1201            Body::Nested { entries, child } => Some((entries, child)),
1202            _ => None,
1203        }
1204    }
1205
1206    /// A vector of `len` copies of one value.
1207    ///
1208    /// Costs one value regardless of the length, which is what makes a literal in a predicate free
1209    /// and what makes a projection of a constant free.
1210    #[must_use]
1211    pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
1212        let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
1213        Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
1214    }
1215
1216    /// A vector of `len` values starting at `start` and stepping by `step`.
1217    ///
1218    /// This is what a row identifier column is, and it costs sixteen bytes rather than eight
1219    /// kilobytes. A scan that produces row ids for a later fetch produces one of these.
1220    #[must_use]
1221    pub fn sequence(start: i64, step: i64, len: usize) -> Self {
1222        Self {
1223            ty: LogicalType::BigInt,
1224            len,
1225            validity: Validity::AllValid,
1226            body: Body::Sequence { start, step },
1227        }
1228    }
1229
1230    /// A vector of codes into a smaller vector of distinct values.
1231    ///
1232    /// The form the whole M3 thesis rests on. A dictionary vector handed to a group by is an
1233    /// integer column, and an aggregate over one is an aggregate over integers no matter what the
1234    /// logical type says.
1235    ///
1236    /// A dictionary over a dictionary is composed into one level here rather than left as two, so
1237    /// the form has a depth of one always and a kernel that reads [`Self::dictionary_parts`] is
1238    /// reading the values rather than another layer of codes. Two filters over the same chunk build
1239    /// the second case and four conjuncts pushed down separately build four of it.
1240    ///
1241    /// The cost of leaving them stacked turned out to be a cliff rather than a slope. Every loop in
1242    /// `rudb-kernels` reaches for the values behind the codes with [`Self::data`], a dictionary
1243    /// pointing at a dictionary has no data to hand back, so the second level does not make the
1244    /// kernels slower, it turns them off and drops the work onto the row at a time path that exists
1245    /// to be correct rather than fast. Measured on server3 over a chunk of two numeric columns and a
1246    /// consumer of two vectorized passes, one level reads at 3.5 nanoseconds a row and two levels at
1247    /// 104, and the third and fourth levels cost almost nothing more because the first one had
1248    /// already given up everything there was to give. Composing is one pass over the outer codes,
1249    /// which the range check above is already making.
1250    ///
1251    /// The one dictionary that is not composed past is one carrying a validity of its own. A
1252    /// dictionary is built all valid and only [`Self::with_validity`] can change that, so such a
1253    /// vector is saying that its nulls are at this level rather than in the values it points at, and
1254    /// composing past it would drop them.
1255    ///
1256    /// # Errors
1257    ///
1258    /// If any code is past the end of the value vector.
1259    pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
1260        Self::dictionary_over(codes, Arc::new(values))
1261    }
1262
1263    /// The same, over a set of values somebody else is holding too.
1264    ///
1265    /// The body holds its values in an `Arc` either way, so a caller that already has one has
1266    /// nothing to hand over but a pointer. The caller this is for is a Parquet chunk: one dictionary
1267    /// page serves every data page of the chunk, and going through [`Self::dictionary`] meant
1268    /// copying the whole dictionary into each page's vector on the way to putting it in an `Arc`
1269    /// that then had a single holder. On a ClickBench scan that copy was sixteen percent of the
1270    /// instructions the query ran.
1271    ///
1272    /// Composing a dictionary over a dictionary keeps the handle too. The leaf of the stack is what
1273    /// the composed dictionary points at and neither its values nor anything about it changes, so
1274    /// there is nothing to own and the new dictionary shares the same leaf the old one did.
1275    ///
1276    /// The range check takes the highest code rather than stopping at the first bad one. Stopping
1277    /// early sounds cheaper and is not, because a loop that can exit anywhere cannot be vectorized
1278    /// and a running maximum can, and the only run that would have exited early is the one about to
1279    /// fail the query anyway. Every other run reads the whole of `codes` either way. It was 5.2
1280    /// percent of a ClickBench scan as a `find`.
1281    ///
1282    /// # Errors
1283    ///
1284    /// If any code is past the end of the value vector.
1285    pub fn dictionary_over(codes: Vec<u32>, values: Arc<Vector>) -> Result<Self> {
1286        if !below(&codes, values.len()) {
1287            let highest = codes.iter().copied().fold(0, u32::max);
1288            return Err(Error::internal(format!(
1289                "dictionary code {highest} is past the end of a {} value dictionary",
1290                values.len()
1291            )));
1292        }
1293        let (codes, values) = compose(codes, values);
1294        Ok(Self {
1295            ty: values.ty.clone(),
1296            len: codes.len(),
1297            validity: Validity::AllValid,
1298            body: Body::Dictionary { codes: Buffer::from_vec(codes), values, stable: false },
1299        })
1300    }
1301
1302    /// A dictionary whose codes keep the same meaning across every page of its source.
1303    pub fn stable_dictionary(codes: Vec<u32>, values: Arc<Vector>) -> Result<Self> {
1304        let mut vector = Self::dictionary_over(codes, values)?;
1305        if let Body::Dictionary { stable, .. } = &mut vector.body {
1306            *stable = true;
1307        }
1308        Ok(vector)
1309    }
1310
1311    /// The same vector without the promise that its codes mean the same thing on every page of its
1312    /// source, for a source that no longer keeps it. Nothing is copied.
1313    #[must_use]
1314    pub fn loosened(mut self) -> Self {
1315        if let Body::Dictionary { stable, .. } = &mut self.body {
1316            *stable = false;
1317        }
1318        self
1319    }
1320
1321    /// A stable dictionary whose caller already found the largest code while decoding it.
1322    pub fn stable_dictionary_validated(
1323        codes: Vec<u32>,
1324        values: Arc<Vector>,
1325        highest: Option<u32>,
1326    ) -> Result<Self> {
1327        if highest.is_some_and(|code| code as usize >= values.len()) {
1328            return Err(Error::internal("a stable dictionary code is past its value dictionary"));
1329        }
1330        Ok(Self {
1331            ty: values.ty.clone(),
1332            len: codes.len(),
1333            validity: Validity::AllValid,
1334            body: Body::Dictionary { codes: Buffer::from_vec(codes), values, stable: true },
1335        })
1336    }
1337
1338    /// One row of `source` per id, without reading any of them.
1339    ///
1340    /// What a link join emits for each of its parent columns, per `spec/graph/08-vector-engine.md`
1341    /// section 8.2. Row `r` is row `rids[r]` of `source`, and is null where that is [`NO_ROW`].
1342    ///
1343    /// The ids are taken by `Arc` rather than by value because one link join fills one buffer of
1344    /// parent rows per child chunk and then hands the same buffer to every projected parent column,
1345    /// so a gather of eight columns is eight pointers and one buffer. [`Self::gathered_from`] is the
1346    /// same thing starting part way in, which is what a cut of one produces.
1347    ///
1348    /// # Errors
1349    ///
1350    /// If an id is past the end of the source and is not [`NO_ROW`]. That check is a pass over the
1351    /// ids and it is the only thing standing between a link built against the wrong parent and a
1352    /// read of whatever happens to be at that offset, so it is not optional and it is not deferred:
1353    /// `spec/graph/03-the-file-format.md` section 3.1 says a stale section is ignored rather than
1354    /// repaired, and this is where a stale one stops being ignorable.
1355    pub fn gathered(source: Arc<Vector>, rids: Arc<Vec<u32>>) -> Result<Self> {
1356        let len = rids.len();
1357        Self::gathered_from(source, rids, 0, len)
1358    }
1359
1360    /// The same, reading `len` ids starting at `offset`.
1361    ///
1362    /// # Errors
1363    ///
1364    /// If the range runs past the end of the ids, or if an id in it is past the end of the source.
1365    pub fn gathered_from(
1366        source: Arc<Vector>,
1367        rids: Arc<Vec<u32>>,
1368        offset: usize,
1369        len: usize,
1370    ) -> Result<Self> {
1371        let end = offset.checked_add(len).ok_or_else(|| Error::internal("a gather that wraps"))?;
1372        let Some(taken) = rids.get(offset..end) else {
1373            return Err(Error::internal(format!(
1374                "rows {offset} to {end} of a gather over {} ids",
1375                rids.len()
1376            )));
1377        };
1378        let rows = source.len();
1379        if taken.iter().any(|&rid| rid != NO_ROW && rid as usize >= rows) {
1380            return Err(Error::internal(format!(
1381                "a gathered row id is past the {rows} rows of its source"
1382            )));
1383        }
1384        Ok(Self {
1385            ty: source.ty.clone(),
1386            len,
1387            // The mask is all valid and the nulls are real, which is the same split a dictionary
1388            // makes: this level says every row exists and the body says what each one holds, and
1389            // `is_null_at` reads through to answer. A mask here would be a second copy of what the
1390            // ids already say and the two could disagree.
1391            validity: Validity::AllValid,
1392            body: Body::Gathered { source, rids, offset },
1393        })
1394    }
1395
1396    /// The source and the ids of a gathered vector, and `None` for any other form.
1397    #[must_use]
1398    pub fn gathered_parts(&self) -> Option<(&Arc<Self>, &[u32])> {
1399        match &self.body {
1400            Body::Gathered { source, rids, offset } => {
1401                Some((source, rids.get(*offset..offset + self.len)?))
1402            }
1403            _ => None,
1404        }
1405    }
1406
1407    /// Whether a kernel over this vector should fold over the source once and then index.
1408    ///
1409    /// Section 8.2's dispatch rule, which is one comparison and is the whole difference between a
1410    /// gather and a dictionary. Every kernel with a dictionary arm already folds over the values
1411    /// once and indexes, and that arm is right for a gather exactly when the source is shorter than
1412    /// the rows being answered. A dictionary always is, by construction. A gather off a parent
1413    /// table almost never is, and a kernel that took the dictionary arm anyway would read fifteen
1414    /// million parent rows to answer two thousand child ones.
1415    ///
1416    /// `false` for every other form, so a kernel can ask this without first asking what it has.
1417    #[must_use]
1418    pub fn fold_over_source(&self) -> bool {
1419        match &self.body {
1420            Body::Gathered { source, .. } => source.len() < self.len,
1421            _ => false,
1422        }
1423    }
1424
1425    /// A vector of runs, one value each, with the row each run ends at.
1426    ///
1427    /// `ends` is exclusive and strictly increasing, so run `i` covers the rows from `ends[i - 1]` to
1428    /// `ends[i]` and run zero starts at nothing. The length of the vector is the last end.
1429    ///
1430    /// The depth is one, the same way a dictionary's is, and for a sharper reason. Every kernel that
1431    /// wants runs wants the value of a run without another search, and a run length vector over a
1432    /// run length vector turns one search into two and then into three. Rather than compose, this
1433    /// refuses: nothing in the engine builds a stacked one, because [`Self::run_encoded`] only ever
1434    /// reads a flat body, so a stacked one is a caller doing something by hand and the useful answer
1435    /// is to say so rather than to quietly do a pass of work they did not ask for.
1436    ///
1437    /// A run over a dictionary is fine and is not that case. The two forms answer different
1438    /// questions and a column that is both clustered and low cardinality genuinely wants both.
1439    ///
1440    /// # Errors
1441    ///
1442    /// If there is not exactly one value per run, if the ends do not increase, or if the values are
1443    /// themselves run length encoded.
1444    pub fn runs(ends: Vec<u32>, values: Vector) -> Result<Self> {
1445        if matches!(values.body, Body::Runs { .. }) {
1446            return Err(Error::internal("runs of runs, which is two searches to read one row"));
1447        }
1448        if ends.len() != values.len() {
1449            return Err(Error::internal(format!(
1450                "{} runs and {} values to put in them",
1451                ends.len(),
1452                values.len()
1453            )));
1454        }
1455        if ends.windows(2).any(|pair| pair[0] >= pair[1]) || ends.first() == Some(&0) {
1456            return Err(Error::internal("run ends that do not increase"));
1457        }
1458        let len = ends.last().copied().unwrap_or(0) as usize;
1459        Ok(Self {
1460            ty: values.ty.clone(),
1461            len,
1462            validity: Validity::AllValid,
1463            body: Body::Runs { ends, values: Arc::new(values) },
1464        })
1465    }
1466
1467    /// The same values as runs, when there are few enough runs for that to be smaller.
1468    ///
1469    /// Costs one pass over the column to find out, which is why this is a call somebody makes rather
1470    /// than something a constructor does. The decision is the same arithmetic every time: a row in
1471    /// flat form costs one value, a run costs one value plus the four bytes of its end, so runs are
1472    /// smaller once there are fewer than about half as many runs as rows, and the narrower the
1473    /// column the more runs it takes. `RUNS_PAY_AT` is that ratio, written down rather than spelt
1474    /// into an `if`, because it is the number a sweep will want to move.
1475    ///
1476    /// Only a flat body is looked at. A constant and a sequence are already one value and two
1477    /// numbers, so there is nothing to win, and a dictionary that is also clustered is a real case
1478    /// that wants its codes run length encoded rather than its values, which is a different function
1479    /// and not this one.
1480    ///
1481    /// Two adjacent nulls are one run. Two adjacent equal values with a null between them are three,
1482    /// because the null is a value of the column as far as anything reading it is concerned.
1483    ///
1484    /// # Errors
1485    ///
1486    /// From the gather this does at the end, and nowhere else. A body that is not flat comes back
1487    /// unchanged rather than as an error, so a nested vector never reaches the part that can fail.
1488    pub fn run_encoded(&self) -> Result<Self> {
1489        let Body::Flat(data) = &self.body else {
1490            return Ok(self.clone());
1491        };
1492        let ends = boundaries(data, &self.validity, self.len);
1493        if ends.len().saturating_mul(RUNS_PAY_AT) >= self.len {
1494            return Ok(self.clone());
1495        }
1496        let starts: Vec<u32> =
1497            std::iter::once(0).chain(ends.iter().copied()).take(ends.len()).collect();
1498        Self::runs(ends, self.gather(&starts)?)
1499    }
1500
1501    /// A vector of `len` integers packed `width` bits each, every one an offset from `base`.
1502    ///
1503    /// The way in for a reader that already has the packed bits, which is what a column file holds
1504    /// and what a network frame carries. Nothing unpacks on the way in, so a scan of a packed column
1505    /// hands the bits straight to the chunk and the cost of the form is paid by whoever reads a
1506    /// value rather than by the scan.
1507    ///
1508    /// The range check is on the two ends rather than on every code, which is the whole check. A
1509    /// code is between zero and `2^width - 1` by construction, so if `base` and `base + 2^width - 1`
1510    /// both fit the column's layout then every value does, and that is two comparisons instead of
1511    /// one per row.
1512    ///
1513    /// # Errors
1514    ///
1515    /// If the type is not one of the integer layouts, if the width is not between one and
1516    /// [`PACKED_WIDTH_MAX`], if there are not enough words for the length, or if either end of the
1517    /// range would not fit the type.
1518    pub fn packed(
1519        ty: LogicalType,
1520        words: Vec<u64>,
1521        width: u32,
1522        base: i128,
1523        len: usize,
1524    ) -> Result<Self> {
1525        let Some((low, high)) = layout_range(&ty) else {
1526            return Err(Error::internal(format!("a {ty} vector has no integer layout to pack")));
1527        };
1528        if width == 0 || width > PACKED_WIDTH_MAX {
1529            return Err(Error::internal(format!(
1530                "a packed width of {width}, which is outside 1 to {PACKED_WIDTH_MAX}"
1531            )));
1532        }
1533        let needed = words_for(len, width);
1534        if words.len() < needed {
1535            return Err(Error::internal(format!(
1536                "{} words for {len} values of {width} bits, which needs {needed}",
1537                words.len()
1538            )));
1539        }
1540        let top = base + i128::from(u64::MAX >> (64 - width));
1541        if base < low || top > high {
1542            return Err(Error::internal(format!(
1543                "packed values from {base} to {top}, which a {ty} cannot hold"
1544            )));
1545        }
1546        Ok(Self {
1547            ty,
1548            len,
1549            validity: Validity::AllValid,
1550            body: Body::Packed { words: Arc::new(words), width, base, offset: 0 },
1551        })
1552    }
1553
1554    /// The same values bit packed, when the range of the column makes that smaller.
1555    ///
1556    /// Costs one pass to find the range and one to write the bits, which is why this is a call
1557    /// somebody makes rather than something a constructor does. It is the counterpart of
1558    /// [`Self::run_encoded`] and the decision has the same shape: a row flat costs the width of its
1559    /// layout, a row packed costs the bits the column's range needs, and the form is worth having
1560    /// only when the second is a good deal smaller than the first. [`PACKING_PAYS_AT`] is that
1561    /// ratio, written down rather than spelt into an `if`, because it is the number a sweep will
1562    /// want to move.
1563    ///
1564    /// Only a flat integer body is looked at. A constant and a sequence are already smaller than any
1565    /// packing of them, a dictionary's codes are the thing that would want packing rather than its
1566    /// values, and a float has no range to pack into since the bits of an `f64` are not an integer
1567    /// that arithmetic on the column agrees with.
1568    ///
1569    /// The range is taken over every slot including the null ones, which hold a zero. A column of
1570    /// large values with one null in it therefore packs a range that reaches down to zero and comes
1571    /// out wider than it needed to be. The alternative is a pass that consults the validity per slot
1572    /// to find the range and a second rule for what to write into a null slot, and this form exists
1573    /// to make reads cheap rather than to squeeze the last bit out of a sparse column.
1574    ///
1575    /// A column whose values are all the same packs to nothing at all, and rather than invent a zero
1576    /// bit code this declines and leaves it to [`Self::run_encoded`], which turns that column into
1577    /// one run and is smaller than any packing of it.
1578    ///
1579    /// # Errors
1580    ///
1581    /// If the packed bits and the length disagree, which would be a bug here rather than a caller
1582    /// doing something wrong.
1583    pub fn bit_packed(&self) -> Result<Self> {
1584        let Body::Flat(data) = &self.body else {
1585            return Ok(self.clone());
1586        };
1587        let Some((low, high)) = span_of(data, self.len) else {
1588            return Ok(self.clone());
1589        };
1590        let Some(range) = high.checked_sub(low).and_then(|range| u64::try_from(range).ok()) else {
1591            return Ok(self.clone());
1592        };
1593        let width = u64::BITS - range.leading_zeros();
1594        if width == 0 || width > PACKED_WIDTH_MAX {
1595            return Ok(self.clone());
1596        }
1597        // Against the bytes the rows take and not the footprint, because a window of a shared page
1598        // reports its share of the page. That made the answer, and so the file a load writes,
1599        // depend on how big the page was and how many readers it had.
1600        if words_for(self.len, width) * size_of::<u64>() * PACKING_PAYS_AT
1601            > flat_bytes(data, self.len)
1602        {
1603            return Ok(self.clone());
1604        }
1605        // A range can fit the type while that width up from the smallest value does not: a column
1606        // of a thousand values under `i32::MAX` needs ten bits, and ten bits up from the smallest
1607        // of them runs past `i32::MAX`. The packed form checks both ends of what its width can
1608        // say, so the base moves down until they both fit rather than the column being left flat.
1609        let Some(base) = packing_base(&self.ty, low, high, width) else {
1610            return Ok(self.clone());
1611        };
1612        let words = pack(data, self.len, base, width);
1613        let packed = Self::packed(self.ty.clone(), words, width, base, self.len)?;
1614        Ok(packed.with_validity(self.validity.clone()))
1615    }
1616
1617    /// A vector of string views over an arena somebody else is holding too.
1618    ///
1619    /// The way in for a scan that has a page of strings and wants several chunks over it. Each chunk
1620    /// gets its own run of views and they all share the one arena, so the bytes are read where the
1621    /// page put them and nothing copies them.
1622    ///
1623    /// Every view is checked against the arena here rather than when a row is read. That is a pass
1624    /// over the views at construction, which is the same pass the caller just did to build them, and
1625    /// what it buys is that a row of this form cannot resolve to bytes that are not there. The check
1626    /// is on the offsets and not on the bytes, so it says nothing about whether the payload is text,
1627    /// which is the same promise a `BLOB` column makes.
1628    ///
1629    /// # Errors
1630    ///
1631    /// If the type is not one stored as views, or if a view points past the end of the arena.
1632    pub fn string_views(
1633        ty: LogicalType,
1634        views: Vec<StringView>,
1635        arena: Arc<Buffer<u8>>,
1636    ) -> Result<Self> {
1637        if ty.physical() != rudb_common::PhysicalType::Varlen {
1638            return Err(Error::internal(format!("a {ty} vector cannot hold string views")));
1639        }
1640        if views.iter().any(|view| view.bytes_in(&arena).is_none()) {
1641            return Err(Error::internal("a string view points past the end of its arena"));
1642        }
1643        let len = views.len();
1644        Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Views { views, arena } })
1645    }
1646
1647    /// A text vector whose values remain in a storage source until they are read.
1648    pub fn external_text(ty: LogicalType, source: Arc<dyn TextSource>) -> Result<Self> {
1649        if ty.physical() != rudb_common::PhysicalType::Varlen {
1650            return Err(Error::internal(format!(
1651                "a {ty} vector cannot use an external text source"
1652            )));
1653        }
1654        let len = source.len();
1655        Ok(Self { ty, len, validity: Validity::AllValid, body: Body::ExternalText { source } })
1656    }
1657
1658    /// The same strings, in a form where a cut of them does not copy the bytes.
1659    ///
1660    /// The counterpart of [`Self::run_encoded`] and [`Self::bit_packed`] for a string column, and
1661    /// the only one of the three that takes `self` by value. It has to: what it does is move the
1662    /// arena into an `Arc` so nothing copies it again, and a version taking `&self` would start by
1663    /// copying the arena once to have one to move.
1664    ///
1665    /// Anything that is not a flat string column comes back as it was, which includes a column that
1666    /// is already in this form.
1667    ///
1668    /// # Errors
1669    ///
1670    /// Nothing here fails today. The result is a `Result` because the check inside
1671    /// [`Self::string_views`] is worth running on the views this builds rather than trusting that
1672    /// this function built them right.
1673    pub fn shared_text(self) -> Result<Self> {
1674        let Body::Flat(Data::Varlen(column)) = self.body else {
1675            return Ok(self);
1676        };
1677        let (views, arena) = column.into_parts();
1678        let shared = Self::string_views(self.ty, views, Arc::new(arena))?;
1679        Ok(shared.with_validity(self.validity))
1680    }
1681
1682    /// A vector of FSST codes against a table somebody else trained.
1683    ///
1684    /// The way in for a reader that has a page of compressed strings and the table that goes with
1685    /// it. The codes are not copied and the table is not retrained, so laying several chunks over
1686    /// one page costs the spans and nothing else.
1687    ///
1688    /// # Errors
1689    ///
1690    /// If the type is not one stored as text, or if a span runs past the end of the codes.
1691    pub fn coded(
1692        ty: LogicalType,
1693        codes: Arc<Vec<u8>>,
1694        spans: Vec<(u32, u32)>,
1695        table: Arc<SymbolTable>,
1696    ) -> Result<Self> {
1697        if ty.physical() != rudb_common::PhysicalType::Varlen {
1698            return Err(Error::internal(format!("a {ty} vector cannot hold FSST codes")));
1699        }
1700        let end = u32::try_from(codes.len()).unwrap_or(u32::MAX);
1701        if spans.iter().any(|&(from, to)| from > to || to > end) {
1702            return Err(Error::internal("an FSST span runs past the end of the codes"));
1703        }
1704        let len = spans.len();
1705        Ok(Self {
1706            ty,
1707            len,
1708            validity: Validity::AllValid,
1709            body: Body::Coded { codes, spans, table },
1710        })
1711    }
1712
1713    /// The same strings, compressed against a table trained on them.
1714    ///
1715    /// The counterpart of [`Self::run_encoded`] and [`Self::bit_packed`] for a text column, and it
1716    /// takes `self` by value for the reason [`Self::shared_text`] does.
1717    ///
1718    /// The table is trained on every row rather than on a sample. A vector is at most 1024 rows, so
1719    /// the sample would be most of the column anyway, and the systematic sampling
1720    /// `spec/06-compression.md` section 6.3 asks for is a decision about a page and belongs to
1721    /// whoever is holding one.
1722    ///
1723    /// It declines unless the codes are at most half the bytes the strings are. FSST gets about that
1724    /// on text and rather less on anything already short or already random, and below that the
1725    /// decompression per row read is not bought back. A column it declines on comes back as it was.
1726    ///
1727    /// # Errors
1728    ///
1729    /// Nothing here fails today. The result is a `Result` because the checks inside [`Self::coded`]
1730    /// are worth running on what this builds rather than trusting that this built it right.
1731    pub fn compressed(self) -> Result<Self> {
1732        let Body::Flat(Data::Varlen(column)) = &self.body else {
1733            return Ok(self);
1734        };
1735        let rows: Vec<&[u8]> = (0..self.len).filter_map(|row| column.bytes(row)).collect();
1736        if rows.len() != self.len {
1737            return Ok(self);
1738        }
1739        let plain: usize = rows.iter().map(|row| row.len()).sum();
1740        let table = SymbolTable::train(&rows);
1741        let mut codes = Vec::with_capacity(plain);
1742        let mut spans = Vec::with_capacity(self.len);
1743        for row in &rows {
1744            let from = u32::try_from(codes.len()).unwrap_or(u32::MAX);
1745            table.compress(row, &mut codes);
1746            spans.push((from, u32::try_from(codes.len()).unwrap_or(u32::MAX)));
1747        }
1748        if codes.len() * FSST_PAYS_AT > plain {
1749            return Ok(self);
1750        }
1751        let coded = Self::coded(self.ty.clone(), Arc::new(codes), spans, Arc::new(table))?;
1752        Ok(coded.with_validity(self.validity.clone()))
1753    }
1754
1755    /// The same values under a wider decimal type that stores them the same way.
1756    ///
1757    /// A decimal is kept as its unscaled integer, so two decimal types with one scale and one
1758    /// storage width describe the same bits, and going from the narrower of them to the wider is a
1759    /// relabelling rather than a conversion. The binder writes three of those into
1760    /// `l_extendedprice * (1 - l_discount)`, because a product's operands are given the answer's
1761    /// width and the answer's width is eighteen while both columns are fifteen, and each one was a
1762    /// pass over six million rows that wrote back the bytes it had just read.
1763    ///
1764    /// A flat run only, and deliberately. The general cast flattens whatever it is given, so a
1765    /// dictionary column came out of a width change as a run of values, and a relabelling that kept
1766    /// the dictionary would hand the arithmetic above two columns it has to read through a code per
1767    /// row instead of two it can read end to end. That was measured and it is the worse of the two:
1768    /// on `sum(l_extendedprice * l_discount)` under the filter q6 puts on it, where the rows left
1769    /// are few and scattered and the indirection is a cache miss each, keeping the dictionary cost
1770    /// half again as much as the flattening it saved. The flat case has no such question, since
1771    /// what it hands on is exactly what the pass would have built.
1772    ///
1773    /// Only widening, because a narrower width is a range every value has to be checked against and
1774    /// checking it is the pass this exists to avoid. `None` for anything else, including a narrower
1775    /// width, a changed scale, a changed storage width and any form but the flat one.
1776    #[must_use]
1777    pub fn as_wider_decimal(&self, target: &LogicalType) -> Option<Self> {
1778        let (
1779            LogicalType::Decimal { width: from, scale: held },
1780            LogicalType::Decimal { width: into, scale },
1781        ) = (&self.ty, target)
1782        else {
1783            return None;
1784        };
1785        if held != scale || from > into || self.ty.decimal_storage() != target.decimal_storage() {
1786            return None;
1787        }
1788        // Nothing in a flat run says what its numbers mean, so the relabelling is the type and
1789        // nothing else, and the buffer underneath is shared rather than copied.
1790        if !matches!(self.body, Body::Flat(_)) {
1791            return None;
1792        }
1793        Some(Self {
1794            ty: target.clone(),
1795            len: self.len,
1796            validity: self.validity.clone(),
1797            body: self.body.clone(),
1798        })
1799    }
1800
1801    /// The same vector with a different validity.
1802    #[must_use]
1803    pub fn with_validity(mut self, validity: Validity) -> Self {
1804        self.validity = validity;
1805        self
1806    }
1807
1808    /// What kind of values these are.
1809    #[must_use]
1810    pub fn logical_type(&self) -> &LogicalType {
1811        &self.ty
1812    }
1813
1814    /// How many values there are.
1815    #[must_use]
1816    pub fn len(&self) -> usize {
1817        self.len
1818    }
1819
1820    /// Whether there are no values.
1821    #[must_use]
1822    pub fn is_empty(&self) -> bool {
1823        self.len == 0
1824    }
1825
1826    /// How many bytes of memory this vector is holding.
1827    ///
1828    /// What the memory limit charges for it. A constant and a sequence hold one value and two
1829    /// numbers however long they are, which is the point of both forms, so the number here is the
1830    /// form's cost and not the column's width times its length.
1831    ///
1832    /// A part that is behind an `Arc` counts as one holder's share of it, which is
1833    /// [`Buffer::footprint`]'s rule for a shared page applied to the other shared parts. A
1834    /// dictionary counted in full in every vector sharing it is not a conservative over count, it is
1835    /// a number with the chunk count in it: an aggregate that emits nineteen thousand chunks of
1836    /// groups out of one stable dictionary reported that dictionary nineteen thousand times and
1837    /// refused itself a budget of twenty five gigabytes while the process held one. Dividing by the
1838    /// holders makes the sum over everything sharing the part come to about the part, which is what
1839    /// the number is supposed to mean, and it errs high rather than low whenever the holders arrive
1840    /// one after another, because each of them counts what it sees at the time it asks.
1841    #[must_use]
1842    pub fn footprint(&self) -> usize {
1843        let body = match &self.body {
1844            Body::Flat(data) => data.footprint(),
1845            Body::Constant(value) => value.footprint(),
1846            Body::Sequence { .. } => 0,
1847            Body::Dictionary { codes, values, .. } => {
1848                codes.footprint() + share(values.footprint(), values)
1849            }
1850            Body::Packed { words, .. } => share(words.capacity() * size_of::<u64>(), words),
1851            Body::Views { views, arena } => {
1852                views.capacity() * size_of::<StringView>() + share(arena.footprint(), arena)
1853            }
1854            Body::ExternalText { source } => share(source.footprint(), source),
1855            Body::Coded { codes, spans, table } => {
1856                share(codes.capacity(), codes)
1857                    + spans.capacity() * size_of::<(u32, u32)>()
1858                    + share(table.footprint(), table)
1859            }
1860            Body::Runs { ends, values } => {
1861                ends.capacity() * size_of::<u32>() + share(values.footprint(), values)
1862            }
1863            // The ids are shared between every cut of one link join's output, and the source is
1864            // shared with every other column gathered off the same parent, so both are divided by
1865            // their holders for the reason the dictionary above is. A gather whose source counted in
1866            // full would report a parent table per projected column per chunk.
1867            Body::Gathered { source, rids, .. } => {
1868                share(rids.capacity() * size_of::<u32>(), rids) + share(source.footprint(), source)
1869            }
1870            Body::Nested { entries, child } => {
1871                entries.capacity() * size_of::<(u32, u32)>() + share(child.footprint(), child)
1872            }
1873            // A struct is as wide as its fields are, so this is the one body whose cost is a sum
1874            // over children rather than one number, and a struct of a hundred narrow fields costs
1875            // what the hundred columns cost.
1876            Body::Fields { children } => {
1877                children.capacity() * size_of::<Arc<Self>>()
1878                    + children.iter().map(|child| share(child.footprint(), child)).sum::<usize>()
1879            }
1880        };
1881        size_of::<Self>() + self.validity.footprint() + body
1882    }
1883
1884    /// Which of the values are not null, at this level and no deeper.
1885    ///
1886    /// This is not the same question as [`Self::is_null_at`] and the difference has already cost
1887    /// one wrong answer. A dictionary and a run length vector keep their nulls in the values they
1888    /// point at rather than in a mask of their own, so both are built with every row marked present
1889    /// here and a row whose value is null reads as valid. A caller that wants to know whether a row
1890    /// is null wants the other one. A caller that wants the mask of a flat column, to copy it or to
1891    /// count it, wants this one.
1892    #[must_use]
1893    pub fn validity(&self) -> &Validity {
1894        &self.validity
1895    }
1896
1897    /// Whether the row at `index` is null, in whichever form the vector is in.
1898    ///
1899    /// Reads through a dictionary or a run to the value it stands for, which is where those two
1900    /// forms keep their nulls, and answers from the mask for every other form. A row past the end
1901    /// is null, the same answer [`Self::value_at`] gives it.
1902    #[must_use]
1903    pub fn is_null_at(&self, index: usize) -> bool {
1904        if index >= self.len || !self.validity.is_valid(index) {
1905            return true;
1906        }
1907        match &self.body {
1908            Body::Dictionary { codes, values, .. } => match codes.get(index) {
1909                Some(&code) => values.is_null_at(code as usize),
1910                None => true,
1911            },
1912            Body::Runs { ends, values } => match run_holding(ends, index) {
1913                Some(run) => values.is_null_at(run),
1914                None => true,
1915            },
1916            // Section 8.2's lazy validity, which is this line. A gather has no mask of its own and
1917            // does not need one: the id says whether there is a row and the source says whether that
1918            // row is null, and both of those are already in memory.
1919            Body::Gathered { source, rids, offset } => match rids.get(offset + index) {
1920                Some(&NO_ROW) | None => true,
1921                Some(&rid) => source.is_null_at(rid as usize),
1922            },
1923            _ => false,
1924        }
1925    }
1926
1927    /// Whether no row in range is null, answered without reading a row.
1928    ///
1929    /// This is the cheap side of [`Self::is_null_at`] and has to follow it exactly. A dictionary and
1930    /// a run keep their nulls in the values they stand for, so both levels have to say they have
1931    /// none. Every other form answers from its own mask. A false means only that the cheap answer
1932    /// was not available, so a caller that gets one still has to ask row by row.
1933    ///
1934    /// Public because the alternative a caller has is a pass over the values, and on a dictionary
1935    /// that is the size of a Parquet column chunk's that pass is the thing it was trying to avoid.
1936    #[must_use]
1937    pub fn never_null(&self) -> bool {
1938        if self.validity.has_nulls(self.len) {
1939            return false;
1940        }
1941        match &self.body {
1942            Body::Dictionary { values, .. } | Body::Runs { values, .. } => values.never_null(),
1943            // A gather is never null when no id is the sentinel and the source holds no nulls. The
1944            // first of those is a pass over the ids rather than a constant, which is the one place
1945            // this question is not free, and it is worth paying: the ids are four bytes a row and
1946            // contiguous, and the alternative is reading through to the source once per row for the
1947            // whole vector, which is the random access this form exists to postpone.
1948            Body::Gathered { source, rids, offset } => {
1949                source.never_null()
1950                    && !rids[*offset..].iter().take(self.len).any(|&rid| rid == NO_ROW)
1951            }
1952            _ => true,
1953        }
1954    }
1955
1956    /// Which physical form this vector is in.
1957    #[must_use]
1958    pub fn form(&self) -> Form {
1959        match self.body {
1960            Body::Flat(_) => Form::Flat,
1961            Body::Constant(_) => Form::Constant,
1962            Body::Sequence { .. } => Form::Sequence,
1963            Body::Dictionary { .. } => Form::Dictionary,
1964            Body::Packed { .. } => Form::BitPacked,
1965            Body::Views { .. } => Form::StringView,
1966            Body::ExternalText { .. } => Form::StringView,
1967            Body::Coded { .. } => Form::Fsst,
1968            Body::Runs { .. } => Form::Rle,
1969            Body::Nested { .. } => Form::List,
1970            Body::Fields { .. } => Form::Struct,
1971            Body::Gathered { .. } => Form::Gathered,
1972        }
1973    }
1974
1975    /// The data, for a flat vector, and `None` for any other form.
1976    ///
1977    /// A kernel that wants a slice asks for it and takes the flat path if it gets one. A kernel
1978    /// that can do better on a constant or a dictionary checks [`Self::form`] first.
1979    #[must_use]
1980    pub fn data(&self) -> Option<&Data> {
1981        match &self.body {
1982            Body::Flat(data) => Some(data),
1983            _ => None,
1984        }
1985    }
1986
1987    /// The one value, for a constant vector, and `None` for any other form.
1988    ///
1989    /// A kernel comparing a column against a literal wants the literal once rather than 1024
1990    /// times, and [`Self::value_at`] on a constant clones it on every call because it has to be
1991    /// able to hand back a `Value` for any form. This is the accessor that lets the specialized
1992    /// path hoist the clone out of the loop.
1993    #[must_use]
1994    pub fn constant_value(&self) -> Option<&Value> {
1995        match &self.body {
1996            Body::Constant(value) => Some(value.as_ref()),
1997            _ => None,
1998        }
1999    }
2000
2001    /// The codes and the values, for a dictionary vector, and `None` for any other form.
2002    ///
2003    /// The reason a kernel needs this rather than reading the dictionary through
2004    /// [`Self::value_at`] is the entire argument for the form existing. A filter against a
2005    /// dictionary column of 1024 rows and 40 distinct values is 40 comparisons and 1024 lookups,
2006    /// not 1024 comparisons, and there is no way to write that loop without seeing the codes.
2007    ///
2008    /// Note what the validity of the returned vector means. A dictionary keeps its nulls in the
2009    /// vector it points at, and the dictionary's own validity says nothing about them, so a caller
2010    /// deciding whether row `i` is null has to ask the value vector about `codes[i]` rather than
2011    /// asking this vector about `i`. [`Self::flatten`] has the same note on it for the same
2012    /// reason, because getting this wrong is a null that survives being selected and comes out as
2013    /// a zero.
2014    #[must_use]
2015    pub fn dictionary_parts(&self) -> Option<(&[u32], &Self)> {
2016        match &self.body {
2017            Body::Dictionary { codes, values, .. } => Some((codes, values.as_ref())),
2018            _ => None,
2019        }
2020    }
2021
2022    /// The codes and the shared dictionary handle for a dictionary vector.
2023    ///
2024    /// Storage readers use the identity of this handle to prove that codes from separate pages
2025    /// belong to one table-wide dictionary. Kernels that only read values should continue to use
2026    /// [`Self::dictionary_parts`].
2027    #[must_use]
2028    pub fn shared_dictionary_parts(&self) -> Option<(&[u32], &Arc<Self>)> {
2029        match &self.body {
2030            Body::Dictionary { codes, values, .. } => Some((codes, values)),
2031            _ => None,
2032        }
2033    }
2034
2035    /// Stable codes and their shared values, when storage guarantees one code space across pages.
2036    #[must_use]
2037    pub fn stable_dictionary_parts(&self) -> Option<(&[u32], &Arc<Self>)> {
2038        match &self.body {
2039            Body::Dictionary { codes, values, stable: true } => Some((codes, values)),
2040            _ => None,
2041        }
2042    }
2043
2044    /// The run ends and the run values, for a run length vector, and `None` for any other form.
2045    ///
2046    /// The ends are exclusive and increasing, and there is exactly one value per run, so a kernel
2047    /// that wants to walk this walks the pairs and never asks which run a row is in. That is the
2048    /// whole argument for the form: an aggregate over a clustered column is one multiply per run
2049    /// instead of one add per row, and there is no way to write that loop without seeing the ends.
2050    ///
2051    /// The nulls are in the values, the way a dictionary's are, so a caller deciding whether row `i`
2052    /// is null asks the value vector about the run rather than asking this vector about `i`.
2053    #[must_use]
2054    pub fn run_parts(&self) -> Option<(&[u32], &Self)> {
2055        match &self.body {
2056            Body::Runs { ends, values } => Some((ends, values.as_ref())),
2057            _ => None,
2058        }
2059    }
2060
2061    /// Where each row's value is, for the two forms that keep their values somewhere else.
2062    ///
2063    /// A dictionary and a run length vector are the same shape seen from a kernel: a run of
2064    /// positions and a vector to read them out of. The difference is that a dictionary stores the
2065    /// positions and a run length vector works them out, and a kernel writing `values[at[row]]` does
2066    /// not care which. So every specialization written against [`Self::dictionary_parts`] covers
2067    /// both forms by asking this instead, and the day a third form with an indirection arrives it
2068    /// covers that one too without any of those kernels being reopened.
2069    ///
2070    /// The run length side costs an allocation of one position per row and a pass to fill it, which
2071    /// is the same four bytes a row a dictionary was already carrying and is paid once per kernel
2072    /// call rather than once per row. That is the price of this being one accessor rather than a
2073    /// second arm in eighteen kernels, and it is not the last word: a kernel that wants a run at a
2074    /// time reads [`Self::run_parts`] and pays nothing, which is the specialization this makes it
2075    /// possible to skip writing until a sweep says it is worth it.
2076    #[must_use]
2077    pub fn positions(&self) -> Option<(Cow<'_, [u32]>, &Self)> {
2078        match &self.body {
2079            Body::Dictionary { codes, values, .. } => Some((Cow::Borrowed(codes), values.as_ref())),
2080            Body::Runs { ends, values } => {
2081                let mut at = Vec::with_capacity(self.len);
2082                for (run, &stop) in ends.iter().enumerate() {
2083                    let run = u32::try_from(run).unwrap_or(u32::MAX);
2084                    at.resize(stop as usize, run);
2085                }
2086                Some((Cow::Owned(at), values.as_ref()))
2087            }
2088            _ => None,
2089        }
2090    }
2091
2092    /// The bits and what they mean, for a bit packed vector, and `None` for any other form.
2093    ///
2094    /// What a kernel needs to stay in code space. A comparison against a literal is the case that
2095    /// pays: `column > 900` over a column packed from a base of 40 is `code > 860`, which is the
2096    /// same shift and mask the read was going to do anyway and no unpacking at all, and a literal
2097    /// outside the packed range answers the whole vector without reading a bit of it. None of that
2098    /// can be written without seeing the width and the base.
2099    #[must_use]
2100    pub fn packed_parts(&self) -> Option<Packed<'_>> {
2101        match &self.body {
2102            Body::Packed { words, width, base, offset } => {
2103                Some(Packed { words, width: *width, base: *base, offset: *offset })
2104            }
2105            _ => None,
2106        }
2107    }
2108
2109    /// The views and the arena, for either form that stores strings, and `None` for the rest.
2110    ///
2111    /// This is to the two string forms what [`Self::positions`] is to the two forms that point
2112    /// somewhere else. A flat varchar column owns its arena and a string view column shares one, and
2113    /// a kernel reading a row wants the view and the bytes either way, so every specialization
2114    /// written against this covers both forms and neither has to be reopened when a third way of
2115    /// holding an arena arrives.
2116    ///
2117    /// The arena is whatever the long strings live in, which for a column over a page is the page,
2118    /// including the parts of it no view points at. Only the views say which bytes are a row.
2119    #[must_use]
2120    pub fn text_parts(&self) -> Option<(&[StringView], &[u8])> {
2121        match &self.body {
2122            Body::Flat(Data::Varlen(column)) => Some((column.views(), column.arena())),
2123            Body::Views { views, arena } => Some((views, arena)),
2124            _ => None,
2125        }
2126    }
2127
2128    /// The views and the arena they point into, for a vector of string views and nothing else.
2129    ///
2130    /// [`Self::text_parts`] answers the same question for a flat column too, and gives the arena as
2131    /// bytes. This gives the `Arc`, which is what a caller laying several of these end to end needs
2132    /// to see that they share one arena and can keep it rather than copying out of it.
2133    #[must_use]
2134    pub fn shared_views(&self) -> Option<(&[StringView], &Arc<Buffer<u8>>)> {
2135        match &self.body {
2136            Body::Views { views, arena } => Some((views, arena)),
2137            _ => None,
2138        }
2139    }
2140
2141    /// The codes and the table, for an FSST vector, and `None` for any other form.
2142    ///
2143    /// What a kernel needs to stay in code space. An equality filter is the case that pays, and it
2144    /// pays completely: the literal is compressed once against the same table and after that a row
2145    /// matches exactly when its code bytes match, because compressing is a function and so is
2146    /// decompressing. No row is decompressed at all. An ordering comparison cannot do that, since a
2147    /// symbol code says nothing about where its symbol sorts, so those decompress and say so.
2148    #[must_use]
2149    pub fn coded_parts(&self) -> Option<Coded<'_>> {
2150        match &self.body {
2151            Body::Coded { codes, spans, table } => Some(Coded { codes, spans, table }),
2152            _ => None,
2153        }
2154    }
2155
2156    /// The start and the step, for a sequence vector, and `None` for any other form.
2157    #[must_use]
2158    pub fn sequence_parts(&self) -> Option<(i64, i64)> {
2159        match self.body {
2160            Body::Sequence { start, step } => Some((start, step)),
2161            _ => None,
2162        }
2163    }
2164
2165    /// The positions of an `ENUM` vector, as the unsigned integers they are held in.
2166    ///
2167    /// What `enum_code` answers, and what an `ENUM` is ordered by. A flat vector hands its run over
2168    /// as it is under the new type, and any other form is flattened first, since a dictionary or a
2169    /// gather over one would read its values back out as strings.
2170    ///
2171    /// # Errors
2172    ///
2173    /// If this is not an `ENUM` vector, or a constant holds a string that is not one of the list.
2174    pub fn enum_codes(&self) -> Result<Self> {
2175        if self.ty.labels().is_none() {
2176            return Err(Error::internal(format!("enum_code over a {} vector", self.ty)));
2177        }
2178        let ty = enum_code_type(&self.ty);
2179        if let Body::Constant(value) = &self.body {
2180            return Ok(Self::constant(ty, enum_position(&self.ty, value)?, self.len));
2181        }
2182        // flatten: an enum's codes are its dictionary's codes read as integers, and a dictionary
2183        // or run form would need the same relabelling done inside it, so the one flat copy is it.
2184        let flat = self.flatten()?;
2185        Ok(Self { ty, ..flat })
2186    }
2187
2188    /// The value at `index`, as a single value.
2189    ///
2190    /// This is the slow path on purpose. It is what a result set is read out with and what a test
2191    /// asserts on, and an operator that calls it per row is an operator that has already lost the
2192    /// argument the vector interface exists to win.
2193    #[must_use]
2194    pub fn value_at(&self, index: usize) -> Value {
2195        if index >= self.len || !self.validity.is_valid(index) {
2196            return Value::Null;
2197        }
2198        match &self.body {
2199            Body::Constant(value) => value.as_ref().clone(),
2200            Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
2201            Body::Dictionary { codes, values, .. } => match codes.get(index) {
2202                Some(&code) => values.value_at(code as usize),
2203                None => Value::Null,
2204            },
2205            Body::Runs { ends, values } => match run_holding(ends, index) {
2206                Some(run) => values.value_at(run),
2207                None => Value::Null,
2208            },
2209            // The one read every other reader of this form is: follow the id, and answer null when
2210            // there is no row to follow. Written out once per reader rather than through a helper
2211            // because each of them returns a different kind of nothing.
2212            Body::Gathered { source, rids, offset } => match rids.get(offset + index) {
2213                Some(&NO_ROW) | None => Value::Null,
2214                Some(&rid) => source.value_at(rid as usize),
2215            },
2216            // One value unpacked into a run of one, so that what a packed value means is decided in
2217            // the same place a flat one is rather than in a second copy of the type mapping that
2218            // could drift from it. It allocates, which this path is allowed to do and the typed
2219            // unpack in `copied` is not, and it is the reason anything about to read a packed
2220            // column a row at a time should flatten it once instead.
2221            Body::Packed { words, width, base, offset } => {
2222                unpack(&self.ty, words, *offset, *width, *base, &[index])
2223                    .map_or(Value::Null, |data| value_from(&self.ty, &data, 0))
2224            }
2225            // The bytes are where the arena has them, and what they are read as is the logical
2226            // type's business, so this hands the row to the same reader a flat column goes through
2227            // rather than deciding here that a `BLOB` is a string.
2228            Body::Views { views, arena } => {
2229                match views.get(index).and_then(|v| v.bytes_in(arena)) {
2230                    Some(bytes) => bytes_as(&self.ty, bytes),
2231                    None => Value::Null,
2232                }
2233            }
2234            Body::ExternalText { source } => source
2235                .bytes_at(index)
2236                .ok()
2237                .flatten()
2238                .map_or(Value::Null, |bytes| bytes_as(&self.ty, bytes)),
2239            // One row decompressed on its own, which is the property the form is chosen for. It
2240            // allocates, which this path is allowed to do, and it is the reason anything about to
2241            // read a compressed column a row at a time should flatten it once instead.
2242            Body::Coded { codes, spans, table } => {
2243                match spans.get(index).and_then(|&(from, to)| {
2244                    let mut out = Vec::new();
2245                    table.decompress(codes.get(from as usize..to as usize)?, &mut out).ok()?;
2246                    Some(out)
2247                }) {
2248                    Some(bytes) => bytes_as(&self.ty, &bytes),
2249                    None => Value::Null,
2250                }
2251            }
2252            // A row's elements are read out of the child one at a time, which is the slow path this
2253            // whole function is and is why a kernel over a list column reads `list_parts` instead.
2254            // The element type comes from the child rather than from this vector's type, so a list
2255            // whose child was built narrower than the column claims still hands back what is in it.
2256            //
2257            // A map is stored in this body too, so which value comes out is decided by the logical
2258            // type rather than by the body. That is the one place the composition shows: the bytes of
2259            // a map really are the bytes of a list of two field structs, and the only thing that
2260            // remembers it is a map is the type.
2261            Body::Nested { entries, child } => match (entries.get(index), &self.ty) {
2262                (Some(&(start, len)), LogicalType::Map(key, value)) => {
2263                    let pairs = child.struct_parts().unwrap_or_default();
2264                    Value::map(
2265                        key.as_ref().clone(),
2266                        value.as_ref().clone(),
2267                        (start..start + len)
2268                            .filter_map(|at| {
2269                                let [keys, values] = pairs else { return None };
2270                                Some((keys.value_at(at as usize), values.value_at(at as usize)))
2271                            })
2272                            .collect(),
2273                    )
2274                }
2275                (Some(&(start, len)), _) => Value::List {
2276                    element: child.ty.clone(),
2277                    values: (start..start + len).map(|at| child.value_at(at as usize)).collect(),
2278                },
2279                (None, _) => Value::Null,
2280            },
2281            // One value read out of each child at the same position, which is the slow path this whole
2282            // function is and is why a kernel over a struct column reads `struct_parts` instead. The
2283            // names come from this vector's type rather than from the children, because a child is a
2284            // vector and a vector has no name, and the type is where the field order is written down.
2285            Body::Fields { children } => Value::Struct(
2286                fields_of(&self.ty)
2287                    .iter()
2288                    .zip(children)
2289                    .map(|(field, child)| (field.name.clone(), child.value_at(index)))
2290                    .collect(),
2291            ),
2292            Body::Flat(data) => value_from(&self.ty, data, index),
2293        }
2294    }
2295
2296    /// One value of this vector's type, built out of bytes the caller already holds.
2297    ///
2298    /// [`try_value_at`](Self::try_value_at) finds the bytes itself, which over a dictionary that
2299    /// keeps its payload in a file means a read. A caller that swept the values out has the bytes in
2300    /// hand already and wants nothing from here but the type.
2301    pub fn value_of(&self, bytes: &[u8]) -> Value {
2302        bytes_as(&self.ty, bytes)
2303    }
2304
2305    /// The value at `index`, preserving storage read and validation failures.
2306    pub fn try_value_at(&self, index: usize) -> Result<Value> {
2307        if index >= self.len || !self.validity.is_valid(index) {
2308            return Ok(Value::Null);
2309        }
2310        match &self.body {
2311            Body::ExternalText { source } => {
2312                Ok(source.bytes_at(index)?.map_or(Value::Null, |bytes| bytes_as(&self.ty, bytes)))
2313            }
2314            Body::Dictionary { codes, values, .. } => match codes.get(index) {
2315                Some(&code) => values.try_value_at(code as usize),
2316                None => Ok(Value::Null),
2317            },
2318            Body::Runs { ends, values } => match run_holding(ends, index) {
2319                Some(run) => values.try_value_at(run),
2320                None => Ok(Value::Null),
2321            },
2322            Body::Nested { entries, child } => match (entries.get(index), &self.ty) {
2323                (Some(&(start, len)), LogicalType::Map(key, value)) => {
2324                    let pairs = child.struct_parts().unwrap_or_default();
2325                    let [keys, values] = pairs else { return Ok(Value::Null) };
2326                    let mut entries = Vec::with_capacity(len as usize);
2327                    for at in start..start + len {
2328                        entries.push((
2329                            keys.try_value_at(at as usize)?,
2330                            values.try_value_at(at as usize)?,
2331                        ));
2332                    }
2333                    Ok(Value::map(key.as_ref().clone(), value.as_ref().clone(), entries))
2334                }
2335                (Some(&(start, len)), _) => {
2336                    let mut values = Vec::with_capacity(len as usize);
2337                    for at in start..start + len {
2338                        values.push(child.try_value_at(at as usize)?);
2339                    }
2340                    Ok(Value::List { element: child.ty.clone(), values })
2341                }
2342                (None, _) => Ok(Value::Null),
2343            },
2344            Body::Fields { children } => {
2345                let mut values = Vec::with_capacity(children.len());
2346                for (field, child) in fields_of(&self.ty).iter().zip(children) {
2347                    values.push((field.name.clone(), child.try_value_at(index)?));
2348                }
2349                Ok(Value::Struct(values))
2350            }
2351            _ => Ok(self.value_at(index)),
2352        }
2353    }
2354
2355    /// The text at `index`, borrowed rather than copied.
2356    ///
2357    /// [`Self::value_at`] on a `VARCHAR` column allocates a `String` per call, and a group by that
2358    /// reads a string column keys on one string per input row. This hands back the bytes where they
2359    /// already are, so a caller with somewhere to put them does not go to the allocator at all.
2360    ///
2361    /// `None` for a null, for an index past the end, for a column that is not `VARCHAR`, and for the
2362    /// constant and sequence forms, whose values are not stored per position. A caller that gets
2363    /// `None` has to fall back to [`Self::value_at`], which is correct for all of those.
2364    #[must_use]
2365    pub fn text_at(&self, index: usize) -> Option<&str> {
2366        if self.ty != LogicalType::Varchar || index >= self.len || !self.validity.is_valid(index) {
2367            return None;
2368        }
2369        match &self.body {
2370            Body::Flat(data) => data.str_at(index),
2371            Body::Dictionary { codes, values, .. } => {
2372                values.text_at(usize::try_from(*codes.get(index)?).ok()?)
2373            }
2374            Body::Runs { ends, values } => values.text_at(run_holding(ends, index)?),
2375            Body::Gathered { source, rids, offset } => {
2376                source.text_at(row_of(rids, *offset, index)?)
2377            }
2378            Body::Views { views, arena } => {
2379                std::str::from_utf8(views.get(index)?.bytes_in(arena)?).ok()
2380            }
2381            Body::ExternalText { source } => {
2382                std::str::from_utf8(source.bytes_at(index).ok().flatten()?).ok()
2383            }
2384            _ => None,
2385        }
2386    }
2387
2388    /// The variable length bytes at `index`, borrowed without validating or copying them.
2389    ///
2390    /// String data is validated when it enters a vector. Hashing and equality only need its bytes,
2391    /// so those kernels should not pay for UTF-8 validation again on every read.
2392    #[must_use]
2393    pub fn bytes_at(&self, index: usize) -> Option<&[u8]> {
2394        if index >= self.len || !self.validity.is_valid(index) {
2395            return None;
2396        }
2397        match &self.body {
2398            Body::Constant(value) => match value.as_ref() {
2399                Value::Varchar(text) => Some(text.as_bytes()),
2400                Value::Blob(bytes) | Value::Bit(bytes) => Some(bytes),
2401                _ => None,
2402            },
2403            Body::Dictionary { codes, values, .. } => {
2404                values.bytes_at(usize::try_from(*codes.get(index)?).ok()?)
2405            }
2406            Body::Runs { ends, values } => values.bytes_at(run_holding(ends, index)?),
2407            Body::Gathered { source, rids, offset } => {
2408                source.bytes_at(row_of(rids, *offset, index)?)
2409            }
2410            Body::Views { views, arena } => views.get(index)?.bytes_in(arena),
2411            Body::ExternalText { source } => source.bytes_at(index).ok().flatten(),
2412            Body::Flat(data) => data.bytes_at(index),
2413            // The same `None` [`Self::text_at`] gives, for the same reason. A compressed row is not
2414            // anywhere in its plain bytes, so there is nothing here to hand back a borrow of, and a
2415            // caller that gets `None` goes to `value_at` and gets the row decompressed into a value.
2416            // A list row is `None` for a nearer reason: it is not bytes at all, and a caller wanting
2417            // its elements wants [`Self::list_parts`] rather than a borrow of one row.
2418            Body::Coded { .. }
2419            | Body::Sequence { .. }
2420            | Body::Packed { .. }
2421            | Body::Nested { .. }
2422            | Body::Fields { .. } => None,
2423        }
2424    }
2425
2426    /// Variable length bytes at `index`, preserving storage read and validation failures.
2427    pub fn try_bytes_at(&self, index: usize) -> Result<Option<&[u8]>> {
2428        if index >= self.len || !self.validity.is_valid(index) {
2429            return Ok(None);
2430        }
2431        match &self.body {
2432            Body::Constant(value) => Ok(match value.as_ref() {
2433                Value::Varchar(text) => Some(text.as_bytes()),
2434                Value::Blob(bytes) | Value::Bit(bytes) => Some(bytes.as_slice()),
2435                _ => None,
2436            }),
2437            Body::Dictionary { codes, values, .. } => match codes.get(index) {
2438                Some(&code) => values.try_bytes_at(code as usize),
2439                None => Ok(None),
2440            },
2441            Body::Runs { ends, values } => match run_holding(ends, index) {
2442                Some(run) => values.try_bytes_at(run),
2443                None => Ok(None),
2444            },
2445            Body::Gathered { source, rids, offset } => match row_of(rids, *offset, index) {
2446                Some(row) => source.try_bytes_at(row),
2447                None => Ok(None),
2448            },
2449            Body::Views { views, arena } => {
2450                Ok(views.get(index).and_then(|view| view.bytes_in(arena)))
2451            }
2452            Body::ExternalText { source } => source.bytes_at(index),
2453            Body::Flat(data) => Ok(data.bytes_at(index)),
2454            Body::Coded { .. }
2455            | Body::Sequence { .. }
2456            | Body::Packed { .. }
2457            | Body::Nested { .. }
2458            | Body::Fields { .. } => Ok(None),
2459        }
2460    }
2461
2462    /// Walks the values from `first` up to at most `limit`, without keeping what it read.
2463    ///
2464    /// [`TextSource::sweep`] is what this is for and what the doc on it explains. Everything else
2465    /// here is the honest fallback: a vector that is not reading text out of a file has its values
2466    /// already, so there is nothing to avoid keeping, and it hands over one value and lets the
2467    /// caller come back. The answer is one past the last value visited either way, so the loop that
2468    /// calls this is the same loop whichever form it got.
2469    ///
2470    /// Nulls go the slow way. A source that reads a file holds no validity of its own, so the
2471    /// vector's own mask is the only thing that knows, and rather than teach the sweep about it the
2472    /// one form that can have both hands over a value at a time through the reader that checks.
2473    ///
2474    /// # Errors
2475    ///
2476    /// Whatever reading a value raises, and whatever `body` raises.
2477    pub fn sweep_text(
2478        &self,
2479        first: usize,
2480        limit: usize,
2481        body: &mut dyn FnMut(usize, &[u8]) -> Result<()>,
2482    ) -> Result<usize> {
2483        let limit = limit.min(self.len);
2484        if first >= limit {
2485            return Ok(first);
2486        }
2487        if let Body::ExternalText { source } = &self.body
2488            && matches!(self.validity, Validity::AllValid)
2489        {
2490            return source.sweep(first, limit, body);
2491        }
2492        body(first, self.try_bytes_at(first)?.unwrap_or_default())?;
2493        Ok(first + 1)
2494    }
2495
2496    /// A conservative substring test for the payload block holding `first`.
2497    ///
2498    /// Only a file-backed string source with all-valid values can skip a whole block. Every other
2499    /// form returns true and lets the ordinary sweep decide its values.
2500    pub fn text_block_might_contain(&self, first: usize, literal: &[u8]) -> Result<bool> {
2501        match &self.body {
2502            Body::ExternalText { source } if matches!(self.validity, Validity::AllValid) => {
2503                source.might_contain(first, literal)
2504            }
2505            _ => Ok(true),
2506        }
2507    }
2508
2509    /// The values at `indices`, which rise, without keeping what reading them decoded.
2510    ///
2511    /// [`TextSource::visit`] is what this is for. A vector that is not reading text out of a file, or
2512    /// that has nulls of its own, reads a value at a time through the reader that checks.
2513    ///
2514    /// # Errors
2515    ///
2516    /// Whatever reading a value raises.
2517    pub fn try_values_visited(&self, indices: &[usize]) -> Result<Vec<Value>> {
2518        if let Body::ExternalText { source } = &self.body
2519            && matches!(self.validity, Validity::AllValid)
2520        {
2521            let mut out = vec![Value::Null; indices.len()];
2522            let mut own = |at: usize, bytes: &[u8]| {
2523                if indices[at] < self.len {
2524                    out[at] = bytes_as(&self.ty, bytes);
2525                }
2526                Ok(())
2527            };
2528            source.visit(indices, &mut own)?;
2529            return Ok(out);
2530        }
2531        indices.iter().map(|&index| self.try_value_at(index)).collect()
2532    }
2533
2534    /// Variable length byte count at `index`, preserving storage failures.
2535    pub fn try_bytes_len_at(&self, index: usize) -> Result<Option<usize>> {
2536        if index >= self.len || !self.validity.is_valid(index) {
2537            return Ok(None);
2538        }
2539        match &self.body {
2540            Body::Dictionary { codes, values, .. } => match codes.get(index) {
2541                Some(&code) => values.try_bytes_len_at(code as usize),
2542                None => Ok(None),
2543            },
2544            Body::Runs { ends, values } => match run_holding(ends, index) {
2545                Some(run) => values.try_bytes_len_at(run),
2546                None => Ok(None),
2547            },
2548            Body::ExternalText { source } => source.bytes_len_at(index),
2549            _ => Ok(self.bytes_at(index).map(<[u8]>::len)),
2550        }
2551    }
2552
2553    /// The byte length of every row, in one call to whatever holds the text, when that is possible.
2554    ///
2555    /// `into` is cleared and given one length per row. The answer is whether it was: a vector with
2556    /// nulls in it,
2557    /// or one whose text is not read from a [`TextSource`], answers `false` and leaves the caller to
2558    /// ask a row at a time through [`Self::try_bytes_len_at`], which is right for every shape. The
2559    /// two shapes taken here are the two a scan of a stored string column hands out, the text itself
2560    /// and a dictionary of codes over it, and each is one call to the source for the whole vector
2561    /// rather than a call per row down through this type.
2562    ///
2563    /// # Errors
2564    ///
2565    /// Whatever reading the lengths out of storage raises.
2566    pub fn try_bytes_lens(&self, into: &mut Vec<i64>) -> Result<bool> {
2567        self.lens_through(into, false, |source, indices, into| source.bytes_lens_at(indices, into))
2568    }
2569
2570    /// The character length of every row, in one call to whatever holds the text, when that is
2571    /// possible.
2572    ///
2573    /// The same shapes as [`Self::try_bytes_lens`], counting characters rather than bytes, which is
2574    /// `length` where that one is `strlen`. It goes through [`TextSource::chars_lens_at`] so that a
2575    /// source reading its text out of a file can keep the counts rather than the text, which is the
2576    /// difference between a scan of `length` over a stored column holding four bytes a distinct
2577    /// value and holding every distinct value decoded.
2578    ///
2579    /// Unlike that one it answers a vector with nulls too, and a null row gets the count of
2580    /// whatever its slot points at, so the caller masks the nulls itself. Declining a vector with
2581    /// nulls sent `length` a row at a time through the bytes, which on a stored column is the path
2582    /// that keeps every block it reads, so one null in a vector was enough to bring that back.
2583    ///
2584    /// # Errors
2585    ///
2586    /// Whatever reading the text out of storage raises.
2587    pub fn try_chars_lens(&self, into: &mut Vec<i64>) -> Result<bool> {
2588        self.lens_through(into, true, |source, indices, into| source.chars_lens_at(indices, into))
2589    }
2590
2591    /// One call to `ask` for every row, over the source this vector reads its text from.
2592    ///
2593    /// `false` for a vector whose text does not come from a [`TextSource`], and for a vector with
2594    /// nulls unless `nulls` says the caller will mask them, for the reasons
2595    /// [`Self::try_bytes_lens`] gives.
2596    fn lens_through(
2597        &self,
2598        into: &mut Vec<i64>,
2599        nulls: bool,
2600        ask: impl Fn(&dyn TextSource, &[u32], &mut Vec<i64>) -> Result<()>,
2601    ) -> Result<bool> {
2602        if !nulls && !matches!(self.validity, Validity::AllValid) {
2603            return Ok(false);
2604        }
2605        into.clear();
2606        match &self.body {
2607            Body::ExternalText { source } => {
2608                let Ok(rows) = u32::try_from(self.len) else { return Ok(false) };
2609                let indices = (0..rows).collect::<Vec<_>>();
2610                ask(source.as_ref(), &indices, into)?;
2611                Ok(true)
2612            }
2613            Body::Dictionary { codes, values, .. } => match &values.body {
2614                Body::ExternalText { source } if matches!(values.validity, Validity::AllValid) => {
2615                    let Some(codes) = codes.get(..self.len) else { return Ok(false) };
2616                    ask(source.as_ref(), codes, into)?;
2617                    Ok(true)
2618                }
2619                _ => Ok(false),
2620            },
2621            _ => Ok(false),
2622        }
2623    }
2624
2625    /// Hands `body` the bytes of every row that is not null, when the text is read from a
2626    /// [`TextSource`], and answers whether it did.
2627    ///
2628    /// The rows come in whatever order the source reads them in, each with its row number, so a
2629    /// caller that writes an answer per row has to put it back in row order itself. That is the
2630    /// price of the source seeing the whole vector at once, which is what lets one that decodes its
2631    /// text a block at a time decode each block once for the call rather than keep every block a
2632    /// row lands in. See [`TextSource::visit_at`]. The shapes taken are the two a scan of a stored
2633    /// string column hands out, the text itself and a dictionary of codes over it, and anything
2634    /// else answers `false` and is read a row at a time through [`Self::try_bytes_at`], which is
2635    /// right for every shape.
2636    ///
2637    /// # Errors
2638    ///
2639    /// Whatever reading the text out of storage raises, and whatever `body` raises.
2640    pub fn try_visit_text(&self, body: &mut dyn FnMut(usize, &[u8]) -> Result<()>) -> Result<bool> {
2641        let (source, codes) = match &self.body {
2642            Body::ExternalText { source } => (source, None),
2643            Body::Dictionary { codes, values, .. } => match &values.body {
2644                Body::ExternalText { source } if matches!(values.validity, Validity::AllValid) => {
2645                    let Some(codes) = codes.get(..self.len) else { return Ok(false) };
2646                    (source, Some(codes))
2647                }
2648                _ => return Ok(false),
2649            },
2650            _ => return Ok(false),
2651        };
2652        let Ok(len) = u32::try_from(self.len) else { return Ok(false) };
2653        // The rows asked for, which are all of them unless some are null. A null row is left out
2654        // rather than read, because a row at a time read answers it with no value at all.
2655        let rows: Option<Vec<u32>> = match &self.validity {
2656            Validity::AllValid => None,
2657            Validity::AllInvalid => return Ok(true),
2658            Validity::Mask(mask) => Some((0..len).filter(|&row| mask.get(row as usize)).collect()),
2659        };
2660        let indices = match (codes, &rows) {
2661            (Some(codes), None) => Cow::Borrowed(codes),
2662            (Some(codes), Some(rows)) => rows.iter().map(|&row| codes[row as usize]).collect(),
2663            (None, None) => (0..len).collect(),
2664            (None, Some(rows)) => Cow::Borrowed(rows.as_slice()),
2665        };
2666        source.visit_at(&indices, &mut |at, bytes| {
2667            let row = rows.as_ref().map_or(at, |rows| rows[at] as usize);
2668            body(row, bytes)
2669        })?;
2670        Ok(true)
2671    }
2672
2673    /// How many ranks this vector's values have in sorted order, when whatever holds them knows.
2674    ///
2675    /// See [`TextSource::ranks`] for what a rank is and what a source promises by answering with
2676    /// one. Only a vector whose values come from storage can answer, because only storage is in a
2677    /// position to have sorted them once and written the answer down.
2678    #[must_use]
2679    pub fn ranks(&self) -> Option<usize> {
2680        match &self.body {
2681            Body::ExternalText { source } => source.ranks(),
2682            _ => None,
2683        }
2684    }
2685
2686    /// How the value at `rank` compares against `wanted`. See [`TextSource::compare_rank`].
2687    pub fn compare_rank(&self, rank: usize, wanted: &[u8]) -> Result<Ordering> {
2688        match &self.body {
2689            Body::ExternalText { source } => source.compare_rank(rank, wanted),
2690            _ => {
2691                Err(Error::internal("a vector without a sorted order was asked to compare a rank"))
2692            }
2693        }
2694    }
2695
2696    /// Where `wanted` would go in the sorted order. See [`TextSource::below`].
2697    ///
2698    /// # Errors
2699    ///
2700    /// If this vector has no sorted order, or if a probe of it fails.
2701    pub fn below(&self, ranks: usize, wanted: &[u8]) -> Result<(usize, bool)> {
2702        match &self.body {
2703            Body::ExternalText { source } => source.below(ranks, wanted),
2704            _ => Err(Error::internal("a vector without a sorted order was asked for a boundary")),
2705        }
2706    }
2707
2708    /// The position of the value at `rank`. See [`TextSource::code_at_rank`].
2709    pub fn code_at_rank(&self, rank: usize) -> Result<u32> {
2710        match &self.body {
2711            Body::ExternalText { source } => source.code_at_rank(rank),
2712            _ => Err(Error::internal("a vector without a sorted order was asked for a rank")),
2713        }
2714    }
2715
2716    /// The rank of every value, indexed by position. See [`TextSource::code_ranks`].
2717    #[must_use]
2718    pub fn code_ranks(&self) -> Option<&[u32]> {
2719        match &self.body {
2720            Body::ExternalText { source } => source.code_ranks(),
2721            _ => None,
2722        }
2723    }
2724
2725    /// Text at `index`, preserving storage read, validation and UTF-8 failures.
2726    pub fn try_text_at(&self, index: usize) -> Result<Option<&str>> {
2727        if self.ty != LogicalType::Varchar {
2728            return Ok(None);
2729        }
2730        self.try_bytes_at(index)?
2731            .map(|bytes| {
2732                std::str::from_utf8(bytes).map_err(|error| {
2733                    Error::conversion(format!("invalid UTF-8 in VARCHAR: {error}"))
2734                })
2735            })
2736            .transpose()
2737    }
2738
2739    /// Read every storage-backed value reachable through this vector.
2740    pub fn validate_external(&self) -> Result<()> {
2741        match &self.body {
2742            Body::ExternalText { source } => {
2743                for index in 0..source.len() {
2744                    source.bytes_at(index)?;
2745                }
2746            }
2747            Body::Dictionary { codes, values, .. } => {
2748                if values.reaches_storage() {
2749                    for &code in codes.iter() {
2750                        values.try_bytes_at(code as usize)?;
2751                    }
2752                }
2753            }
2754            Body::Runs { values, .. } | Body::Gathered { source: values, .. } => {
2755                values.validate_external()?;
2756            }
2757            Body::Nested { child, .. } => child.validate_external()?,
2758            Body::Fields { children } => {
2759                for child in children {
2760                    child.validate_external()?;
2761                }
2762            }
2763            _ => {}
2764        }
2765        Ok(())
2766    }
2767
2768    /// Whether any value of this vector is read from storage when it is asked for.
2769    ///
2770    /// A dictionary over values already in memory has nothing that can fail to read, and checking
2771    /// it a code at a time cost the thread that drains a query about a fifth of a sorted table
2772    /// copy for no answer at all.
2773    fn reaches_storage(&self) -> bool {
2774        match &self.body {
2775            Body::ExternalText { .. } => true,
2776            Body::Dictionary { values, .. }
2777            | Body::Runs { values, .. }
2778            | Body::Gathered { source: values, .. } => values.reaches_storage(),
2779            Body::Nested { child, .. } => child.reaches_storage(),
2780            Body::Fields { children } => children.iter().any(|child| child.reaches_storage()),
2781            _ => false,
2782        }
2783    }
2784
2785    /// The signed integer at `index`, widened, read without building a [`Value`].
2786    ///
2787    /// The integer sibling of [`Self::bytes_at`], and it is here for the same caller. A group by on
2788    /// an integer column compares one key per input row against the group it probed, and doing that
2789    /// through [`Self::value_at`] built and dropped a sixty four byte value a row at a time for a
2790    /// number that was already sitting in the column.
2791    ///
2792    /// Widened to `i128` because that is what [`Data::signed_at`] hands back underneath, and one
2793    /// method that covers every signed width is worth more than five that do not. A caller that
2794    /// wants a narrower type narrows it, which is a range check against a value in a register.
2795    ///
2796    /// The types this answers for are the ones whose flat data is read through `signed_at`, so the
2797    /// five signed integer widths and the decimal, date, time and timestamp types that are stored
2798    /// in them. A decimal answers with its unscaled value, which is the number the column holds.
2799    ///
2800    /// `None` for a null, for an index past the end, for a column of any other type, and for the
2801    /// compressed form. Packed integers stay in code space and answer `base + code` directly. A
2802    /// caller that gets `None` falls back to [`Self::value_at`], which is correct for the remaining
2803    /// forms.
2804    #[must_use]
2805    pub fn signed_at(&self, index: usize) -> Option<i128> {
2806        if index >= self.len || !self.validity.is_valid(index) {
2807            return None;
2808        }
2809        match &self.body {
2810            Body::Flat(data) => data.signed_at(index),
2811            Body::Constant(value) => match value.as_ref() {
2812                Value::TinyInt(x) => Some(i128::from(*x)),
2813                Value::SmallInt(x) => Some(i128::from(*x)),
2814                Value::Integer(x) | Value::Date(x) => Some(i128::from(*x)),
2815                Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => Some(i128::from(*x)),
2816                Value::HugeInt(x) | Value::Decimal { unscaled: x, .. } => Some(*x),
2817                _ => None,
2818            },
2819            // The same arithmetic [`Self::value_at`] does on a sequence, so the two agree about a
2820            // sequence that runs off the end of the width it is stored in.
2821            Body::Sequence { start, step } => {
2822                Some(i128::from(start.wrapping_add(step.wrapping_mul(index as i64))))
2823            }
2824            Body::Dictionary { codes, values, .. } => {
2825                values.signed_at(usize::try_from(*codes.get(index)?).ok()?)
2826            }
2827            Body::Runs { ends, values } => values.signed_at(run_holding(ends, index)?),
2828            Body::Gathered { source, rids, offset } => {
2829                source.signed_at(row_of(rids, *offset, index)?)
2830            }
2831            Body::Packed { words, width, base, offset } => Some(
2832                *base + i128::from(code_at(words, (*offset + index) * *width as usize, *width)),
2833            ),
2834            // The same `None` [`Self::bytes_at`] gives, for the same reason. A compressed row is not
2835            // an integer anywhere until it has been unpacked, and a caller that gets
2836            // `None` goes to `value_at` and gets the row unpacked into a value. A list row is not an
2837            // integer in any form, however many integers are in it, and a struct row is not one even
2838            // when it has exactly one integer field, since the row is the struct and not the field.
2839            Body::Coded { .. }
2840            | Body::Views { .. }
2841            | Body::ExternalText { .. }
2842            | Body::Nested { .. }
2843            | Body::Fields { .. } => None,
2844        }
2845    }
2846
2847    /// The rows `at` names, read as signed integers, widened and written into `out`.
2848    ///
2849    /// The gathered form of [`Self::signed_block`] for a flat vector, which is what a filter's
2850    /// selection over a flat integer column wants. `false`, with `out` cleared, for every other
2851    /// form and for a row past the end, and the caller then goes the way it went before.
2852    #[must_use]
2853    pub fn signed_gather(&self, at: &[u32], out: &mut Vec<i64>) -> bool {
2854        out.clear();
2855        match &self.body {
2856            Body::Flat(data) => data.signed_gather(self.len, at, out),
2857            _ => false,
2858        }
2859    }
2860
2861    /// The runs of equal values among rows `from..to`, each as its value widened to `i64` and the
2862    /// row it ends before, written into `out`.
2863    ///
2864    /// For a flat signed integer vector, the form a sorted key column is in under a filter's
2865    /// selection. `false`, with `out` cleared, for every other form, and once the runs come more
2866    /// often than one in every `every` rows. See [`Data::signed_runs`].
2867    #[must_use]
2868    pub fn signed_runs(
2869        &self,
2870        (from, to): (usize, usize),
2871        every: usize,
2872        out: &mut Vec<(i64, usize)>,
2873    ) -> bool {
2874        out.clear();
2875        match &self.body {
2876            Body::Flat(data) => data.signed_runs(self.len, (from, to), every, out),
2877            _ => false,
2878        }
2879    }
2880
2881    /// Every signed value in order, widened to `i64`, written into `out`.
2882    ///
2883    /// The bulk form of [`Self::signed_at`], for a caller that is going to read the whole vector
2884    /// anyway. A group by on two integer columns called `signed_at` once per column per row, and
2885    /// every one of those matched on the body, called into the data and matched again on the
2886    /// layout, which is about sixty five instructions to read a number that was already sitting in
2887    /// a slice. It was a fifth of ClickBench 32 on its own.
2888    ///
2889    /// A null writes whatever the body holds under it, which is the zero a flat column keeps behind
2890    /// its mask. Nulls are a separate question and the caller asks it separately, from
2891    /// [`Self::none_null`] once for the vector when that answers and a row at a time when it does
2892    /// not.
2893    ///
2894    /// `false`, with `out` left empty, for a vector this cannot hand over as a block: `HUGEINT` and
2895    /// the wide decimals, whose values do not fit an `i64`, the string and nested forms, the
2896    /// compressed form, and the run form. A caller that gets `false` reads the vector the way it
2897    /// read it before, with [`Self::signed_at`].
2898    ///
2899    /// A dictionary is read as its entries widened once and then a gather through the codes. That
2900    /// is the form a Parquet integer column arrives in, because DuckDB writes most of them with a
2901    /// dictionary, and reading one a row at a time was 4 percent of the CPU of loading the 10m
2902    /// ClickBench file, all of it in the sieve the writer builds for each part. A dictionary whose
2903    /// entries hold a null is refused, since the row that points at one is null and the only null
2904    /// check a caller of this makes on a dictionary may be on its codes.
2905    #[must_use]
2906    pub fn signed_block(&self, out: &mut Vec<i64>) -> bool {
2907        out.clear();
2908        match &self.body {
2909            Body::Flat(data) => data.signed_block(self.len, out),
2910            Body::Constant(value) => {
2911                let held = match value.as_ref() {
2912                    Value::TinyInt(x) => i64::from(*x),
2913                    Value::SmallInt(x) => i64::from(*x),
2914                    Value::Integer(x) | Value::Date(x) => i64::from(*x),
2915                    Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => *x,
2916                    _ => return false,
2917                };
2918                out.resize(self.len, held);
2919                true
2920            }
2921            // The same arithmetic [`Self::signed_at`] does on a sequence, once per row rather than
2922            // once per call, and it wraps where that one wraps.
2923            Body::Sequence { start, step } => {
2924                out.extend(
2925                    (0..self.len).map(|index| start.wrapping_add(step.wrapping_mul(index as i64))),
2926                );
2927                true
2928            }
2929            // Sixty four codes at a time through [`Packed::unpack`], with the blocks lined up on the
2930            // words so that every one after the first is the constant width loop rather than a
2931            // code at a time. A code at a time was about twenty instructions a row, and q21 reads
2932            // two packed columns of lineitem through here for every line of the orders it keeps.
2933            Body::Packed { words, width, base, offset } => match i64::try_from(*base) {
2934                Ok(base) => {
2935                    let packed =
2936                        Packed { words, width: *width, base: i128::from(base), offset: *offset };
2937                    let mut block = [0u64; 64];
2938                    let mut from = 0;
2939                    out.reserve(self.len);
2940                    while from < self.len {
2941                        let rows = (64 - (*offset + from) % 64).min(self.len - from);
2942                        let codes = &mut block[..rows];
2943                        packed.unpack(from, codes);
2944                        out.extend(codes.iter().map(|&code| base.wrapping_add(code as i64)));
2945                        from += rows;
2946                    }
2947                    true
2948                }
2949                Err(_) => false,
2950            },
2951            Body::Dictionary { codes, values, .. } => {
2952                // A selection over row numbers is a dictionary over a sequence as long as the part
2953                // it came from, and working each code out is cheaper than laying all of those out.
2954                if let Some((start, step)) = values.sequence_parts() {
2955                    let Some(codes) = codes.get(..self.len) else {
2956                        return false;
2957                    };
2958                    if codes.iter().any(|&code| code as usize >= values.len()) {
2959                        return false;
2960                    }
2961                    out.extend(
2962                        codes
2963                            .iter()
2964                            .map(|&code| start.wrapping_add(step.wrapping_mul(i64::from(code)))),
2965                    );
2966                    return true;
2967                }
2968                let mut entries = Vec::new();
2969                if !values.none_null() || !values.signed_block(&mut entries) {
2970                    return false;
2971                }
2972                let Some(codes) = codes.get(..self.len) else {
2973                    return false;
2974                };
2975                out.reserve(codes.len());
2976                for &code in codes {
2977                    match entries.get(code as usize) {
2978                        Some(&entry) => out.push(entry),
2979                        None => {
2980                            out.clear();
2981                            return false;
2982                        }
2983                    }
2984                }
2985                true
2986            }
2987            Body::Runs { .. }
2988            | Body::Gathered { .. }
2989            | Body::Coded { .. }
2990            | Body::Views { .. }
2991            | Body::ExternalText { .. }
2992            | Body::Nested { .. }
2993            | Body::Fields { .. } => false,
2994        }
2995    }
2996
2997    /// Whether the vector holds no nulls at all, asked once rather than a row at a time.
2998    ///
2999    /// The bulk form of [`Self::is_null_at`], and it answers the same question that one does, so a
3000    /// dictionary and a run are read through to the values behind them where those two keep their
3001    /// nulls. A dictionary that holds a null no code points at answers `false` here and `false` at
3002    /// every row, which is the safe direction and is the only place the two can differ.
3003    ///
3004    /// A caller that gets `false` goes back to asking a row at a time.
3005    #[must_use]
3006    pub fn none_null(&self) -> bool {
3007        if self.validity.has_nulls(self.len) {
3008            return false;
3009        }
3010        match &self.body {
3011            Body::Dictionary { values, .. } | Body::Runs { values, .. } => values.none_null(),
3012            Body::Gathered { source, rids, offset } => {
3013                source.none_null()
3014                    && !rids[*offset..].iter().take(self.len).any(|&rid| rid == NO_ROW)
3015            }
3016            _ => true,
3017        }
3018    }
3019
3020    /// Every value in order, as single values.
3021    pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
3022        (0..self.len).map(|index| self.value_at(index))
3023    }
3024
3025    /// This vector with its payload held as a page, so that copying or cutting it is free.
3026    ///
3027    /// For a producer that means to hand the same values out many times, which is what a stored
3028    /// column is. A flat body, a dictionary and a string body are the forms this changes, because
3029    /// each owns a run a copy would have to copy: the values of a flat body, the codes of a
3030    /// dictionary and the arena of a string body. The rest come back as they were, because a packed
3031    /// body shares its words, an FSST body shares its codes and its table, and a constant and a
3032    /// sequence have nothing to share.
3033    ///
3034    /// The string body is the one worth spelling out, because an `Arc` around the arena looks like
3035    /// sharing and is not the sharing that matters. Every reader that wants a run of an arena
3036    /// without copying the bytes asks [`Buffer::is_shared`], which is a question about the store
3037    /// inside the `Arc` and not about the `Arc`: an owned store clones by copying every byte and a
3038    /// page clones by taking a handle. So an arena that was built rather than read stays a thing
3039    /// each reader copies out of until somebody calls this, however many `Arc`s point at it. The
3040    /// reader this is for is [`Self::gather`] over a parent column, which without it copies the
3041    /// bytes of every gathered string once per chunk.
3042    ///
3043    /// Only when the arena is this vector's alone, which is the case a producer that has just built
3044    /// one is in. An arena with another holder is left as it is, because turning it into a page
3045    /// behind their back would mean copying it, which is the cost this exists to avoid.
3046    ///
3047    /// Not recursive into a nested column's children, because a `LIST` or a `STRUCT` holds its
3048    /// children behind an `Arc` already.
3049    #[must_use]
3050    pub fn into_pages(self) -> Self {
3051        let body = match self.body {
3052            Body::Flat(data) => Body::Flat(data.into_pages()),
3053            Body::Dictionary { codes, values, stable } => {
3054                Body::Dictionary { codes: codes.into_page(), values, stable }
3055            }
3056            Body::Views { views, arena } => Body::Views { views, arena: paged(arena) },
3057            other => other,
3058        };
3059        Self { body, ..self }
3060    }
3061
3062    /// A contiguous run of the values, in the form they are already in.
3063    ///
3064    /// This is the cut [`Self::gather`] cannot do. A gather walks a dictionary to its leaf and
3065    /// copies, so gathering a piece of a dictionary encoded column hands back a flat one, and a
3066    /// caller that only wanted the first thousand rows of a page has silently paid for a copy and
3067    /// thrown the dictionary away. A group by over a dictionary encoded column is the case that
3068    /// cares, and it is most of ClickBench.
3069    ///
3070    /// So each form is cut as itself. A dictionary keeps its dictionary and slices its codes, a
3071    /// sequence stays arithmetic with its start moved along, a constant stays a shorter constant,
3072    /// and a flat body is a window into its page when it has one and a copy of its range when it
3073    /// does not, which [`Self::into_pages`] is how a producer decides.
3074    ///
3075    /// The dictionary itself is shared rather than copied, so a cut is the codes and nothing else.
3076    /// It used to be copied, and on a read of a ClickBench partition that copy was ten percent of
3077    /// the cycles: a page holds one dictionary and is cut into chunk sized pieces, so the whole
3078    /// dictionary was copied once per chunk to be read the same way each time.
3079    ///
3080    /// # Errors
3081    ///
3082    /// If the range runs past the end of the vector, or if the type has no flat layout and the
3083    /// body is one that has to be copied.
3084    pub fn slice(&self, at: usize, len: usize) -> Result<Self> {
3085        let end = at.checked_add(len).ok_or_else(|| Error::internal("a slice that wraps"))?;
3086        if end > self.len {
3087            return Err(Error::internal(format!("rows {at} to {end} of a vector of {}", self.len)));
3088        }
3089        if at == 0 && len == self.len {
3090            return Ok(self.clone());
3091        }
3092        let validity = self.validity.slice(at, len);
3093        let body = match &self.body {
3094            Body::Constant(value) => Body::Constant(value.clone()),
3095            Body::Sequence { start, step } => {
3096                Body::Sequence { start: start + step * at as i64, step: *step }
3097            }
3098            Body::Dictionary { codes, values, stable } => Body::Dictionary {
3099                codes: codes.slice(at, len),
3100                values: Arc::clone(values),
3101                stable: *stable,
3102            },
3103            // The same cut [`Body::Packed`] below takes and for the same reason, and here it is free
3104            // rather than merely cheap: a link join fills one buffer of parent rows per child chunk
3105            // and the pipeline cuts it, so moving the starting row is what keeps the ids from being
3106            // copied once per cut. Both ends of the gather stay shared, the ids and the source.
3107            Body::Gathered { source, rids, offset } => Body::Gathered {
3108                source: Arc::clone(source),
3109                rids: Arc::clone(rids),
3110                offset: offset + at,
3111            },
3112            // The bits are not byte aligned, so a cut either repacks them or moves the row the
3113            // reading starts at. Moving it is one addition and repacking is a pass, and a page is
3114            // cut into chunk sized pieces often enough that the difference is the form.
3115            Body::Packed { words, width, base, offset } => Body::Packed {
3116                words: Arc::clone(words),
3117                width: *width,
3118                base: *base,
3119                offset: offset + at,
3120            },
3121            // The cut a flat string column cannot do. Sixteen bytes a row move and the payload stays
3122            // where the page put it, so taking a chunk out of a column of long strings costs the
3123            // same as taking one out of a column of integers. A flat varchar body copies every byte
3124            // of every long string in the range instead, which is the measurement written down in
3125            // `Chunk::compact`: compaction loses on a varchar column, and this is the half of the
3126            // reason that is about cutting rather than about selecting.
3127            Body::Views { views, arena } => {
3128                Body::Views { views: views[at..end].to_vec(), arena: Arc::clone(arena) }
3129            }
3130            // The spans are absolute positions in the shared codes, so a cut is a run of them and
3131            // nothing has to be rebased. One page of compressed strings, one table, and as many
3132            // chunks over it as the reader wants.
3133            Body::Coded { codes, spans, table } => Body::Coded {
3134                codes: Arc::clone(codes),
3135                spans: spans[at..end].to_vec(),
3136                table: Arc::clone(table),
3137            },
3138            // Only the runs the range touches survive, the first and last of them cut back to where
3139            // the range starts and stops, and every end moved to be relative to the new row zero. A
3140            // cut of a hundred rows out of a column of a hundred million is a handful of runs, which
3141            // is the reason this form is worth cutting as itself rather than copying out.
3142            Body::Runs { ends, values } if len > 0 => {
3143                let first = run_holding(ends, at).unwrap_or(0);
3144                let last = run_holding(ends, end - 1).unwrap_or(first);
3145                let cut: Vec<u32> = ends[first..=last]
3146                    .iter()
3147                    .map(|&stop| stop.min(end as u32) - at as u32)
3148                    .collect();
3149                let values = values.slice(first, last - first + 1)?;
3150                Body::Runs { ends: cut, values: Arc::new(values) }
3151            }
3152            // An empty cut has no run to point at and an empty run length body would be a vector of
3153            // no runs claiming a length, so it comes back as the empty flat vector instead.
3154            Body::Runs { .. } => return self.gather(&[]),
3155            // The entries are absolute positions in the shared child, so a cut is a run of them and
3156            // nothing has to be rebased, the same as a cut of FSST spans. The elements outside the
3157            // range stay in the child unreferenced, which is the trade this form makes: a chunk cut
3158            // out of a page of lists moves eight bytes a row and copies no elements at all.
3159            Body::Nested { entries, child } => {
3160                Body::Nested { entries: entries[at..end].to_vec(), child: Arc::clone(child) }
3161            }
3162            // Every child cut at the same place, because a struct row is one value per field at the
3163            // same position in each and there is no entry standing between the row and the child to
3164            // rewrite instead. So this is the one nested form whose cut is not free, and what it costs
3165            // is whatever cutting each field costs, which for a field of string views is sixteen bytes
3166            // a row and for a field of packed integers is one addition.
3167            Body::Fields { children } => Body::Fields {
3168                children: children
3169                    .iter()
3170                    .map(|child| child.slice(at, len).map(Arc::new))
3171                    .collect::<Result<Vec<_>>>()?,
3172            },
3173            Body::ExternalText { source } => {
3174                let mut out = StringColumn::with_capacity(len);
3175                for index in at..end {
3176                    out.push_bytes(source.bytes_at(index)?.unwrap_or_default());
3177                }
3178                Body::Flat(Data::Varlen(out))
3179            }
3180            // The one form with nowhere to point, so its range is copied out. A run and not a
3181            // gather: this used to build a vector of the positions `at..end` and hand it to
3182            // `gather`, which then built a vector of `usize` from it, a vector of `bool` beside
3183            // that, and read the values back one bounds checked index at a time. That is five
3184            // passes and three allocations to say `memcpy`, and on a scan it was the largest thing
3185            // in the program after the aggregation itself, because every chunk of every column of
3186            // every page comes through here.
3187            Body::Flat(data) => Body::Flat(run_of(data, at, end)),
3188        };
3189        Ok(Self { ty: self.ty.clone(), len, validity, body })
3190    }
3191
3192    /// The same values in flat form.
3193    ///
3194    /// Flattening a vector that is already flat is free. Flattening any other form costs a copy,
3195    /// which is exactly why the other forms exist and why nothing on the hot path should call
3196    /// this. It is here for the operators that genuinely cannot do better and for the tests that
3197    /// check the other forms against it.
3198    ///
3199    /// A call that copies counts itself against [`Cause::Flatten`], because a flatten on a hot path
3200    /// is the most expensive thing in this crate and the only way to find one is to have the number.
3201    /// A call on a vector that is already flat does not count, since it neither copies nor gives
3202    /// anything up.
3203    ///
3204    /// # Errors
3205    ///
3206    /// If the type is one there is no vector for yet, which today means `ARRAY` and `UNION`. A `LIST`
3207    /// and a `MAP` flatten to themselves and a `STRUCT` to a struct of flattened fields, since none of
3208    /// the three has a data slice in any form and there is nothing flatter to become.
3209    pub fn flatten(&self) -> Result<Self> {
3210        if let Body::Flat(_) = self.body {
3211            return Ok(self.clone());
3212        }
3213        slow::took(Cause::Flatten);
3214        if let Some(flat) = self.decoded_codes() {
3215            return Ok(flat);
3216        }
3217        if let Some(flat) = self.unpacked_whole() {
3218            return Ok(flat);
3219        }
3220        self.copied((0..self.len).collect(), false)
3221    }
3222
3223    /// A packed column with no nulls written out whole, a block of 64 codes at a time.
3224    ///
3225    /// The general copy builds a list of every position and then reads each code on its own, working
3226    /// out its word and whether it straddles into the next every time. Every row of the column is
3227    /// wanted in order, so [`Packed::unpack_mapped`] unpacks whole blocks with the width a constant
3228    /// and hands each code to the value it stands for as it goes. Laying out the `orders` side of
3229    /// TPC-H q9 flattens a million and a half packed dates, and the copy was a third of the layout.
3230    fn unpacked_whole(&self) -> Option<Self> {
3231        let Body::Packed { words, width, base, offset } = &self.body else {
3232            return None;
3233        };
3234        if self.validity.has_nulls(self.len) {
3235            return None;
3236        }
3237        let packed = Packed { words, width: *width, base: *base, offset: *offset };
3238        let low = i64::try_from(packed.base()).ok()?;
3239        i64::try_from(packed.ceiling()).ok()?;
3240        // The same arithmetic as [`Self::unpacked_at`]: both ends fit, so every value does.
3241        #[expect(clippy::cast_possible_wrap, reason = "a code is below the span, which fits")]
3242        let value = |code: u64| low.wrapping_add(code as i64);
3243        let rows = self.len;
3244        #[expect(clippy::cast_possible_truncation, reason = "the layout holds every value")]
3245        let data = match self.ty.physical() {
3246            rudb_common::PhysicalType::Int64 => {
3247                let mut out = Vec::with_capacity(rows);
3248                packed.unpack_mapped(0, rows, &mut out, value);
3249                Data::Int64(Buffer::from_vec(out))
3250            }
3251            rudb_common::PhysicalType::Int32 => {
3252                let mut out = Vec::with_capacity(rows);
3253                packed.unpack_mapped(0, rows, &mut out, |code| value(code) as i32);
3254                Data::Int32(Buffer::from_vec(out))
3255            }
3256            rudb_common::PhysicalType::Int16 => {
3257                let mut out = Vec::with_capacity(rows);
3258                packed.unpack_mapped(0, rows, &mut out, |code| value(code) as i16);
3259                Data::Int16(Buffer::from_vec(out))
3260            }
3261            _ => return None,
3262        };
3263        Some(Self {
3264            ty: self.ty.clone(),
3265            len: rows,
3266            validity: Validity::AllValid,
3267            body: Body::Flat(data),
3268        })
3269    }
3270
3271    /// A dictionary with no nulls over flat values with none, written out by its codes.
3272    ///
3273    /// The general copy walks the positions down through every layer and marks each one that
3274    /// lands on a null, and then builds the validity back up from those marks. With no null on
3275    /// either side the codes are already the positions and the validity is already known, so that
3276    /// is one pass over the codes rather than four. A Parquet column that was dictionary encoded
3277    /// comes in as this form, and flattening columns on the way to the file was four percent of a
3278    /// ClickBench load.
3279    fn decoded_codes(&self) -> Option<Self> {
3280        let Body::Dictionary { codes, values, .. } = &self.body else {
3281            return None;
3282        };
3283        if !matches!(self.validity, Validity::AllValid)
3284            || !matches!(values.validity, Validity::AllValid)
3285        {
3286            return None;
3287        }
3288        let Body::Flat(data) = &values.body else {
3289            return None;
3290        };
3291        if matches!(data, Data::Empty) {
3292            return None;
3293        }
3294        let codes = codes.as_slice().get(..self.len)?;
3295        if !below(codes, values.len) {
3296            return None;
3297        }
3298        let at = codes.iter().map(|&code| code as usize).collect::<Vec<_>>();
3299        Some(Self {
3300            ty: self.ty.clone(),
3301            len: self.len,
3302            validity: Validity::AllValid,
3303            body: Body::Flat(copy_of(data, &at)),
3304        })
3305    }
3306
3307    /// The same values in flat form, taking the vector rather than borrowing it.
3308    ///
3309    /// A vector that is already flat comes back as itself, which is the whole reason this exists
3310    /// beside [`Self::flatten`]. Flattening through a borrow has to clone that vector, and a clone
3311    /// of a flat vector that owns its values copies every one of them to produce a vector that is
3312    /// identical to the one it was handed. Anything not already flat goes the same way it does
3313    /// through [`Self::flatten`], since the copy is real work there rather than work for nothing.
3314    ///
3315    /// # Errors
3316    ///
3317    /// The same values flat, for a kernel that has a loop over runs and was handed a form it has
3318    /// no way to index into.
3319    ///
3320    /// This is [`Self::flatten`] without the count against [`Cause::Flatten`], and the difference
3321    /// is who is calling. A flatten is counted because it is usually a shortcut past a loop nobody
3322    /// wrote. This is for the caller that has the loop and whose alternative is a `Value` per row,
3323    /// which costs a good deal more than the copy. ClickBench q40 adds three `SMALLINT` columns out
3324    /// of Parquet, a packed one and runs over the others after the filter, and every `+` went a
3325    /// row at a time.
3326    ///
3327    /// # Errors
3328    ///
3329    /// Whatever the copy raises.
3330    pub fn opened(&self) -> Result<Self> {
3331        if let Body::Flat(_) = self.body {
3332            return Ok(self.clone());
3333        }
3334        if let Some(flat) = self.decoded_codes() {
3335            return Ok(flat);
3336        }
3337        self.copied((0..self.len).collect(), false)
3338    }
3339
3340    /// The same as [`Self::flatten`].
3341    pub fn into_flat(self) -> Result<Self> {
3342        if let Body::Flat(_) = self.body {
3343            return Ok(self);
3344        }
3345        // flatten: the caller asked for flat, and the form that is already flat took the branch
3346        // above, so this is the one case where the copy is what was wanted rather than a shortcut
3347        // somebody took instead of reading the column where it lies.
3348        self.flatten()
3349    }
3350
3351    /// The values at the given positions, copied, in a form that does not point back at this vector.
3352    ///
3353    /// This is the copying counterpart to [`Self::dictionary`], and the two are the two halves of
3354    /// the decision `spec/07-execution.md` section 7.1 describes. Which half is right is measured
3355    /// rather than argued, and [`Chunk::compact`](crate::Chunk::compact) is where the measurement
3356    /// is written down.
3357    ///
3358    /// A dictionary chain is walked to its leaf first and the codes composed on the way down, so the
3359    /// copy runs once over the data rather than once per level, and a position that is null at any
3360    /// level comes out null here. The copy is a typed loop per physical layout rather than a `Value`
3361    /// per row, which is the whole point of it and is what [`Self::flatten`] now goes through too.
3362    ///
3363    /// # Errors
3364    ///
3365    /// If the type is one there is no vector for yet, which today means `ARRAY` and `UNION`. A `LIST`
3366    /// and a `MAP` gather by permuting their entries and a `STRUCT` by gathering every field.
3367    pub fn gather(&self, indices: &[u32]) -> Result<Self> {
3368        // Straight off the positions a filter handed over, since a gather of a stable dictionary is
3369        // its codes gathered and nothing else, and widening every position first was a pass and an
3370        // allocation per filtered chunk of `URL` on ClickBench 28.
3371        if let Body::Dictionary { codes, values, stable: true } = &self.body {
3372            let inside = below(indices, codes.len());
3373            return self.stable_gathered(codes, values, indices, inside, |index| index as usize);
3374        }
3375        // A constant gathered is the same constant at the new length, as long as every position is
3376        // a row of it or the value is null anyway. A join's probe gathers every column of its driving
3377        // side, and a scan hands up a null constant for a column only its filter read.
3378        if let Body::Constant(value) = &self.body {
3379            let null = value.is_null() && matches!(self.validity, Validity::AllInvalid);
3380            let valid = matches!(self.validity, Validity::AllValid) && !value.is_null();
3381            if null || (valid && below(indices, self.len)) {
3382                return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), indices.len()));
3383            }
3384        }
3385        if let Some(gathered) = self.unpacked_at(indices) {
3386            return Ok(gathered);
3387        }
3388        if let Some(gathered) = self.flat_at(indices) {
3389            return Ok(gathered);
3390        }
3391        self.copied(indices.iter().map(|&index| index as usize).collect(), true)
3392    }
3393
3394    /// A gather off a flat run of fixed width values with no nulls, every position inside it.
3395    ///
3396    /// That is what a join hands out on both of its sides, and the general copy below made a run of
3397    /// wide positions, walked them for nulls, made a flag per row and a validity out of the flags
3398    /// before it moved a value. On q09 at SF1 those passes were about half of the gathers. Here it is
3399    /// one pass for the range and one for the values, and `None` for anything else.
3400    fn flat_at(&self, indices: &[u32]) -> Option<Self> {
3401        let Body::Flat(data) = &self.body else { return None };
3402        if self.validity.has_nulls(self.len) {
3403            return None;
3404        }
3405        if !below(indices, self.len) {
3406            return None;
3407        }
3408        macro_rules! gathered {
3409            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3410                match data {
3411                    $(Data::$variant(values) => {
3412                        let values = values.as_slice();
3413                        let out: Vec<$native> =
3414                            indices.iter().map(|&index| values[index as usize]).collect();
3415                        Data::$variant(Buffer::from_vec(out))
3416                    })+
3417                    Data::Empty | Data::Varlen(_) => return None,
3418                }
3419            };
3420        }
3421        let data = crate::for_each_layout!(fixed, gathered);
3422        Some(Self {
3423            ty: self.ty.clone(),
3424            len: indices.len(),
3425            validity: Validity::AllValid,
3426            body: Body::Flat(data),
3427        })
3428    }
3429
3430    /// A gather off a stable dictionary, which is its codes gathered over the same values.
3431    ///
3432    /// Generic over the position type because a filter hands over `u32` positions and a nested
3433    /// gather hands over `usize` ones, and each is read where it lies rather than widened first.
3434    fn stable_gathered<T: Copy>(
3435        &self,
3436        codes: &Buffer<u32>,
3437        values: &Arc<Vector>,
3438        at: &[T],
3439        inside: bool,
3440        index: impl Fn(T) -> usize,
3441    ) -> Result<Self> {
3442        let rows = at.len();
3443        // The ordinary case, a column with no nulls and a filter's rows all inside it, in one pass
3444        // for the range and one for the gather. Every code taken is one of this vector's codes,
3445        // which were range checked when it was built, so the result is not checked again the way
3446        // a dictionary from outside is. On q1 the two passes this replaces and the check after
3447        // them were a tenth of the instructions of the scan.
3448        if inside && self.never_null() {
3449            return Ok(Self {
3450                ty: values.ty.clone(),
3451                len: rows,
3452                validity: Validity::AllValid,
3453                body: Body::Dictionary {
3454                    codes: at.iter().map(|&at| codes[index(at)]).collect(),
3455                    values: Arc::clone(values),
3456                    stable: true,
3457                },
3458            });
3459        }
3460        // Otherwise the rows past the end and the nulls are found one row at a time. The per row
3461        // question reads through the dictionary to the value it stands for, which is why the case
3462        // above answers it for the whole column at once.
3463        let validity = if self.never_null() && at.iter().all(|&at| index(at) < self.len) {
3464            Validity::AllValid
3465        } else {
3466            Validity::from_iter(rows, |row| {
3467                at.get(row)
3468                    .map(|&at| index(at))
3469                    .is_some_and(|index| index < self.len && !self.is_null_at(index))
3470            })
3471        };
3472        let gathered: Vec<u32> =
3473            at.iter().map(|&at| codes.get(index(at)).copied().unwrap_or(0)).collect();
3474        // Every code here is one this vector already held, which was checked against the same
3475        // values on the way in, or the zero a row past the end is written as. So the only code that
3476        // can be out of range is that zero over no values at all, and the pass that looks for the
3477        // largest code is not needed to find it. On ClickBench 28 that pass was four percent of the
3478        // query, because every filtered chunk of `URL` came through here.
3479        // Values that are themselves a dictionary are composed through by the constructor, and this
3480        // skips the constructor, so that shape still goes the checked way.
3481        if matches!(values.body, Body::Dictionary { .. }) {
3482            return Ok(
3483                Self::stable_dictionary(gathered, Arc::clone(values))?.with_validity(validity)
3484            );
3485        }
3486        let highest = (values.is_empty() && !gathered.is_empty()).then_some(0);
3487        Ok(Self::stable_dictionary_validated(gathered, Arc::clone(values), highest)?
3488            .with_validity(validity))
3489    }
3490
3491    /// A packed column's rows at `indices`, unpacked in bulk into a flat column.
3492    ///
3493    /// The general copy reads a packed row a code at a time, which is what [`Packed::codes_at`]
3494    /// exists to avoid. `None` for anything but a packed column with no nulls, every index in range
3495    /// and both ends of its range inside an `i64`, which is every packed column of TPC-H.
3496    fn unpacked_at(&self, indices: &[u32]) -> Option<Self> {
3497        let Body::Packed { words, width, base, offset } = &self.body else {
3498            return None;
3499        };
3500        if self.validity.has_nulls(self.len) {
3501            return None;
3502        }
3503        if !below(indices, self.len) {
3504            return None;
3505        }
3506        let packed = Packed { words, width: *width, base: *base, offset: *offset };
3507        let low = i64::try_from(packed.base()).ok()?;
3508        i64::try_from(packed.ceiling()).ok()?;
3509        // Every value is between the two ends, which both fit, so the add lands without wrapping
3510        // and the narrowing below keeps every value, since the layout was chosen to hold them.
3511        #[expect(clippy::cast_possible_wrap, reason = "a code is below the span, which fits")]
3512        let value = |code: u64| low.wrapping_add(code as i64);
3513        #[expect(clippy::cast_possible_truncation, reason = "the layout holds every value")]
3514        let data = match self.ty.physical() {
3515            rudb_common::PhysicalType::Int64 => {
3516                Data::Int64(Buffer::from_vec(packed.values_at(indices, value)))
3517            }
3518            rudb_common::PhysicalType::Int32 => {
3519                Data::Int32(Buffer::from_vec(packed.values_at(indices, |code| value(code) as i32)))
3520            }
3521            rudb_common::PhysicalType::Int16 => {
3522                Data::Int16(Buffer::from_vec(packed.values_at(indices, |code| value(code) as i16)))
3523            }
3524            _ => return None,
3525        };
3526        Some(Self {
3527            ty: self.ty.clone(),
3528            len: indices.len(),
3529            validity: Validity::AllValid,
3530            body: Body::Flat(data),
3531        })
3532    }
3533
3534    /// The copy both [`Self::gather`] and [`Self::flatten`] are.
3535    ///
3536    /// `forms_stay` is the one thing the two want differently. A gather of a constant is a shorter
3537    /// constant and copying it out would be a thousand writes of the same value for nothing, and a
3538    /// gather of string views is a shorter run of views over the same arena rather than a copy of
3539    /// the bytes. Flattening promises flat form to a caller that is about to read the data slice, so
3540    /// for that one both of them have to be written out.
3541    fn copied(&self, at: Vec<usize>, forms_stay: bool) -> Result<Self> {
3542        let rows = at.len();
3543        if forms_stay && let Body::Dictionary { codes, values, stable: true } = &self.body {
3544            let inside = at.iter().max().is_none_or(|&top| top < codes.len());
3545            return self.stable_gathered(codes, values, &at, inside, |index| index);
3546        }
3547        let (at, leaf) = self.resolve(at);
3548        let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
3549        let validity = Validity::from_run(&live);
3550        let body = match &leaf.body {
3551            // The same gather the arm below is, for a type that has no flat layout to be written out
3552            // into. It goes through the nested builders rather than through a run of data, because they
3553            // are the one place that knows a row of a list column is a range of a child and a row of a
3554            // struct column is one position in each of several, and a second copy of that here would
3555            // be a second thing to keep in step with them.
3556            Body::Constant(value)
3557                if matches!(
3558                    self.ty,
3559                    LogicalType::List(_) | LogicalType::Struct(_) | LogicalType::Map(_, _)
3560                ) =>
3561            {
3562                if forms_stay && matches!(validity, Validity::AllValid) {
3563                    return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
3564                }
3565                let rows: Vec<Value> = at
3566                    .iter()
3567                    .map(
3568                        |&index| {
3569                            if index == NOWHERE { Value::Null } else { value.as_ref().clone() }
3570                        },
3571                    )
3572                    .collect();
3573                return Self::from_values(self.ty.clone(), &rows);
3574            }
3575            // Every position holds the same value, so the only thing the gather can change is the
3576            // length and which positions are null. A gather with no null in it is still a constant.
3577            Body::Constant(value) => {
3578                if forms_stay && matches!(validity, Validity::AllValid) {
3579                    return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
3580                }
3581                let mut data = empty_data_for(&self.ty)?;
3582                let value = stored(&self.ty, value)?;
3583                for &index in &at {
3584                    push_value(&mut data, if index == NOWHERE { &Value::Null } else { &value })?;
3585                }
3586                Body::Flat(data)
3587            }
3588            // A sequence is arithmetic rather than storage, so the gather is the arithmetic done at
3589            // the positions asked for, and a null writes the zero every other layout writes.
3590            Body::Sequence { start, step } => Body::Flat(Data::Int64(
3591                at.iter()
3592                    .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
3593                    .collect(),
3594            )),
3595            // A flat body with no values is the untyped null, so every position asked for is null
3596            // whatever was asked for. Going through the copy would build a run of no values and
3597            // call it `rows` long, which is a vector whose length and data disagree.
3598            Body::Flat(Data::Empty) => {
3599                return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
3600            }
3601            Body::Flat(data) => Body::Flat(copy_of(data, &at)),
3602            // The one form whose copy is arithmetic rather than a move of bytes. It goes through a
3603            // typed loop per layout the way the flat copy does, because the alternative is a `Value`
3604            // per row and this is the path a flatten of a scanned column takes.
3605            Body::Packed { words, width, base, offset } => {
3606                Body::Flat(unpack(&self.ty, words, *offset, *width, *base, &at)?)
3607            }
3608            // A gather keeps the form, which is what makes selecting rows out of a string column
3609            // cost sixteen bytes a row instead of the bytes of the strings. The arena it shares is
3610            // the whole arena and not the part the kept rows point at, so a selection that throws
3611            // most of a page away goes on holding the page. That is the trade the form is: a cut and
3612            // a filter are cheap and the memory comes back when the last vector over the page goes,
3613            // and a caller that wants the bytes narrowed asks for a flatten.
3614            Body::Views { views, arena } if forms_stay => Body::Views {
3615                views: at
3616                    .iter()
3617                    .map(|&index| views.get(index).copied().unwrap_or_else(StringView::empty))
3618                    .collect(),
3619                arena: Arc::clone(arena),
3620            },
3621            // Flattening promises a data slice, and a flat string column is views over an arena
3622            // just as this form is, so when the arena is a page the flatten is the views and
3623            // nothing else. The form is given up, which is what was asked for, and not the sharing,
3624            // which nobody asked to have given up: a result set of six million strings used to copy
3625            // every byte of them out of the pages they were already sitting in.
3626            Body::Views { views, arena } if arena.is_shared() => {
3627                Body::Flat(Data::Varlen(StringColumn::from_parts(
3628                    at.iter()
3629                        .map(|&index| views.get(index).copied().unwrap_or_else(StringView::empty))
3630                        .collect(),
3631                    (**arena).clone(),
3632                )))
3633            }
3634            // The arena is this vector's own, so there is nothing to share and the bytes are copied
3635            // out into an arena of their own. The total is known before any of it is copied, the
3636            // way the flat copy works it out, so the new arena is one allocation.
3637            Body::Views { views, arena } => {
3638                let mut out = StringColumn::with_capacity(at.len());
3639                out.reserve_bytes(
3640                    at.iter()
3641                        .filter_map(|&index| views.get(index))
3642                        .filter(|view| !view.is_inline())
3643                        .map(StringView::len)
3644                        .sum(),
3645                );
3646                for &index in &at {
3647                    let bytes = views.get(index).and_then(|view| view.bytes_in(arena));
3648                    out.push_bytes(bytes.unwrap_or_default());
3649                }
3650                Body::Flat(Data::Varlen(out))
3651            }
3652            Body::ExternalText { source } => {
3653                let mut out = StringColumn::with_capacity(at.len());
3654                for &index in &at {
3655                    out.push_bytes(source.bytes_at(index)?.unwrap_or_default());
3656                }
3657                Body::Flat(Data::Varlen(out))
3658            }
3659            // A gather keeps the form, because the codes do not move and a span survives being put
3660            // in an order the codes are not in. A position that resolved to nowhere gets the empty
3661            // span, which decompresses to no bytes, which is the zero every other layout writes.
3662            Body::Coded { codes, spans, table } if forms_stay => Body::Coded {
3663                codes: Arc::clone(codes),
3664                spans: at
3665                    .iter()
3666                    .map(|&index| spans.get(index).copied().unwrap_or((0, 0)))
3667                    .collect(),
3668                table: Arc::clone(table),
3669            },
3670            // Flattening decompresses, which is the price of the data slice it promises. The scratch
3671            // buffer is reused across rows, so this is one allocation for the whole column rather
3672            // than one per row the way reading it a value at a time would be.
3673            Body::Coded { codes, spans, table } => {
3674                let mut out = StringColumn::with_capacity(at.len());
3675                let mut scratch = Vec::new();
3676                for &index in &at {
3677                    scratch.clear();
3678                    let span = spans
3679                        .get(index)
3680                        .and_then(|&(from, to)| codes.get(from as usize..to as usize));
3681                    if let Some(span) = span {
3682                        table.decompress(span, &mut scratch)?;
3683                    }
3684                    out.push_bytes(&scratch);
3685                }
3686                Body::Flat(Data::Varlen(out))
3687            }
3688            // The entries move and the child does not, which is the same trade the string forms
3689            // make and is why a gather of a list column costs eight bytes a row however long the
3690            // lists are. A position that resolved to nowhere gets a zero length entry, and the mask
3691            // already says it is null, so the entry is never read.
3692            //
3693            // This arm ignores `forms_stay`, unlike every arm above it, because there is nothing
3694            // flatter for a list to become. The other forms are all cheaper ways of writing down a
3695            // column of scalars and flattening gives up the saving to hand back a data slice, and a
3696            // list has no data slice in any form, so a flatten of one is this and a caller reading it
3697            // goes through `list_parts` either way.
3698            Body::Nested { entries, child } => Body::Nested {
3699                entries: at
3700                    .iter()
3701                    .map(|&index| entries.get(index).copied().unwrap_or((0, 0)))
3702                    .collect(),
3703                child: Arc::clone(child),
3704            },
3705            // Every child gathered at the same positions, for the reason the cut cuts every child:
3706            // there are no entries to permute instead, so the permutation happens once per field. The
3707            // positions handed down are the resolved ones, sentinel and all, so a row that resolved to
3708            // nowhere comes back null in each field as well as null here.
3709            //
3710            // `forms_stay` is passed straight through rather than ignored, which is the opposite of
3711            // what the list arm does, and the difference is real. There is nothing flatter for a list
3712            // to become, and a struct is only as flat as its fields are, so a flatten of a struct
3713            // column is a flatten of each field and a caller that asked for data slices gets them.
3714            Body::Fields { children } => Body::Fields {
3715                children: children
3716                    .iter()
3717                    .map(|child| child.copied(at.clone(), forms_stay).map(Arc::new))
3718                    .collect::<Result<Vec<_>>>()?,
3719            },
3720            // Unreachable, because `resolve` walks past every form that points at another vector
3721            // and stops at the first body that does not.
3722            Body::Dictionary { .. } | Body::Runs { .. } | Body::Gathered { .. } => {
3723                return Err(Error::internal(
3724                    "a form that points somewhere survived being resolved",
3725                ));
3726            }
3727        };
3728        Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
3729    }
3730
3731    /// Where each wanted position lives in the first body that points nowhere else, and that body.
3732    ///
3733    /// A position that is null anywhere on the way down, or past the end of anything on the way
3734    /// down, comes back as [`NOWHERE`]. That single sentinel is what keeps the copy loop from
3735    /// carrying a validity mask alongside the positions it is already walking.
3736    fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
3737        let mut source = self;
3738        loop {
3739            for slot in &mut at {
3740                if *slot >= source.len || !source.validity.is_valid(*slot) {
3741                    *slot = NOWHERE;
3742                }
3743            }
3744            source = match &source.body {
3745                Body::Dictionary { codes, values, .. } => {
3746                    for slot in &mut at {
3747                        *slot = match codes.get(*slot) {
3748                            Some(&code) => code as usize,
3749                            None => NOWHERE,
3750                        };
3751                    }
3752                    values.as_ref()
3753                }
3754                // A run length body is a dictionary whose code is worked out from the position
3755                // rather than stored, so the walk down is the same walk with a search where the
3756                // lookup was. `NOWHERE` searches for nothing and stays `NOWHERE`.
3757                Body::Runs { ends, values } => {
3758                    for slot in &mut at {
3759                        *slot = run_holding(ends, *slot).unwrap_or(NOWHERE);
3760                    }
3761                    values.as_ref()
3762                }
3763                // The same walk the dictionary above takes, with the sentinel folded into the one
3764                // this loop already has. That composition is the whole reason a gather is a body
3765                // rather than an operator: a filter over the output of a link join selects into the
3766                // ids and copies nothing, and a gather off a gather is one walk down to whatever is
3767                // at the bottom rather than two passes over the parent.
3768                Body::Gathered { source: below, rids, offset } => {
3769                    for slot in &mut at {
3770                        *slot = if *slot == NOWHERE {
3771                            NOWHERE
3772                        } else {
3773                            row_of(rids, *offset, *slot).unwrap_or(NOWHERE)
3774                        };
3775                    }
3776                    below.as_ref()
3777                }
3778                _ => return (at, source),
3779            };
3780        }
3781    }
3782}
3783
3784/// So that a kernel can take its operands as either a list of vectors or a list of references.
3785///
3786/// A caller that built a `Vec<Vector>` and a caller whose operands are already somewhere else, in a
3787/// chunk or in an evaluator's scratch, want the same kernel. Without this the second kind has to
3788/// clone every operand into a `Vec` to satisfy the signature, and a clone of a vector is a copy of
3789/// the whole column, so the type would be charging real memory traffic for nothing.
3790impl AsRef<Vector> for Vector {
3791    fn as_ref(&self) -> &Vector {
3792        self
3793    }
3794}
3795
3796/// The bits of a packed vector and what they mean, for a kernel that wants to stay in code space.
3797///
3798/// Borrowed from the vector rather than owning anything, so getting one costs nothing and a kernel
3799/// that finds it cannot use them has given up nothing by asking.
3800#[derive(Debug, Clone, Copy)]
3801pub struct Packed<'a> {
3802    words: &'a [u64],
3803    width: u32,
3804    base: i128,
3805    offset: usize,
3806}
3807
3808impl Packed<'_> {
3809    /// Packed words. A persisted vector also records [`Self::offset`].
3810    #[must_use]
3811    pub fn words(&self) -> &[u64] {
3812        self.words
3813    }
3814
3815    /// Bit offset, in rows, of the first value.
3816    #[must_use]
3817    pub fn offset(&self) -> usize {
3818        self.offset
3819    }
3820
3821    /// How many bits one code takes, between one and [`PACKED_WIDTH_MAX`].
3822    #[must_use]
3823    pub fn width(&self) -> u32 {
3824        self.width
3825    }
3826
3827    /// What zero means, so that the value of a row is the base plus its code.
3828    #[must_use]
3829    pub fn base(&self) -> i128 {
3830        self.base
3831    }
3832
3833    /// The largest value this vector can be holding, whatever it is actually holding.
3834    ///
3835    /// With [`Self::base`] this is the pair a comparison kernel wants first. A literal outside the
3836    /// two answers every row of the vector the same way, which is a whole chunk decided without a
3837    /// bit being read, and that is the case a zone map would have caught if there were one here.
3838    #[must_use]
3839    pub fn ceiling(&self) -> i128 {
3840        self.base + i128::from(u64::MAX >> (u64::BITS - self.width))
3841    }
3842
3843    /// The code of row `row`, which is its value minus [`Self::base`].
3844    ///
3845    /// Out of range rows read as zero rather than panicking, the way every other accessor in this
3846    /// file answers for a row that is not there.
3847    ///
3848    /// Marked inline because every caller that matters is a kernel in another crate reading one code
3849    /// per row, and thin LTO was leaving it as a call there. On TPC-H SF1 that call was 1.5 percent of
3850    /// the suite and a tenth of q12.
3851    #[must_use]
3852    #[inline]
3853    pub fn code(&self, row: usize) -> u64 {
3854        code_at(self.words, (self.offset + row) * self.width as usize, self.width)
3855    }
3856
3857    /// Which code a value would have, and `None` for a value this vector cannot be holding.
3858    ///
3859    /// The translation a comparison does once per vector so that it does not have to unpack once per
3860    /// row. `None` is the useful answer rather than a failure: it says the literal is outside the
3861    /// packed range, so every row compares against it the same way.
3862    #[must_use]
3863    pub fn code_of(&self, value: i128) -> Option<u64> {
3864        u64::try_from(value.checked_sub(self.base)?).ok().filter(|&code| code <= self.mask())
3865    }
3866
3867    /// The largest code the width allows.
3868    fn mask(&self) -> u64 {
3869        u64::MAX >> (u64::BITS - self.width)
3870    }
3871
3872    /// The codes of rows `from` to `from + out.len()`, in one pass over the words.
3873    ///
3874    /// [`Self::code`] is a code at a time, and every one of them works out which word it is in, reads
3875    /// it through a bound, and asks whether it straddles into the next. Sixty four codes of one
3876    /// width fill exactly that many words and the straddles fall in the same places every time, so a
3877    /// block of them is unpacked by a loop the width is a constant in, where every shift and every
3878    /// straddle is known before it runs. On TPC-H q1 the code at a time reads were a third of the
3879    /// instructions the query ran. The rows before the first whole block and after the last one
3880    /// still go a code at a time.
3881    pub fn unpack(&self, from: usize, out: &mut [u64]) {
3882        let width = self.width as usize;
3883        let start = self.offset + from;
3884        let end = start + out.len();
3885        let first = start.next_multiple_of(64).min(end);
3886        let mut at = 0;
3887        for row in start..first {
3888            out[at] = code_at(self.words, row * width, self.width);
3889            at += 1;
3890        }
3891        let mut row = first;
3892        while row + 64 <= end {
3893            let word = row / 64 * width;
3894            let Some(words) = self.words.get(word..word + width) else { break };
3895            let Some(Ok(block)) = out.get_mut(at..at + 64).map(<&mut [u64; 64]>::try_from) else {
3896                break;
3897            };
3898            unpack_block(words, self.width, block);
3899            row += 64;
3900            at += 64;
3901        }
3902        for row in row..end {
3903            out[at] = code_at(self.words, row * width, self.width);
3904            at += 1;
3905        }
3906    }
3907
3908    /// The codes of rows `from` to `from + rows`, each of them through `value`, appended to `out`.
3909    ///
3910    /// [`Self::unpack`] leaves its codes in a slice of `u64` that a caller wanting something else then
3911    /// walks a second time, which costs a vector to allocate, that vector zeroed before a single code
3912    /// is written into it, and a pass over every row that loads and stores it again. A caller reading a
3913    /// whole chunk in order wants one vector and one pass, so the block this unpacks into is 64 codes
3914    /// of stack that the next block writes over, and what reaches `out` is already the value asked
3915    /// for. The vector grows into room it reserved once, so nothing here is zeroed at all.
3916    ///
3917    /// Unpacking a block at a time was tried for random rows and lost, see [`Self::codes_into`], but
3918    /// that walk pays to ask which block each row falls in and this one goes straight through.
3919    pub fn unpack_mapped<U: Copy>(
3920        &self,
3921        from: usize,
3922        rows: usize,
3923        out: &mut Vec<U>,
3924        value: impl Fn(u64) -> U,
3925    ) {
3926        let width = self.width as usize;
3927        let start = self.offset + from;
3928        let end = start + rows;
3929        let first = start.next_multiple_of(64).min(end);
3930        out.reserve(rows);
3931        for row in start..first {
3932            out.push(value(code_at(self.words, row * width, self.width)));
3933        }
3934        let mut row = first;
3935        let mut block = [0_u64; 64];
3936        while row + 64 <= end {
3937            let word = row / 64 * width;
3938            let Some(words) = self.words.get(word..word + width) else { break };
3939            unpack_block(words, self.width, &mut block);
3940            out.extend(block.iter().map(|&code| value(code)));
3941            row += 64;
3942        }
3943        // Whatever the blocks did not cover, which is the tail and also everything after a width that
3944        // ran out of words, the same way [`Self::unpack`] leaves it to `code_at` to read as zero.
3945        for row in row..end {
3946            out.push(value(code_at(self.words, row * width, self.width)));
3947        }
3948    }
3949
3950    /// The code of each of `rows` rows `at` names, in order.
3951    ///
3952    /// [`Self::codes_into`] into a vector of its own. A caller reading a column a chunk at a time
3953    /// wants that vector once rather than once a chunk, and calls the other one.
3954    pub fn codes_at<M: Fn(usize) -> usize>(&self, at: M, rows: usize) -> Vec<u64> {
3955        let mut codes = vec![0; rows];
3956        self.codes_into(at, rows, &mut codes);
3957        codes
3958    }
3959
3960    /// The code of each of `rows` rows `at` names, in order, left in `out[..rows]`.
3961    ///
3962    /// A filter's selection names rows close together and in order, so the span they cover is
3963    /// unpacked whole with [`Self::unpack`] and each row read out of it. Rows spread too far apart
3964    /// for that to pay are read a code at a time.
3965    ///
3966    /// Unpacking a block at a time into a buffer on the stack, and reading each row out of the
3967    /// block it falls in, keeps less in the cache and was tried. The question of which block a row
3968    /// is in, asked for every row, cost more than the misses it saved, 40.2 G instructions for ten
3969    /// runs of q1 against 34.1 G this way.
3970    ///
3971    /// Rows that turn out to be a run, which is every row of the vector in order and is what a
3972    /// comparison over a whole chunk asks for, are unpacked straight into the answer. The span and
3973    /// the answer are the same rows in the same order there, so the buffer, the zeroing of it and
3974    /// the pass copying it out are all a copy of a thing onto itself. A filter over a packed `DATE`
3975    /// column of six million rows spent 37 percent of the query in here and the compare it fed 4.8
3976    /// percent, which is the shape of paying three passes for one. Whether the rows are a run is one
3977    /// compare a row in the pass that was already reading them.
3978    ///
3979    /// Rows that are not a run, which is the second conjunct of a filter reading only the rows the
3980    /// first one kept, unpack the span they cover into a buffer each thread keeps rather than a
3981    /// fresh one. The span of a selection over a chunk is about as wide as the chunk whatever the
3982    /// selection keeps, so the fresh buffer was an allocation and a page of zeroes a chunk for a run
3983    /// of zeroes that the unpack immediately writes over. [`Self::values_at`] below keeps its span
3984    /// the same way and for the same reason.
3985    ///
3986    /// `out` is grown to hold `rows` and is not otherwise touched, so a buffer longer than the rows
3987    /// keeps whatever is past them, and a buffer already long enough is not zeroed on the way in.
3988    /// Every one of `out[..rows]` is written before this returns.
3989    pub fn codes_into<M: Fn(usize) -> usize>(&self, at: M, rows: usize, out: &mut Vec<u64>) {
3990        thread_local! {
3991            static SPAN: RefCell<Vec<u64>> = const { RefCell::new(Vec::new()) };
3992        }
3993        if out.len() < rows {
3994            out.resize(rows, 0);
3995        }
3996        if rows == 0 {
3997            return;
3998        }
3999        let first = at(0);
4000        let (mut low, mut high) = (first, first);
4001        let mut ascends = true;
4002        for index in 1..rows {
4003            let row = at(index);
4004            low = low.min(row);
4005            high = high.max(row);
4006            ascends &= row == first + index;
4007        }
4008        if ascends {
4009            self.unpack(first, &mut out[..rows]);
4010            return;
4011        }
4012        if high - low >= rows.saturating_mul(4) {
4013            for (index, code) in out[..rows].iter_mut().enumerate() {
4014                *code = self.code(at(index));
4015            }
4016            return;
4017        }
4018        // Taken out of the thread's slot and put back rather than borrowed for the body, so that the
4019        // body is the straight line it was when it allocated. Handing the buffer to a closure and
4020        // calling that closure from both arms of a borrow left the gather a call rather than a loop.
4021        let span = high - low + 1;
4022        let mut run = SPAN.with_borrow_mut(std::mem::take);
4023        if run.len() < span {
4024            run.resize(span, 0);
4025        }
4026        self.unpack(low, &mut run[..span]);
4027        for (index, code) in out[..rows].iter_mut().enumerate() {
4028            *code = run[at(index) - low];
4029        }
4030        SPAN.with_borrow_mut(|held| *held = run);
4031    }
4032
4033    /// The value of each row `at` names, in order, made from its code by `value`.
4034    ///
4035    /// [`Self::codes_at`] for a filter's `u32` positions, with the value made as each row is read
4036    /// rather than in a second pass over the codes. Three things it did cost more than the reads on
4037    /// q01, where a filter keeps nearly every row of every packed column. The smallest and largest
4038    /// position were a scalar compare and move a row, because SSE2 has no unsigned or 64 bit
4039    /// minimum, and here they are signed 32 bit ones, which it has. The span was a fresh buffer
4040    /// of zeroes, and here each thread keeps one. And the codes were written out whole before the
4041    /// values were made from them.
4042    pub fn values_at<T>(&self, at: &[u32], value: impl Fn(u64) -> T) -> Vec<T> {
4043        thread_local! {
4044            static SPAN: RefCell<Vec<u64>> = const { RefCell::new(Vec::new()) };
4045        }
4046        let Some((low, high)) = extent(at) else { return Vec::new() };
4047        let (low, high) = (low as usize, high as usize);
4048        if high - low >= at.len().saturating_mul(4) {
4049            return at.iter().map(|&row| value(self.code(row as usize))).collect();
4050        }
4051        let span = high - low + 1;
4052        let gathered = |run: &mut Vec<u64>| {
4053            if run.len() < span {
4054                run.resize(span, 0);
4055            }
4056            let run = &mut run[..span];
4057            self.unpack(low, run);
4058            at.iter().map(|&row| value(run[row as usize - low])).collect()
4059        };
4060        SPAN.with(|held| match held.try_borrow_mut() {
4061            Ok(mut held) => gathered(&mut held),
4062            Err(_) => gathered(&mut Vec::new()),
4063        })
4064    }
4065}
4066
4067/// Sixty four codes of `width` bits out of the `width` words that hold them, with the width made a
4068/// constant so that the loop in [`unpack_width`] has nothing left to work out as it goes.
4069fn unpack_block(words: &[u64], width: u32, out: &mut [u64; 64]) {
4070    macro_rules! widths {
4071        ($($width:literal)*) => {
4072            match width {
4073                $($width => unpack_width::<$width>(words, out),)*
4074                _ => {
4075                    for (at, code) in out.iter_mut().enumerate() {
4076                        *code = code_at(words, at * width as usize, width);
4077                    }
4078                }
4079            }
4080        };
4081    }
4082    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
4083        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);
4084}
4085
4086#[inline(always)]
4087fn unpack_width<const WIDTH: usize>(words: &[u64], out: &mut [u64; 64]) {
4088    let Ok(words) = <&[u64; WIDTH]>::try_from(&words[..WIDTH]) else { return };
4089    // Written out sixty four times rather than as a loop, because the compiler kept the loop and
4090    // with it a shift and a branch on the straddle for every code. Spelled out, the row is a
4091    // constant in each step, so its word, its shift and whether it straddles are all worked out
4092    // before the program runs and a code is a shift, an or where it straddles and a mask.
4093    macro_rules! steps {
4094        ($($at:literal)*) => {
4095            $(unpack_step::<WIDTH, $at>(words, out);)*
4096        };
4097    }
4098    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
4099        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);
4100}
4101
4102#[inline(always)]
4103fn unpack_step<const WIDTH: usize, const AT: usize>(words: &[u64; WIDTH], out: &mut [u64; 64]) {
4104    let bit = AT * WIDTH;
4105    let word = bit / 64;
4106    let shift = bit % 64;
4107    let mut value = words[word] >> shift;
4108    if shift + WIDTH > 64 {
4109        value |= words[word + 1] << (64 - shift);
4110    }
4111    out[AT] = value & (u64::MAX >> (64 - WIDTH));
4112}
4113
4114/// The widest a packed code is allowed to be.
4115///
4116/// Sixty three rather than sixty four so that a mask is `u64::MAX >> (64 - width)` with no shift of
4117/// a whole word in it, and reading a code is one branch on whether it straddles rather than two. A
4118/// sixty four bit code saves nothing anyway, since it is the layout it came from.
4119pub const PACKED_WIDTH_MAX: u32 = 63;
4120
4121/// How much smaller packing has to be before it is worth the shift and the mask on every read.
4122///
4123/// Two, so a column packs when the bits come to half the flat size or less. A column that would save
4124/// a tenth stays flat, because a tenth of a column is not worth turning every read of it into
4125/// arithmetic, and the whole argument for the form is that a narrow column saves most of itself.
4126pub const PACKING_PAYS_AT: usize = 2;
4127
4128/// How much smaller compressing has to be before it is worth a decompression on every read.
4129///
4130/// Two, the same rule packing follows and for the same reason. FSST gets about that on text, so a
4131/// column of English or of URLs compresses and a column of short codes or of random bytes does not,
4132/// which is the right answer for both.
4133pub const FSST_PAYS_AT: usize = 2;
4134
4135/// The codes of a compressed column and the table they are against.
4136///
4137/// Handed out by [`Vector::coded_parts`] so a kernel can work in code space. Nothing here
4138/// decompresses, which is the point: [`Self::encode`] puts the literal into the same space the rows
4139/// are already in, and after that an equality test is a byte slice comparison.
4140#[derive(Debug, Clone, Copy)]
4141pub struct Coded<'a> {
4142    codes: &'a [u8],
4143    spans: &'a [(u32, u32)],
4144    table: &'a SymbolTable,
4145}
4146
4147impl Coded<'_> {
4148    /// The table every row in this vector is compressed against.
4149    #[must_use]
4150    pub fn table(&self) -> &SymbolTable {
4151        self.table
4152    }
4153
4154    /// The code bytes of one row, still compressed.
4155    #[must_use]
4156    pub fn row(&self, row: usize) -> Option<&[u8]> {
4157        let &(from, to) = self.spans.get(row)?;
4158        self.codes.get(from as usize..to as usize)
4159    }
4160
4161    /// Some bytes in the code space this vector is in.
4162    ///
4163    /// The literal side of an equality filter. Compressing is a function of the table and the bytes,
4164    /// so two strings compress to the same codes exactly when they are the same string, and an
4165    /// equality test on the codes is an equality test on the strings with no decompression in it.
4166    #[must_use]
4167    pub fn encode(&self, bytes: &[u8]) -> Vec<u8> {
4168        let mut out = Vec::with_capacity(bytes.len());
4169        self.table.compress(bytes, &mut out);
4170        out
4171    }
4172}
4173
4174/// The first `len` of a run of some narrower signed width, sign extended into `out`.
4175///
4176/// Written once and called from the three narrow arms of [`Data::signed_block`], so that the sign
4177/// extension is one loop the compiler can widen rather than three written out by hand.
4178fn widen<T: Copy + Into<i64>>(run: &[T], len: usize, out: &mut Vec<i64>) -> bool {
4179    match run.get(..len) {
4180        Some(run) => {
4181            out.extend(run.iter().map(|&x| x.into()));
4182            true
4183        }
4184        None => false,
4185    }
4186}
4187
4188/// The rows `at` of the first `len` of `run`, widened, appended to `out`. The range is checked
4189/// with a maximum first, because a maximum vectorizes and a check on every read would not.
4190fn gather_widened<T: Copy + Into<i64>>(
4191    run: &[T],
4192    len: usize,
4193    at: &[u32],
4194    out: &mut Vec<i64>,
4195) -> bool {
4196    let Some(run) = run.get(..len) else {
4197        return false;
4198    };
4199    // See `below`: the largest of `at` is a scalar loop here and was three quarters of this.
4200    if !below(at, run.len()) {
4201        return false;
4202    }
4203    out.extend(at.iter().map(|&row| run[row as usize].into()));
4204    true
4205}
4206
4207/// See [`Data::signed_runs`]. Sixteen values are compared against the current one at once, which
4208/// the compiler turns into a few vector compares, and only a block where something changed is
4209/// walked a value at a time.
4210fn runs_widened<T: Copy + Eq + Into<i64>>(
4211    run: &[T],
4212    len: usize,
4213    (from, to): (usize, usize),
4214    every: usize,
4215    out: &mut Vec<(i64, usize)>,
4216) -> bool {
4217    out.clear();
4218    let Some(values) = run.get(..len).and_then(|run| run.get(from..to)) else {
4219        return false;
4220    };
4221    let Some(&first) = values.first() else {
4222        return true;
4223    };
4224    let mut current = first;
4225    for (block, stretch) in values.chunks(16).enumerate() {
4226        if !stretch.iter().fold(false, |differ, &value| differ | (value != current)) {
4227            continue;
4228        }
4229        let start = from + block * 16;
4230        for (row, &value) in stretch.iter().enumerate() {
4231            if value != current {
4232                out.push((current.into(), start + row));
4233                current = value;
4234            }
4235        }
4236        if out.len() > (block * 16) / every.max(1) + 64 {
4237            out.clear();
4238            return false;
4239        }
4240    }
4241    out.push((current.into(), to));
4242    true
4243}
4244
4245/// One holder's share of a part that several vectors are reading at the same time.
4246///
4247/// The rule [`Buffer::footprint`] already uses for a shared page. Everything holding the part asks
4248/// this, so what they say between them comes to about what the part costs rather than to the part
4249/// times the number of them, and the answer is never zero for a part that costs anything, because a
4250/// caller with a reference is at least one holder.
4251fn share<T: ?Sized>(bytes: usize, held: &Arc<T>) -> usize {
4252    bytes / Arc::strong_count(held).max(1)
4253}
4254
4255/// How many words hold `len` codes of `width` bits.
4256fn words_for(len: usize, width: u32) -> usize {
4257    (len * width as usize).div_ceil(u64::BITS as usize)
4258}
4259
4260/// The lowest and highest value a type's layout can hold, and `None` for a type with no integer one.
4261///
4262/// This is also the test of whether a type can be packed at all, and it is the only one, so the
4263/// layouts listed here and the layouts [`pack`] and [`unpack`] know how to walk are the same list
4264/// from the same macro and cannot drift apart.
4265fn layout_range(ty: &LogicalType) -> Option<(i128, i128)> {
4266    use rudb_common::PhysicalType as P;
4267    macro_rules! ranges {
4268        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4269            match ty.physical() {
4270                $(P::$variant => Some((i128::from(<$native>::MIN), i128::from(<$native>::MAX))),)+
4271                _ => None,
4272            }
4273        };
4274    }
4275    crate::for_each_layout!(exact, ranges)
4276}
4277
4278/// The bytes the first `len` slots of a run take laid flat, whether the run is owned or a window.
4279fn flat_bytes(data: &Data, len: usize) -> usize {
4280    macro_rules! widths {
4281        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4282            match data {
4283                Data::Empty => 0,
4284                $(Data::$variant(_) => len * size_of::<$native>(),)+
4285            }
4286        };
4287    }
4288    crate::for_each_layout!(all, widths)
4289}
4290
4291/// What to subtract before packing, so that the whole code range lands inside the column's type.
4292///
4293/// The smallest value in the column is the obvious base and it is the wrong one near the top of a
4294/// type. [`Vector::packed`] checks the two ends of what the codes could say rather than the values
4295/// that are actually there, which is one check instead of one per row and is what makes reading a
4296/// packed column cheap. An `INTEGER` column of a thousand values just under `i32::MAX` needs ten
4297/// bits, and based at its own smallest value those ten bits could say a number an `INTEGER` cannot
4298/// hold, so the column was refused and the table would not write at all.
4299///
4300/// The base does not have to be the smallest value. Any base works where every code is still
4301/// non-negative and the widest code the width allows still fits the type, which is `base <= low`,
4302/// `high - base <= 2^width - 1`, `type low <= base` and `base + 2^width - 1 <= type high` together.
4303///
4304/// The largest base meeting all four is the one below, and it exists whenever the values fit the
4305/// type at all: `high - (2^width - 1) <= low` because that is how the width was chosen, and
4306/// `type low <= type high - (2^width - 1)` because a width wider than the type's own span is
4307/// already refused. `None` is for a type with no integer layout, which cannot be packed anyway.
4308fn packing_base(ty: &LogicalType, low: i128, high: i128, width: u32) -> Option<i128> {
4309    let (floor, ceiling) = layout_range(ty)?;
4310    let span = i128::from(u64::MAX >> (64 - width));
4311    let base = low.min(ceiling - span);
4312    (base >= floor && base >= high - span).then_some(base)
4313}
4314
4315/// The lowest and highest value in the first `len` slots of a run of integer data.
4316///
4317/// `None` for data that is not integers, which is what says a column cannot be packed. The null
4318/// slots are in the span, holding whatever zero was written into them, which
4319/// [`Vector::bit_packed`] says more about.
4320fn span_of(data: &Data, len: usize) -> Option<(i128, i128)> {
4321    macro_rules! spans {
4322        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4323            match data {
4324                $(Data::$variant(values) => {
4325                    // In the value's own type and one end at a time, which the compiler turns
4326                    // into vector compares. Widening each value to `i128` first kept both ends in
4327                    // register pairs and made this two percent of a ClickBench load.
4328                    let values = values.as_slice();
4329                    let values = &values[..len.min(values.len())];
4330                    let low = values.iter().copied().min()?;
4331                    let high = values.iter().copied().max()?;
4332                    Some((i128::from(low), i128::from(high)))
4333                })+
4334                _ => None,
4335            }
4336        };
4337    }
4338    crate::for_each_layout!(exact, spans)
4339}
4340
4341/// The first `len` values of a run of integer data, written out as codes of `width` bits from `base`.
4342fn pack(data: &Data, len: usize, base: i128, width: u32) -> Vec<u64> {
4343    let mut words = vec![0u64; words_for(len, width)];
4344    macro_rules! packing {
4345        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4346            match data {
4347                $(Data::$variant(values) => {
4348                    for (row, &value) in values.as_slice().iter().take(len).enumerate() {
4349                        // In range because `base` and `width` came from the span of this same run.
4350                        let code = u64::try_from(i128::from(value) - base).unwrap_or(0);
4351                        write_code(&mut words, row * width as usize, width, code);
4352                    }
4353                })+
4354                _ => {}
4355            }
4356        };
4357    }
4358    crate::for_each_layout!(exact, packing);
4359    words
4360}
4361
4362/// The codes at the given rows, unpacked into the flat layout the type calls for.
4363///
4364/// A row of [`NOWHERE`] writes the layout's zero, which is the rule [`copy_of`] follows for the same
4365/// reason: every layout here is a parallel array to a validity mask, so a null takes a slot.
4366///
4367/// # Errors
4368///
4369/// If the type has no flat layout, which a packed vector cannot have and which is checked when one
4370/// is built, so an error here is a bug rather than a caller mistake.
4371fn unpack(
4372    ty: &LogicalType,
4373    words: &[u64],
4374    offset: usize,
4375    width: u32,
4376    base: i128,
4377    at: &[usize],
4378) -> Result<Data> {
4379    let mut out = empty_data_for(ty)?;
4380    let value_of = |row: usize| {
4381        if row == NOWHERE {
4382            return None;
4383        }
4384        Some(base + i128::from(code_at(words, (offset + row) * width as usize, width)))
4385    };
4386    macro_rules! unpacking {
4387        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4388            match &mut out {
4389                $(Data::$variant(values) => {
4390                    values.reserve(at.len());
4391                    for &row in at {
4392                        // In range because both ends of it were checked when the vector was built.
4393                        let value = value_of(row)
4394                            .and_then(|value| <$native>::try_from(value).ok())
4395                            .unwrap_or($zero);
4396                        values.push(value);
4397                    }
4398                })+
4399                _ => {
4400                    return Err(Error::internal(format!(
4401                        "a {ty} vector was packed, which no integer layout allows"
4402                    )));
4403                }
4404            }
4405        };
4406    }
4407    crate::for_each_layout!(exact, unpacking);
4408    Ok(out)
4409}
4410
4411/// The `width` bits starting at `bit`, low end first.
4412///
4413/// Zero for bits past the end of the words, which keeps a read of a row that is not there from
4414/// panicking and matches what every other accessor here does with one.
4415#[inline]
4416fn code_at(words: &[u64], bit: usize, width: u32) -> u64 {
4417    let word = bit / u64::BITS as usize;
4418    let shift = (bit % u64::BITS as usize) as u32;
4419    let mask = u64::MAX >> (u64::BITS - width);
4420    let low = words.get(word).copied().unwrap_or(0) >> shift;
4421    let taken = u64::BITS - shift;
4422    if taken >= width {
4423        return low & mask;
4424    }
4425    // The code straddles two words, and `taken` is under the width here so it is under sixty four,
4426    // which is what makes the shift below one the hardware will do rather than one it refuses.
4427    let high = words.get(word + 1).copied().unwrap_or(0) << taken;
4428    (low | high) & mask
4429}
4430
4431/// Writes `width` bits of `code` starting at `bit`, over words that started out zero.
4432fn write_code(words: &mut [u64], bit: usize, width: u32, code: u64) {
4433    let word = bit / u64::BITS as usize;
4434    let shift = (bit % u64::BITS as usize) as u32;
4435    words[word] |= code << shift;
4436    let taken = u64::BITS - shift;
4437    if taken < width {
4438        words[word + 1] |= code >> taken;
4439    }
4440}
4441
4442/// One level of dictionary out of however many levels were handed to [`Vector::dictionary`].
4443///
4444/// Every dictionary in the system is built through that constructor and every one of them comes
4445/// through here first, so the invariant this maintains is that the vector a dictionary points at is
4446/// never itself a dictionary that could have been composed away. That makes the work a single `if`
4447/// rather than a loop: the inner vector was already composed when it was built, so composing the
4448/// outer codes through it leaves the result no deeper than the inner vector already was.
4449///
4450/// The codes are indexed rather than fetched with `get`, because the caller has already walked the
4451/// whole outer array to check that every code is in range and the inner array is exactly as long as
4452/// the vector those codes were checked against.
4453fn compose(codes: Vec<u32>, values: Arc<Vector>) -> (Vec<u32>, Arc<Vector>) {
4454    // A dictionary carrying a validity of its own is one whose nulls live at this level rather than
4455    // in the values, which is the one thing composition cannot carry down with it.
4456    if !matches!(values.validity, Validity::AllValid) {
4457        return (codes, values);
4458    }
4459    let Body::Dictionary { codes: inner, values: leaf, .. } = &values.body else {
4460        return (codes, values);
4461    };
4462    debug_assert!(
4463        !matches!(leaf.body, Body::Dictionary { .. })
4464            || !matches!(leaf.validity, Validity::AllValid),
4465        "a dictionary was stacked on a dictionary without going through the constructor"
4466    );
4467    // The leaf is handed on as the handle it already is. Nothing here reads it and nothing here
4468    // changes it, so the composed dictionary points at the same values the stacked one did and
4469    // whoever else is holding them keeps holding them. This used to take them out of the `Arc`,
4470    // which copied the whole leaf whenever anybody else was still reading it, and a scan selecting
4471    // rows out of a chunk whose column came from a shared page dictionary is exactly that: the page
4472    // holds the leaf, every chunk cut from the page composes through it, and every one of those
4473    // cuts copied the page's dictionary. TPC-H q21 does it once per thousand rows of `lineitem`.
4474    let composed = codes.iter().map(|&code| inner[code as usize]).collect();
4475    (composed, Arc::clone(leaf))
4476}
4477
4478/// How many rows a run has to cover on average before run length encoding is smaller.
4479///
4480/// A run costs its value plus the four bytes of its end, so on a four byte column a run of two rows
4481/// breaks even and a run of three wins. Wider columns win sooner and narrower ones later, and this
4482/// is the one ratio for all of them because a threshold per width is a table that has to be right
4483/// nine times rather than once. It is a constant with a name so that the sweep that eventually moves
4484/// it has something to move.
4485const RUNS_PAY_AT: usize = 2;
4486
4487/// A string body's arena as a page, when this is the only holder of it.
4488///
4489/// The move out of the `Arc` and back into one is what makes this free: [`Buffer::into_page`] takes
4490/// the run by value and puts it behind an `Arc` without touching a byte of it, so the whole of this
4491/// is two allocations of a pointer's worth each however large the arena is.
4492///
4493/// An arena somebody else is holding comes back untouched. Paging it would mean copying it, since
4494/// the other holder's view of it has to go on meaning what it meant, and a copy is what the caller
4495/// asked to avoid.
4496fn paged(arena: Arc<Buffer<u8>>) -> Arc<Buffer<u8>> {
4497    if arena.is_shared() {
4498        return arena;
4499    }
4500    match Arc::try_unwrap(arena) {
4501        Ok(owned) => Arc::new(owned.into_page()),
4502        Err(held) => held,
4503    }
4504}
4505
4506/// Which run holds `row`, given ends that are exclusive and increasing.
4507///
4508/// A binary search rather than a scan, because the callers that ask this are the ones that are not
4509/// walking the runs in order: a single value read out of a result set, or a gather at scattered
4510/// positions. Anything walking in order should be reading [`Vector::run_parts`] instead, which is
4511/// what the form is for.
4512fn run_holding(ends: &[u32], row: usize) -> Option<usize> {
4513    let row = u32::try_from(row).ok()?;
4514    let run = match ends.binary_search(&row) {
4515        // The ends are exclusive, so landing exactly on one means the row is the first of the next.
4516        Ok(at) => at + 1,
4517        Err(at) => at,
4518    };
4519    (run < ends.len()).then_some(run)
4520}
4521
4522/// The row each run ends at, for a flat body read alongside the validity that goes with it.
4523///
4524/// Two adjacent nulls are one run, because a reader of either gets a null and cannot tell them
4525/// apart. A null between two equal values is three runs for the same reason, since the null is a
4526/// value of the column as far as anything reading it is concerned.
4527///
4528/// The comparison is per layout rather than per `Value`, which is the whole reason this is a macro.
4529/// A `Value` a row would allocate a string per row on a `VARCHAR` column and would be the exact
4530/// defect `cargo xtask rowloop` exists to fail the build on.
4531fn boundaries(data: &Data, validity: &Validity, len: usize) -> Vec<u32> {
4532    if len == 0 {
4533        return Vec::new();
4534    }
4535    let breaks = |ends: &mut Vec<u32>, mut differs: Box<dyn FnMut(usize, usize) -> bool + '_>| {
4536        for row in 1..len {
4537            let same = match (validity.is_valid(row), validity.is_valid(row - 1)) {
4538                (false, false) => true,
4539                (true, true) => !differs(row, row - 1),
4540                _ => false,
4541            };
4542            if !same {
4543                ends.push(u32::try_from(row).unwrap_or(u32::MAX));
4544            }
4545        }
4546        ends.push(u32::try_from(len).unwrap_or(u32::MAX));
4547    };
4548    let mut ends = Vec::new();
4549    macro_rules! walked {
4550        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4551            match data {
4552                // No values at all, so every row is the same null and the column is one run.
4553                Data::Empty => ends.push(u32::try_from(len).unwrap_or(u32::MAX)),
4554                $(Data::$variant(values) => {
4555                    breaks(&mut ends, Box::new(|a, b| values.get(a) != values.get(b)));
4556                })+
4557                Data::Varlen(values) => {
4558                    breaks(&mut ends, Box::new(|a, b| values.bytes(a) != values.bytes(b)));
4559                }
4560            }
4561        };
4562    }
4563    crate::for_each_layout!(fixed, walked);
4564    ends
4565}
4566
4567/// The position of a value that is not anywhere, because it is null or out of range.
4568///
4569/// `usize::MAX` rather than an `Option<usize>`, because the copy loop's bounds check rejects it for
4570/// free and an `Option` would put a second branch next to the one already there.
4571pub(crate) const NOWHERE: usize = usize::MAX;
4572
4573/// The row id of a row that is not in the source, which reads as null.
4574///
4575/// Public because whoever builds a [`Form::Gathered`] vector has to write it, and it is `u32::MAX`
4576/// for the reason the crate's own offset sentinel is `usize::MAX`: a bounds check the reader is
4577/// doing anyway rejects it, where an `Option<u32>` would be eight bytes a row instead of four and a
4578/// second branch beside the one already there. It costs the last row of a four billion row source,
4579/// which is a source no column in this engine has.
4580pub const NO_ROW: u32 = u32::MAX;
4581
4582/// Which source row a gathered row names, and `None` when it names none.
4583///
4584/// The `Option` is what every reader of [`Body::Gathered`] that returns an `Option` wants, so the
4585/// three cases that are all *there is nothing here*, past the end of the ids, the sentinel, and an
4586/// id that does not fit a `usize`, are collapsed once here rather than three times each.
4587fn row_of(rids: &[u32], offset: usize, index: usize) -> Option<usize> {
4588    match rids.get(offset + index) {
4589        Some(&NO_ROW) | None => None,
4590        Some(&rid) => Some(rid as usize),
4591    }
4592}
4593
4594/// A run of data copied at the given positions, with a zero wherever the position is [`NOWHERE`].
4595///
4596/// A zero and not a skip, because every layout here is a parallel array to a validity mask and a
4597/// short one would put every value after the first null at the wrong index. It is the same rule
4598/// [`push_value`] follows for a null.
4599/// A contiguous run of a flat body, copied out.
4600///
4601/// The counterpart to [`copy_of`] for the one case that is a range rather than a set of positions,
4602/// which is what [`Vector::slice`] asks for. Every fixed width layout is one `memcpy` and the
4603/// string layout is a run of views and their bytes, where `copy_of` is a bounds checked index and a
4604/// null test per row.
4605///
4606/// The caller has already checked that `end` is inside the vector, and a body whose data is shorter
4607/// than its vector claims is a bug elsewhere, so a short run is clamped rather than reported.
4608///
4609/// A fixed width run over a buffer that is a window into a page does not copy anything, because
4610/// [`Buffer::slice`] moves the offset instead. That is the case a scan over stored memory is in, and
4611/// it is why the flat body is no longer the one form of a vector whose cut costs an allocation.
4612fn run_of(data: &Data, at: usize, end: usize) -> Data {
4613    macro_rules! run {
4614        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4615            match data {
4616                Data::Empty => Data::Empty,
4617                $(Data::$variant(values) => {
4618                    let held = values.len();
4619                    let from = at.min(held);
4620                    let to = end.max(from).min(held);
4621                    if to == end {
4622                        // The whole run is there, so this is a window on a shared page and a copy on
4623                        // an owned one, decided inside the buffer rather than here.
4624                        Data::$variant(values.slice(from, end - from))
4625                    } else {
4626                        let values = values.as_slice();
4627                        let mut out = Buffer::with_capacity(end - at);
4628                        out.extend_from_slice(&values[from..to]);
4629                        // A body shorter than the rows asked for pads with the zero every layout
4630                        // uses for a null, which is the answer `copy_of` gives for a position past
4631                        // the end.
4632                        // row at a time: never runs on a vector whose data matches its length.
4633                        for _ in to..end {
4634                            out.push($zero);
4635                        }
4636                        Data::$variant(out)
4637                    }
4638                })+
4639                // A view says where its bytes are, so a run of rows is not a run of bytes and this
4640                // is the one layout whose cut is still a loop. The total is known before any of it
4641                // is copied, so the arena is one allocation.
4642                //
4643                // Unless the payload is a page, in which case the cut points at the same page the
4644                // column does and no byte of it moves. That is the case a scan of a stored column
4645                // is in, and it is the whole of why a producer pages its payload: a page cut into
4646                // chunk sized pieces used to copy every byte of every long string once per piece.
4647                Data::Varlen(values) => {
4648                    if let Some(shared) =
4649                        values.window(at, end).or_else(|| values.viewing(at..end))
4650                    {
4651                        return Data::Varlen(shared);
4652                    }
4653                    let views = values.views();
4654                    let mut out = StringColumn::with_capacity(end - at);
4655                    out.reserve_bytes(
4656                        views
4657                            .get(at.min(views.len())..end.min(views.len()))
4658                            .unwrap_or(&[])
4659                            .iter()
4660                            .filter(|view| !view.is_inline())
4661                            .map(StringView::len)
4662                            .sum(),
4663                    );
4664                    // row at a time: see above, the bytes of consecutive rows need not be next to
4665                    // each other.
4666                    for index in at..end {
4667                        out.push_from(values, index);
4668                    }
4669                    Data::Varlen(out)
4670                }
4671            }
4672        };
4673    }
4674    crate::for_each_layout!(fixed, run)
4675}
4676
4677/// The values of `data` written to the places `inverse` gives them, the other way round from
4678/// [`copy_of`]: value `n` lands at `inverse[n]`.
4679///
4680/// `inverse` is a permutation of the positions of `data` and the answer is as long as it. A place
4681/// past the end is dropped rather than trusted, and a place nobody wrote keeps the zero, the same
4682/// zero a gather writes for a position that resolved to nowhere. Strings are turned back into
4683/// positions and gathered, because their one caller moves the views itself and never sends them.
4684pub(crate) fn placed_of(data: &Data, inverse: &[u32]) -> Data {
4685    macro_rules! placed {
4686        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4687            match data {
4688                $(Data::$variant(values) => {
4689                    let mut out: Vec<$native> = vec![$zero; inverse.len()];
4690                    for (value, &to) in values.as_slice().iter().zip(inverse) {
4691                        if let Some(slot) = out.get_mut(to as usize) {
4692                            *slot = *value;
4693                        }
4694                    }
4695                    Data::$variant(Buffer::from_vec(out))
4696                })+
4697                Data::Empty => Data::Empty,
4698                // Turned back round into positions and gathered, so a caller that does hand this
4699                // strings gets the right answer rather than a missing arm.
4700                Data::Varlen(_) => {
4701                    let mut at = vec![NOWHERE; inverse.len()];
4702                    for (row, &to) in inverse.iter().enumerate() {
4703                        if let Some(slot) = at.get_mut(to as usize) {
4704                            *slot = row;
4705                        }
4706                    }
4707                    copy_of(data, &at)
4708                }
4709            }
4710        };
4711    }
4712    crate::for_each_layout!(fixed, placed)
4713}
4714
4715pub(crate) fn copy_of(data: &Data, at: &[usize]) -> Data {
4716    macro_rules! copied {
4717        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4718            match data {
4719                Data::Empty => Data::Empty,
4720                $(Data::$variant(values) => {
4721                    let values = values.as_slice();
4722                    // Into a `Vec` and then into a buffer, rather than pushing at the buffer. A
4723                    // push asks the buffer whether it owns its run and copies the page out if it
4724                    // does not, which is the copy on write point and is the right answer for a
4725                    // caller writing one value. This caller is writing `at.len()` of them into a
4726                    // run it made itself one line earlier, so the question has one answer and it
4727                    // is asked once by not being asked at all. The map is exact sized, so the
4728                    // extend reserves once and writes without a capacity check per value.
4729                    let mut out: Vec<$native> = Vec::with_capacity(at.len());
4730                    // One bounds check rather than a null test and a bounds check, because
4731                    // `NOWHERE` is past the end of every slice there can be.
4732                    out.extend(at.iter().map(|&index| values.get(index).copied().unwrap_or($zero)));
4733                    Data::$variant(Buffer::from_vec(out))
4734                })+
4735                // The one layout where a gather is a copy of bytes rather than a copy of fixed
4736                // width slots, and the reason compaction is a decision rather than a default on a
4737                // string column. A payload that is a page is the exception: the gathered views
4738                // point at the page the column already points at, so the gather is sixteen bytes a
4739                // row and the bytes stay where the page put them.
4740                Data::Varlen(values) => {
4741                    if let Some(shared) = values.viewing(at.iter().copied()) {
4742                        return Data::Varlen(shared);
4743                    }
4744                    let mut out = StringColumn::with_capacity(at.len());
4745                    // The bytes are known before any of them are copied, because a view carries its
4746                    // length and the wanted positions are already in hand, so the arena is one
4747                    // allocation rather than a run of doublings that each copy what the last one
4748                    // copied.
4749                    let views = values.views();
4750                    out.reserve_bytes(
4751                        at.iter()
4752                            .filter_map(|&index| views.get(index))
4753                            .filter(|view| !view.is_inline())
4754                            .map(StringView::len)
4755                            .sum(),
4756                    );
4757                    for &index in at {
4758                        out.push_from(values, index);
4759                    }
4760                    Data::Varlen(out)
4761                }
4762            }
4763        };
4764    }
4765    crate::for_each_layout!(fixed, copied)
4766}
4767
4768/// The physical layout a run of data is in, for the check that it matches its type.
4769///
4770/// The two enums name their variants the same way on purpose, so this is one generated arm rather
4771/// than sixteen chances to pair the wrong two up.
4772pub(crate) fn layout_of(data: &Data) -> rudb_common::PhysicalType {
4773    use rudb_common::PhysicalType as P;
4774    macro_rules! layouts {
4775        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4776            match data {
4777                Data::Empty => P::Empty,
4778                $(Data::$variant(_) => P::$variant,)+
4779            }
4780        };
4781    }
4782    crate::for_each_layout!(all, layouts)
4783}
4784
4785/// One value out of a run of data, given what the run means.
4786///
4787/// The match is on the logical type rather than on the data, because the data cannot tell a `DATE`
4788/// from an `INTEGER` and that is the whole reason the two are kept apart.
4789fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
4790    let signed = || data.signed_at(index);
4791    let unsigned = || data.unsigned_at(index);
4792    let value = match ty {
4793        LogicalType::Boolean => match data {
4794            Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
4795            _ => None,
4796        },
4797        LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
4798        LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
4799        LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
4800        LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
4801        LogicalType::HugeInt => signed().map(Value::HugeInt),
4802        LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
4803        LogicalType::USmallInt => {
4804            unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
4805        }
4806        LogicalType::UInteger => {
4807            unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
4808        }
4809        LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
4810        LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
4811        LogicalType::Float => match data {
4812            Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
4813            _ => None,
4814        },
4815        LogicalType::Double => match data {
4816            Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
4817            _ => None,
4818        },
4819        LogicalType::Decimal { width, scale } => {
4820            signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
4821        }
4822        LogicalType::Varchar | LogicalType::Blob | LogicalType::Bit => {
4823            data.bytes_at(index).map(|bytes| bytes_as(ty, bytes))
4824        }
4825        LogicalType::Enum(labels) => unsigned()
4826            .and_then(|code| labels.get(usize::try_from(code).ok()?))
4827            .map(|label| Value::Varchar(label.clone())),
4828        LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
4829        LogicalType::Time => signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time),
4830        LogicalType::TimeTz => signed().and_then(|x| i64::try_from(x).ok()).map(Value::TimeTz),
4831        LogicalType::Timestamp
4832        | LogicalType::TimestampS
4833        | LogicalType::TimestampMs
4834        | LogicalType::TimestampNs => {
4835            signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
4836        }
4837        LogicalType::TimestampTz => {
4838            signed().and_then(|x| i64::try_from(x).ok()).map(Value::TimestampTz)
4839        }
4840        LogicalType::Interval => match data {
4841            Data::Interval(v) => {
4842                v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
4843            }
4844            _ => None,
4845        },
4846        _ => None,
4847    };
4848    value.unwrap_or(Value::Null)
4849}
4850
4851/// The fields a struct type names, and nothing for any other type.
4852///
4853/// Only a `STRUCT` vector has a [`Body::Fields`] body, and the two are built together, so in practice
4854/// the empty slice is unreachable and is here so that reading a field name is not a panic if that ever
4855/// stops being true. A struct vector whose type has fewer fields than it has children answers about
4856/// the fields it can name, because the zip stops at the shorter of the two.
4857fn fields_of(ty: &LogicalType) -> &[Field] {
4858    match ty {
4859        LogicalType::Struct(fields) => fields,
4860        _ => &[],
4861    }
4862}
4863
4864/// One row of a string column as a value, given what its bytes are meant to be read as.
4865///
4866/// Both forms that hold strings come through here, so a row that is a `BLOB` in a flat column is a
4867/// `BLOB` in a string view column too. Bytes that are not text in a `VARCHAR` column are a null
4868/// rather than a panic, since everything that got in went in as a string and a column that has
4869/// something else in it is a bug somewhere earlier that a read should not turn into a crash.
4870fn bytes_as(ty: &LogicalType, bytes: &[u8]) -> Value {
4871    match ty {
4872        LogicalType::Varchar => {
4873            std::str::from_utf8(bytes).map_or(Value::Null, |text| Value::Varchar(text.to_owned()))
4874        }
4875        LogicalType::Blob => Value::Blob(bytes.to_vec()),
4876        LogicalType::Bit => Value::Bit(bytes.to_vec()),
4877        _ => Value::Null,
4878    }
4879}
4880
4881/// An empty run of data of the right layout for a type.
4882pub(crate) fn empty_data_for(ty: &LogicalType) -> Result<Data> {
4883    use rudb_common::PhysicalType as P;
4884    macro_rules! empties {
4885        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4886            match ty.physical() {
4887                P::Empty => Data::Empty,
4888                $(P::$variant => Data::$variant(Buffer::new()),)+
4889                P::Varlen => Data::Varlen(StringColumn::new()),
4890                other => {
4891                    return Err(Error::not_implemented(format!(
4892                        "a flat vector of {other:?} data, which arrives with the storage layer"
4893                    )));
4894                }
4895            }
4896        };
4897    }
4898    Ok(crate::for_each_layout!(fixed, empties))
4899}
4900
4901/// An empty run of the type's layout with room for `rows` values already taken.
4902///
4903/// For a caller that knows how many values are going in before the first one does, which is a
4904/// producer laying pieces end to end. Growing from empty instead reallocates once per doubling and
4905/// finishes holding a run rounded up to the next power of two, and on a row group of 122,880 values
4906/// that rounding is the last 8,192 of them carried for the life of the table.
4907///
4908/// Bytes are not reserved for a varlen run, because how many of them there are is not the number of
4909/// rows and the caller appending them is the one that can work it out.
4910///
4911/// # Errors
4912///
4913/// If the type has no flat layout, the same as [`empty_data_for`].
4914pub(crate) fn data_for(ty: &LogicalType, rows: usize) -> Result<Data> {
4915    let mut data = empty_data_for(ty)?;
4916    macro_rules! reserved {
4917        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4918            match &mut data {
4919                Data::Empty => {}
4920                $(Data::$variant(values) => values.reserve(rows),)+
4921                Data::Varlen(values) => values.reserve_views(rows),
4922            }
4923        };
4924    }
4925    crate::for_each_layout!(fixed, reserved);
4926    Ok(data)
4927}
4928
4929/// A value the way a run of this type holds it.
4930///
4931/// Only an `ENUM` holds something other than the value itself. A value of one is its string,
4932/// which is what a result reads out and what a test asserts on, and the run holds the position of
4933/// the string in the list instead. Everything else comes back as it went in.
4934fn stored<'v>(ty: &LogicalType, value: &'v Value) -> Result<Cow<'v, Value>> {
4935    match (ty, value) {
4936        (LogicalType::Enum(_), Value::Varchar(_)) => enum_position(ty, value).map(Cow::Owned),
4937        _ => Ok(Cow::Borrowed(value)),
4938    }
4939}
4940
4941/// Where a value of an `ENUM` sits in its list, as the unsigned integer a run of the type holds,
4942/// with a null staying null.
4943///
4944/// # Errors
4945///
4946/// If the type is not an `ENUM` or the value is not one of its strings.
4947pub fn enum_position(ty: &LogicalType, value: &Value) -> Result<Value> {
4948    let label = match (ty, value) {
4949        (_, Value::Null) => return Ok(Value::Null),
4950        (LogicalType::Enum(_), Value::Varchar(label)) => label,
4951        _ => return Err(Error::internal(format!("{value:?} is not a value of {ty}"))),
4952    };
4953    let code = ty
4954        .labels()
4955        .and_then(|labels| labels.iter().position(|one| one == label))
4956        .and_then(|code| u32::try_from(code).ok())
4957        .ok_or_else(|| Error::internal(format!("{label:?} is not a value of {ty}")))?;
4958    Ok(match enum_code_type(ty) {
4959        LogicalType::UTinyInt => Value::UTinyInt(code as u8),
4960        LogicalType::USmallInt => Value::USmallInt(code as u16),
4961        _ => Value::UInteger(code),
4962    })
4963}
4964
4965/// The unsigned integer type the positions of an `ENUM` are held in, which is what `enum_code`
4966/// answers with.
4967#[must_use]
4968pub fn enum_code_type(ty: &LogicalType) -> LogicalType {
4969    match ty.physical() {
4970        rudb_common::PhysicalType::UInt8 => LogicalType::UTinyInt,
4971        rudb_common::PhysicalType::UInt16 => LogicalType::USmallInt,
4972        _ => LogicalType::UInteger,
4973    }
4974}
4975
4976/// Appends one value to a run of data, or a zero of the right shape when it is null.
4977///
4978/// The zero matters. A null still occupies a position, the validity mask is what says it is null,
4979/// and a run of data with a hole in it would put every value after the hole in the wrong place.
4980fn push_value(data: &mut Data, value: &Value) -> Result<()> {
4981    macro_rules! push {
4982        ($vec:expr, $variant:path, $zero:expr) => {
4983            match value {
4984                Value::Null => $vec.push($zero),
4985                $variant(x) => $vec.push(*x),
4986                other => {
4987                    return Err(Error::internal(format!(
4988                        "{other:?} does not belong in this vector"
4989                    )));
4990                }
4991            }
4992        };
4993    }
4994    // A decimal is stored as its unscaled integer in whatever width its precision needs, which
4995    // `LogicalType::physical` decides and which is why the same `Value::Decimal` is at home in four
4996    // different runs. The narrowing cannot fail for a value the binder produced, because the width
4997    // that chose the run is the width in the value, but it is checked rather than assumed because
4998    // an unchecked cast here would silently store a different number.
4999    macro_rules! decimal {
5000        ($vec:expr, $ty:ty, $unscaled:expr) => {
5001            match <$ty>::try_from(*$unscaled) {
5002                Ok(x) => $vec.push(x),
5003                Err(_) => {
5004                    return Err(Error::internal(format!(
5005                        "an unscaled decimal of {} does not fit the run its precision chose",
5006                        $unscaled
5007                    )));
5008                }
5009            }
5010        };
5011    }
5012    match data {
5013        Data::Empty => {}
5014        Data::Bool(v) => push!(v, Value::Boolean, false),
5015        Data::Int8(v) => push!(v, Value::TinyInt, 0),
5016        Data::Int16(v) => match value {
5017            Value::Null => v.push(0),
5018            Value::SmallInt(x) => v.push(*x),
5019            Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
5020            other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
5021        },
5022        Data::Int32(v) => match value {
5023            Value::Null => v.push(0),
5024            Value::Integer(x) | Value::Date(x) => v.push(*x),
5025            Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
5026            other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
5027        },
5028        Data::Int64(v) => match value {
5029            Value::Null => v.push(0),
5030            Value::BigInt(x)
5031            | Value::Time(x)
5032            | Value::TimeTz(x)
5033            | Value::Timestamp(x)
5034            | Value::TimestampTz(x) => v.push(*x),
5035            Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
5036            other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
5037        },
5038        Data::Int128(v) => match value {
5039            Value::Null => v.push(0),
5040            Value::HugeInt(x) => v.push(*x),
5041            Value::Decimal { unscaled, .. } => v.push(*unscaled),
5042            other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
5043        },
5044        Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
5045        Data::UInt16(v) => push!(v, Value::USmallInt, 0),
5046        Data::UInt32(v) => push!(v, Value::UInteger, 0),
5047        Data::UInt64(v) => push!(v, Value::UBigInt, 0),
5048        Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
5049        Data::Float32(v) => push!(v, Value::Float, 0.0),
5050        Data::Float64(v) => push!(v, Value::Double, 0.0),
5051        Data::Interval(v) => match value {
5052            Value::Null => v.push((0, 0, 0)),
5053            Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
5054            other => return Err(Error::internal(format!("{other:?} is not an interval"))),
5055        },
5056        Data::Varlen(column) => match value {
5057            Value::Null => {
5058                column.push("");
5059            }
5060            Value::Varchar(text) => {
5061                column.push(text);
5062            }
5063            // A blob goes in as the bytes it is. The column stores a length and some bytes either
5064            // way, so text is the reading of one rather than a different column, and a blob that
5065            // is not UTF-8 is stored exactly like one that happens to be.
5066            Value::Blob(bytes) | Value::Bit(bytes) => {
5067                column.push_bytes(bytes);
5068            }
5069            other => return Err(Error::internal(format!("{other:?} is not a string"))),
5070        },
5071    }
5072    Ok(())
5073}
5074
5075#[cfg(test)]
5076mod tests {
5077    use std::sync::Arc;
5078
5079    use rudb_common::{Field, LogicalType, Value};
5080
5081    use super::{
5082        Body, Data, FSST_PAYS_AT, Form, MAP_KEY, MAP_VALUE, NO_ROW, VECTOR_SIZE, Vector, below,
5083        packing_base,
5084    };
5085    use crate::buffer::Buffer;
5086    use crate::fsst::SymbolTable;
5087    use crate::string::{StringColumn, StringView};
5088    use crate::validity::Validity;
5089
5090    fn integers(values: &[i32]) -> Vector {
5091        Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec().into())).unwrap()
5092    }
5093
5094    #[test]
5095    fn below_agrees_with_the_largest_code_whether_the_or_settles_it_or_not() {
5096        let cases: [(&[u32], usize); 8] = [
5097            (&[], 0),
5098            (&[], 5),
5099            (&[0, 1, 8191], 8192),
5100            (&[0, 8192], 8192),
5101            // The `or` of 4 and 1 is 5, which is not below 5, so these take the maximum.
5102            (&[4, 1], 5),
5103            (&[4, 5], 5),
5104            (&[3, 4, 2], 5),
5105            (&[7], 7),
5106        ];
5107        for (codes, len) in cases {
5108            let expected = codes.iter().all(|&code| (code as usize) < len);
5109            assert_eq!(below(codes, len), expected, "{codes:?} below {len}");
5110        }
5111    }
5112
5113    #[test]
5114    fn flattening_a_dictionary_by_its_codes_matches_the_general_copy() {
5115        let words = Vector::from_values(
5116            LogicalType::Varchar,
5117            &["alpha", "a string past the inline length", ""]
5118                .map(|text| Value::Varchar(text.into())),
5119        )
5120        .unwrap();
5121        let codes = vec![2, 0, 1, 1, 0, 2, 1];
5122        let cases = [
5123            Vector::dictionary(codes.clone(), integers(&[7, -3, 40])).unwrap(),
5124            Vector::dictionary(codes.clone(), words.clone()).unwrap(),
5125            Vector::dictionary(codes.clone(), words.clone()).unwrap().slice(2, 4).unwrap(),
5126            // The ones the codes cannot answer alone, which take the general copy.
5127            Vector::dictionary(codes.clone(), words.clone())
5128                .unwrap()
5129                .with_validity(Validity::from_run(&[true, false, true, true, true, true, false])),
5130            Vector::dictionary(
5131                vec![0, 1, 1],
5132                integers(&[1, 2]).with_validity(Validity::from_run(&[true, false])),
5133            )
5134            .unwrap(),
5135        ];
5136        for (case, vector) in cases.iter().enumerate() {
5137            let flat = vector.flatten().unwrap();
5138            let general = vector.copied((0..vector.len()).collect(), false).unwrap();
5139            assert!(matches!(flat.body, Body::Flat(_)), "case {case}");
5140            assert_eq!(flat.validity, general.validity, "case {case}");
5141            for row in 0..vector.len() {
5142                assert_eq!(flat.value_at(row), general.value_at(row), "case {case} row {row}");
5143            }
5144            assert_eq!(flat, vector.opened().unwrap(), "case {case}");
5145        }
5146    }
5147
5148    #[test]
5149    fn extent_keeps_the_unsigned_order_across_the_sign_bit() {
5150        assert_eq!(super::extent(&[]), None);
5151        assert_eq!(super::extent(&[7]), Some((7, 7)));
5152        let rows = [0x8000_0000, 3, u32::MAX, 0x7fff_ffff, 9];
5153        assert_eq!(super::extent(&rows), Some((3, u32::MAX)));
5154    }
5155
5156    #[test]
5157    fn unpacking_in_bulk_reads_what_a_code_at_a_time_reads_at_every_width() {
5158        let mut state = 0x5eed_0b17_u64;
5159        let mut next = || {
5160            state ^= state << 13;
5161            state ^= state >> 7;
5162            state ^= state << 17;
5163            state
5164        };
5165        let words: Vec<u64> = (0..700).map(|_| next()).collect();
5166        for width in 1..=super::PACKED_WIDTH_MAX {
5167            for offset in [0, 1, 63, 64, 65] {
5168                let packed = super::Packed { words: &words, width, base: 0, offset };
5169                for (from, rows) in [(0, 0), (0, 1), (0, 64), (3, 200), (61, 130), (128, 512)] {
5170                    let mut out = vec![u64::MAX; rows];
5171                    packed.unpack(from, &mut out);
5172                    let want: Vec<u64> = (from..from + rows).map(|row| packed.code(row)).collect();
5173                    assert_eq!(out, want, "width {width} offset {offset} from {from}");
5174                    // The mapped unpack reads the same codes in one pass, and appends, so a vector
5175                    // with something in it already keeps it and the rows land after.
5176                    let mut mapped = vec![-1_i64];
5177                    packed.unpack_mapped(from, rows, &mut mapped, |code| 7 - code as i64);
5178                    let wanted: Vec<i64> = std::iter::once(-1)
5179                        .chain(want.iter().map(|&code| 7 - code as i64))
5180                        .collect();
5181                    assert_eq!(mapped, wanted, "mapped width {width} offset {offset} from {from}");
5182                }
5183                let at = [5_usize, 9, 9, 70, 6, 200, 131];
5184                let want: Vec<u64> = at.iter().map(|&row| packed.code(row)).collect();
5185                assert_eq!(packed.codes_at(|index| at[index], at.len()), want);
5186                let far = [0_usize, 5000];
5187                let want: Vec<u64> = far.iter().map(|&row| packed.code(row)).collect();
5188                assert_eq!(packed.codes_at(|index| far[index], far.len()), want);
5189                // A run, which is the shape unpacked straight into the answer, and two shapes that
5190                // cover the same rows and are not one: reversed and with a row repeated. All three
5191                // have to answer what a code at a time answers, whichever path they take.
5192                for start in [0_usize, 1, 63, 64, 65, 130] {
5193                    for rows in [1_usize, 2, 63, 64, 65, 200] {
5194                        let run: Vec<usize> = (start..start + rows).collect();
5195                        let back: Vec<usize> = run.iter().rev().copied().collect();
5196                        let mut same = run.clone();
5197                        same[rows - 1] = start;
5198                        for shape in [&run, &back, &same] {
5199                            let want: Vec<u64> =
5200                                shape.iter().map(|&row| packed.code(row)).collect();
5201                            assert_eq!(
5202                                packed.codes_at(|index| shape[index], shape.len()),
5203                                want,
5204                                "width {width} offset {offset} start {start} rows {rows}"
5205                            );
5206                        }
5207                    }
5208                }
5209                // The same shapes into a buffer the caller keeps, filled with a code no width can
5210                // hold first, so that a row left as it arrived is a wrong answer rather than a zero
5211                // that happens to be right. A buffer wider than the rows asked for keeps the rest.
5212                let mut held = vec![u64::MAX; 260];
5213                for start in [0_usize, 1, 64, 130] {
5214                    for rows in [1_usize, 63, 64, 200] {
5215                        let run: Vec<usize> = (start..start + rows).collect();
5216                        let back: Vec<usize> = run.iter().rev().copied().collect();
5217                        for shape in [&run, &back] {
5218                            held.iter_mut().for_each(|code| *code = u64::MAX);
5219                            packed.codes_into(|index| shape[index], shape.len(), &mut held);
5220                            let want: Vec<u64> =
5221                                shape.iter().map(|&row| packed.code(row)).collect();
5222                            assert_eq!(
5223                                &held[..rows],
5224                                &want[..],
5225                                "width {width} offset {offset} start {start} rows {rows}"
5226                            );
5227                            assert!(
5228                                held[rows..].iter().all(|&code| code == u64::MAX),
5229                                "width {width} wrote past the {rows} rows it was asked for"
5230                            );
5231                        }
5232                    }
5233                }
5234                for rows in [&[][..], &[5, 9, 9, 70, 6, 200, 131], &[0, 5000], &[3, 4, 5, 6]] {
5235                    let want: Vec<u64> =
5236                        rows.iter().map(|&row| packed.code(row as usize)).collect();
5237                    assert_eq!(packed.values_at(rows, |code| code), want, "width {width}");
5238                }
5239            }
5240        }
5241    }
5242
5243    /// A `Value::List` of integers, which is what a row of a list column arrives as.
5244    fn list(values: &[i32]) -> Value {
5245        Value::List {
5246            element: LogicalType::Integer,
5247            values: values.iter().map(|&v| Value::Integer(v)).collect(),
5248        }
5249    }
5250
5251    fn list_column(rows: &[Value]) -> Vector {
5252        Vector::from_values(LogicalType::list(LogicalType::Integer), rows).unwrap()
5253    }
5254
5255    #[test]
5256    fn a_list_column_is_one_child_and_a_range_per_row() {
5257        let rows = vec![list(&[1, 2, 3]), list(&[]), Value::Null, list(&[4])];
5258        let column = list_column(&rows);
5259        assert_eq!(column.form(), Form::List);
5260        assert_eq!(column.len(), 4);
5261        assert_eq!(column.logical_type(), &LogicalType::list(LogicalType::Integer));
5262        // Four rows and four elements, because a null and an empty list both contribute none.
5263        let (entries, child) = column.list_parts().expect("a list");
5264        assert_eq!(entries, [(0, 3), (3, 0), (3, 0), (3, 1)]);
5265        assert_eq!(child.len(), 4);
5266        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
5267    }
5268
5269    /// The one thing the entries cannot say on their own, so it has to be checked that the mask says
5270    /// it. An empty list is a row that is there and holds nothing, a null is a row that is not there,
5271    /// and both of them have an entry of length zero.
5272    #[test]
5273    fn an_empty_list_and_a_null_list_have_the_same_entry_and_are_different_rows() {
5274        let column = list_column(&[list(&[]), Value::Null]);
5275        let (entries, _) = column.list_parts().expect("a list");
5276        assert_eq!(entries[0].1, entries[1].1, "both entries are empty");
5277        assert!(!column.is_null_at(0), "an empty list is not null");
5278        assert!(column.is_null_at(1), "a null list is null");
5279        assert_eq!(column.value_at(0), list(&[]));
5280        assert_eq!(column.value_at(1), Value::Null);
5281    }
5282
5283    #[test]
5284    fn slicing_a_list_column_shares_the_child_rather_than_copying_it() {
5285        let rows: Vec<Value> = (0..64).map(|row| list(&[row, row + 1, row + 2])).collect();
5286        let column = list_column(&rows);
5287        let cut = column.slice(8, 4).unwrap();
5288        assert_eq!(cut.form(), Form::List);
5289        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[8..12]);
5290        // The entries are absolute positions in a child that was not cut, which is what makes the
5291        // cut eight bytes a row however long the lists are. The elements outside the range are still
5292        // there and nothing points at them.
5293        let (entries, child) = cut.list_parts().expect("a list");
5294        assert_eq!(entries[0], (24, 3));
5295        assert_eq!(child.len(), 192);
5296    }
5297
5298    #[test]
5299    fn gathering_a_list_column_permutes_the_entries_and_leaves_the_child_alone() {
5300        let rows = vec![list(&[1]), list(&[2, 2]), list(&[3, 3, 3])];
5301        let column = list_column(&rows);
5302        let picked = column.gather(&[2, 0, 2]).unwrap();
5303        assert_eq!(
5304            picked.iter().collect::<Vec<_>>(),
5305            [list(&[3, 3, 3]), list(&[1]), list(&[3, 3, 3])]
5306        );
5307        // Two of the three rows are the same row, which is the case a run of offsets cannot write
5308        // down and a start and a length can. That is the whole reason this form carries both.
5309        assert_eq!(picked.list_parts().expect("a list").1.len(), 6);
5310    }
5311
5312    #[test]
5313    fn a_gather_past_the_end_of_a_list_column_is_null_rather_than_somebody_elses_elements() {
5314        let column = list_column(&[list(&[1, 2]), list(&[3])]);
5315        let picked = column.gather(&[1, 9]).unwrap();
5316        assert_eq!(picked.value_at(0), list(&[3]));
5317        assert_eq!(picked.value_at(1), Value::Null);
5318    }
5319
5320    #[test]
5321    fn a_list_of_lists_nests_as_far_as_it_is_written() {
5322        let outer = Value::List {
5323            element: LogicalType::list(LogicalType::Integer),
5324            values: vec![list(&[1, 2]), list(&[3])],
5325        };
5326        let column = Vector::from_values(
5327            LogicalType::list(LogicalType::list(LogicalType::Integer)),
5328            std::slice::from_ref(&outer),
5329        )
5330        .unwrap();
5331        assert_eq!(column.value_at(0), outer);
5332        assert_eq!(column.list_parts().expect("a list").1.form(), Form::List);
5333    }
5334
5335    /// A list row is not bytes and not an integer, and a caller that asks for either gets nothing
5336    /// rather than the first element or a length. Both of those would be a wrong answer that a
5337    /// group by or a hash would read without complaining.
5338    #[test]
5339    fn the_scalar_readers_decline_a_list_instead_of_answering_about_its_elements() {
5340        let column = list_column(&[list(&[7])]);
5341        assert_eq!(column.signed_at(0), None);
5342        assert_eq!(column.bytes_at(0), None);
5343        assert_eq!(column.data(), None);
5344    }
5345
5346    fn pair(a: i32, b: &str) -> Value {
5347        Value::Struct(vec![
5348            ("a".to_string(), Value::Integer(a)),
5349            ("b".to_string(), Value::Varchar(b.to_string())),
5350        ])
5351    }
5352
5353    fn pair_type() -> LogicalType {
5354        LogicalType::Struct(vec![
5355            Field::new("a", LogicalType::Integer),
5356            Field::new("b", LogicalType::Varchar),
5357        ])
5358    }
5359
5360    fn pair_column(rows: &[Value]) -> Vector {
5361        Vector::from_values(pair_type(), rows).unwrap()
5362    }
5363
5364    #[test]
5365    fn a_struct_column_is_one_child_per_field_as_long_as_the_column() {
5366        let rows = vec![pair(1, "x"), pair(2, "y"), pair(3, "z")];
5367        let column = pair_column(&rows);
5368        assert_eq!(column.form(), Form::Struct);
5369        assert_eq!(column.len(), 3);
5370        assert_eq!(column.logical_type(), &pair_type());
5371        // Two children rather than two entries and a child, and both of them as long as the column,
5372        // which is the whole difference between this form and the list one.
5373        let children = column.struct_parts().expect("a struct");
5374        assert_eq!(children.len(), 2);
5375        assert_eq!(children[0].len(), 3);
5376        assert_eq!(children[1].len(), 3);
5377        assert_eq!(children[0].logical_type(), &LogicalType::Integer);
5378        assert_eq!(children[1].logical_type(), &LogicalType::Varchar);
5379        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
5380    }
5381
5382    /// Picking one field out of a struct is picking one child, which is the reason this accessor is
5383    /// public. A projection of `s.a` hands back a vector that already exists, so it costs a pointer
5384    /// rather than a pass over the rows, and that is only true while the children are full length.
5385    #[test]
5386    fn one_field_of_a_struct_column_is_a_column_that_is_already_there() {
5387        let column = pair_column(&[pair(10, "x"), pair(20, "y")]);
5388        let field = &column.struct_parts().expect("a struct")[0];
5389        assert_eq!(field.iter().collect::<Vec<_>>(), [Value::Integer(10), Value::Integer(20)]);
5390        assert_eq!(field.signed_at(1), Some(20), "the field is a scalar column and reads like one");
5391    }
5392
5393    /// A null struct is a bit in the mask at the top and nothing deeper, which is how every other type
5394    /// records a null and is what DuckDB does. The row reads as a single null rather than as a struct of
5395    /// nulls, and the fields underneath are still their own columns.
5396    #[test]
5397    fn a_null_struct_is_the_mask_at_the_top_and_not_a_struct_full_of_nulls() {
5398        let column = pair_column(&[pair(1, "x"), Value::Null]);
5399        assert!(!column.is_null_at(0));
5400        assert!(column.is_null_at(1));
5401        assert_eq!(column.value_at(1), Value::Null);
5402        // A struct row whose every field happens to be null is a different row, and it is not null.
5403        let all_null = pair_column(&[Value::Struct(vec![
5404            ("a".to_string(), Value::Null),
5405            ("b".to_string(), Value::Null),
5406        ])]);
5407        assert!(!all_null.is_null_at(0), "a struct of nulls is a row that is there");
5408        assert_ne!(all_null.value_at(0), Value::Null);
5409    }
5410
5411    #[test]
5412    fn slicing_a_struct_column_cuts_every_field_at_the_same_place() {
5413        let rows: Vec<Value> = (0..64).map(|row| pair(row, "s")).collect();
5414        let column = pair_column(&rows);
5415        let cut = column.slice(8, 4).unwrap();
5416        assert_eq!(cut.form(), Form::Struct);
5417        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[8..12]);
5418        // The cut a list column does not have to do. A list shares its child untouched because the
5419        // entries carry the range, and a struct has no entry standing between the row and the child,
5420        // so every child is four rows long here rather than sixty four.
5421        for child in cut.struct_parts().expect("a struct") {
5422            assert_eq!(child.len(), 4);
5423        }
5424    }
5425
5426    #[test]
5427    fn gathering_a_struct_column_gathers_every_field_at_the_same_positions() {
5428        let column = pair_column(&[pair(1, "x"), pair(2, "y"), pair(3, "z")]);
5429        let picked = column.gather(&[2, 0, 2]).unwrap();
5430        assert_eq!(picked.iter().collect::<Vec<_>>(), [pair(3, "z"), pair(1, "x"), pair(3, "z")]);
5431        for child in picked.struct_parts().expect("a struct") {
5432            assert_eq!(child.len(), 3, "a field is as long as the gather, not as the source");
5433        }
5434    }
5435
5436    #[test]
5437    fn a_gather_past_the_end_of_a_struct_column_is_null_in_every_field_and_at_the_top() {
5438        let column = pair_column(&[pair(1, "x"), pair(2, "y")]);
5439        let picked = column.gather(&[1, 9]).unwrap();
5440        assert_eq!(picked.value_at(0), pair(2, "y"));
5441        assert_eq!(picked.value_at(1), Value::Null);
5442        for child in picked.struct_parts().expect("a struct") {
5443            assert!(child.is_null_at(1), "a row that came from nowhere has no field value either");
5444        }
5445    }
5446
5447    /// The names are matched and not counted, because a caller holding a struct value built in a
5448    /// different order from the type's would otherwise get its columns transposed, and that is a wrong
5449    /// answer that reads as a right one.
5450    #[test]
5451    fn the_fields_of_a_struct_value_go_in_by_name_rather_than_by_position() {
5452        let swapped = Value::Struct(vec![
5453            ("b".to_string(), Value::Varchar("x".to_string())),
5454            ("a".to_string(), Value::Integer(1)),
5455        ]);
5456        let column = pair_column(&[swapped]);
5457        assert_eq!(column.value_at(0), pair(1, "x"));
5458        let wrong = Value::Struct(vec![
5459            ("a".to_string(), Value::Integer(1)),
5460            ("c".to_string(), Value::Varchar("x".to_string())),
5461        ]);
5462        let failed = Vector::from_values(pair_type(), &[wrong]);
5463        assert!(failed.is_err(), "a row with no b field is an error rather than a null b");
5464    }
5465
5466    #[test]
5467    fn a_struct_built_from_children_takes_its_field_names_from_the_caller() {
5468        let column = Vector::structure(vec![
5469            ("a".to_string(), integers(&[1, 2, 3])),
5470            ("b".to_string(), integers(&[4, 5, 6])),
5471        ])
5472        .expect("two columns of three");
5473        assert_eq!(column.len(), 3);
5474        assert_eq!(
5475            column.logical_type(),
5476            &LogicalType::Struct(vec![
5477                Field::new("a", LogicalType::Integer),
5478                Field::new("b", LogicalType::Integer),
5479            ])
5480        );
5481        assert_eq!(
5482            column.value_at(1),
5483            Value::Struct(vec![
5484                ("a".to_string(), Value::Integer(2)),
5485                ("b".to_string(), Value::Integer(5)),
5486            ])
5487        );
5488    }
5489
5490    /// The two mistakes this constructor makes easy, both refused rather than stored. A short field is
5491    /// the one that matters: it would be a struct that reads past the end of one of its own children,
5492    /// which is the same mistake `Vector::list` checks for at the other end.
5493    #[test]
5494    fn a_struct_of_uneven_children_or_of_no_children_is_refused() {
5495        let uneven = Vector::structure(vec![
5496            ("a".to_string(), integers(&[1, 2, 3])),
5497            ("b".to_string(), integers(&[4, 5])),
5498        ]);
5499        assert!(uneven.is_err(), "a field shorter than the struct");
5500        assert!(Vector::structure(vec![]).is_err(), "no field to take a length from");
5501    }
5502
5503    #[test]
5504    fn a_struct_of_lists_and_a_list_of_structs_both_nest() {
5505        let ty =
5506            LogicalType::Struct(vec![Field::new("a", LogicalType::list(LogicalType::Integer))]);
5507        let row = Value::Struct(vec![("a".to_string(), list(&[1, 2]))]);
5508        let column = Vector::from_values(ty, std::slice::from_ref(&row)).unwrap();
5509        assert_eq!(column.value_at(0), row);
5510        assert_eq!(column.struct_parts().expect("a struct")[0].form(), Form::List);
5511
5512        let outer = Value::List { element: pair_type(), values: vec![pair(1, "x"), pair(2, "y")] };
5513        let lists =
5514            Vector::from_values(LogicalType::list(pair_type()), std::slice::from_ref(&outer))
5515                .unwrap();
5516        assert_eq!(lists.value_at(0), outer);
5517        assert_eq!(lists.list_parts().expect("a list").1.form(), Form::Struct);
5518    }
5519
5520    fn tags(pairs: &[(&str, &str)]) -> Value {
5521        Value::map(
5522            LogicalType::Varchar,
5523            LogicalType::Varchar,
5524            pairs
5525                .iter()
5526                .map(|&(key, value)| {
5527                    (Value::Varchar(key.to_string()), Value::Varchar(value.to_string()))
5528                })
5529                .collect(),
5530        )
5531    }
5532
5533    fn tag_column(rows: &[Value]) -> Vector {
5534        Vector::from_values(LogicalType::map(LogicalType::Varchar, LogicalType::Varchar), rows)
5535            .unwrap()
5536    }
5537
5538    /// A map is a list of two field structs, which is the whole design, so the test that says so is
5539    /// the one that reaches through both layers and finds the pieces where each of them puts them.
5540    #[test]
5541    fn a_map_column_is_a_list_whose_child_is_a_struct_of_keys_and_values() {
5542        let rows =
5543            vec![tags(&[("a", "b"), ("c", "d")]), tags(&[]), Value::Null, tags(&[("e", "f")])];
5544        let column = tag_column(&rows);
5545        assert_eq!(column.len(), 4);
5546        assert_eq!(
5547            column.logical_type(),
5548            &LogicalType::map(LogicalType::Varchar, LogicalType::Varchar)
5549        );
5550        // The physical form is a list's, because the bytes are a list's. The logical type is what
5551        // remembers it is a map, which is the same split `LogicalType::physical` already makes.
5552        assert_eq!(column.form(), Form::List);
5553        let (entries, child) = column.list_parts().expect("the layout of a list");
5554        assert_eq!(entries, [(0, 2), (2, 0), (2, 0), (2, 1)]);
5555        assert_eq!(child.form(), Form::Struct);
5556        assert_eq!(
5557            child.logical_type(),
5558            &LogicalType::Struct(vec![
5559                Field::new(MAP_KEY, LogicalType::Varchar),
5560                Field::new(MAP_VALUE, LogicalType::Varchar),
5561            ])
5562        );
5563        // And the accessor that reaches through it hands back the two columns rather than the struct.
5564        let (entries, keys, values) = column.map_parts().expect("a map");
5565        assert_eq!(entries.len(), 4);
5566        assert_eq!(keys.text_at(0), Some("a"));
5567        assert_eq!(values.text_at(0), Some("b"));
5568        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
5569    }
5570
5571    /// The same distinction a list has, checked again here rather than assumed from the composition,
5572    /// because the empty map is the one every catalog table in D2 is full of and a null map is what a
5573    /// column with no tags at all would be.
5574    #[test]
5575    fn an_empty_map_and_a_null_map_are_different_rows() {
5576        let column = tag_column(&[tags(&[]), Value::Null]);
5577        assert!(!column.is_null_at(0), "an empty map is a row that is there");
5578        assert!(column.is_null_at(1));
5579        assert_eq!(column.value_at(0), tags(&[]));
5580        assert_eq!(column.value_at(1), Value::Null);
5581        assert_eq!(column.value_at(0).to_string(), "{}");
5582        assert_eq!(column.value_at(1).to_string(), "NULL");
5583    }
5584
5585    /// A map prints `{a=b}` and a struct prints `{'a': b}`, both measured off the pin. They share a
5586    /// layout and they cannot share a printer, which is the one thing about this composition that does
5587    /// not fall out of it.
5588    #[test]
5589    fn a_map_prints_with_equals_signs_and_a_struct_prints_with_quoted_names() {
5590        assert_eq!(tags(&[("a", "b"), ("c", "d")]).to_string(), "{a=b, c=d}");
5591        assert_eq!(pair(1, "x").to_string(), "{'a': 1, 'b': x}");
5592        let numbers = Value::map(
5593            LogicalType::Integer,
5594            LogicalType::Integer,
5595            vec![(Value::Integer(1), Value::Integer(3)), (Value::Integer(2), Value::Integer(4))],
5596        );
5597        assert_eq!(numbers.to_string(), "{1=3, 2=4}");
5598        let null_value = Value::map(
5599            LogicalType::Varchar,
5600            LogicalType::Varchar,
5601            vec![(Value::Varchar("x".to_string()), Value::Null)],
5602        );
5603        assert_eq!(null_value.to_string(), "{x=NULL}");
5604    }
5605
5606    /// A map inherits the list's cut and the list's gather, which is the payoff for storing it as one.
5607    /// Neither of these is code written for maps and both of them are worth a test that says the
5608    /// inheritance works, since the type is rewritten on the way through and a form that came back as a
5609    /// list would still read.
5610    #[test]
5611    fn cutting_and_gathering_a_map_keeps_it_a_map() {
5612        let rows: Vec<Value> =
5613            (0..16).map(|row| tags(&[("k", if row % 2 == 0 { "e" } else { "o" })])).collect();
5614        let column = tag_column(&rows);
5615
5616        let cut = column.slice(4, 3).unwrap();
5617        assert!(matches!(cut.logical_type(), LogicalType::Map(_, _)), "still a map after a cut");
5618        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[4..7]);
5619        // The child was not cut, the same as for a list, which is what makes the cut eight bytes a row.
5620        assert_eq!(cut.map_parts().expect("a map").1.len(), 16);
5621
5622        let picked = column.gather(&[3, 0, 3]).unwrap();
5623        assert!(matches!(picked.logical_type(), LogicalType::Map(_, _)));
5624        assert_eq!(
5625            picked.iter().collect::<Vec<_>>(),
5626            [rows[3].clone(), rows[0].clone(), rows[3].clone()]
5627        );
5628        let past = column.gather(&[0, 99]).unwrap();
5629        assert_eq!(past.value_at(1), Value::Null);
5630    }
5631
5632    #[test]
5633    fn a_map_built_from_two_columns_pairs_them_by_position() {
5634        let keys = Vector::from_values(
5635            LogicalType::Varchar,
5636            &[Value::Varchar("a".to_string()), Value::Varchar("c".to_string())],
5637        )
5638        .unwrap();
5639        let values = Vector::from_values(
5640            LogicalType::Varchar,
5641            &[Value::Varchar("b".to_string()), Value::Varchar("d".to_string())],
5642        )
5643        .unwrap();
5644        let column = Vector::map(vec![(0, 2), (2, 0)], keys, values).expect("two rows");
5645        assert_eq!(column.len(), 2);
5646        assert_eq!(
5647            column.logical_type(),
5648            &LogicalType::map(LogicalType::Varchar, LogicalType::Varchar)
5649        );
5650        assert_eq!(column.value_at(0), tags(&[("a", "b"), ("c", "d")]));
5651        assert_eq!(column.value_at(1), tags(&[]));
5652        // The entry check the list constructor does is the one a map gets, so an entry past the end of
5653        // the pair of columns is refused here too rather than read as somebody else's keys.
5654        let short =
5655            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("a".to_string())]).unwrap();
5656        let other =
5657            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("b".to_string())]).unwrap();
5658        assert!(Vector::map(vec![(0, 9)], short, other).is_err(), "an entry past the end");
5659    }
5660
5661    /// `map_parts` is about the logical type and `list_parts` is about the layout, so a list has to
5662    /// decline the first and a map has to answer the second. Getting that backwards would let a kernel
5663    /// written for maps read a list of two field structs as if it were one.
5664    #[test]
5665    fn a_list_is_not_a_map_however_much_its_child_looks_like_one() {
5666        let pairs = Value::List { element: pair_type(), values: vec![pair(1, "x")] };
5667        let column =
5668            Vector::from_values(LogicalType::list(pair_type()), std::slice::from_ref(&pairs))
5669                .unwrap();
5670        assert!(column.map_parts().is_none(), "a list of structs is a list");
5671        assert!(column.list_parts().is_some());
5672        let map = tag_column(&[tags(&[("a", "b")])]);
5673        assert!(map.map_parts().is_some());
5674        assert!(map.list_parts().is_some(), "a map has a list's layout and says so");
5675    }
5676
5677    /// A struct row is not bytes and not an integer, and it stays that way when it has exactly one
5678    /// integer field, which is the case where answering about the field would look reasonable and would
5679    /// be a hash keyed on the wrong thing.
5680    #[test]
5681    fn the_scalar_readers_decline_a_struct_of_one_integer_field() {
5682        let ty = LogicalType::Struct(vec![Field::new("a", LogicalType::Integer)]);
5683        let row = Value::Struct(vec![("a".to_string(), Value::Integer(7))]);
5684        let column = Vector::from_values(ty, &[row]).unwrap();
5685        assert_eq!(column.signed_at(0), None);
5686        assert_eq!(column.bytes_at(0), None);
5687        assert_eq!(column.data(), None);
5688    }
5689
5690    #[test]
5691    fn a_clustered_column_becomes_runs_and_reads_back_the_same() {
5692        let mut values = Vec::new();
5693        for (value, times) in [(7, 400), (8, 300), (7, 324)] {
5694            values.extend(std::iter::repeat_n(value, times));
5695        }
5696        let flat = integers(&values);
5697        let runs = flat.run_encoded().unwrap();
5698        assert_eq!(runs.form(), Form::Rle);
5699        assert_eq!(runs.run_parts().expect("runs").0, [400, 700, 1024]);
5700        assert_eq!(runs.len(), flat.len());
5701        assert_eq!(runs.iter().collect::<Vec<_>>(), flat.iter().collect::<Vec<_>>());
5702        assert!(
5703            runs.footprint() * 10 < flat.footprint(),
5704            "three runs against a thousand rows: {} against {}",
5705            runs.footprint(),
5706            flat.footprint()
5707        );
5708    }
5709
5710    /// The check is worth having in both directions. A form that is only ever bigger than what it
5711    /// replaced is a form that costs a pass over the column to decide not to use.
5712    #[test]
5713    fn a_column_that_does_not_repeat_is_left_flat() {
5714        let flat = integers(&(0..1024).collect::<Vec<i32>>());
5715        assert_eq!(flat.run_encoded().unwrap().form(), Form::Flat);
5716        // Two runs over four rows is exactly break even on a four byte column, and break even is
5717        // not a reason to change form.
5718        assert_eq!(integers(&[1, 1, 2, 2]).run_encoded().unwrap().form(), Form::Flat);
5719        assert_eq!(integers(&[1, 1, 1, 2, 2]).run_encoded().unwrap().form(), Form::Rle);
5720    }
5721
5722    #[test]
5723    fn two_nulls_beside_each_other_are_one_run_and_a_null_between_two_equals_is_a_break() {
5724        let mut values = vec![Value::Integer(4), Value::Integer(4)];
5725        values.extend([Value::Null, Value::Null, Value::Null]);
5726        values.extend(std::iter::repeat_n(Value::Integer(4), 5));
5727        let flat = Vector::from_values(LogicalType::Integer, &values).unwrap();
5728        let runs = flat.run_encoded().unwrap();
5729        assert_eq!(runs.run_parts().expect("runs").0, [2, 5, 10]);
5730        assert_eq!(runs.iter().collect::<Vec<_>>(), values);
5731    }
5732
5733    #[test]
5734    fn slicing_runs_keeps_them_runs_and_cuts_the_first_and_last_one_back() {
5735        let flat = integers(&[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]);
5736        let runs = flat.run_encoded().unwrap();
5737        let piece = runs.slice(3, 6).unwrap();
5738        assert_eq!(piece.form(), Form::Rle, "the form is the whole point");
5739        assert_eq!(piece.run_parts().expect("runs").0, [1, 5, 6]);
5740        assert_eq!(
5741            piece.iter().collect::<Vec<_>>(),
5742            flat.slice(3, 6).unwrap().iter().collect::<Vec<_>>()
5743        );
5744        assert_eq!(runs.slice(0, 0).unwrap().len(), 0);
5745        assert_eq!(runs.slice(0, 12).unwrap().form(), Form::Rle);
5746    }
5747
5748    #[test]
5749    fn gathering_out_of_runs_walks_to_the_values_the_way_it_walks_a_dictionary() {
5750        let mut values = vec![Value::Varchar("red".into()); 4];
5751        values.extend([Value::Null, Value::Null, Value::Null]);
5752        values.extend(vec![Value::Varchar("blue".into()); 4]);
5753        let runs =
5754            Vector::from_values(LogicalType::Varchar, &values).unwrap().run_encoded().unwrap();
5755        assert_eq!(runs.form(), Form::Rle);
5756        let picked = runs.gather(&[8, 0, 5, 2]).unwrap();
5757        assert_eq!(picked.form(), Form::Flat, "a gather copies, whatever it gathered from");
5758        assert_eq!(
5759            picked.iter().collect::<Vec<_>>(),
5760            [values[8].clone(), values[0].clone(), Value::Null, values[2].clone()]
5761        );
5762        assert_eq!(runs.text_at(1), Some("red"));
5763        assert_eq!(runs.text_at(5), None, "a null has no text");
5764        assert_eq!(runs.flatten().unwrap().iter().collect::<Vec<_>>(), values);
5765    }
5766
5767    /// A run length vector over a run length vector turns one search per row into two, and there is
5768    /// nothing in the engine that builds one, so it is refused rather than composed.
5769    #[test]
5770    fn runs_of_runs_are_refused_and_runs_of_a_dictionary_are_not() {
5771        let inner = integers(&[1, 1, 1, 1, 2]).run_encoded().unwrap();
5772        assert_eq!(inner.form(), Form::Rle);
5773        let error = Vector::runs(vec![2, 8], inner).unwrap_err();
5774        assert!(error.to_string().contains("runs of runs"), "{error}");
5775
5776        let words = Vector::from_values(
5777            LogicalType::Varchar,
5778            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
5779        )
5780        .unwrap();
5781        let dictionary = Vector::dictionary(vec![1, 0], words).unwrap();
5782        let stacked = Vector::runs(vec![4, 9], dictionary).unwrap();
5783        assert_eq!(stacked.len(), 9);
5784        assert_eq!(stacked.value_at(3), Value::Varchar("blue".into()));
5785        assert_eq!(stacked.value_at(4), Value::Varchar("red".into()));
5786    }
5787
5788    #[test]
5789    fn run_ends_have_to_increase_and_there_is_one_value_for_each_of_them() {
5790        let values = integers(&[1, 2]);
5791        assert!(Vector::runs(vec![4], values.clone()).is_err(), "two values and one run");
5792        assert!(Vector::runs(vec![4, 4], values.clone()).is_err(), "an end that repeats");
5793        assert!(Vector::runs(vec![4, 2], values.clone()).is_err(), "an end that goes backwards");
5794        assert!(Vector::runs(vec![0, 2], values.clone()).is_err(), "a first run holding no rows");
5795        assert_eq!(Vector::runs(vec![4, 9], values).unwrap().len(), 9);
5796    }
5797
5798    #[test]
5799    fn a_form_that_is_already_compact_is_left_where_it_is() {
5800        let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1000);
5801        assert_eq!(constant.run_encoded().unwrap().form(), Form::Constant);
5802        assert_eq!(Vector::sequence(0, 1, 1000).run_encoded().unwrap().form(), Form::Sequence);
5803    }
5804
5805    /// What makes one accessor cover both forms. A dictionary hands back the codes it stores and a
5806    /// run length vector works the same numbers out, and a kernel writing `values[at[row]]` reads
5807    /// the same rows out of either.
5808    #[test]
5809    fn both_forms_that_point_somewhere_hand_back_a_position_per_row() {
5810        let words = Vector::from_values(
5811            LogicalType::Varchar,
5812            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
5813        )
5814        .unwrap();
5815        let runs = Vector::runs(vec![3, 5], words.clone()).unwrap();
5816        let (at, values) = runs.positions().expect("runs point somewhere");
5817        assert_eq!(at.as_ref(), [0, 0, 0, 1, 1]);
5818        assert_eq!(values.value_at(at[3] as usize), runs.value_at(3));
5819
5820        let dictionary = Vector::dictionary(vec![1, 0, 1], words).unwrap();
5821        let (at, values) = dictionary.positions().expect("a dictionary points somewhere");
5822        assert_eq!(at.as_ref(), [1, 0, 1]);
5823        assert_eq!(values.value_at(at[0] as usize), dictionary.value_at(0));
5824
5825        assert!(integers(&[1, 2, 3]).positions().is_none(), "a flat vector points at itself");
5826        assert!(Vector::sequence(0, 1, 4).positions().is_none(), "a sequence stores nothing");
5827    }
5828
5829    #[test]
5830    fn slicing_a_dictionary_keeps_it_a_dictionary_where_gathering_would_not() {
5831        let values = Vector::from_values(
5832            LogicalType::Varchar,
5833            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
5834        )
5835        .unwrap();
5836        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
5837
5838        let piece = vector.slice(1, 3).unwrap();
5839        assert_eq!(piece.form(), Form::Dictionary, "the form is the whole point");
5840        assert_eq!(piece.len(), 3);
5841        assert_eq!(
5842            piece.iter().collect::<Vec<_>>(),
5843            [
5844                Value::Varchar("blue".into()),
5845                Value::Varchar("blue".into()),
5846                Value::Varchar("red".into())
5847            ]
5848        );
5849        assert_eq!(vector.gather(&[1, 2, 3]).unwrap().form(), Form::Flat, "which a gather loses");
5850    }
5851
5852    #[test]
5853    fn slicing_a_dictionary_shares_the_dictionary_rather_than_copying_it() {
5854        // The assertion is about the address and not about the values, because the values were
5855        // right when the dictionary was copied too. A page holds one dictionary and is cut into a
5856        // chunk of codes at a time, so copying the dictionary here is a copy of every string in it
5857        // per chunk, and on a read of a ClickBench partition it was ten percent of the cycles.
5858        let values = Vector::from_values(
5859            LogicalType::Varchar,
5860            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
5861        )
5862        .unwrap();
5863        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
5864        let Body::Dictionary { values: whole, .. } = &vector.body else {
5865            panic!("a dictionary vector holds a dictionary");
5866        };
5867
5868        let piece = vector.slice(1, 3).unwrap();
5869        let Body::Dictionary { codes, values: cut, .. } = &piece.body else {
5870            panic!("a slice of a dictionary is a dictionary");
5871        };
5872        assert!(Arc::ptr_eq(whole, cut), "the cut copied the dictionary");
5873        assert_eq!(codes.as_slice(), &[1, 1, 0], "the codes are the part that is cut");
5874
5875        // And a cut of a cut shares it too, since that is what a scan does to a page it reads twice.
5876        let again = piece.slice(1, 2).unwrap();
5877        let Body::Dictionary { values: cut, .. } = &again.body else {
5878            panic!("a slice of a slice of a dictionary is a dictionary");
5879        };
5880        assert!(Arc::ptr_eq(whole, cut), "the second cut copied the dictionary");
5881        assert_eq!(
5882            again.iter().collect::<Vec<_>>(),
5883            [Value::Varchar("blue".into()), Value::Varchar("red".into())]
5884        );
5885    }
5886
5887    /// A parent column read for a link join, and the copy per chunk that not paging it was.
5888    ///
5889    /// The path is the one a kernel takes. A link join emits [`Body::Gathered`] over the parent and
5890    /// reads nothing, and the kernel that first wants the values flattens it, which is where the
5891    /// arena is either taken by handle or copied out of. The arena was already behind an `Arc`
5892    /// before this and every flatten still copied every byte it reached, because the question
5893    /// [`Buffer::is_shared`] answers is about the store inside the `Arc` rather than the `Arc`. On
5894    /// TPC-H q12 that was fourteen hundred copies a query out of a column of five distinct values.
5895    #[test]
5896    fn flattening_a_gather_off_a_paged_parent_takes_the_arena_rather_than_copying_it() {
5897        let arena = Arc::new(Buffer::from_vec(b"1-URGENT2-HIGH".to_vec()));
5898        let views = vec![
5899            StringView::over(b"1-URGENT", 0),
5900            StringView::over(b"2-HIGH", 8),
5901            StringView::over(b"1-URGENT", 0),
5902        ];
5903        let built = Vector::string_views(LogicalType::Varchar, views, arena).unwrap();
5904        let owned = match &built.body {
5905            Body::Views { arena, .. } => arena.is_shared(),
5906            _ => panic!("string views are a views body"),
5907        };
5908        assert!(!owned, "concat builds an arena rather than reading one, so it starts owned");
5909
5910        let bytes = |vector: &Vector| match &vector.body {
5911            Body::Views { arena, .. } => arena.as_slice().as_ptr() as usize,
5912            Body::Flat(Data::Varlen(column)) => column.arena().as_ptr() as usize,
5913            _ => panic!("a string vector holds string bytes"),
5914        };
5915        let gathered = |parent: &Vector| {
5916            Vector::gathered(Arc::new(parent.clone()), Arc::new(vec![1, 0])).unwrap()
5917        };
5918
5919        // Built again rather than cloned, because a clone would be a second holder of the arena and
5920        // paging would decline it, which is the case the test below this one is about.
5921        let paged = Vector::string_views(
5922            LogicalType::Varchar,
5923            built.shared_views().unwrap().0.to_vec(),
5924            Arc::new(Buffer::from_vec(b"1-URGENT2-HIGH".to_vec())),
5925        )
5926        .unwrap()
5927        .into_pages();
5928        assert_eq!(
5929            bytes(&gathered(&paged).flatten().unwrap()),
5930            bytes(&paged),
5931            "a flatten off a page shares the arena"
5932        );
5933        assert_ne!(
5934            bytes(&gathered(&built).flatten().unwrap()),
5935            bytes(&built),
5936            "and off an owned arena it copies, which is what this changed"
5937        );
5938        assert_eq!(
5939            gathered(&paged).flatten().unwrap().iter().collect::<Vec<_>>(),
5940            [Value::Varchar("2-HIGH".into()), Value::Varchar("1-URGENT".into())]
5941        );
5942    }
5943
5944    /// An arena somebody else is still holding is left as it was, because the only way to page it
5945    /// would be to copy it and a copy is the thing the caller asked not to pay for.
5946    #[test]
5947    fn paging_a_string_column_whose_arena_has_another_holder_leaves_it_alone() {
5948        let arena = Arc::new(Buffer::from_vec(b"red".to_vec()));
5949        let vector =
5950            Vector::string_views(LogicalType::Varchar, vec![StringView::over(b"red", 0)], arena)
5951                .unwrap();
5952        // The clone is the other holder: both vectors point at the one arena.
5953        let paged = vector.clone().into_pages();
5954        match &paged.body {
5955            Body::Views { arena, .. } => assert!(!arena.is_shared(), "it was not ours to move"),
5956            _ => panic!("string views are a views body"),
5957        }
5958        assert_eq!(paged.iter().collect::<Vec<_>>(), [Value::Varchar("red".into())]);
5959    }
5960
5961    /// Once the codes are a page, a cut and a clone of a coded column point at the same codes, which
5962    /// is what a scan does to every page of a dictionary encoded Parquet column.
5963    #[test]
5964    fn a_paged_dictionary_shares_its_codes_with_its_cuts_and_clones() {
5965        let values = Vector::from_values(
5966            LogicalType::Varchar,
5967            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
5968        )
5969        .unwrap();
5970        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap().into_pages();
5971        let codes = |vector: &Vector| match &vector.body {
5972            Body::Dictionary { codes, .. } => codes.as_slice().as_ptr() as usize,
5973            _ => panic!("a dictionary vector holds a dictionary"),
5974        };
5975        assert_eq!(codes(&vector.slice(1, 3).unwrap()), codes(&vector) + 4, "the cut copied");
5976        assert_eq!(codes(&vector.clone()), codes(&vector), "the clone copied");
5977        assert_eq!(
5978            vector.slice(1, 3).unwrap().iter().collect::<Vec<_>>(),
5979            [
5980                Value::Varchar("blue".into()),
5981                Value::Varchar("blue".into()),
5982                Value::Varchar("red".into())
5983            ]
5984        );
5985    }
5986
5987    #[test]
5988    fn a_slice_carries_the_nulls_that_were_in_its_range_and_not_the_others() {
5989        let vector =
5990            integers(&[1, 2, 3, 4]).with_validity(Validity::from_run(&[false, true, false, true]));
5991        let piece = vector.slice(1, 2).unwrap();
5992        assert!(piece.validity().is_valid(0));
5993        assert!(!piece.validity().is_valid(1));
5994        assert_eq!(piece.value_at(1), Value::Null);
5995    }
5996
5997    #[test]
5998    fn slicing_a_sequence_moves_its_start_rather_than_writing_the_values_out() {
5999        let vector = Vector::sequence(100, 5, 10);
6000        let piece = vector.slice(3, 4).unwrap();
6001        assert_eq!(piece.form(), Form::Sequence);
6002        assert_eq!(
6003            piece.iter().collect::<Vec<_>>(),
6004            [Value::BigInt(115), Value::BigInt(120), Value::BigInt(125), Value::BigInt(130)]
6005        );
6006    }
6007
6008    #[test]
6009    fn slicing_a_constant_is_a_shorter_constant() {
6010        let vector = Vector::constant(LogicalType::Integer, Value::Integer(9), 8);
6011        let piece = vector.slice(2, 3).unwrap();
6012        assert_eq!(piece.form(), Form::Constant);
6013        assert_eq!(piece.len(), 3);
6014        assert_eq!(piece.value_at(2), Value::Integer(9));
6015    }
6016
6017    #[test]
6018    fn slicing_the_whole_vector_hands_it_back_as_it_was() {
6019        let vector = integers(&[1, 2, 3]);
6020        assert_eq!(
6021            vector.slice(0, 3).unwrap().iter().collect::<Vec<_>>(),
6022            [Value::Integer(1), Value::Integer(2), Value::Integer(3)]
6023        );
6024    }
6025
6026    /// The short way through a gather, a flat run with no nulls, answers what the long way does,
6027    /// and a position past the end still takes the long way and comes back null.
6028    #[test]
6029    fn a_gather_off_a_flat_run_with_no_nulls_answers_what_the_general_copy_does() {
6030        let rows: Vec<i32> = (0..50).map(|row| row * 3 - 20).collect();
6031        let vector = integers(&rows);
6032        let positions: Vec<u32> = [49, 0, 7, 7, 31, 2].into_iter().collect();
6033        let gathered = vector.gather(&positions).unwrap();
6034        assert_eq!(gathered.form(), Form::Flat);
6035        assert_eq!(
6036            gathered.iter().collect::<Vec<_>>(),
6037            positions.iter().map(|&at| Value::Integer(rows[at as usize])).collect::<Vec<_>>()
6038        );
6039        let past = vector.gather(&[3, 50]).unwrap();
6040        assert_eq!(past.iter().collect::<Vec<_>>(), [Value::Integer(-11), Value::Null]);
6041    }
6042
6043    #[test]
6044    fn cutting_a_flat_body_answers_what_gathering_the_same_rows_answers() {
6045        // The cut of a flat body used to be written as a gather over the positions in the range,
6046        // and it is now a run copied out, so the two have to keep saying the same thing. Every
6047        // start and every length, with nulls in the range and out of it, since the validity is the
6048        // half of this that changed shape.
6049        let rows: Vec<i32> = (0..70).collect();
6050        let valid: Vec<bool> = (0..70).map(|row| row % 7 != 0 && row % 11 != 3).collect();
6051        let vector = integers(&rows).with_validity(Validity::from_run(&valid));
6052        for at in 0..70usize {
6053            for len in 0..=(70 - at) {
6054                let cut = vector.slice(at, len).unwrap();
6055                let positions: Vec<u32> = (at..at + len).map(|row| row as u32).collect();
6056                let gathered = vector.gather(&positions).unwrap();
6057                assert_eq!(cut.len(), len, "rows {at} to {}", at + len);
6058                assert_eq!(
6059                    cut.iter().collect::<Vec<_>>(),
6060                    gathered.iter().collect::<Vec<_>>(),
6061                    "rows {at} to {}",
6062                    at + len
6063                );
6064            }
6065        }
6066    }
6067
6068    /// The flat body used to be the one form of a vector whose cut cost an allocation and a copy,
6069    /// and it is not any more when its buffer is a run inside a page. Asserted on the address,
6070    /// because the values are the same either way and the address is the whole claim.
6071    #[test]
6072    fn cutting_a_flat_body_over_a_page_does_not_copy_it() {
6073        let page = Arc::new((0i64..64).collect::<Vec<_>>());
6074        let address = page.as_ptr() as usize;
6075        let data = Data::Int64(Buffer::from_arc(Arc::clone(&page)));
6076        let vector = Vector::flat(LogicalType::BigInt, data).unwrap();
6077        let cut = vector.slice(16, 8).unwrap();
6078        assert_eq!(cut.form(), Form::Flat);
6079        assert_eq!(cut.len(), 8);
6080        let Some(Data::Int64(run)) = cut.data() else {
6081            panic!("the layout changed under the test")
6082        };
6083        assert!(run.is_shared(), "the cut copied the run out of the page");
6084        assert_eq!(run.as_slice().as_ptr() as usize, address + 16 * 8);
6085        assert_eq!(run.as_slice(), &(16i64..24).collect::<Vec<_>>()[..]);
6086        assert_eq!(cut.value_at(0), Value::BigInt(16));
6087        // And the same cut of an owned run says the same thing, by copying it.
6088        let owned = Vector::flat(LogicalType::BigInt, Data::Int64((0i64..64).collect())).unwrap();
6089        let copied = owned.slice(16, 8).unwrap();
6090        let Some(Data::Int64(run)) = copied.data() else {
6091            panic!("the layout changed under the test")
6092        };
6093        assert!(!run.is_shared());
6094        assert_eq!(run.as_slice(), &(16i64..24).collect::<Vec<_>>()[..]);
6095    }
6096
6097    /// `into_pages` is how a producer says its values will be handed out many times. A flat body is
6098    /// the form it changes, and after it a copy of the vector is a reference count bump.
6099    #[test]
6100    fn a_vector_over_pages_is_copied_and_cut_without_its_values_moving() {
6101        let vector = integers(&[1, 2, 3, 4, 5, 6, 7, 8]).into_pages();
6102        let address = |vector: &Vector| match vector.data() {
6103            Some(Data::Int32(values)) => values.as_slice().as_ptr() as usize,
6104            _ => panic!("the layout changed under the test"),
6105        };
6106        let stored = address(&vector);
6107        assert_eq!(address(&vector.clone()), stored, "a copy moved the values");
6108        assert_eq!(address(&vector.slice(2, 4).unwrap()), stored + 2 * 4, "a cut moved the values");
6109        assert_eq!(
6110            vector.slice(2, 4).unwrap().iter().collect::<Vec<_>>(),
6111            [Value::Integer(3), Value::Integer(4), Value::Integer(5), Value::Integer(6)]
6112        );
6113        // Twice is not two pages.
6114        assert_eq!(address(&vector.clone().into_pages()), stored);
6115    }
6116
6117    /// A cut, a gather and a flatten of a string column over a page all move views and no bytes.
6118    ///
6119    /// This is the string half of the paging that `a_vector_over_pages_is_copied_and_cut_without_
6120    /// its_values_moving` checks for a fixed width column, and it is worth its own test because a
6121    /// string column is two allocations rather than one: the cut that matters is the payload
6122    /// staying where it is while the views move.
6123    #[test]
6124    fn a_string_column_over_a_page_is_cut_and_gathered_without_its_payload_moving() {
6125        let long = ["the first of the long strings", "the second one", "and a third long one here"];
6126        let mut built = StringColumn::with_capacity(long.len());
6127        for text in long {
6128            built.push(text);
6129        }
6130        let vector = Vector::flat(LogicalType::Varchar, Data::Varlen(built.into_page())).unwrap();
6131        let payload = |vector: &Vector| match vector.data() {
6132            Some(Data::Varlen(column)) => column.arena().as_ptr() as usize,
6133            _ => panic!("the layout changed under the test"),
6134        };
6135        let stored = payload(&vector);
6136        let cut = vector.slice(1, 2).unwrap();
6137        assert_eq!(payload(&cut), stored, "a cut moved the payload");
6138        assert_eq!(cut.text_at(0), Some(long[1]));
6139        assert_eq!(cut.text_at(1), Some(long[2]));
6140        let gathered = vector.gather(&[2, 0]).unwrap();
6141        assert_eq!(payload(&gathered), stored, "a gather moved the payload");
6142        assert_eq!(gathered.text_at(0), Some(long[2]));
6143        assert_eq!(gathered.text_at(1), Some(long[0]));
6144        // And the same column with its own arena still copies, because sharing an owned arena
6145        // means cloning every byte of it including the bytes nobody asked for.
6146        let mut owned = StringColumn::with_capacity(long.len());
6147        for text in long {
6148            owned.push(text);
6149        }
6150        let held = Vector::flat(LogicalType::Varchar, Data::Varlen(owned)).unwrap();
6151        let copied = held.slice(1, 2).unwrap();
6152        assert_ne!(payload(&copied), payload(&held), "an owned payload was shared");
6153        assert_eq!(copied.text_at(0), Some(long[1]));
6154    }
6155
6156    /// A flatten gives up the form and not the sharing. The views form is already views over an
6157    /// arena, so flattening one over a page is the views and nothing else, and the flat column
6158    /// that comes out reads the same strings out of the same bytes.
6159    #[test]
6160    fn flattening_string_views_over_a_page_keeps_the_page() {
6161        let mut built = StringColumn::with_capacity(2);
6162        built.push("a string too long to sit inside a view");
6163        built.push("another string that is also too long");
6164        let (views, arena) = built.into_page().into_parts();
6165        let stored = arena.as_slice().as_ptr() as usize;
6166        let vector = Vector::string_views(LogicalType::Varchar, views, Arc::new(arena)).unwrap();
6167        assert_eq!(vector.form(), Form::StringView);
6168        let flat = vector.flatten().unwrap();
6169        assert_eq!(flat.form(), Form::Flat);
6170        let Some(Data::Varlen(column)) = flat.data() else {
6171            panic!("the layout changed under the test")
6172        };
6173        assert_eq!(column.arena().as_ptr() as usize, stored, "the flatten moved the payload");
6174        assert_eq!(flat.text_at(0), Some("a string too long to sit inside a view"));
6175        assert_eq!(flat.text_at(1), Some("another string that is also too long"));
6176    }
6177
6178    /// Every form that is not flat already shares what is expensive, so this is a no op on them and
6179    /// in particular does not flatten anything. A form that came back flat would be a column that
6180    /// lost its encoding on the way into a table.
6181    #[test]
6182    fn putting_a_vector_on_pages_does_not_change_any_other_form() {
6183        let dictionary = Vector::dictionary(
6184            vec![0, 1, 0, 1],
6185            Vector::from_values(
6186                LogicalType::Varchar,
6187                &[Value::Varchar("a".into()), Value::Varchar("b".into())],
6188            )
6189            .unwrap(),
6190        )
6191        .unwrap();
6192        let cases = [
6193            Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
6194            Vector::sequence(4, 0, 1),
6195            dictionary,
6196        ];
6197        for vector in cases {
6198            let form = vector.form();
6199            let paged = vector.clone().into_pages();
6200            assert_eq!(paged.form(), form, "{form:?} changed form");
6201            assert_eq!(paged.iter().collect::<Vec<_>>(), vector.iter().collect::<Vec<_>>());
6202        }
6203    }
6204
6205    #[test]
6206    fn cutting_a_flat_string_column_answers_what_gathering_it_answers() {
6207        // The string layout is the one whose cut is still a loop, and it is also the one where a
6208        // row is a view into an arena rather than a slot, so it gets the same treatment separately.
6209        // Both inline and out of line strings, since they are copied by different paths.
6210        let rows: Vec<String> =
6211            (0..40).map(|row| "x".repeat(row % 30) + &row.to_string()).collect();
6212        let values: Vec<Value> = rows.iter().map(|row| Value::Varchar(row.clone())).collect();
6213        let vector = Vector::from_values(LogicalType::Varchar, &values).unwrap().flatten().unwrap();
6214        assert_eq!(vector.form(), Form::Flat, "the cut under test is the flat one");
6215        for at in 0..40usize {
6216            for len in 0..=(40 - at) {
6217                let cut = vector.slice(at, len).unwrap();
6218                let positions: Vec<u32> = (at..at + len).map(|row| row as u32).collect();
6219                let gathered = vector.gather(&positions).unwrap();
6220                assert_eq!(
6221                    cut.iter().collect::<Vec<_>>(),
6222                    gathered.iter().collect::<Vec<_>>(),
6223                    "rows {at} to {}",
6224                    at + len
6225                );
6226            }
6227        }
6228    }
6229
6230    #[test]
6231    fn a_slice_past_the_end_is_an_error_rather_than_a_short_vector() {
6232        let error = integers(&[1, 2, 3]).slice(2, 2).unwrap_err();
6233        assert!(error.to_string().contains("of a vector of 3"), "{error}");
6234    }
6235
6236    #[test]
6237    fn the_vector_size_is_the_one_the_design_is_built_around() {
6238        // 8192, which is four times DuckDB's 2048, measured in #480 against 1024, 2048, 4096 and
6239        // 32768. What the rest of the code assumes about it is not the value but the shape: a
6240        // multiple of 1024, which is the FastLanes unit and is what makes a validity mask a whole
6241        // number of u64 words with none of them half used.
6242        assert_eq!(VECTOR_SIZE, 8192);
6243        assert_eq!(VECTOR_SIZE % 1024, 0);
6244        assert_eq!(VECTOR_SIZE % 64, 0);
6245        assert_eq!(VECTOR_SIZE / 64, 128, "the words in a validity mask");
6246    }
6247
6248    #[test]
6249    fn a_flat_vector_reads_back_what_was_put_in_it() {
6250        let vector = integers(&[1, 2, 3]);
6251        assert_eq!(vector.form(), Form::Flat);
6252        assert_eq!(vector.len(), 3);
6253        assert_eq!(vector.value_at(1), Value::Integer(2));
6254        assert_eq!(
6255            vector.iter().collect::<Vec<_>>(),
6256            vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
6257        );
6258    }
6259
6260    #[test]
6261    fn a_vector_built_from_values_reads_the_same_values_back() {
6262        let vector = Vector::from_values(
6263            LogicalType::Varchar,
6264            &[
6265                Value::Varchar("a".to_string()),
6266                Value::Null,
6267                Value::Varchar("a string too long to sit inside a view".to_string()),
6268            ],
6269        )
6270        .expect("strings and a null");
6271        assert_eq!(vector.len(), 3);
6272        assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
6273        assert_eq!(vector.value_at(1), Value::Null);
6274        assert_eq!(
6275            vector.value_at(2),
6276            Value::Varchar("a string too long to sit inside a view".to_string())
6277        );
6278    }
6279
6280    /// A null still occupies a position. If it did not then every value after it would read back
6281    /// one place to the left, which is the kind of bug that looks like a storage bug for a week.
6282    #[test]
6283    fn a_null_in_the_middle_does_not_move_the_values_after_it() {
6284        let vector = Vector::from_values(
6285            LogicalType::Integer,
6286            &[Value::Integer(1), Value::Null, Value::Integer(3)],
6287        )
6288        .expect("integers and a null");
6289        assert_eq!(vector.value_at(2), Value::Integer(3));
6290        assert!(vector.validity().has_nulls(3), "the middle one is null");
6291    }
6292
6293    #[test]
6294    fn a_value_the_type_cannot_hold_is_refused() {
6295        let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
6296        assert!(wrong.is_err(), "a string is not an integer");
6297    }
6298
6299    #[test]
6300    fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
6301        // One comparison here against a wrong answer read out three layers later.
6302        let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1].into()));
6303        assert!(wrong.is_err());
6304        let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1].into()));
6305        assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
6306    }
6307
6308    #[test]
6309    fn a_constant_vector_costs_one_value_whatever_its_length() {
6310        let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
6311        assert_eq!(vector.form(), Form::Constant);
6312        assert_eq!(vector.len(), VECTOR_SIZE);
6313        assert_eq!(vector.value_at(0), Value::Integer(7));
6314        assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
6315        assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
6316    }
6317
6318    #[test]
6319    fn a_constant_null_is_all_invalid_without_being_told() {
6320        let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
6321        assert_eq!(vector.validity(), &Validity::AllInvalid);
6322        assert_eq!(vector.value_at(3), Value::Null);
6323    }
6324
6325    #[test]
6326    fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
6327        let vector = Vector::sequence(100, 1, VECTOR_SIZE);
6328        assert_eq!(vector.form(), Form::Sequence);
6329        assert_eq!(vector.value_at(0), Value::BigInt(100));
6330        assert_eq!(vector.value_at(923), Value::BigInt(1023));
6331        let stepped = Vector::sequence(0, 5, 4);
6332        assert_eq!(
6333            stepped.iter().collect::<Vec<_>>(),
6334            vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
6335        );
6336    }
6337
6338    #[test]
6339    fn a_dictionary_vector_reads_through_its_codes() {
6340        let mut column = StringColumn::new();
6341        column.push("red");
6342        column.push("green");
6343        let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
6344        let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
6345        assert_eq!(vector.form(), Form::Dictionary);
6346        assert_eq!(vector.logical_type(), &LogicalType::Varchar);
6347        assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
6348        assert_eq!(vector.len(), 4);
6349    }
6350
6351    /// The accessor a group by keys a string column through, which has to agree with `value_at` on
6352    /// every position or two rows holding one string end up in two groups.
6353    #[test]
6354    fn text_is_read_where_it_already_is_for_the_forms_that_store_it() {
6355        let mut column = StringColumn::new();
6356        column.push("red");
6357        column.push("green");
6358        column.push("");
6359        let flat = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
6360        for index in 0..flat.len() {
6361            assert_eq!(flat.text_at(index).map(str::to_string), text_of(&flat.value_at(index)));
6362        }
6363        let dictionary = Vector::dictionary(vec![1, 0, 1, 2], flat).unwrap();
6364        for index in 0..dictionary.len() {
6365            assert_eq!(
6366                dictionary.text_at(index).map(str::to_string),
6367                text_of(&dictionary.value_at(index))
6368            );
6369        }
6370        assert_eq!(dictionary.text_at(4), None, "past the end");
6371    }
6372
6373    /// The forms and types that have no text to hand back, which a caller answers by falling back
6374    /// to `value_at`. A blob is the one that would be a correctness bug rather than a slow path,
6375    /// since its bytes are not required to be text and it is not a `VARCHAR` either way.
6376    #[test]
6377    fn text_is_refused_where_it_is_not_stored_as_itself() {
6378        let nulls =
6379            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into()), Value::Null])
6380                .unwrap();
6381        assert_eq!(nulls.text_at(0), Some("red"));
6382        assert_eq!(nulls.text_at(1), None, "a null has no text");
6383        let constant = Vector::constant(LogicalType::Varchar, Value::Varchar("red".into()), 3);
6384        assert_eq!(constant.text_at(0), None, "a constant is not stored per position");
6385        assert_eq!(integers(&[1, 2]).text_at(0), None, "an integer is not text");
6386        let mut bytes = StringColumn::new();
6387        bytes.push("red");
6388        let blob = Vector::flat(LogicalType::Blob, Data::Varlen(bytes)).unwrap();
6389        assert_eq!(blob.text_at(0), None, "a blob is not a varchar");
6390    }
6391
6392    /// The accessor a group by keys an integer column through, which has to agree with `value_at`
6393    /// on every position or two rows holding one number end up in two groups.
6394    #[test]
6395    fn a_signed_integer_is_read_where_it_already_is_for_the_forms_that_store_it() {
6396        let flat = integers(&[7, -3, 0, 2]);
6397        for index in 0..flat.len() {
6398            assert_eq!(flat.signed_at(index), signed_of(&flat.value_at(index)), "flat {index}");
6399        }
6400        let dictionary = Vector::dictionary(vec![1, 0, 3, 2], flat).unwrap();
6401        for index in 0..dictionary.len() {
6402            assert_eq!(
6403                dictionary.signed_at(index),
6404                signed_of(&dictionary.value_at(index)),
6405                "dictionary {index}"
6406            );
6407        }
6408        assert_eq!(dictionary.signed_at(4), None, "past the end");
6409
6410        let runs = Vector::runs(vec![2, 5], integers(&[4, 9])).unwrap();
6411        for index in 0..runs.len() {
6412            assert_eq!(runs.signed_at(index), signed_of(&runs.value_at(index)), "run {index}");
6413        }
6414        let constant = Vector::constant(LogicalType::BigInt, Value::BigInt(11), 3);
6415        assert_eq!(constant.signed_at(2), Some(11));
6416        let sequence = Vector::sequence(100, 5, 4);
6417        for index in 0..sequence.len() {
6418            assert_eq!(
6419                sequence.signed_at(index),
6420                signed_of(&sequence.value_at(index)),
6421                "sequence {index}"
6422            );
6423        }
6424    }
6425
6426    /// A window of a shared page packs exactly when the same rows owned would, and a range its
6427    /// type cannot hold at the width it needs stays flat rather than failing. A load of ClickBench
6428    /// `hits` hit both: its windows were judged by their share of the page, packed at 32 bits, and
6429    /// the packed form refused a range that ran past `i32::MAX`.
6430    #[test]
6431    fn a_window_of_a_page_packs_the_way_the_same_rows_owned_do() {
6432        let wide: Vec<i32> = (0..122_880)
6433            .map(|at| if at % 2 == 0 { i32::MIN + 5 + at } else { i32::MAX - 9 - at })
6434            .collect();
6435        let narrow: Vec<i32> = (0..122_880).map(|at| 1_000 + at % 200).collect();
6436        for values in [wide, narrow] {
6437            let page = integers(&values).into_pages();
6438            let window = page.slice(0, 8_192).unwrap();
6439            let owned = integers(&values[..8_192]);
6440            let packed_window = window.bit_packed().unwrap();
6441            let packed_owned = owned.bit_packed().unwrap();
6442            assert_eq!(
6443                packed_window.packed_parts().is_some(),
6444                packed_owned.packed_parts().is_some()
6445            );
6446            for at in [0, 1, 4_095, 8_191] {
6447                assert_eq!(packed_window.value_at(at), owned.value_at(at));
6448            }
6449        }
6450    }
6451
6452    /// The forms and types that have no integer to hand back, which a caller answers by falling
6453    /// back to `value_at`.
6454    #[test]
6455    fn a_signed_integer_is_refused_where_it_is_not_stored_as_itself() {
6456        let nulls =
6457            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
6458        assert_eq!(nulls.signed_at(0), Some(4));
6459        assert_eq!(nulls.signed_at(1), None, "a null is not a number");
6460        let packed = integers(&[1, 2, 3, 1]).bit_packed().unwrap();
6461        assert_eq!(packed.signed_at(0), Some(1), "a packed integer is read in code space");
6462        let mut bytes = StringColumn::new();
6463        bytes.push("red");
6464        let text = Vector::flat(LogicalType::Varchar, Data::Varlen(bytes)).unwrap();
6465        assert_eq!(text.signed_at(0), None, "a string is not a number");
6466        let double = Vector::flat(LogicalType::Double, Data::Float64(vec![1.5].into())).unwrap();
6467        assert_eq!(double.signed_at(0), None, "a double is not a signed integer");
6468    }
6469
6470    /// The block form has to agree with the row at a time form on every position of every shape it
6471    /// answers for, because a caller picks one of the two and a group by that read two different
6472    /// numbers for one row would put that row in two groups.
6473    #[test]
6474    fn a_block_of_signed_integers_holds_what_the_row_at_a_time_accessor_hands_back() {
6475        let mut out = Vec::new();
6476        let shapes = [
6477            integers(&[7, -3, 0, 2]),
6478            Vector::flat(LogicalType::Integer, Data::Int32(vec![5, -6, 7].into())).unwrap(),
6479            Vector::flat(LogicalType::SmallInt, Data::Int16(vec![1, -2].into())).unwrap(),
6480            Vector::flat(LogicalType::TinyInt, Data::Int8(vec![-128, 127].into())).unwrap(),
6481            Vector::constant(LogicalType::BigInt, Value::BigInt(11), 3),
6482            Vector::sequence(100, 5, 4),
6483            integers(&[1, 2, 3, 1]).bit_packed().unwrap(),
6484            Vector::dictionary(vec![1, 0, 1, 3], integers(&[7, -3, 0, 2])).unwrap(),
6485            Vector::dictionary(
6486                vec![2, 2, 0],
6487                Vector::flat(LogicalType::SmallInt, Data::Int16(vec![9, -9, 4].into())).unwrap(),
6488            )
6489            .unwrap(),
6490        ];
6491        for column in &shapes {
6492            assert!(column.signed_block(&mut out), "{:?} hands over a block", column.form());
6493            assert_eq!(out.len(), column.len(), "{:?} filled the whole chunk", column.form());
6494            for (index, &held) in out.iter().enumerate() {
6495                assert_eq!(
6496                    Some(i128::from(held)),
6497                    column.signed_at(index),
6498                    "{:?} at {index}",
6499                    column.form()
6500                );
6501            }
6502        }
6503    }
6504
6505    /// The gathered form reads what the row at a time accessor reads at the rows it is given, and
6506    /// refuses a row past the end and a vector that is not flat, leaving nothing behind.
6507    #[test]
6508    fn a_gather_of_signed_integers_holds_what_the_row_at_a_time_accessor_hands_back() {
6509        let mut out = Vec::new();
6510        let at = [0, 2, 2, 3];
6511        let shapes = [
6512            integers(&[7, -3, 0, 2]),
6513            Vector::flat(LogicalType::Integer, Data::Int32(vec![5, -6, 7, -8].into())).unwrap(),
6514            Vector::flat(LogicalType::TinyInt, Data::Int8(vec![-128, 127, 1, 0].into())).unwrap(),
6515        ];
6516        for column in &shapes {
6517            assert!(column.signed_gather(&at, &mut out), "{:?} is gathered", column.logical_type());
6518            let wanted: Vec<i64> = at
6519                .iter()
6520                .map(|&row| i64::try_from(column.signed_at(row as usize).unwrap()).unwrap())
6521                .collect();
6522            assert_eq!(out, wanted);
6523        }
6524        let short = integers(&[1, 2, 3]);
6525        assert!(!short.signed_gather(&at, &mut out), "row 3 is past the end");
6526        assert!(out.is_empty());
6527        assert!(!Vector::sequence(100, 5, 4).signed_gather(&at, &mut out));
6528        assert!(integers(&[1]).signed_gather(&[], &mut out) && out.is_empty());
6529    }
6530
6531    /// The runs of a flat column are its values where they change and the rows they end before,
6532    /// counted from the row the runs were asked from, and a column that changes on every row is
6533    /// given up on.
6534    #[test]
6535    fn the_runs_of_a_flat_column_end_where_its_values_change() {
6536        let mut out = Vec::new();
6537        let column =
6538            Vector::flat(LogicalType::SmallInt, Data::Int16(vec![4, 4, 4, -1, -1, 4, 9].into()))
6539                .unwrap();
6540        assert!(column.signed_runs((1, 7), 1, &mut out));
6541        assert_eq!(out, [(4, 3), (-1, 5), (4, 6), (9, 7)]);
6542        assert!(!column.signed_runs((1, 8), 1, &mut out), "row 7 is past the end");
6543        assert!(out.is_empty());
6544        let changing = integers(&(0..1000).collect::<Vec<_>>());
6545        assert!(!changing.signed_runs((0, 1000), 8, &mut out));
6546        assert!(out.is_empty());
6547        assert!(!Vector::sequence(100, 5, 4).signed_runs((0, 4), 8, &mut out));
6548    }
6549
6550    /// The rows a filter kept out of a part's row numbers are a dictionary over the numbers of the
6551    /// whole part, and the block holds the numbers the codes pick without laying the rest out.
6552    #[test]
6553    fn a_block_of_picked_row_numbers_holds_the_numbers_picked() {
6554        let mut out = Vec::new();
6555        let picked =
6556            Vector::dictionary(vec![0, 3, 3, 8191], Vector::sequence(100, 5, 8192)).unwrap();
6557        assert!(picked.signed_block(&mut out));
6558        assert_eq!(out, [100, 115, 115, 100 + 5 * 8191]);
6559    }
6560
6561    /// What the block form will not answer for, where the caller reads the vector a row at a time
6562    /// instead. A null is not one of them: it writes whatever sits under it and the caller reads the
6563    /// null from the column.
6564    #[test]
6565    fn a_block_is_refused_for_the_shapes_it_would_have_to_gather_or_widen() {
6566        let mut out = Vec::new();
6567        let nulled =
6568            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
6569        assert!(
6570            !Vector::dictionary(vec![1, 0], nulled).unwrap().signed_block(&mut out),
6571            "a dictionary with a null entry would hand its row over as a number"
6572        );
6573        assert!(!Vector::runs(vec![2, 5], integers(&[4, 9])).unwrap().signed_block(&mut out));
6574        let wide = Vector::flat(LogicalType::HugeInt, Data::Int128(vec![1, 2].into())).unwrap();
6575        assert!(!wide.signed_block(&mut out), "a hugeint does not fit sixty four bits");
6576        let double = Vector::flat(LogicalType::Double, Data::Float64(vec![1.5].into())).unwrap();
6577        assert!(!double.signed_block(&mut out), "a double is not a signed integer");
6578        assert!(out.is_empty(), "a refusal leaves the buffer empty");
6579
6580        let nulls =
6581            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
6582        assert!(nulls.signed_block(&mut out), "a flat column with nulls still hands over");
6583        assert_eq!(out[0], 4);
6584    }
6585
6586    /// Asked once for a chunk, and it has to agree with `is_null_at` asked for every row of it.
6587    #[test]
6588    fn a_vector_says_whether_it_holds_any_null_at_all() {
6589        let flat = integers(&[7, -3, 0, 2]);
6590        assert!(flat.none_null());
6591        let nulls =
6592            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
6593        assert!(!nulls.none_null());
6594        assert!(Vector::dictionary(vec![1, 0], flat.clone()).unwrap().none_null());
6595        // The null is in the dictionary rather than in the mask, which is the case the row at a time
6596        // form reads through for and the reason this one does too.
6597        let holed = Vector::dictionary(vec![0, 0], nulls.clone()).unwrap();
6598        assert!(!holed.none_null(), "a dictionary is read through to its values");
6599        assert!(!holed.is_null_at(0), "and no code points at the null it holds");
6600        assert!(Vector::runs(vec![2, 5], integers(&[4, 9])).unwrap().none_null());
6601        assert!(!Vector::runs(vec![1, 2], nulls).unwrap().none_null());
6602        assert!(Vector::constant(LogicalType::BigInt, Value::BigInt(11), 3).none_null());
6603        assert!(!Vector::constant(LogicalType::BigInt, Value::Null, 3).none_null());
6604    }
6605
6606    /// The integer of a value, for comparing `signed_at` against `value_at` position by position.
6607    fn signed_of(value: &Value) -> Option<i128> {
6608        match value {
6609            Value::TinyInt(x) => Some(i128::from(*x)),
6610            Value::SmallInt(x) => Some(i128::from(*x)),
6611            Value::Integer(x) | Value::Date(x) => Some(i128::from(*x)),
6612            Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => Some(i128::from(*x)),
6613            Value::HugeInt(x) | Value::Decimal { unscaled: x, .. } => Some(*x),
6614            _ => None,
6615        }
6616    }
6617
6618    /// The text of a value, for comparing `text_at` against `value_at` position by position.
6619    fn text_of(value: &Value) -> Option<String> {
6620        match value {
6621            Value::Varchar(text) => Some(text.clone()),
6622            _ => None,
6623        }
6624    }
6625
6626    #[test]
6627    fn a_dictionary_code_past_the_end_is_refused() {
6628        // The alternative is a silent read of the wrong value, which is the failure mode the
6629        // entire M3 design has to be careful about.
6630        let values = integers(&[1, 2]);
6631        assert!(Vector::dictionary(vec![0, 2], values).is_err());
6632        // The check runs on the highest code rather than the first bad one, so it has to say that
6633        // no codes at all is fine even when there are no values for them to point at either.
6634        let empty = Vector::dictionary(Vec::new(), integers(&[])).expect("no codes, no values");
6635        assert_eq!(empty.len(), 0);
6636        // And a code of zero against an empty dictionary is still past the end.
6637        assert!(Vector::dictionary(vec![0], integers(&[])).is_err());
6638    }
6639
6640    #[test]
6641    fn every_form_flattens_to_the_same_values_it_reads_out() {
6642        // This is the shape of the equivalence testing in spec/16-testing.md section 16.2, in
6643        // miniature and long before there is an encoded kernel to point it at. A form that reads
6644        // out one way and flattens another is the exact bug that testing exists to catch.
6645        let mut column = StringColumn::new();
6646        column.push("alpha");
6647        column.push("beta");
6648        let dictionary = Vector::dictionary(
6649            vec![1, 0, 1],
6650            Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
6651        )
6652        .unwrap();
6653        let cases = [
6654            Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
6655            Vector::sequence(7, -2, 5),
6656            dictionary,
6657        ];
6658        for vector in cases {
6659            let flat = vector.flatten().unwrap();
6660            assert_eq!(flat.form(), Form::Flat);
6661            assert_eq!(flat.len(), vector.len());
6662            for index in 0..vector.len() {
6663                assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
6664            }
6665        }
6666    }
6667
6668    #[test]
6669    fn a_null_still_occupies_a_position_after_flattening() {
6670        // The reason push_value writes a zero for a null rather than skipping it. A run of data
6671        // with a hole in it puts every value after the hole in the wrong place, and the validity
6672        // mask is what says the position is null.
6673        let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
6674        let flat = vector.flatten().unwrap();
6675        assert_eq!(flat.value_at(0), Value::BigInt(0));
6676        assert_eq!(flat.value_at(1), Value::Null);
6677        assert_eq!(flat.value_at(2), Value::BigInt(2));
6678        assert_eq!(flat.value_at(3), Value::BigInt(3));
6679    }
6680
6681    /// A dictionary holds its nulls in the vector it points at, so its own validity is all valid
6682    /// and reading that instead of the values turns a null into whatever zero means for the type.
6683    /// A filter over a nullable column produces exactly this vector, so the bug reaches a result
6684    /// set as `LEFT JOIN` padding that comes back as zeros.
6685    #[test]
6686    fn a_null_behind_a_dictionary_survives_flattening() {
6687        let values =
6688            Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
6689        let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
6690        let flat = dictionary.flatten().unwrap();
6691        assert_eq!(flat.value_at(0), Value::Null);
6692        assert_eq!(flat.value_at(1), Value::Integer(3));
6693        assert_eq!(flat.value_at(2), Value::Null);
6694    }
6695
6696    /// The property that makes `gather` usable at all: it has to be the same function as reading the
6697    /// wanted positions one at a time, over every form, or compaction changes answers.
6698    #[test]
6699    fn gathering_reads_what_reading_one_position_at_a_time_reads() {
6700        let mut column = StringColumn::new();
6701        column.push("alpha");
6702        column.push("beta");
6703        column.push("gamma");
6704        let cases = [
6705            integers(&[10, 20, 30, 40]),
6706            integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
6707            Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
6708            Vector::sequence(100, -7, 4),
6709            Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
6710            Vector::dictionary(
6711                vec![2, 0, 1, 2],
6712                Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
6713            )
6714            .unwrap(),
6715            Vector::dictionary(
6716                vec![1, 0, 1, 0],
6717                Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
6718                    .unwrap(),
6719            )
6720            .unwrap(),
6721        ];
6722        let wanted = [3_u32, 0, 2, 2, 1];
6723        for vector in cases {
6724            let gathered = vector.gather(&wanted).unwrap();
6725            assert_eq!(gathered.len(), wanted.len());
6726            assert_eq!(gathered.logical_type(), vector.logical_type());
6727            for (slot, &index) in wanted.iter().enumerate() {
6728                assert_eq!(
6729                    gathered.value_at(slot),
6730                    vector.value_at(index as usize),
6731                    "slot {slot} of {:?}",
6732                    vector.form()
6733                );
6734            }
6735        }
6736    }
6737
6738    /// A gather past the end is not an error, because the selection that produced the indices is
6739    /// checked by its caller and the one thing that must not happen here is a read of the wrong
6740    /// value. An index nothing answers is null, which is what an outer join pad needs anyway.
6741    #[test]
6742    fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
6743        let vector = integers(&[1, 2, 3]);
6744        let gathered = vector.gather(&[2, 9]).unwrap();
6745        assert_eq!(gathered.value_at(0), Value::Integer(3));
6746        assert_eq!(gathered.value_at(1), Value::Null);
6747    }
6748
6749    /// The vector with nothing in it at all, which is what an untyped `NULL` is stored as. Every
6750    /// position asked for is past its end, so the answer is nulls and the length has to be the
6751    /// length that was asked for rather than the length that was there.
6752    #[test]
6753    fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
6754        let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
6755        let gathered = vector.gather(&[0, 1, 2]).unwrap();
6756        assert_eq!(gathered.len(), 3);
6757        assert_eq!(gathered.value_at(0), Value::Null);
6758        assert_eq!(gathered.value_at(2), Value::Null);
6759    }
6760
6761    /// Every position holds the same value, so a gather with no hole in it has nothing to copy and
6762    /// the result is the constant again rather than a run of a thousand copies of it.
6763    #[test]
6764    fn gathering_a_constant_stays_a_constant() {
6765        let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
6766        let gathered = vector.gather(&[7, 7, 99]).unwrap();
6767        assert_eq!(gathered.form(), Form::Constant);
6768        assert_eq!(gathered.len(), 3);
6769        assert_eq!(gathered.value_at(2), Value::Integer(4));
6770    }
6771
6772    /// A dictionary over a dictionary is what a second filter over an already filtered chunk builds,
6773    /// and the gather has to walk to the bottom of that chain rather than one step down it. The
6774    /// constructor composes the ordinary chain away, so the one built here is the kind it cannot,
6775    /// which is a level holding nulls of its own.
6776    #[test]
6777    fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
6778        let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
6779            .unwrap()
6780            .with_validity(Validity::from_iter(3, |index| index != 2));
6781        let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
6782        let gathered = outer.gather(&[0, 1]).unwrap();
6783        assert_eq!(gathered.form(), Form::Flat);
6784        assert_eq!(gathered.value_at(0), Value::Integer(8));
6785        assert_eq!(gathered.value_at(1), Value::Null);
6786    }
6787
6788    /// Two filters over one chunk build a dictionary over a dictionary, four conjuncts pushed down
6789    /// separately build four levels of it, and every level is a dependent load on every later read
6790    /// of every row plus a code array that cannot be freed. Composing at construction is one pass
6791    /// over the codes the range check was walking anyway.
6792    #[test]
6793    fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
6794        let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
6795        let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
6796        let (codes, values) = outer.dictionary_parts().unwrap();
6797        assert_eq!(codes, [1, 0]);
6798        assert_eq!(values.form(), Form::Flat);
6799        assert_eq!(outer.value_at(0), Value::Integer(8));
6800        assert_eq!(outer.value_at(1), Value::Integer(7));
6801    }
6802
6803    /// The invariant stated as the thing it is there for, which is that the depth does not grow with
6804    /// the number of filters. Four levels stacked one at a time are one level at the end of it.
6805    #[test]
6806    fn stacking_dictionaries_does_not_make_them_deeper() {
6807        let mut vector = integers(&[10, 20, 30, 40]);
6808        for _ in 0..4 {
6809            vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
6810        }
6811        let (codes, values) = vector.dictionary_parts().unwrap();
6812        assert_eq!(values.form(), Form::Flat);
6813        assert_eq!(codes, [0, 1, 2, 3]);
6814        assert_eq!(
6815            vector.iter().collect::<Vec<_>>(),
6816            integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
6817        );
6818    }
6819
6820    /// Composing has to carry the nulls down with it. The values hold them, the codes point at them,
6821    /// and a composed code that lands on a null position is still a null.
6822    #[test]
6823    fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
6824        let values =
6825            Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
6826        let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
6827        let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
6828        assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
6829        assert_eq!(outer.value_at(0), Value::Null);
6830        assert_eq!(outer.value_at(1), Value::Integer(3));
6831    }
6832
6833    /// The one level composition cannot go past. A dictionary that was given a validity of its own is
6834    /// saying its nulls are at that level rather than in the values, and pointing the outer codes
6835    /// straight at the values would read through the holes instead of stopping at them.
6836    #[test]
6837    fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
6838        let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
6839            .unwrap()
6840            .with_validity(Validity::from_iter(3, |index| index != 1));
6841        let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
6842        assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
6843        assert_eq!(outer.value_at(0), Value::Null);
6844        assert_eq!(outer.value_at(1), Value::Integer(3));
6845        assert_eq!(outer.value_at(2), Value::Integer(1));
6846    }
6847
6848    /// The difference between the two questions about nulls, which a group by got wrong. A filtered
6849    /// chunk is dictionary vectors, those are built with every row marked present at their own
6850    /// level, and the nulls are down in the values. So the mask says the row has a value and the
6851    /// row does not.
6852    #[test]
6853    fn a_null_behind_a_dictionary_reads_as_null_even_though_the_mask_says_otherwise() {
6854        let values = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
6855            .unwrap()
6856            .with_validity(Validity::from_iter(2, |index| index != 0));
6857        let vector = Vector::dictionary(vec![0, 1, 0], values).unwrap();
6858        assert!(vector.validity().is_valid(0), "the mask at this level says present");
6859        assert!(vector.is_null_at(0));
6860        assert!(!vector.is_null_at(1));
6861        assert!(vector.is_null_at(2));
6862        assert!(vector.is_null_at(3), "a row past the end is null");
6863    }
6864
6865    /// The same for runs, which are built the same way and keep their nulls in the same place.
6866    #[test]
6867    fn a_null_inside_a_run_reads_as_null_even_though_the_mask_says_otherwise() {
6868        let values = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
6869            .unwrap()
6870            .with_validity(Validity::from_iter(2, |index| index != 0));
6871        let vector = Vector::runs(vec![2, 3], values).unwrap();
6872        assert!(vector.validity().is_valid(0));
6873        assert!(vector.is_null_at(0));
6874        assert!(vector.is_null_at(1));
6875        assert!(!vector.is_null_at(2));
6876    }
6877
6878    /// Every other form keeps its nulls in its own mask, so the two answers agree there.
6879    #[test]
6880    fn the_forms_that_hold_their_own_nulls_answer_the_same_either_way() {
6881        let flat = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
6882            .unwrap()
6883            .with_validity(Validity::from_iter(2, |index| index != 0));
6884        let constant = Vector::constant(LogicalType::Integer, Value::Null, 2);
6885        let sequence = Vector::sequence(10, 2, 2);
6886        for vector in [flat, constant, sequence] {
6887            for row in 0..vector.len() {
6888                assert_eq!(vector.is_null_at(row), !vector.validity().is_valid(row));
6889            }
6890        }
6891    }
6892
6893    #[test]
6894    fn flattening_a_flat_vector_is_the_same_vector() {
6895        let vector = integers(&[1, 2, 3]);
6896        assert_eq!(vector.flatten().unwrap(), vector);
6897    }
6898
6899    /// The same answer as `flatten` and, for the vector that is already flat and owns its values,
6900    /// the same allocation. Asserted on the address because that is the whole claim: the values
6901    /// come back where they were rather than in a copy of themselves. A flatten through a borrow
6902    /// cannot do that, and at the top of a query it copied every column of every chunk of the
6903    /// result to hand back the bytes it was given.
6904    #[test]
6905    fn flattening_a_vector_that_owns_its_values_moves_them_rather_than_copying_them() {
6906        let vector = integers(&[1, 2, 3, 4]);
6907        let address = |vector: &Vector| match vector.data() {
6908            Some(Data::Int32(values)) => values.as_slice().as_ptr() as usize,
6909            _ => panic!("the layout changed under the test"),
6910        };
6911        let stored = address(&vector);
6912        let flat = vector.into_flat().unwrap();
6913        assert_eq!(address(&flat), stored, "the values moved");
6914        assert_eq!(
6915            flat.iter().collect::<Vec<_>>(),
6916            (1..=4).map(Value::Integer).collect::<Vec<_>>()
6917        );
6918        // And a form that is not flat is flattened, which is the case the copy is deserved in.
6919        let dictionary = Vector::dictionary(vec![1, 0, 1], integers(&[7, 8])).unwrap();
6920        let flat = dictionary.clone().into_flat().unwrap();
6921        assert_eq!(flat.form(), Form::Flat);
6922        assert_eq!(flat.iter().collect::<Vec<_>>(), dictionary.iter().collect::<Vec<_>>());
6923    }
6924
6925    #[test]
6926    fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
6927        let ty = LogicalType::decimal(9, 2).unwrap();
6928        let vector = Vector::flat(ty, Data::Int32(vec![1234].into())).unwrap();
6929        assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
6930        assert_eq!(vector.value_at(0).to_string(), "12.34");
6931    }
6932
6933    #[test]
6934    fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
6935        // The read path worked at every width and the write path only accepted the 128 bit run, so
6936        // `SELECT 2.5` produced a value nothing could store. All four widths round trip now.
6937        for (width, scale, unscaled) in
6938            [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
6939        {
6940            let ty = LogicalType::decimal(width, scale).unwrap();
6941            let value = Value::Decimal { unscaled, width, scale };
6942            let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
6943            assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
6944            assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
6945        }
6946    }
6947
6948    /// The bytes a blob holds are not required to be text, and a vector of them used to refuse the
6949    /// ones that were not. A byte array column in a Parquet file that nothing annotated is a blob,
6950    /// which is what ClickHouse writes and what ten of the ClickBench queries compare against, so
6951    /// this is the path those take rather than a corner of the type system.
6952    #[test]
6953    fn a_blob_holds_bytes_that_are_not_text() {
6954        let bytes = |raw: &[u8]| Value::Blob(raw.to_vec());
6955        let values = [
6956            bytes(b"a\xffb"),
6957            bytes(b"\x00\x01\x02"),
6958            Value::Null,
6959            bytes(b"\xed\xa0\x80 and long enough to leave the view"),
6960            bytes(b""),
6961        ];
6962        let vector = Vector::from_values(LogicalType::Blob, &values).unwrap();
6963        for (index, value) in values.iter().enumerate() {
6964            assert_eq!(&vector.value_at(index), value, "row {index}");
6965        }
6966    }
6967
6968    #[test]
6969    fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
6970        // Only reachable by hand, since a value's width is what picked the run. Truncating here
6971        // would store a different number and say nothing about it.
6972        let ty = LogicalType::decimal(4, 1).unwrap();
6973        let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
6974        let error = Vector::from_values(ty, &[value]).unwrap_err();
6975        assert!(error.to_string().contains("does not fit"), "{error}");
6976    }
6977
6978    #[test]
6979    fn a_flat_vector_costs_its_values_and_a_constant_costs_one() {
6980        let flat = integers(&[1; 1000]);
6981        assert!(
6982            flat.footprint() >= 4000,
6983            "a thousand i32 are four thousand bytes: {}",
6984            flat.footprint()
6985        );
6986        // The forms that compute their values rather than storing them cost nothing per value,
6987        // which is the point of having them and is what the memory limit should see.
6988        let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1_000_000);
6989        assert!(constant.footprint() < 200, "a constant is one value: {}", constant.footprint());
6990        let sequence = Vector::sequence(0, 1, 1_000_000);
6991        assert!(sequence.footprint() < 200, "a sequence is two numbers: {}", sequence.footprint());
6992    }
6993
6994    #[test]
6995    fn a_gather_off_a_dictionary_answers_the_same_nulls_either_way_round() {
6996        let words = [Value::Varchar("north".into()), Value::Null, Value::Varchar("south".into())];
6997        let plain: Vec<Value> =
6998            ["north", "east", "south"].iter().map(|word| Value::Varchar((*word).into())).collect();
6999        let clean = Arc::new(Vector::from_values(LogicalType::Varchar, &plain).unwrap());
7000        let dirty = Arc::new(Vector::from_values(LogicalType::Varchar, &words).unwrap());
7001        let codes = vec![0, 1, 2, 0, 1, 2];
7002        let sources = [
7003            Vector::stable_dictionary(codes.clone(), Arc::clone(&clean)).unwrap(),
7004            Vector::stable_dictionary(codes.clone(), Arc::clone(&dirty)).unwrap(),
7005            Vector::stable_dictionary(codes, Arc::clone(&clean))
7006                .unwrap()
7007                .with_validity(Validity::from_run(&[true, true, false, true, true, true])),
7008        ];
7009        // What a gather says about a row has to be what the column it came out of says about the
7010        // row it was taken from, whichever of the two ways the nulls are reached: the mask over the
7011        // codes, or the value a code stands for. The fast answer is only allowed when neither has
7012        // any, and an index past the end is null in both readings.
7013        for source in &sources {
7014            let picks: Vec<u32> = vec![5, 0, 3, 2, 1, 99, 4];
7015            let taken = source.gather(&picks).unwrap();
7016            for (row, &pick) in picks.iter().enumerate() {
7017                assert_eq!(
7018                    taken.is_null_at(row),
7019                    source.is_null_at(pick as usize),
7020                    "row {row} of a gather of {picks:?}"
7021                );
7022            }
7023        }
7024    }
7025
7026    #[test]
7027    fn a_dictionary_read_by_many_cuts_is_counted_about_once_between_them() {
7028        let strings: Vec<Value> = (0..2000)
7029            .map(|at| Value::Varchar(format!("a value well past the inline limit, number {at}")))
7030            .collect();
7031        let values = Arc::new(Vector::from_values(LogicalType::Varchar, &strings).unwrap());
7032        let dictionary = values.footprint();
7033        let cuts: Vec<Vector> = (0..500)
7034            .map(|_| Vector::stable_dictionary(vec![0; 8], Arc::clone(&values)).unwrap())
7035            .collect();
7036        let together: usize = cuts.iter().map(Vector::footprint).sum();
7037        // Five hundred chunks cut out of one page hold one dictionary, and what they say they hold
7038        // has to be about one dictionary. Before this it was five hundred of them, which is a
7039        // reading that grows with the answer and refuses a query holding a gigabyte a budget of
7040        // twenty five.
7041        assert!(
7042            together < dictionary * 2,
7043            "five hundred cuts are not five hundred dictionaries: {together} against {dictionary}"
7044        );
7045        assert!(
7046            together > dictionary / 2,
7047            "the dictionary is still counted: {together} against {dictionary}"
7048        );
7049    }
7050
7051    #[test]
7052    fn a_string_vector_costs_the_bytes_of_its_long_strings() {
7053        let short =
7054            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into())]).unwrap();
7055        let long = "a string well past the sixteen bytes a view holds inline".to_string();
7056        let spilled =
7057            Vector::from_values(LogicalType::Varchar, &[Value::Varchar(long.clone())]).unwrap();
7058        assert!(
7059            spilled.footprint() >= short.footprint() + long.len(),
7060            "the arena is counted: {} against {}",
7061            spilled.footprint(),
7062            short.footprint()
7063        );
7064    }
7065
7066    /// The cases worth checking are the widths where a code straddles a word boundary, which is
7067    /// every width that does not divide sixty four, and the two ends of the range.
7068    #[test]
7069    fn a_narrow_column_packs_and_reads_back_the_same_at_every_width() {
7070        for width in 1..=20u32 {
7071            let span = (1i64 << width) - 1;
7072            let values: Vec<i64> =
7073                (0..1000).map(|row| 1_000_000 + (row * 7919) % (span + 1)).collect();
7074            let flat =
7075                Vector::flat(LogicalType::BigInt, Data::Int64(values.clone().into())).unwrap();
7076            let packed = flat.bit_packed().unwrap();
7077            assert_eq!(packed.len(), flat.len());
7078            assert_eq!(
7079                packed.iter().collect::<Vec<_>>(),
7080                flat.iter().collect::<Vec<_>>(),
7081                "width {width} read back differently"
7082            );
7083        }
7084    }
7085
7086    #[test]
7087    fn the_width_is_the_bits_the_range_needs_and_not_the_bits_the_type_has() {
7088        let values: Vec<i32> = (0..1024).map(|row| 40 + (row * 2560) / 1023).collect();
7089        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
7090        let packed = flat.bit_packed().unwrap();
7091        assert_eq!(packed.form(), Form::BitPacked);
7092        let parts = packed.packed_parts().expect("packed");
7093        assert_eq!(parts.width(), 12, "0 to 2560 is twelve bits");
7094        assert_eq!(parts.base(), 40);
7095        assert!(
7096            packed.footprint() * 2 < flat.footprint(),
7097            "twelve bits against thirty two: {} against {}",
7098            packed.footprint(),
7099            flat.footprint()
7100        );
7101    }
7102
7103    /// The check is worth having in both directions, the way the run length one is. A form that is
7104    /// only ever bigger than what it replaced costs a pass over the column to decide not to use.
7105    #[test]
7106    fn a_column_that_uses_its_whole_type_is_left_flat() {
7107        let values: Vec<i32> = (0..1024).map(|row| row * 2_000_000 - 1_000_000_000).collect();
7108        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
7109        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
7110    }
7111
7112    /// The column that would not write. A thousand values just under `i32::MAX` need ten bits, and
7113    /// based at the smallest of them those ten bits could say a number an `INTEGER` cannot hold, so
7114    /// the range check refused the column and `CREATE TABLE` came back with an internal error. The
7115    /// base is what moves, not the check: it drops to where the widest code the width allows is the
7116    /// largest value the type has.
7117    #[test]
7118    fn a_column_against_the_top_of_its_type_packs_rather_than_being_refused() {
7119        let values: Vec<i32> = (0..4096).map(|row| i32::MAX - (row % 1000)).collect();
7120        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.clone().into())).unwrap();
7121        let packed = flat.bit_packed().unwrap();
7122        assert_eq!(packed.form(), Form::BitPacked);
7123        let parts = packed.packed_parts().expect("packed");
7124        assert_eq!(parts.width(), 10, "a thousand values apart is ten bits");
7125        assert_eq!(
7126            parts.base() + i128::from(u64::MAX >> (64 - parts.width())),
7127            i128::from(i32::MAX),
7128            "the widest code the width allows is the largest value the type holds"
7129        );
7130        assert_eq!(
7131            packed.iter().collect::<Vec<_>>(),
7132            flat.iter().collect::<Vec<_>>(),
7133            "the values came back different"
7134        );
7135    }
7136
7137    /// The other end of the same thing. A column that reaches both ends of its type needs every bit
7138    /// the type has, and the only base that leaves room for those codes is the bottom of the type.
7139    #[test]
7140    fn a_column_that_reaches_both_ends_of_its_type_bases_at_the_bottom_of_it() {
7141        let values: Vec<i32> = (0..4096)
7142            .map(|row| if row % 2 == 0 { i32::MIN + row } else { i32::MAX - row })
7143            .collect();
7144        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.clone().into())).unwrap();
7145        // Thirty two bits of codes for a thirty two bit type buys nothing, so the size check leaves
7146        // it flat. What matters is that it is left flat rather than refused.
7147        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
7148        assert_eq!(
7149            packing_base(&LogicalType::Integer, i128::from(i32::MIN), i128::from(i32::MAX), 32),
7150            Some(i128::from(i32::MIN))
7151        );
7152    }
7153
7154    /// A column of one value would pack to no bits at all, and one run is smaller than any packing
7155    /// of it, so the two forms do not fight over that column.
7156    #[test]
7157    fn a_column_of_one_value_is_left_to_the_run_length_form() {
7158        let flat = integers(&[9; 1024]);
7159        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
7160        assert_eq!(flat.run_encoded().unwrap().form(), Form::Rle);
7161    }
7162
7163    #[test]
7164    fn a_string_column_has_no_range_to_pack() {
7165        let text = Vector::from_values(
7166            LogicalType::Varchar,
7167            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
7168        )
7169        .unwrap();
7170        assert_eq!(text.bit_packed().unwrap().form(), Form::Flat);
7171    }
7172
7173    /// The cut is the reason the form carries a row to start reading at. It stays packed, it shares
7174    /// the same words, and it reads the rows the range asked for.
7175    #[test]
7176    fn a_cut_of_a_packed_column_stays_packed_and_shares_its_bits() {
7177        let values: Vec<i32> = (0..1024).map(|row| 100 + row % 300).collect();
7178        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
7179        let packed = flat.bit_packed().unwrap();
7180        let cut = packed.slice(500, 24).unwrap();
7181        assert_eq!(cut.form(), Form::BitPacked);
7182        assert_eq!(cut.len(), 24);
7183        assert_eq!(
7184            cut.iter().collect::<Vec<_>>(),
7185            flat.slice(500, 24).unwrap().iter().collect::<Vec<_>>()
7186        );
7187        assert!(
7188            cut.footprint() >= packed.footprint(),
7189            "a cut shares the words rather than copying a piece of them"
7190        );
7191    }
7192
7193    #[test]
7194    fn a_gather_of_a_packed_column_comes_out_flat_and_keeps_the_nulls() {
7195        let values: Vec<i32> = (0..64).map(|row| 10 + row).collect();
7196        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
7197        let packed =
7198            flat.bit_packed().unwrap().with_validity(Validity::from_iter(64, |row| row % 3 != 0));
7199        let taken = packed.gather(&[0, 1, 2, 3, 62]).unwrap();
7200        assert_eq!(taken.form(), Form::Flat);
7201        assert_eq!(
7202            taken.iter().collect::<Vec<_>>(),
7203            vec![
7204                Value::Null,
7205                Value::Integer(11),
7206                Value::Integer(12),
7207                Value::Null,
7208                Value::Integer(72)
7209            ]
7210        );
7211    }
7212
7213    /// The pair a comparison kernel asks for before it reads a bit. A literal inside the range has a
7214    /// code and a literal outside it does not, which answers the whole vector at once.
7215    #[test]
7216    fn a_literal_outside_the_packed_range_has_no_code() {
7217        let values: Vec<i32> = (0..256).map(|row| 1000 + row).collect();
7218        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
7219        let packed = flat.bit_packed().unwrap();
7220        let parts = packed.packed_parts().expect("packed");
7221        assert_eq!(parts.code_of(1000), Some(0));
7222        assert_eq!(parts.code_of(1100), Some(100));
7223        assert_eq!(parts.code_of(999), None);
7224        assert!(parts.ceiling() >= 1255);
7225        assert_eq!(parts.code_of(parts.ceiling() + 1), None);
7226    }
7227
7228    /// The bits arriving from a file rather than from a flat vector, which is what the form is for.
7229    #[test]
7230    fn packed_bits_can_be_handed_in_without_a_flat_vector_to_start_from() {
7231        let packed = Vector::packed(LogicalType::SmallInt, vec![0x0000_0000_0000_4321], 4, 7, 4)
7232            .expect("four codes of four bits");
7233        assert_eq!(
7234            packed.iter().collect::<Vec<_>>(),
7235            vec![Value::SmallInt(8), Value::SmallInt(9), Value::SmallInt(10), Value::SmallInt(11)]
7236        );
7237    }
7238
7239    /// A packed column read as a block, cut at rows that do and do not start a word, at widths
7240    /// that do and do not straddle, answers what a row at a time answers.
7241    #[test]
7242    fn a_packed_block_reads_what_each_row_reads() {
7243        let words: Vec<u64> =
7244            (0..400_u64).map(|word| word.wrapping_mul(0x9E37_79B9_7F4A_7C15)).collect();
7245        for width in [1, 7, 13, 32, 33, 50] {
7246            let whole = Vector::packed(LogicalType::BigInt, words.clone(), width, -1_000, 300)
7247                .expect("enough words for 300 codes");
7248            for (at, len) in [(0, 300), (1, 299), (63, 130), (64, 64), (100, 5), (250, 50)] {
7249                let cut = whole.slice(at, len).expect("a cut inside the column");
7250                let mut block = Vec::new();
7251                assert!(cut.signed_block(&mut block));
7252                let want: Vec<i64> = (0..len)
7253                    .map(|row| i64::try_from(cut.signed_at(row).expect("a row")).expect("fits"))
7254                    .collect();
7255                assert_eq!(block, want, "width {width} cut at {at} for {len}");
7256            }
7257        }
7258    }
7259
7260    /// A packed column flattened whole, cut at rows that do and do not start a word, answers what
7261    /// a row at a time answers, and a column with nulls in it keeps them.
7262    #[test]
7263    fn a_packed_column_flattened_whole_reads_what_each_row_reads() {
7264        let words: Vec<u64> =
7265            (0..400_u64).map(|word| word.wrapping_mul(0x9E37_79B9_7F4A_7C15)).collect();
7266        for (ty, width) in [
7267            (LogicalType::BigInt, 50),
7268            (LogicalType::Integer, 13),
7269            (LogicalType::SmallInt, 7),
7270            (LogicalType::Date, 1),
7271        ] {
7272            let whole = Vector::packed(ty.clone(), words.clone(), width, -1_000, 300)
7273                .expect("enough words for 300 codes");
7274            for (at, len) in [(0, 300), (1, 299), (63, 130), (64, 64), (100, 5)] {
7275                let cut = whole.slice(at, len).expect("a cut inside the column");
7276                let flat = cut.flatten().expect("a packed column flattens");
7277                assert_eq!(flat.form(), Form::Flat, "{ty:?} cut at {at}");
7278                assert_eq!(
7279                    flat.iter().collect::<Vec<_>>(),
7280                    cut.iter().collect::<Vec<_>>(),
7281                    "{ty:?} width {width} cut at {at} for {len}"
7282                );
7283            }
7284        }
7285        let nulls = Vector::packed(LogicalType::Integer, words, 13, 0, 300)
7286            .expect("300 codes")
7287            .with_validity(Validity::from_iter(300, |row| row % 5 != 0));
7288        let flat = nulls.flatten().expect("flattens");
7289        assert_eq!(flat.iter().collect::<Vec<_>>(), nulls.iter().collect::<Vec<_>>());
7290        assert!(flat.is_null_at(0) && !flat.is_null_at(1));
7291    }
7292
7293    #[test]
7294    fn packed_bits_that_could_not_hold_what_they_claim_are_refused() {
7295        assert!(Vector::packed(LogicalType::Varchar, vec![0], 4, 0, 4).is_err(), "not an integer");
7296        assert!(Vector::packed(LogicalType::Integer, vec![0], 0, 0, 4).is_err(), "no width");
7297        assert!(Vector::packed(LogicalType::Integer, vec![0], 64, 0, 4).is_err(), "too wide");
7298        assert!(Vector::packed(LogicalType::Integer, vec![0], 8, 0, 9).is_err(), "too few words");
7299        assert!(Vector::packed(LogicalType::TinyInt, vec![0], 8, 100, 8).is_err(), "would not fit");
7300    }
7301
7302    /// A column of strings long enough that the payload is in the arena rather than in the views.
7303    fn long_strings(count: usize) -> Vector {
7304        let values: Vec<Value> = (0..count)
7305            .map(|row| {
7306                Value::Varchar(format!("a string too long to sit inside a view, number {row}"))
7307            })
7308            .collect();
7309        Vector::from_values(LogicalType::Varchar, &values).unwrap()
7310    }
7311
7312    #[test]
7313    fn a_string_column_in_view_form_reads_back_the_same_strings() {
7314        let flat = long_strings(40);
7315        let shared = flat.clone().shared_text().unwrap();
7316        assert_eq!(shared.form(), Form::StringView);
7317        assert_eq!(shared.len(), 40);
7318        for row in 0..40 {
7319            assert_eq!(shared.value_at(row), flat.value_at(row), "row {row}");
7320            assert_eq!(shared.text_at(row), flat.text_at(row), "row {row}");
7321        }
7322    }
7323
7324    #[test]
7325    fn a_short_string_is_read_out_of_its_view_and_never_out_of_the_arena() {
7326        let flat = Vector::from_values(
7327            LogicalType::Varchar,
7328            &[Value::Varchar("red".into()), Value::Varchar("green".into()), Value::Null],
7329        )
7330        .unwrap();
7331        let shared = flat.shared_text().unwrap();
7332        // Nothing went to the arena, so the whole column resolves with an empty one.
7333        let (views, arena) = shared.text_parts().unwrap();
7334        assert!(arena.is_empty(), "three short strings need no arena");
7335        assert_eq!(views[0].bytes_in(arena), Some(&b"red"[..]));
7336        assert_eq!(shared.value_at(1), Value::Varchar("green".into()));
7337        assert_eq!(shared.value_at(2), Value::Null, "the validity came across");
7338    }
7339
7340    #[test]
7341    fn a_cut_of_a_view_column_shares_the_arena_rather_than_copying_the_bytes() {
7342        let shared = long_strings(64).shared_text().unwrap();
7343        let cut = shared.slice(16, 8).unwrap();
7344        assert_eq!(cut.form(), Form::StringView, "a cut of views is views");
7345        assert_eq!(cut.len(), 8);
7346        assert_eq!(cut.value_at(0), shared.value_at(16));
7347        assert_eq!(cut.value_at(7), shared.value_at(23));
7348        // The arena is the same bytes at the same address, which is the whole point of the form.
7349        let (_, whole) = shared.text_parts().unwrap();
7350        let (_, piece) = cut.text_parts().unwrap();
7351        assert_eq!(piece.as_ptr(), whole.as_ptr(), "the cut shares the page");
7352        assert_eq!(piece.len(), whole.len());
7353    }
7354
7355    #[test]
7356    fn a_flat_string_column_has_to_copy_the_bytes_its_cut_keeps() {
7357        let flat = long_strings(64);
7358        let cut = flat.slice(16, 8).unwrap();
7359        assert_eq!(cut.form(), Form::Flat);
7360        let (_, whole) = flat.text_parts().unwrap();
7361        let (_, piece) = cut.text_parts().unwrap();
7362        assert!(piece.len() < whole.len(), "the flat cut carries only what it kept");
7363    }
7364
7365    #[test]
7366    fn a_gather_of_a_view_column_keeps_the_form_and_a_flatten_copies_out_of_it() {
7367        let shared = long_strings(32).shared_text().unwrap();
7368        let picked: Vec<u32> = (0..32).step_by(3).collect();
7369        let gathered = shared.gather(&picked).unwrap();
7370        assert_eq!(gathered.form(), Form::StringView, "selecting rows moves views, not bytes");
7371        assert_eq!(gathered.len(), picked.len());
7372        for (row, &from) in picked.iter().enumerate() {
7373            assert_eq!(gathered.value_at(row), shared.value_at(from as usize), "row {row}");
7374        }
7375        let flattened = gathered.flatten().unwrap();
7376        assert_eq!(flattened.form(), Form::Flat);
7377        assert_eq!(flattened.iter().collect::<Vec<_>>(), gathered.iter().collect::<Vec<_>>());
7378        // The flatten is what narrows the bytes, so the arena it built holds only the rows it kept.
7379        let (_, narrowed) = flattened.text_parts().unwrap();
7380        let (_, whole) = shared.text_parts().unwrap();
7381        assert!(narrowed.len() < whole.len(), "flattening lets the page go");
7382    }
7383
7384    #[test]
7385    fn a_null_in_a_view_column_survives_being_gathered_and_flattened() {
7386        let shared = long_strings(8)
7387            .with_validity(Validity::from_iter(8, |row| row % 3 != 0))
7388            .shared_text()
7389            .unwrap();
7390        let gathered = shared.gather(&[0, 1, 2, 3, 4]).unwrap();
7391        let expected =
7392            [Value::Null, shared.value_at(1), shared.value_at(2), Value::Null, shared.value_at(4)];
7393        assert_eq!(gathered.iter().collect::<Vec<_>>(), expected);
7394        assert_eq!(gathered.flatten().unwrap().iter().collect::<Vec<_>>(), expected);
7395    }
7396
7397    #[test]
7398    fn both_string_forms_hand_a_kernel_the_same_views_and_the_same_bytes() {
7399        let flat = long_strings(6);
7400        let shared = flat.clone().shared_text().unwrap();
7401        let (flat_views, flat_arena) = flat.text_parts().unwrap();
7402        let (shared_views, shared_arena) = shared.text_parts().unwrap();
7403        assert_eq!(flat_views.len(), shared_views.len());
7404        for row in 0..6 {
7405            assert_eq!(
7406                flat_views[row].bytes_in(flat_arena),
7407                shared_views[row].bytes_in(shared_arena),
7408                "row {row}"
7409            );
7410        }
7411        // Nothing else answers this, which is what keeps a kernel from taking it for a string column.
7412        assert!(Vector::sequence(0, 1, 4).text_parts().is_none());
7413        assert!(integers(&[1, 2, 3]).text_parts().is_none());
7414    }
7415
7416    #[test]
7417    fn a_column_that_is_not_strings_cannot_be_held_as_views() {
7418        let views = vec![StringView::inline("red")];
7419        let arena = Arc::new(Buffer::new());
7420        let wrong = Vector::string_views(LogicalType::Integer, views, arena);
7421        assert!(wrong.is_err(), "an integer column has no views");
7422        assert_eq!(integers(&[1, 2]).shared_text().unwrap().form(), Form::Flat, "left alone");
7423    }
7424
7425    /// A column with enough repeated structure for a symbol table to find something, which is what
7426    /// a real text column has and a column of random bytes does not.
7427    fn sentences(count: usize) -> Vector {
7428        let values: Vec<Value> = (0..count)
7429            .map(|row| {
7430                Value::Varchar(format!(
7431                    "http://example.test/catalogue/section/{}/item/{row}",
7432                    row % 7
7433                ))
7434            })
7435            .collect();
7436        Vector::from_values(LogicalType::Varchar, &values).unwrap()
7437    }
7438
7439    #[test]
7440    fn a_compressed_column_reads_back_the_strings_that_went_into_it() {
7441        let flat = sentences(64);
7442        let coded = flat.clone().compressed().unwrap();
7443        assert_eq!(coded.form(), Form::Fsst, "a text column compresses");
7444        assert_eq!(coded.len(), 64);
7445        for row in 0..64 {
7446            assert_eq!(coded.value_at(row), flat.value_at(row), "row {row}");
7447        }
7448        assert_eq!(coded.flatten().unwrap(), flat, "flattening is the column it came from");
7449    }
7450
7451    #[test]
7452    fn compressing_halves_the_bytes_or_the_column_is_left_flat() {
7453        let flat = sentences(200);
7454        let coded = flat.clone().compressed().unwrap();
7455        let parts = coded.coded_parts().expect("compressed");
7456        // Read through the flat column, because the compressed one has no bytes to hand back where
7457        // they are and answers `None` to `text_at` rather than decompressing into a borrow.
7458        assert_eq!(coded.text_at(0), None, "nothing to borrow until it is flattened");
7459        let plain: usize = (0..200).map(|row| flat.text_at(row).map_or(0, str::len)).sum();
7460        let codes: usize = (0..200).map(|row| parts.row(row).map_or(0, <[u8]>::len)).sum();
7461        assert!(codes * FSST_PAYS_AT <= plain, "{codes} codes against {plain} bytes");
7462        // Text with no repeated structure in it gives a table nothing longer than a byte to find,
7463        // so the codes are the bytes and the column stays where it is rather than paying a
7464        // decompression per read to save nothing.
7465        let mut seed = 0x2545_f491_4f6c_dd1du64;
7466        let values: Vec<Value> = (0..256)
7467            .map(|_| {
7468                let mut text = String::new();
7469                while text.len() < 12 {
7470                    seed = seed.wrapping_mul(6_364_136_223_846_793_005).wrapping_add(1);
7471                    text.push(char::from(b'!' + ((seed >> 33) % 90) as u8));
7472                }
7473                Value::Varchar(text)
7474            })
7475            .collect();
7476        let noise = Vector::from_values(LogicalType::Varchar, &values).unwrap();
7477        assert_eq!(noise.compressed().unwrap().form(), Form::Flat);
7478    }
7479
7480    #[test]
7481    fn a_cut_of_a_compressed_column_shares_the_codes_and_the_table() {
7482        let coded = sentences(64).compressed().unwrap();
7483        let cut = coded.slice(8, 16).unwrap();
7484        assert_eq!(cut.form(), Form::Fsst);
7485        assert_eq!(cut.len(), 16);
7486        for row in 0..16 {
7487            assert_eq!(cut.value_at(row), coded.value_at(8 + row), "row {row}");
7488        }
7489        let (whole, piece) = (coded.coded_parts().unwrap(), cut.coded_parts().unwrap());
7490        assert_eq!(piece.row(0), whole.row(8), "the spans point into the same codes");
7491    }
7492
7493    #[test]
7494    fn a_gather_of_a_compressed_column_stays_compressed_and_keeps_the_nulls() {
7495        let coded = sentences(32)
7496            .with_validity(Validity::from_iter(32, |row| row % 5 != 2))
7497            .compressed()
7498            .unwrap();
7499        let picked: Vec<u32> = (0..32).step_by(2).collect();
7500        let gathered = coded.gather(&picked).unwrap();
7501        assert_eq!(gathered.form(), Form::Fsst, "selecting rows moves spans, not bytes");
7502        for (row, &from) in picked.iter().enumerate() {
7503            assert_eq!(gathered.value_at(row), coded.value_at(from as usize), "row {row}");
7504        }
7505        assert_eq!(
7506            gathered.flatten().unwrap().iter().collect::<Vec<_>>(),
7507            gathered.iter().collect::<Vec<_>>()
7508        );
7509    }
7510
7511    #[test]
7512    fn a_literal_lands_in_the_same_codes_the_row_holding_it_does() {
7513        let coded = sentences(40).compressed().unwrap();
7514        let parts = coded.coded_parts().expect("compressed");
7515        let text = coded.value_at(11);
7516        let Value::Varchar(text) = text else { panic!("a string column reads back strings") };
7517        assert_eq!(parts.encode(text.as_bytes()), parts.row(11).expect("row 11"));
7518        assert_ne!(parts.encode(b"something else entirely"), parts.row(11).unwrap());
7519    }
7520
7521    #[test]
7522    fn codes_that_run_past_what_is_there_are_refused() {
7523        let table = Arc::new(SymbolTable::empty());
7524        let codes = Arc::new(vec![1u8, 2, 3, 4]);
7525        let good = vec![(0u32, 2u32), (2, 4)];
7526        assert!(
7527            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), good, Arc::clone(&table))
7528                .is_ok()
7529        );
7530        let past = vec![(0u32, 9u32)];
7531        assert!(
7532            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), past, Arc::clone(&table))
7533                .is_err(),
7534            "a span past the end of the codes"
7535        );
7536        let backwards = vec![(3u32, 1u32)];
7537        assert!(
7538            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), backwards, Arc::clone(&table))
7539                .is_err(),
7540            "a span that ends before it starts"
7541        );
7542        let wrong = vec![(0u32, 2u32)];
7543        assert!(
7544            Vector::coded(LogicalType::Integer, codes, wrong, table).is_err(),
7545            "an integer column has no codes"
7546        );
7547    }
7548
7549    #[test]
7550    fn a_view_pointing_past_its_arena_is_refused_at_construction() {
7551        let long = "a string too long to sit inside a view";
7552        let arena: Arc<Buffer<u8>> = Arc::new(long.as_bytes().to_vec().into());
7553        let good = vec![StringView::over(long.as_bytes(), 0)];
7554        assert!(Vector::string_views(LogicalType::Varchar, good, Arc::clone(&arena)).is_ok());
7555        let bad = vec![StringView::over(long.as_bytes(), 4)];
7556        assert!(
7557            Vector::string_views(LogicalType::Varchar, bad, arena).is_err(),
7558            "four bytes short of what the view claims"
7559        );
7560    }
7561
7562    /// The form at its simplest: an id per row, and the row it names.
7563    #[test]
7564    fn a_gathered_vector_reads_the_source_row_its_id_names() {
7565        let source = Arc::new(integers(&[10, 20, 30, 40]));
7566        let vector = Vector::gathered(source, Arc::new(vec![3, 0, 3, 1])).unwrap();
7567        assert_eq!(vector.form(), Form::Gathered);
7568        assert_eq!(vector.len(), 4);
7569        assert_eq!(
7570            vector.iter().collect::<Vec<_>>(),
7571            vec![Value::Integer(40), Value::Integer(10), Value::Integer(40), Value::Integer(20)]
7572        );
7573    }
7574
7575    /// Section 8.2's lazy validity. The sentinel is a null and it is not in a mask anywhere, which is
7576    /// what lets a left link join gather null for an unmatched child row without allocating one.
7577    #[test]
7578    fn a_gathered_row_with_no_source_row_is_null_without_a_mask() {
7579        let source = Arc::new(integers(&[10, 20]));
7580        let vector = Vector::gathered(source, Arc::new(vec![1, NO_ROW, 0])).unwrap();
7581        assert!(!vector.validity().has_nulls(vector.len()), "the mask at this level says nothing");
7582        assert!(vector.is_null_at(1));
7583        assert!(!vector.is_null_at(0) && !vector.is_null_at(2));
7584        assert_eq!(
7585            vector.iter().collect::<Vec<_>>(),
7586            vec![Value::Integer(20), Value::Null, Value::Integer(10)]
7587        );
7588        assert!(!vector.none_null(), "a sentinel is a null and the bulk answer has to agree");
7589    }
7590
7591    /// The other half of the same rule: a null in the source is a null here, the way a dictionary's
7592    /// nulls live in its values. Two ways for a row to be null and one answer from `is_null_at`.
7593    #[test]
7594    fn a_gather_of_a_null_source_row_is_null() {
7595        let source = Arc::new(
7596            Vector::from_values(LogicalType::Integer, &[Value::Integer(7), Value::Null]).unwrap(),
7597        );
7598        let vector = Vector::gathered(source, Arc::new(vec![1, 0, 1])).unwrap();
7599        assert!(vector.is_null_at(0) && vector.is_null_at(2));
7600        assert_eq!(vector.value_at(1), Value::Integer(7));
7601        assert!(!vector.none_null());
7602    }
7603
7604    /// An id past the end of the source is the one failure in this form that reads whatever happens
7605    /// to be at that offset rather than failing, so it is refused where the vector is built.
7606    #[test]
7607    fn a_gathered_id_past_the_end_of_its_source_is_refused() {
7608        let source = Arc::new(integers(&[1, 2, 3]));
7609        assert!(Vector::gathered(Arc::clone(&source), Arc::new(vec![0, 3])).is_err());
7610        assert!(
7611            Vector::gathered(source, Arc::new(vec![0, NO_ROW])).is_ok(),
7612            "the sentinel is not an id past the end, it is the absence of one"
7613        );
7614    }
7615
7616    /// A cut is the offset and nothing else, which is what keeps a pipeline from copying the ids once
7617    /// per operator. Both ends stay shared and the rows answer the same.
7618    #[test]
7619    fn cutting_a_gather_moves_where_it_starts_and_copies_nothing() {
7620        let source = Arc::new(integers(&[10, 20, 30, 40, 50]));
7621        let rids = Arc::new(vec![4, 3, 2, 1, 0]);
7622        let vector = Vector::gathered(Arc::clone(&source), Arc::clone(&rids)).unwrap();
7623        let held = Arc::strong_count(&rids);
7624        let cut = vector.slice(1, 3).unwrap();
7625        assert_eq!(cut.form(), Form::Gathered);
7626        assert_eq!(
7627            Arc::strong_count(&rids),
7628            held + 1,
7629            "the cut shares the ids rather than copying"
7630        );
7631        assert_eq!(
7632            cut.iter().collect::<Vec<_>>(),
7633            vec![Value::Integer(40), Value::Integer(30), Value::Integer(20)]
7634        );
7635        assert_eq!(cut.gathered_parts().unwrap().1, [3, 2, 1]);
7636    }
7637
7638    /// Composition, which is why this is a body and not an operator. A filter over the output of a
7639    /// link join selects into the ids, and what comes out is one level rather than two.
7640    #[test]
7641    fn a_gather_of_a_gather_resolves_to_one_walk_over_the_source() {
7642        let source = Arc::new(integers(&[10, 20, 30, 40]));
7643        let inner = Vector::gathered(source, Arc::new(vec![3, 2, 1, 0])).unwrap();
7644        let outer = inner.gather(&[0, 3]).unwrap();
7645        assert_eq!(outer.iter().collect::<Vec<_>>(), vec![Value::Integer(40), Value::Integer(10)]);
7646        assert_ne!(outer.form(), Form::Gathered, "the walk stops at what the ids point into");
7647    }
7648
7649    /// The sentinel survives being gathered through, which it has to: a filter over a left link
7650    /// join's output keeps the unmatched rows it kept and they are still null.
7651    #[test]
7652    fn gathering_through_a_sentinel_keeps_it_null() {
7653        let source = Arc::new(integers(&[10, 20]));
7654        let inner = Vector::gathered(source, Arc::new(vec![0, NO_ROW, 1])).unwrap();
7655        let outer = inner.gather(&[1, 2, 1]).unwrap();
7656        assert_eq!(
7657            outer.iter().collect::<Vec<_>>(),
7658            vec![Value::Null, Value::Integer(20), Value::Null]
7659        );
7660    }
7661
7662    /// Section 8.2's dispatch rule, which is the whole difference between this form and a dictionary
7663    /// and is one comparison. A gather off a parent larger than the chunk does not want the
7664    /// dictionary arm of any kernel, and a gather off a source smaller than the chunk does.
7665    #[test]
7666    fn folding_over_the_source_is_worth_it_only_when_the_source_is_the_shorter_one() {
7667        let wide = Arc::new(integers(&(0..64).collect::<Vec<i32>>()));
7668        let narrow = Arc::new(integers(&[1, 2]));
7669        let off_wide = Vector::gathered(wide, Arc::new(vec![0, 1, 2])).unwrap();
7670        let off_narrow = Vector::gathered(narrow, Arc::new(vec![0, 1, 0, 1, 0])).unwrap();
7671        assert!(!off_wide.fold_over_source(), "sixty four source rows to answer three");
7672        assert!(off_narrow.fold_over_source(), "two source rows to answer five");
7673        assert!(!integers(&[1, 2]).fold_over_source(), "and every other form says no");
7674    }
7675
7676    /// Strings, which read their bytes where the source already has them rather than through a value.
7677    /// A gather of a string column is four bytes a row and no arena is touched until something asks.
7678    #[test]
7679    fn a_gathered_string_is_read_where_the_source_put_it() {
7680        let mut column = StringColumn::new();
7681        column.push("red");
7682        column.push("a string too long to sit inside a sixteen byte view");
7683        let source = Arc::new(Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap());
7684        let vector = Vector::gathered(source, Arc::new(vec![1, 0, NO_ROW])).unwrap();
7685        assert_eq!(vector.text_at(0), Some("a string too long to sit inside a sixteen byte view"));
7686        assert_eq!(vector.text_at(1), Some("red"));
7687        assert_eq!(vector.text_at(2), None);
7688        assert_eq!(vector.bytes_at(1), Some(b"red".as_slice()));
7689        assert_eq!(vector.value_at(1), Value::Varchar("red".into()));
7690    }
7691
7692    /// The integer accessor a group by keys through, which has to agree with `value_at` at every
7693    /// row or two rows holding one value land in two groups.
7694    #[test]
7695    fn the_signed_reader_of_a_gather_agrees_with_the_value_reader() {
7696        let source = Arc::new(integers(&[10, 20, 30]));
7697        let vector = Vector::gathered(source, Arc::new(vec![2, NO_ROW, 0, 1])).unwrap();
7698        for row in 0..vector.len() {
7699            let signed = vector.signed_at(row);
7700            match vector.value_at(row) {
7701                Value::Null => assert_eq!(signed, None),
7702                Value::Integer(held) => assert_eq!(signed, Some(i128::from(held))),
7703                other => panic!("an integer column answered {other}"),
7704            }
7705        }
7706    }
7707
7708    /// Flattening gives up the form, which is what it is for, and what comes out holds the values the
7709    /// gather stood for, nulls included.
7710    #[test]
7711    fn flattening_a_gather_writes_out_the_rows_it_pointed_at() {
7712        let source = Arc::new(integers(&[10, 20, 30]));
7713        let vector = Vector::gathered(source, Arc::new(vec![2, NO_ROW, 0])).unwrap();
7714        let flat = vector.flatten().unwrap();
7715        assert_eq!(flat.form(), Form::Flat);
7716        assert_eq!(
7717            flat.iter().collect::<Vec<_>>(),
7718            vec![Value::Integer(30), Value::Null, Value::Integer(10)]
7719        );
7720    }
7721
7722    /// A gather counts a share of what it shares, for the reason a dictionary does. Eight columns
7723    /// gathered off one parent are one parent between them, not eight.
7724    #[test]
7725    fn a_parent_gathered_by_many_columns_is_counted_about_once_between_them() {
7726        let source = Arc::new(integers(&(0..4096).collect::<Vec<i32>>()));
7727        let rids = Arc::new(vec![0; 64]);
7728        let alone = Vector::gathered(Arc::clone(&source), Arc::clone(&rids)).unwrap().footprint();
7729        let many = (0..8)
7730            .map(|_| Vector::gathered(Arc::clone(&source), Arc::clone(&rids)).unwrap())
7731            .collect::<Vec<_>>();
7732        let together = many.iter().map(Vector::footprint).sum::<usize>();
7733        assert!(
7734            together < alone * 2,
7735            "eight gathers off one parent reported {together} against {alone} for one"
7736        );
7737    }
7738}