Skip to main content

rudb_vector/
vector.rs

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