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