Skip to main content

rudb_vector/
vector.rs

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