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 and a dictionary are the forms this changes, because they own a run a
2697    /// copy would have to copy: the values of a flat body and the codes of a dictionary. Every other
2698    /// form already shares what is expensive and owns only what a cut has to rewrite, so it comes
2699    /// back as it was: a packed body shares its words, a string body shares its arena, an FSST body
2700    /// shares its codes and its table, and a constant and a sequence have nothing to share.
2701    ///
2702    /// Not recursive into a nested column's children, because a `LIST` or a `STRUCT` holds its
2703    /// children behind an `Arc` already.
2704    #[must_use]
2705    pub fn into_pages(self) -> Self {
2706        let body = match self.body {
2707            Body::Flat(data) => Body::Flat(data.into_pages()),
2708            Body::Dictionary { codes, values, stable } => {
2709                Body::Dictionary { codes: codes.into_page(), values, stable }
2710            }
2711            other => other,
2712        };
2713        Self { body, ..self }
2714    }
2715
2716    /// A contiguous run of the values, in the form they are already in.
2717    ///
2718    /// This is the cut [`Self::gather`] cannot do. A gather walks a dictionary to its leaf and
2719    /// copies, so gathering a piece of a dictionary encoded column hands back a flat one, and a
2720    /// caller that only wanted the first thousand rows of a page has silently paid for a copy and
2721    /// thrown the dictionary away. A group by over a dictionary encoded column is the case that
2722    /// cares, and it is most of ClickBench.
2723    ///
2724    /// So each form is cut as itself. A dictionary keeps its dictionary and slices its codes, a
2725    /// sequence stays arithmetic with its start moved along, a constant stays a shorter constant,
2726    /// and a flat body is a window into its page when it has one and a copy of its range when it
2727    /// does not, which [`Self::into_pages`] is how a producer decides.
2728    ///
2729    /// The dictionary itself is shared rather than copied, so a cut is the codes and nothing else.
2730    /// It used to be copied, and on a read of a ClickBench partition that copy was ten percent of
2731    /// the cycles: a page holds one dictionary and is cut into chunk sized pieces, so the whole
2732    /// dictionary was copied once per chunk to be read the same way each time.
2733    ///
2734    /// # Errors
2735    ///
2736    /// If the range runs past the end of the vector, or if the type has no flat layout and the
2737    /// body is one that has to be copied.
2738    pub fn slice(&self, at: usize, len: usize) -> Result<Self> {
2739        let end = at.checked_add(len).ok_or_else(|| Error::internal("a slice that wraps"))?;
2740        if end > self.len {
2741            return Err(Error::internal(format!("rows {at} to {end} of a vector of {}", self.len)));
2742        }
2743        if at == 0 && len == self.len {
2744            return Ok(self.clone());
2745        }
2746        let validity = self.validity.slice(at, len);
2747        let body = match &self.body {
2748            Body::Constant(value) => Body::Constant(value.clone()),
2749            Body::Sequence { start, step } => {
2750                Body::Sequence { start: start + step * at as i64, step: *step }
2751            }
2752            Body::Dictionary { codes, values, stable } => Body::Dictionary {
2753                codes: codes.slice(at, len),
2754                values: Arc::clone(values),
2755                stable: *stable,
2756            },
2757            // The same cut [`Body::Packed`] below takes and for the same reason, and here it is free
2758            // rather than merely cheap: a link join fills one buffer of parent rows per child chunk
2759            // and the pipeline cuts it, so moving the starting row is what keeps the ids from being
2760            // copied once per cut. Both ends of the gather stay shared, the ids and the source.
2761            Body::Gathered { source, rids, offset } => Body::Gathered {
2762                source: Arc::clone(source),
2763                rids: Arc::clone(rids),
2764                offset: offset + at,
2765            },
2766            // The bits are not byte aligned, so a cut either repacks them or moves the row the
2767            // reading starts at. Moving it is one addition and repacking is a pass, and a page is
2768            // cut into chunk sized pieces often enough that the difference is the form.
2769            Body::Packed { words, width, base, offset } => Body::Packed {
2770                words: Arc::clone(words),
2771                width: *width,
2772                base: *base,
2773                offset: offset + at,
2774            },
2775            // The cut a flat string column cannot do. Sixteen bytes a row move and the payload stays
2776            // where the page put it, so taking a chunk out of a column of long strings costs the
2777            // same as taking one out of a column of integers. A flat varchar body copies every byte
2778            // of every long string in the range instead, which is the measurement written down in
2779            // `Chunk::compact`: compaction loses on a varchar column, and this is the half of the
2780            // reason that is about cutting rather than about selecting.
2781            Body::Views { views, arena } => {
2782                Body::Views { views: views[at..end].to_vec(), arena: Arc::clone(arena) }
2783            }
2784            // The spans are absolute positions in the shared codes, so a cut is a run of them and
2785            // nothing has to be rebased. One page of compressed strings, one table, and as many
2786            // chunks over it as the reader wants.
2787            Body::Coded { codes, spans, table } => Body::Coded {
2788                codes: Arc::clone(codes),
2789                spans: spans[at..end].to_vec(),
2790                table: Arc::clone(table),
2791            },
2792            // Only the runs the range touches survive, the first and last of them cut back to where
2793            // the range starts and stops, and every end moved to be relative to the new row zero. A
2794            // cut of a hundred rows out of a column of a hundred million is a handful of runs, which
2795            // is the reason this form is worth cutting as itself rather than copying out.
2796            Body::Runs { ends, values } if len > 0 => {
2797                let first = run_holding(ends, at).unwrap_or(0);
2798                let last = run_holding(ends, end - 1).unwrap_or(first);
2799                let cut: Vec<u32> = ends[first..=last]
2800                    .iter()
2801                    .map(|&stop| stop.min(end as u32) - at as u32)
2802                    .collect();
2803                let values = values.slice(first, last - first + 1)?;
2804                Body::Runs { ends: cut, values: Arc::new(values) }
2805            }
2806            // An empty cut has no run to point at and an empty run length body would be a vector of
2807            // no runs claiming a length, so it comes back as the empty flat vector instead.
2808            Body::Runs { .. } => return self.gather(&[]),
2809            // The entries are absolute positions in the shared child, so a cut is a run of them and
2810            // nothing has to be rebased, the same as a cut of FSST spans. The elements outside the
2811            // range stay in the child unreferenced, which is the trade this form makes: a chunk cut
2812            // out of a page of lists moves eight bytes a row and copies no elements at all.
2813            Body::Nested { entries, child } => {
2814                Body::Nested { entries: entries[at..end].to_vec(), child: Arc::clone(child) }
2815            }
2816            // Every child cut at the same place, because a struct row is one value per field at the
2817            // same position in each and there is no entry standing between the row and the child to
2818            // rewrite instead. So this is the one nested form whose cut is not free, and what it costs
2819            // is whatever cutting each field costs, which for a field of string views is sixteen bytes
2820            // a row and for a field of packed integers is one addition.
2821            Body::Fields { children } => Body::Fields {
2822                children: children
2823                    .iter()
2824                    .map(|child| child.slice(at, len).map(Arc::new))
2825                    .collect::<Result<Vec<_>>>()?,
2826            },
2827            Body::ExternalText { source } => {
2828                let mut out = StringColumn::with_capacity(len);
2829                for index in at..end {
2830                    out.push_bytes(source.bytes_at(index)?.unwrap_or_default());
2831                }
2832                Body::Flat(Data::Varlen(out))
2833            }
2834            // The one form with nowhere to point, so its range is copied out. A run and not a
2835            // gather: this used to build a vector of the positions `at..end` and hand it to
2836            // `gather`, which then built a vector of `usize` from it, a vector of `bool` beside
2837            // that, and read the values back one bounds checked index at a time. That is five
2838            // passes and three allocations to say `memcpy`, and on a scan it was the largest thing
2839            // in the program after the aggregation itself, because every chunk of every column of
2840            // every page comes through here.
2841            Body::Flat(data) => Body::Flat(run_of(data, at, end)),
2842        };
2843        Ok(Self { ty: self.ty.clone(), len, validity, body })
2844    }
2845
2846    /// The same values in flat form.
2847    ///
2848    /// Flattening a vector that is already flat is free. Flattening any other form costs a copy,
2849    /// which is exactly why the other forms exist and why nothing on the hot path should call
2850    /// this. It is here for the operators that genuinely cannot do better and for the tests that
2851    /// check the other forms against it.
2852    ///
2853    /// A call that copies counts itself against [`Cause::Flatten`], because a flatten on a hot path
2854    /// is the most expensive thing in this crate and the only way to find one is to have the number.
2855    /// A call on a vector that is already flat does not count, since it neither copies nor gives
2856    /// anything up.
2857    ///
2858    /// # Errors
2859    ///
2860    /// If the type is one there is no vector for yet, which today means `ARRAY` and `UNION`. A `LIST`
2861    /// and a `MAP` flatten to themselves and a `STRUCT` to a struct of flattened fields, since none of
2862    /// the three has a data slice in any form and there is nothing flatter to become.
2863    pub fn flatten(&self) -> Result<Self> {
2864        if let Body::Flat(_) = self.body {
2865            return Ok(self.clone());
2866        }
2867        slow::took(Cause::Flatten);
2868        self.copied((0..self.len).collect(), false)
2869    }
2870
2871    /// The same values in flat form, taking the vector rather than borrowing it.
2872    ///
2873    /// A vector that is already flat comes back as itself, which is the whole reason this exists
2874    /// beside [`Self::flatten`]. Flattening through a borrow has to clone that vector, and a clone
2875    /// of a flat vector that owns its values copies every one of them to produce a vector that is
2876    /// identical to the one it was handed. Anything not already flat goes the same way it does
2877    /// through [`Self::flatten`], since the copy is real work there rather than work for nothing.
2878    ///
2879    /// # Errors
2880    ///
2881    /// The same as [`Self::flatten`].
2882    pub fn into_flat(self) -> Result<Self> {
2883        if let Body::Flat(_) = self.body {
2884            return Ok(self);
2885        }
2886        // flatten: the caller asked for flat, and the form that is already flat took the branch
2887        // above, so this is the one case where the copy is what was wanted rather than a shortcut
2888        // somebody took instead of reading the column where it lies.
2889        self.flatten()
2890    }
2891
2892    /// The values at the given positions, copied, in a form that does not point back at this vector.
2893    ///
2894    /// This is the copying counterpart to [`Self::dictionary`], and the two are the two halves of
2895    /// the decision `spec/07-execution.md` section 7.1 describes. Which half is right is measured
2896    /// rather than argued, and [`Chunk::compact`](crate::Chunk::compact) is where the measurement
2897    /// is written down.
2898    ///
2899    /// A dictionary chain is walked to its leaf first and the codes composed on the way down, so the
2900    /// copy runs once over the data rather than once per level, and a position that is null at any
2901    /// level comes out null here. The copy is a typed loop per physical layout rather than a `Value`
2902    /// per row, which is the whole point of it and is what [`Self::flatten`] now goes through too.
2903    ///
2904    /// # Errors
2905    ///
2906    /// If the type is one there is no vector for yet, which today means `ARRAY` and `UNION`. A `LIST`
2907    /// and a `MAP` gather by permuting their entries and a `STRUCT` by gathering every field.
2908    pub fn gather(&self, indices: &[u32]) -> Result<Self> {
2909        self.copied(indices.iter().map(|&index| index as usize).collect(), true)
2910    }
2911
2912    /// The copy both [`Self::gather`] and [`Self::flatten`] are.
2913    ///
2914    /// `forms_stay` is the one thing the two want differently. A gather of a constant is a shorter
2915    /// constant and copying it out would be a thousand writes of the same value for nothing, and a
2916    /// gather of string views is a shorter run of views over the same arena rather than a copy of
2917    /// the bytes. Flattening promises flat form to a caller that is about to read the data slice, so
2918    /// for that one both of them have to be written out.
2919    fn copied(&self, at: Vec<usize>, forms_stay: bool) -> Result<Self> {
2920        let rows = at.len();
2921        if forms_stay {
2922            if let Body::Dictionary { codes, values, stable: true } = &self.body {
2923                // The ordinary case, a column with no nulls and a filter's rows all inside it, in
2924                // one pass for the range and one for the gather. Every code taken is one of this
2925                // vector's codes, which were range checked when it was built, so the result is not
2926                // checked again the way a dictionary from outside is. The highest index rather than
2927                // a test that stops at the first bad one, because a running maximum is vectorized
2928                // and an early exit is not. On q1 the two passes this replaces and the check after
2929                // them were a tenth of the instructions of the scan.
2930                let highest = at.iter().copied().fold(0, usize::max);
2931                if self.never_null() && (at.is_empty() || highest < codes.len()) {
2932                    let gathered = at.iter().map(|&index| codes[index]).collect();
2933                    return Ok(Self {
2934                        ty: values.ty.clone(),
2935                        len: rows,
2936                        validity: Validity::AllValid,
2937                        body: Body::Dictionary {
2938                            codes: gathered,
2939                            values: Arc::clone(values),
2940                            stable: true,
2941                        },
2942                    });
2943                }
2944                // A gather off a column with no nulls in it is all valid as long as every index it
2945                // was handed is in range, and both of those are answered by a word at a time rather
2946                // than by asking each row whether it is null. That per row question reads through
2947                // the dictionary to the value it stands for, which made it the single line a
2948                // filtered scan of a dictionary column spent most of its copy in.
2949                let validity = if self.never_null() && at.iter().all(|&index| index < self.len) {
2950                    Validity::AllValid
2951                } else {
2952                    Validity::from_iter(rows, |row| {
2953                        at.get(row)
2954                            .is_some_and(|&index| index < self.len && !self.is_null_at(index))
2955                    })
2956                };
2957                let gathered: Vec<u32> =
2958                    at.iter().map(|&index| codes.get(index).copied().unwrap_or(0)).collect();
2959                // Every code here is one this vector already held, which was checked against the
2960                // same values on the way in, or the zero a row past the end is written as. So the
2961                // only code that can be out of range is that zero over no values at all, and the
2962                // pass that looks for the largest code is not needed to find it. On ClickBench 28
2963                // that pass was four percent of the query, because every filtered chunk of `URL`
2964                // came through here.
2965                // Values that are themselves a dictionary are composed through by the constructor,
2966                // and this skips the constructor, so that shape still goes the checked way.
2967                if matches!(values.body, Body::Dictionary { .. }) {
2968                    return Ok(Self::stable_dictionary(gathered, Arc::clone(values))?
2969                        .with_validity(validity));
2970                }
2971                let highest = (values.is_empty() && !gathered.is_empty()).then_some(0);
2972                return Ok(Self::stable_dictionary_validated(
2973                    gathered,
2974                    Arc::clone(values),
2975                    highest,
2976                )?
2977                .with_validity(validity));
2978            }
2979        }
2980        let (at, leaf) = self.resolve(at);
2981        let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
2982        let validity = Validity::from_run(&live);
2983        let body = match &leaf.body {
2984            // The same gather the arm below is, for a type that has no flat layout to be written out
2985            // into. It goes through the nested builders rather than through a run of data, because they
2986            // are the one place that knows a row of a list column is a range of a child and a row of a
2987            // struct column is one position in each of several, and a second copy of that here would
2988            // be a second thing to keep in step with them.
2989            Body::Constant(value)
2990                if matches!(
2991                    self.ty,
2992                    LogicalType::List(_) | LogicalType::Struct(_) | LogicalType::Map(_, _)
2993                ) =>
2994            {
2995                if forms_stay && matches!(validity, Validity::AllValid) {
2996                    return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
2997                }
2998                let rows: Vec<Value> = at
2999                    .iter()
3000                    .map(
3001                        |&index| {
3002                            if index == NOWHERE { Value::Null } else { value.as_ref().clone() }
3003                        },
3004                    )
3005                    .collect();
3006                return Self::from_values(self.ty.clone(), &rows);
3007            }
3008            // Every position holds the same value, so the only thing the gather can change is the
3009            // length and which positions are null. A gather with no null in it is still a constant.
3010            Body::Constant(value) => {
3011                if forms_stay && matches!(validity, Validity::AllValid) {
3012                    return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
3013                }
3014                let mut data = empty_data_for(&self.ty)?;
3015                for &index in &at {
3016                    push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
3017                }
3018                Body::Flat(data)
3019            }
3020            // A sequence is arithmetic rather than storage, so the gather is the arithmetic done at
3021            // the positions asked for, and a null writes the zero every other layout writes.
3022            Body::Sequence { start, step } => Body::Flat(Data::Int64(
3023                at.iter()
3024                    .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
3025                    .collect(),
3026            )),
3027            // A flat body with no values is the untyped null, so every position asked for is null
3028            // whatever was asked for. Going through the copy would build a run of no values and
3029            // call it `rows` long, which is a vector whose length and data disagree.
3030            Body::Flat(Data::Empty) => {
3031                return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
3032            }
3033            Body::Flat(data) => Body::Flat(copy_of(data, &at)),
3034            // The one form whose copy is arithmetic rather than a move of bytes. It goes through a
3035            // typed loop per layout the way the flat copy does, because the alternative is a `Value`
3036            // per row and this is the path a flatten of a scanned column takes.
3037            Body::Packed { words, width, base, offset } => {
3038                Body::Flat(unpack(&self.ty, words, *offset, *width, *base, &at)?)
3039            }
3040            // A gather keeps the form, which is what makes selecting rows out of a string column
3041            // cost sixteen bytes a row instead of the bytes of the strings. The arena it shares is
3042            // the whole arena and not the part the kept rows point at, so a selection that throws
3043            // most of a page away goes on holding the page. That is the trade the form is: a cut and
3044            // a filter are cheap and the memory comes back when the last vector over the page goes,
3045            // and a caller that wants the bytes narrowed asks for a flatten.
3046            Body::Views { views, arena } if forms_stay => Body::Views {
3047                views: at
3048                    .iter()
3049                    .map(|&index| views.get(index).copied().unwrap_or_else(StringView::empty))
3050                    .collect(),
3051                arena: Arc::clone(arena),
3052            },
3053            // Flattening promises a data slice, and a flat string column is views over an arena
3054            // just as this form is, so when the arena is a page the flatten is the views and
3055            // nothing else. The form is given up, which is what was asked for, and not the sharing,
3056            // which nobody asked to have given up: a result set of six million strings used to copy
3057            // every byte of them out of the pages they were already sitting in.
3058            Body::Views { views, arena } if arena.is_shared() => {
3059                Body::Flat(Data::Varlen(StringColumn::from_parts(
3060                    at.iter()
3061                        .map(|&index| views.get(index).copied().unwrap_or_else(StringView::empty))
3062                        .collect(),
3063                    (**arena).clone(),
3064                )))
3065            }
3066            // The arena is this vector's own, so there is nothing to share and the bytes are copied
3067            // out into an arena of their own. The total is known before any of it is copied, the
3068            // way the flat copy works it out, so the new arena is one allocation.
3069            Body::Views { views, arena } => {
3070                let mut out = StringColumn::with_capacity(at.len());
3071                out.reserve_bytes(
3072                    at.iter()
3073                        .filter_map(|&index| views.get(index))
3074                        .filter(|view| !view.is_inline())
3075                        .map(StringView::len)
3076                        .sum(),
3077                );
3078                for &index in &at {
3079                    let bytes = views.get(index).and_then(|view| view.bytes_in(arena));
3080                    out.push_bytes(bytes.unwrap_or_default());
3081                }
3082                Body::Flat(Data::Varlen(out))
3083            }
3084            Body::ExternalText { source } => {
3085                let mut out = StringColumn::with_capacity(at.len());
3086                for &index in &at {
3087                    out.push_bytes(source.bytes_at(index)?.unwrap_or_default());
3088                }
3089                Body::Flat(Data::Varlen(out))
3090            }
3091            // A gather keeps the form, because the codes do not move and a span survives being put
3092            // in an order the codes are not in. A position that resolved to nowhere gets the empty
3093            // span, which decompresses to no bytes, which is the zero every other layout writes.
3094            Body::Coded { codes, spans, table } if forms_stay => Body::Coded {
3095                codes: Arc::clone(codes),
3096                spans: at
3097                    .iter()
3098                    .map(|&index| spans.get(index).copied().unwrap_or((0, 0)))
3099                    .collect(),
3100                table: Arc::clone(table),
3101            },
3102            // Flattening decompresses, which is the price of the data slice it promises. The scratch
3103            // buffer is reused across rows, so this is one allocation for the whole column rather
3104            // than one per row the way reading it a value at a time would be.
3105            Body::Coded { codes, spans, table } => {
3106                let mut out = StringColumn::with_capacity(at.len());
3107                let mut scratch = Vec::new();
3108                for &index in &at {
3109                    scratch.clear();
3110                    let span = spans
3111                        .get(index)
3112                        .and_then(|&(from, to)| codes.get(from as usize..to as usize));
3113                    if let Some(span) = span {
3114                        table.decompress(span, &mut scratch)?;
3115                    }
3116                    out.push_bytes(&scratch);
3117                }
3118                Body::Flat(Data::Varlen(out))
3119            }
3120            // The entries move and the child does not, which is the same trade the string forms
3121            // make and is why a gather of a list column costs eight bytes a row however long the
3122            // lists are. A position that resolved to nowhere gets a zero length entry, and the mask
3123            // already says it is null, so the entry is never read.
3124            //
3125            // This arm ignores `forms_stay`, unlike every arm above it, because there is nothing
3126            // flatter for a list to become. The other forms are all cheaper ways of writing down a
3127            // column of scalars and flattening gives up the saving to hand back a data slice, and a
3128            // list has no data slice in any form, so a flatten of one is this and a caller reading it
3129            // goes through `list_parts` either way.
3130            Body::Nested { entries, child } => Body::Nested {
3131                entries: at
3132                    .iter()
3133                    .map(|&index| entries.get(index).copied().unwrap_or((0, 0)))
3134                    .collect(),
3135                child: Arc::clone(child),
3136            },
3137            // Every child gathered at the same positions, for the reason the cut cuts every child:
3138            // there are no entries to permute instead, so the permutation happens once per field. The
3139            // positions handed down are the resolved ones, sentinel and all, so a row that resolved to
3140            // nowhere comes back null in each field as well as null here.
3141            //
3142            // `forms_stay` is passed straight through rather than ignored, which is the opposite of
3143            // what the list arm does, and the difference is real. There is nothing flatter for a list
3144            // to become, and a struct is only as flat as its fields are, so a flatten of a struct
3145            // column is a flatten of each field and a caller that asked for data slices gets them.
3146            Body::Fields { children } => Body::Fields {
3147                children: children
3148                    .iter()
3149                    .map(|child| child.copied(at.clone(), forms_stay).map(Arc::new))
3150                    .collect::<Result<Vec<_>>>()?,
3151            },
3152            // Unreachable, because `resolve` walks past every form that points at another vector
3153            // and stops at the first body that does not.
3154            Body::Dictionary { .. } | Body::Runs { .. } | Body::Gathered { .. } => {
3155                return Err(Error::internal(
3156                    "a form that points somewhere survived being resolved",
3157                ));
3158            }
3159        };
3160        Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
3161    }
3162
3163    /// Where each wanted position lives in the first body that points nowhere else, and that body.
3164    ///
3165    /// A position that is null anywhere on the way down, or past the end of anything on the way
3166    /// down, comes back as [`NOWHERE`]. That single sentinel is what keeps the copy loop from
3167    /// carrying a validity mask alongside the positions it is already walking.
3168    fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
3169        let mut source = self;
3170        loop {
3171            for slot in &mut at {
3172                if *slot >= source.len || !source.validity.is_valid(*slot) {
3173                    *slot = NOWHERE;
3174                }
3175            }
3176            source = match &source.body {
3177                Body::Dictionary { codes, values, .. } => {
3178                    for slot in &mut at {
3179                        *slot = match codes.get(*slot) {
3180                            Some(&code) => code as usize,
3181                            None => NOWHERE,
3182                        };
3183                    }
3184                    values.as_ref()
3185                }
3186                // A run length body is a dictionary whose code is worked out from the position
3187                // rather than stored, so the walk down is the same walk with a search where the
3188                // lookup was. `NOWHERE` searches for nothing and stays `NOWHERE`.
3189                Body::Runs { ends, values } => {
3190                    for slot in &mut at {
3191                        *slot = run_holding(ends, *slot).unwrap_or(NOWHERE);
3192                    }
3193                    values.as_ref()
3194                }
3195                // The same walk the dictionary above takes, with the sentinel folded into the one
3196                // this loop already has. That composition is the whole reason a gather is a body
3197                // rather than an operator: a filter over the output of a link join selects into the
3198                // ids and copies nothing, and a gather off a gather is one walk down to whatever is
3199                // at the bottom rather than two passes over the parent.
3200                Body::Gathered { source: below, rids, offset } => {
3201                    for slot in &mut at {
3202                        *slot = if *slot == NOWHERE {
3203                            NOWHERE
3204                        } else {
3205                            row_of(rids, *offset, *slot).unwrap_or(NOWHERE)
3206                        };
3207                    }
3208                    below.as_ref()
3209                }
3210                _ => return (at, source),
3211            };
3212        }
3213    }
3214}
3215
3216/// So that a kernel can take its operands as either a list of vectors or a list of references.
3217///
3218/// A caller that built a `Vec<Vector>` and a caller whose operands are already somewhere else, in a
3219/// chunk or in an evaluator's scratch, want the same kernel. Without this the second kind has to
3220/// clone every operand into a `Vec` to satisfy the signature, and a clone of a vector is a copy of
3221/// the whole column, so the type would be charging real memory traffic for nothing.
3222impl AsRef<Vector> for Vector {
3223    fn as_ref(&self) -> &Vector {
3224        self
3225    }
3226}
3227
3228/// The bits of a packed vector and what they mean, for a kernel that wants to stay in code space.
3229///
3230/// Borrowed from the vector rather than owning anything, so getting one costs nothing and a kernel
3231/// that finds it cannot use them has given up nothing by asking.
3232#[derive(Debug, Clone, Copy)]
3233pub struct Packed<'a> {
3234    words: &'a [u64],
3235    width: u32,
3236    base: i128,
3237    offset: usize,
3238}
3239
3240impl Packed<'_> {
3241    /// Packed words. A persisted vector also records [`Self::offset`].
3242    #[must_use]
3243    pub fn words(&self) -> &[u64] {
3244        self.words
3245    }
3246
3247    /// Bit offset, in rows, of the first value.
3248    #[must_use]
3249    pub fn offset(&self) -> usize {
3250        self.offset
3251    }
3252
3253    /// How many bits one code takes, between one and [`PACKED_WIDTH_MAX`].
3254    #[must_use]
3255    pub fn width(&self) -> u32 {
3256        self.width
3257    }
3258
3259    /// What zero means, so that the value of a row is the base plus its code.
3260    #[must_use]
3261    pub fn base(&self) -> i128 {
3262        self.base
3263    }
3264
3265    /// The largest value this vector can be holding, whatever it is actually holding.
3266    ///
3267    /// With [`Self::base`] this is the pair a comparison kernel wants first. A literal outside the
3268    /// two answers every row of the vector the same way, which is a whole chunk decided without a
3269    /// bit being read, and that is the case a zone map would have caught if there were one here.
3270    #[must_use]
3271    pub fn ceiling(&self) -> i128 {
3272        self.base + i128::from(u64::MAX >> (u64::BITS - self.width))
3273    }
3274
3275    /// The code of row `row`, which is its value minus [`Self::base`].
3276    ///
3277    /// Out of range rows read as zero rather than panicking, the way every other accessor in this
3278    /// file answers for a row that is not there.
3279    ///
3280    /// Marked inline because every caller that matters is a kernel in another crate reading one code
3281    /// per row, and thin LTO was leaving it as a call there. On TPC-H SF1 that call was 1.5 percent of
3282    /// the suite and a tenth of q12.
3283    #[must_use]
3284    #[inline]
3285    pub fn code(&self, row: usize) -> u64 {
3286        code_at(self.words, (self.offset + row) * self.width as usize, self.width)
3287    }
3288
3289    /// Which code a value would have, and `None` for a value this vector cannot be holding.
3290    ///
3291    /// The translation a comparison does once per vector so that it does not have to unpack once per
3292    /// row. `None` is the useful answer rather than a failure: it says the literal is outside the
3293    /// packed range, so every row compares against it the same way.
3294    #[must_use]
3295    pub fn code_of(&self, value: i128) -> Option<u64> {
3296        u64::try_from(value.checked_sub(self.base)?).ok().filter(|&code| code <= self.mask())
3297    }
3298
3299    /// The largest code the width allows.
3300    fn mask(&self) -> u64 {
3301        u64::MAX >> (u64::BITS - self.width)
3302    }
3303
3304    /// The codes of rows `from` to `from + out.len()`, in one pass over the words.
3305    ///
3306    /// [`Self::code`] is a code at a time, and every one of them works out which word it is in, reads
3307    /// it through a bound, and asks whether it straddles into the next. Sixty four codes of one
3308    /// width fill exactly that many words and the straddles fall in the same places every time, so a
3309    /// block of them is unpacked by a loop the width is a constant in, where every shift and every
3310    /// straddle is known before it runs. On TPC-H q1 the code at a time reads were a third of the
3311    /// instructions the query ran. The rows before the first whole block and after the last one
3312    /// still go a code at a time.
3313    pub fn unpack(&self, from: usize, out: &mut [u64]) {
3314        let width = self.width as usize;
3315        let start = self.offset + from;
3316        let end = start + out.len();
3317        let first = start.next_multiple_of(64).min(end);
3318        let mut at = 0;
3319        for row in start..first {
3320            out[at] = code_at(self.words, row * width, self.width);
3321            at += 1;
3322        }
3323        let mut row = first;
3324        while row + 64 <= end {
3325            let word = row / 64 * width;
3326            let Some(words) = self.words.get(word..word + width) else { break };
3327            let Some(Ok(block)) = out.get_mut(at..at + 64).map(<&mut [u64; 64]>::try_from) else {
3328                break;
3329            };
3330            unpack_block(words, self.width, block);
3331            row += 64;
3332            at += 64;
3333        }
3334        for row in row..end {
3335            out[at] = code_at(self.words, row * width, self.width);
3336            at += 1;
3337        }
3338    }
3339
3340    /// The code of each of `rows` rows `at` names, in order.
3341    ///
3342    /// A filter's selection names rows close together and in order, so the span they cover is
3343    /// unpacked whole with [`Self::unpack`] and each row read out of it. Rows spread too far apart
3344    /// for that to pay are read a code at a time.
3345    ///
3346    /// Unpacking a block at a time into a buffer on the stack, and reading each row out of the
3347    /// block it falls in, keeps less in the cache and was tried. The question of which block a row
3348    /// is in, asked for every row, cost more than the misses it saved, 40.2 G instructions for ten
3349    /// runs of q1 against 34.1 G this way.
3350    pub fn codes_at<M: Fn(usize) -> usize>(&self, at: M, rows: usize) -> Vec<u64> {
3351        let (mut low, mut high) = (usize::MAX, 0);
3352        for index in 0..rows {
3353            let row = at(index);
3354            low = low.min(row);
3355            high = high.max(row);
3356        }
3357        if rows == 0 || high - low >= rows.saturating_mul(4) {
3358            return (0..rows).map(|index| self.code(at(index))).collect();
3359        }
3360        let mut run = vec![0; high - low + 1];
3361        self.unpack(low, &mut run);
3362        (0..rows).map(|index| run[at(index) - low]).collect()
3363    }
3364}
3365
3366/// Sixty four codes of `width` bits out of the `width` words that hold them, with the width made a
3367/// constant so that the loop in [`unpack_width`] has nothing left to work out as it goes.
3368fn unpack_block(words: &[u64], width: u32, out: &mut [u64; 64]) {
3369    macro_rules! widths {
3370        ($($width:literal)*) => {
3371            match width {
3372                $($width => unpack_width::<$width>(words, out),)*
3373                _ => {
3374                    for (at, code) in out.iter_mut().enumerate() {
3375                        *code = code_at(words, at * width as usize, width);
3376                    }
3377                }
3378            }
3379        };
3380    }
3381    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
3382        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);
3383}
3384
3385#[inline(always)]
3386fn unpack_width<const WIDTH: usize>(words: &[u64], out: &mut [u64; 64]) {
3387    let Ok(words) = <&[u64; WIDTH]>::try_from(&words[..WIDTH]) else { return };
3388    // Written out sixty four times rather than as a loop, because the compiler kept the loop and
3389    // with it a shift and a branch on the straddle for every code. Spelled out, the row is a
3390    // constant in each step, so its word, its shift and whether it straddles are all worked out
3391    // before the program runs and a code is a shift, an or where it straddles and a mask.
3392    macro_rules! steps {
3393        ($($at:literal)*) => {
3394            $(unpack_step::<WIDTH, $at>(words, out);)*
3395        };
3396    }
3397    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
3398        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);
3399}
3400
3401#[inline(always)]
3402fn unpack_step<const WIDTH: usize, const AT: usize>(words: &[u64; WIDTH], out: &mut [u64; 64]) {
3403    let bit = AT * WIDTH;
3404    let word = bit / 64;
3405    let shift = bit % 64;
3406    let mut value = words[word] >> shift;
3407    if shift + WIDTH > 64 {
3408        value |= words[word + 1] << (64 - shift);
3409    }
3410    out[AT] = value & (u64::MAX >> (64 - WIDTH));
3411}
3412
3413/// The widest a packed code is allowed to be.
3414///
3415/// Sixty three rather than sixty four so that a mask is `u64::MAX >> (64 - width)` with no shift of
3416/// a whole word in it, and reading a code is one branch on whether it straddles rather than two. A
3417/// sixty four bit code saves nothing anyway, since it is the layout it came from.
3418pub const PACKED_WIDTH_MAX: u32 = 63;
3419
3420/// How much smaller packing has to be before it is worth the shift and the mask on every read.
3421///
3422/// Two, so a column packs when the bits come to half the flat size or less. A column that would save
3423/// a tenth stays flat, because a tenth of a column is not worth turning every read of it into
3424/// arithmetic, and the whole argument for the form is that a narrow column saves most of itself.
3425pub const PACKING_PAYS_AT: usize = 2;
3426
3427/// How much smaller compressing has to be before it is worth a decompression on every read.
3428///
3429/// Two, the same rule packing follows and for the same reason. FSST gets about that on text, so a
3430/// column of English or of URLs compresses and a column of short codes or of random bytes does not,
3431/// which is the right answer for both.
3432pub const FSST_PAYS_AT: usize = 2;
3433
3434/// The codes of a compressed column and the table they are against.
3435///
3436/// Handed out by [`Vector::coded_parts`] so a kernel can work in code space. Nothing here
3437/// decompresses, which is the point: [`Self::encode`] puts the literal into the same space the rows
3438/// are already in, and after that an equality test is a byte slice comparison.
3439#[derive(Debug, Clone, Copy)]
3440pub struct Coded<'a> {
3441    codes: &'a [u8],
3442    spans: &'a [(u32, u32)],
3443    table: &'a SymbolTable,
3444}
3445
3446impl Coded<'_> {
3447    /// The table every row in this vector is compressed against.
3448    #[must_use]
3449    pub fn table(&self) -> &SymbolTable {
3450        self.table
3451    }
3452
3453    /// The code bytes of one row, still compressed.
3454    #[must_use]
3455    pub fn row(&self, row: usize) -> Option<&[u8]> {
3456        let &(from, to) = self.spans.get(row)?;
3457        self.codes.get(from as usize..to as usize)
3458    }
3459
3460    /// Some bytes in the code space this vector is in.
3461    ///
3462    /// The literal side of an equality filter. Compressing is a function of the table and the bytes,
3463    /// so two strings compress to the same codes exactly when they are the same string, and an
3464    /// equality test on the codes is an equality test on the strings with no decompression in it.
3465    #[must_use]
3466    pub fn encode(&self, bytes: &[u8]) -> Vec<u8> {
3467        let mut out = Vec::with_capacity(bytes.len());
3468        self.table.compress(bytes, &mut out);
3469        out
3470    }
3471}
3472
3473/// The first `len` of a run of some narrower signed width, sign extended into `out`.
3474///
3475/// Written once and called from the three narrow arms of [`Data::signed_block`], so that the sign
3476/// extension is one loop the compiler can widen rather than three written out by hand.
3477fn widen<T: Copy + Into<i64>>(run: &[T], len: usize, out: &mut Vec<i64>) -> bool {
3478    match run.get(..len) {
3479        Some(run) => {
3480            out.extend(run.iter().map(|&x| x.into()));
3481            true
3482        }
3483        None => false,
3484    }
3485}
3486
3487/// One holder's share of a part that several vectors are reading at the same time.
3488///
3489/// The rule [`Buffer::footprint`] already uses for a shared page. Everything holding the part asks
3490/// this, so what they say between them comes to about what the part costs rather than to the part
3491/// times the number of them, and the answer is never zero for a part that costs anything, because a
3492/// caller with a reference is at least one holder.
3493fn share<T: ?Sized>(bytes: usize, held: &Arc<T>) -> usize {
3494    bytes / Arc::strong_count(held).max(1)
3495}
3496
3497/// How many words hold `len` codes of `width` bits.
3498fn words_for(len: usize, width: u32) -> usize {
3499    (len * width as usize).div_ceil(u64::BITS as usize)
3500}
3501
3502/// The lowest and highest value a type's layout can hold, and `None` for a type with no integer one.
3503///
3504/// This is also the test of whether a type can be packed at all, and it is the only one, so the
3505/// layouts listed here and the layouts [`pack`] and [`unpack`] know how to walk are the same list
3506/// from the same macro and cannot drift apart.
3507fn layout_range(ty: &LogicalType) -> Option<(i128, i128)> {
3508    use rudb_common::PhysicalType as P;
3509    macro_rules! ranges {
3510        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3511            match ty.physical() {
3512                $(P::$variant => Some((i128::from(<$native>::MIN), i128::from(<$native>::MAX))),)+
3513                _ => None,
3514            }
3515        };
3516    }
3517    crate::for_each_layout!(exact, ranges)
3518}
3519
3520/// The bytes the first `len` slots of a run take laid flat, whether the run is owned or a window.
3521fn flat_bytes(data: &Data, len: usize) -> usize {
3522    macro_rules! widths {
3523        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3524            match data {
3525                Data::Empty => 0,
3526                $(Data::$variant(_) => len * size_of::<$native>(),)+
3527            }
3528        };
3529    }
3530    crate::for_each_layout!(all, widths)
3531}
3532
3533/// What to subtract before packing, so that the whole code range lands inside the column's type.
3534///
3535/// The smallest value in the column is the obvious base and it is the wrong one near the top of a
3536/// type. [`Vector::packed`] checks the two ends of what the codes could say rather than the values
3537/// that are actually there, which is one check instead of one per row and is what makes reading a
3538/// packed column cheap. An `INTEGER` column of a thousand values just under `i32::MAX` needs ten
3539/// bits, and based at its own smallest value those ten bits could say a number an `INTEGER` cannot
3540/// hold, so the column was refused and the table would not write at all.
3541///
3542/// The base does not have to be the smallest value. Any base works where every code is still
3543/// non-negative and the widest code the width allows still fits the type, which is `base <= low`,
3544/// `high - base <= 2^width - 1`, `type low <= base` and `base + 2^width - 1 <= type high` together.
3545///
3546/// The largest base meeting all four is the one below, and it exists whenever the values fit the
3547/// type at all: `high - (2^width - 1) <= low` because that is how the width was chosen, and
3548/// `type low <= type high - (2^width - 1)` because a width wider than the type's own span is
3549/// already refused. `None` is for a type with no integer layout, which cannot be packed anyway.
3550fn packing_base(ty: &LogicalType, low: i128, high: i128, width: u32) -> Option<i128> {
3551    let (floor, ceiling) = layout_range(ty)?;
3552    let span = i128::from(u64::MAX >> (64 - width));
3553    let base = low.min(ceiling - span);
3554    (base >= floor && base >= high - span).then_some(base)
3555}
3556
3557/// The lowest and highest value in the first `len` slots of a run of integer data.
3558///
3559/// `None` for data that is not integers, which is what says a column cannot be packed. The null
3560/// slots are in the span, holding whatever zero was written into them, which
3561/// [`Vector::bit_packed`] says more about.
3562fn span_of(data: &Data, len: usize) -> Option<(i128, i128)> {
3563    macro_rules! spans {
3564        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3565            match data {
3566                $(Data::$variant(values) => {
3567                    let mut low = i128::MAX;
3568                    let mut high = i128::MIN;
3569                    for &value in values.as_slice().iter().take(len) {
3570                        let value = i128::from(value);
3571                        low = low.min(value);
3572                        high = high.max(value);
3573                    }
3574                    (low <= high).then_some((low, high))
3575                })+
3576                _ => None,
3577            }
3578        };
3579    }
3580    crate::for_each_layout!(exact, spans)
3581}
3582
3583/// The first `len` values of a run of integer data, written out as codes of `width` bits from `base`.
3584fn pack(data: &Data, len: usize, base: i128, width: u32) -> Vec<u64> {
3585    let mut words = vec![0u64; words_for(len, width)];
3586    macro_rules! packing {
3587        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3588            match data {
3589                $(Data::$variant(values) => {
3590                    for (row, &value) in values.as_slice().iter().take(len).enumerate() {
3591                        // In range because `base` and `width` came from the span of this same run.
3592                        let code = u64::try_from(i128::from(value) - base).unwrap_or(0);
3593                        write_code(&mut words, row * width as usize, width, code);
3594                    }
3595                })+
3596                _ => {}
3597            }
3598        };
3599    }
3600    crate::for_each_layout!(exact, packing);
3601    words
3602}
3603
3604/// The codes at the given rows, unpacked into the flat layout the type calls for.
3605///
3606/// A row of [`NOWHERE`] writes the layout's zero, which is the rule [`copy_of`] follows for the same
3607/// reason: every layout here is a parallel array to a validity mask, so a null takes a slot.
3608///
3609/// # Errors
3610///
3611/// If the type has no flat layout, which a packed vector cannot have and which is checked when one
3612/// is built, so an error here is a bug rather than a caller mistake.
3613fn unpack(
3614    ty: &LogicalType,
3615    words: &[u64],
3616    offset: usize,
3617    width: u32,
3618    base: i128,
3619    at: &[usize],
3620) -> Result<Data> {
3621    let mut out = empty_data_for(ty)?;
3622    let value_of = |row: usize| {
3623        if row == NOWHERE {
3624            return None;
3625        }
3626        Some(base + i128::from(code_at(words, (offset + row) * width as usize, width)))
3627    };
3628    macro_rules! unpacking {
3629        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3630            match &mut out {
3631                $(Data::$variant(values) => {
3632                    values.reserve(at.len());
3633                    for &row in at {
3634                        // In range because both ends of it were checked when the vector was built.
3635                        let value = value_of(row)
3636                            .and_then(|value| <$native>::try_from(value).ok())
3637                            .unwrap_or($zero);
3638                        values.push(value);
3639                    }
3640                })+
3641                _ => {
3642                    return Err(Error::internal(format!(
3643                        "a {ty} vector was packed, which no integer layout allows"
3644                    )));
3645                }
3646            }
3647        };
3648    }
3649    crate::for_each_layout!(exact, unpacking);
3650    Ok(out)
3651}
3652
3653/// The `width` bits starting at `bit`, low end first.
3654///
3655/// Zero for bits past the end of the words, which keeps a read of a row that is not there from
3656/// panicking and matches what every other accessor here does with one.
3657#[inline]
3658fn code_at(words: &[u64], bit: usize, width: u32) -> u64 {
3659    let word = bit / u64::BITS as usize;
3660    let shift = (bit % u64::BITS as usize) as u32;
3661    let mask = u64::MAX >> (u64::BITS - width);
3662    let low = words.get(word).copied().unwrap_or(0) >> shift;
3663    let taken = u64::BITS - shift;
3664    if taken >= width {
3665        return low & mask;
3666    }
3667    // The code straddles two words, and `taken` is under the width here so it is under sixty four,
3668    // which is what makes the shift below one the hardware will do rather than one it refuses.
3669    let high = words.get(word + 1).copied().unwrap_or(0) << taken;
3670    (low | high) & mask
3671}
3672
3673/// Writes `width` bits of `code` starting at `bit`, over words that started out zero.
3674fn write_code(words: &mut [u64], bit: usize, width: u32, code: u64) {
3675    let word = bit / u64::BITS as usize;
3676    let shift = (bit % u64::BITS as usize) as u32;
3677    words[word] |= code << shift;
3678    let taken = u64::BITS - shift;
3679    if taken < width {
3680        words[word + 1] |= code >> taken;
3681    }
3682}
3683
3684/// One level of dictionary out of however many levels were handed to [`Vector::dictionary`].
3685///
3686/// Every dictionary in the system is built through that constructor and every one of them comes
3687/// through here first, so the invariant this maintains is that the vector a dictionary points at is
3688/// never itself a dictionary that could have been composed away. That makes the work a single `if`
3689/// rather than a loop: the inner vector was already composed when it was built, so composing the
3690/// outer codes through it leaves the result no deeper than the inner vector already was.
3691///
3692/// The codes are indexed rather than fetched with `get`, because the caller has already walked the
3693/// whole outer array to check that every code is in range and the inner array is exactly as long as
3694/// the vector those codes were checked against.
3695fn compose(codes: Vec<u32>, values: Arc<Vector>) -> (Vec<u32>, Arc<Vector>) {
3696    // A dictionary carrying a validity of its own is one whose nulls live at this level rather than
3697    // in the values, which is the one thing composition cannot carry down with it.
3698    if !matches!(values.validity, Validity::AllValid) {
3699        return (codes, values);
3700    }
3701    let Body::Dictionary { codes: inner, values: leaf, .. } = &values.body else {
3702        return (codes, values);
3703    };
3704    debug_assert!(
3705        !matches!(leaf.body, Body::Dictionary { .. })
3706            || !matches!(leaf.validity, Validity::AllValid),
3707        "a dictionary was stacked on a dictionary without going through the constructor"
3708    );
3709    // The leaf is handed on as the handle it already is. Nothing here reads it and nothing here
3710    // changes it, so the composed dictionary points at the same values the stacked one did and
3711    // whoever else is holding them keeps holding them. This used to take them out of the `Arc`,
3712    // which copied the whole leaf whenever anybody else was still reading it, and a scan selecting
3713    // rows out of a chunk whose column came from a shared page dictionary is exactly that: the page
3714    // holds the leaf, every chunk cut from the page composes through it, and every one of those
3715    // cuts copied the page's dictionary. TPC-H q21 does it once per thousand rows of `lineitem`.
3716    let composed = codes.iter().map(|&code| inner[code as usize]).collect();
3717    (composed, Arc::clone(leaf))
3718}
3719
3720/// How many rows a run has to cover on average before run length encoding is smaller.
3721///
3722/// A run costs its value plus the four bytes of its end, so on a four byte column a run of two rows
3723/// breaks even and a run of three wins. Wider columns win sooner and narrower ones later, and this
3724/// is the one ratio for all of them because a threshold per width is a table that has to be right
3725/// nine times rather than once. It is a constant with a name so that the sweep that eventually moves
3726/// it has something to move.
3727const RUNS_PAY_AT: usize = 2;
3728
3729/// Which run holds `row`, given ends that are exclusive and increasing.
3730///
3731/// A binary search rather than a scan, because the callers that ask this are the ones that are not
3732/// walking the runs in order: a single value read out of a result set, or a gather at scattered
3733/// positions. Anything walking in order should be reading [`Vector::run_parts`] instead, which is
3734/// what the form is for.
3735fn run_holding(ends: &[u32], row: usize) -> Option<usize> {
3736    let row = u32::try_from(row).ok()?;
3737    let run = match ends.binary_search(&row) {
3738        // The ends are exclusive, so landing exactly on one means the row is the first of the next.
3739        Ok(at) => at + 1,
3740        Err(at) => at,
3741    };
3742    (run < ends.len()).then_some(run)
3743}
3744
3745/// The row each run ends at, for a flat body read alongside the validity that goes with it.
3746///
3747/// Two adjacent nulls are one run, because a reader of either gets a null and cannot tell them
3748/// apart. A null between two equal values is three runs for the same reason, since the null is a
3749/// value of the column as far as anything reading it is concerned.
3750///
3751/// The comparison is per layout rather than per `Value`, which is the whole reason this is a macro.
3752/// A `Value` a row would allocate a string per row on a `VARCHAR` column and would be the exact
3753/// defect `cargo xtask rowloop` exists to fail the build on.
3754fn boundaries(data: &Data, validity: &Validity, len: usize) -> Vec<u32> {
3755    if len == 0 {
3756        return Vec::new();
3757    }
3758    let breaks = |ends: &mut Vec<u32>, mut differs: Box<dyn FnMut(usize, usize) -> bool + '_>| {
3759        for row in 1..len {
3760            let same = match (validity.is_valid(row), validity.is_valid(row - 1)) {
3761                (false, false) => true,
3762                (true, true) => !differs(row, row - 1),
3763                _ => false,
3764            };
3765            if !same {
3766                ends.push(u32::try_from(row).unwrap_or(u32::MAX));
3767            }
3768        }
3769        ends.push(u32::try_from(len).unwrap_or(u32::MAX));
3770    };
3771    let mut ends = Vec::new();
3772    macro_rules! walked {
3773        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3774            match data {
3775                // No values at all, so every row is the same null and the column is one run.
3776                Data::Empty => ends.push(u32::try_from(len).unwrap_or(u32::MAX)),
3777                $(Data::$variant(values) => {
3778                    breaks(&mut ends, Box::new(|a, b| values.get(a) != values.get(b)));
3779                })+
3780                Data::Varlen(values) => {
3781                    breaks(&mut ends, Box::new(|a, b| values.bytes(a) != values.bytes(b)));
3782                }
3783            }
3784        };
3785    }
3786    crate::for_each_layout!(fixed, walked);
3787    ends
3788}
3789
3790/// The position of a value that is not anywhere, because it is null or out of range.
3791///
3792/// `usize::MAX` rather than an `Option<usize>`, because the copy loop's bounds check rejects it for
3793/// free and an `Option` would put a second branch next to the one already there.
3794pub(crate) const NOWHERE: usize = usize::MAX;
3795
3796/// The row id of a row that is not in the source, which reads as null.
3797///
3798/// Public because whoever builds a [`Form::Gathered`] vector has to write it, and it is `u32::MAX`
3799/// for the reason the crate's own offset sentinel is `usize::MAX`: a bounds check the reader is
3800/// doing anyway rejects it, where an `Option<u32>` would be eight bytes a row instead of four and a
3801/// second branch beside the one already there. It costs the last row of a four billion row source,
3802/// which is a source no column in this engine has.
3803pub const NO_ROW: u32 = u32::MAX;
3804
3805/// Which source row a gathered row names, and `None` when it names none.
3806///
3807/// The `Option` is what every reader of [`Body::Gathered`] that returns an `Option` wants, so the
3808/// three cases that are all *there is nothing here*, past the end of the ids, the sentinel, and an
3809/// id that does not fit a `usize`, are collapsed once here rather than three times each.
3810fn row_of(rids: &[u32], offset: usize, index: usize) -> Option<usize> {
3811    match rids.get(offset + index) {
3812        Some(&NO_ROW) | None => None,
3813        Some(&rid) => Some(rid as usize),
3814    }
3815}
3816
3817/// A run of data copied at the given positions, with a zero wherever the position is [`NOWHERE`].
3818///
3819/// A zero and not a skip, because every layout here is a parallel array to a validity mask and a
3820/// short one would put every value after the first null at the wrong index. It is the same rule
3821/// [`push_value`] follows for a null.
3822/// A contiguous run of a flat body, copied out.
3823///
3824/// The counterpart to [`copy_of`] for the one case that is a range rather than a set of positions,
3825/// which is what [`Vector::slice`] asks for. Every fixed width layout is one `memcpy` and the
3826/// string layout is a run of views and their bytes, where `copy_of` is a bounds checked index and a
3827/// null test per row.
3828///
3829/// The caller has already checked that `end` is inside the vector, and a body whose data is shorter
3830/// than its vector claims is a bug elsewhere, so a short run is clamped rather than reported.
3831///
3832/// A fixed width run over a buffer that is a window into a page does not copy anything, because
3833/// [`Buffer::slice`] moves the offset instead. That is the case a scan over stored memory is in, and
3834/// it is why the flat body is no longer the one form of a vector whose cut costs an allocation.
3835fn run_of(data: &Data, at: usize, end: usize) -> Data {
3836    macro_rules! run {
3837        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3838            match data {
3839                Data::Empty => Data::Empty,
3840                $(Data::$variant(values) => {
3841                    let held = values.len();
3842                    let from = at.min(held);
3843                    let to = end.max(from).min(held);
3844                    if to == end {
3845                        // The whole run is there, so this is a window on a shared page and a copy on
3846                        // an owned one, decided inside the buffer rather than here.
3847                        Data::$variant(values.slice(from, end - from))
3848                    } else {
3849                        let values = values.as_slice();
3850                        let mut out = Buffer::with_capacity(end - at);
3851                        out.extend_from_slice(&values[from..to]);
3852                        // A body shorter than the rows asked for pads with the zero every layout
3853                        // uses for a null, which is the answer `copy_of` gives for a position past
3854                        // the end.
3855                        // row at a time: never runs on a vector whose data matches its length.
3856                        for _ in to..end {
3857                            out.push($zero);
3858                        }
3859                        Data::$variant(out)
3860                    }
3861                })+
3862                // A view says where its bytes are, so a run of rows is not a run of bytes and this
3863                // is the one layout whose cut is still a loop. The total is known before any of it
3864                // is copied, so the arena is one allocation.
3865                //
3866                // Unless the payload is a page, in which case the cut points at the same page the
3867                // column does and no byte of it moves. That is the case a scan of a stored column
3868                // is in, and it is the whole of why a producer pages its payload: a page cut into
3869                // chunk sized pieces used to copy every byte of every long string once per piece.
3870                Data::Varlen(values) => {
3871                    if let Some(shared) =
3872                        values.window(at, end).or_else(|| values.viewing(at..end))
3873                    {
3874                        return Data::Varlen(shared);
3875                    }
3876                    let views = values.views();
3877                    let mut out = StringColumn::with_capacity(end - at);
3878                    out.reserve_bytes(
3879                        views
3880                            .get(at.min(views.len())..end.min(views.len()))
3881                            .unwrap_or(&[])
3882                            .iter()
3883                            .filter(|view| !view.is_inline())
3884                            .map(StringView::len)
3885                            .sum(),
3886                    );
3887                    // row at a time: see above, the bytes of consecutive rows need not be next to
3888                    // each other.
3889                    for index in at..end {
3890                        out.push_from(values, index);
3891                    }
3892                    Data::Varlen(out)
3893                }
3894            }
3895        };
3896    }
3897    crate::for_each_layout!(fixed, run)
3898}
3899
3900/// The values of `data` written to the places `inverse` gives them, the other way round from
3901/// [`copy_of`]: value `n` lands at `inverse[n]`.
3902///
3903/// `inverse` is a permutation of the positions of `data` and the answer is as long as it. A place
3904/// past the end is dropped rather than trusted, and a place nobody wrote keeps the zero, the same
3905/// zero a gather writes for a position that resolved to nowhere. Strings are turned back into
3906/// positions and gathered, because their one caller moves the views itself and never sends them.
3907pub(crate) fn placed_of(data: &Data, inverse: &[u32]) -> Data {
3908    macro_rules! placed {
3909        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3910            match data {
3911                $(Data::$variant(values) => {
3912                    let mut out: Vec<$native> = vec![$zero; inverse.len()];
3913                    for (value, &to) in values.as_slice().iter().zip(inverse) {
3914                        if let Some(slot) = out.get_mut(to as usize) {
3915                            *slot = *value;
3916                        }
3917                    }
3918                    Data::$variant(Buffer::from_vec(out))
3919                })+
3920                Data::Empty => Data::Empty,
3921                // Turned back round into positions and gathered, so a caller that does hand this
3922                // strings gets the right answer rather than a missing arm.
3923                Data::Varlen(_) => {
3924                    let mut at = vec![NOWHERE; inverse.len()];
3925                    for (row, &to) in inverse.iter().enumerate() {
3926                        if let Some(slot) = at.get_mut(to as usize) {
3927                            *slot = row;
3928                        }
3929                    }
3930                    copy_of(data, &at)
3931                }
3932            }
3933        };
3934    }
3935    crate::for_each_layout!(fixed, placed)
3936}
3937
3938pub(crate) fn copy_of(data: &Data, at: &[usize]) -> Data {
3939    macro_rules! copied {
3940        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3941            match data {
3942                Data::Empty => Data::Empty,
3943                $(Data::$variant(values) => {
3944                    let values = values.as_slice();
3945                    // Into a `Vec` and then into a buffer, rather than pushing at the buffer. A
3946                    // push asks the buffer whether it owns its run and copies the page out if it
3947                    // does not, which is the copy on write point and is the right answer for a
3948                    // caller writing one value. This caller is writing `at.len()` of them into a
3949                    // run it made itself one line earlier, so the question has one answer and it
3950                    // is asked once by not being asked at all. The map is exact sized, so the
3951                    // extend reserves once and writes without a capacity check per value.
3952                    let mut out: Vec<$native> = Vec::with_capacity(at.len());
3953                    // One bounds check rather than a null test and a bounds check, because
3954                    // `NOWHERE` is past the end of every slice there can be.
3955                    out.extend(at.iter().map(|&index| values.get(index).copied().unwrap_or($zero)));
3956                    Data::$variant(Buffer::from_vec(out))
3957                })+
3958                // The one layout where a gather is a copy of bytes rather than a copy of fixed
3959                // width slots, and the reason compaction is a decision rather than a default on a
3960                // string column. A payload that is a page is the exception: the gathered views
3961                // point at the page the column already points at, so the gather is sixteen bytes a
3962                // row and the bytes stay where the page put them.
3963                Data::Varlen(values) => {
3964                    if let Some(shared) = values.viewing(at.iter().copied()) {
3965                        return Data::Varlen(shared);
3966                    }
3967                    let mut out = StringColumn::with_capacity(at.len());
3968                    // The bytes are known before any of them are copied, because a view carries its
3969                    // length and the wanted positions are already in hand, so the arena is one
3970                    // allocation rather than a run of doublings that each copy what the last one
3971                    // copied.
3972                    let views = values.views();
3973                    out.reserve_bytes(
3974                        at.iter()
3975                            .filter_map(|&index| views.get(index))
3976                            .filter(|view| !view.is_inline())
3977                            .map(StringView::len)
3978                            .sum(),
3979                    );
3980                    for &index in at {
3981                        out.push_from(values, index);
3982                    }
3983                    Data::Varlen(out)
3984                }
3985            }
3986        };
3987    }
3988    crate::for_each_layout!(fixed, copied)
3989}
3990
3991/// The physical layout a run of data is in, for the check that it matches its type.
3992///
3993/// The two enums name their variants the same way on purpose, so this is one generated arm rather
3994/// than sixteen chances to pair the wrong two up.
3995pub(crate) fn layout_of(data: &Data) -> rudb_common::PhysicalType {
3996    use rudb_common::PhysicalType as P;
3997    macro_rules! layouts {
3998        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3999            match data {
4000                Data::Empty => P::Empty,
4001                $(Data::$variant(_) => P::$variant,)+
4002            }
4003        };
4004    }
4005    crate::for_each_layout!(all, layouts)
4006}
4007
4008/// One value out of a run of data, given what the run means.
4009///
4010/// The match is on the logical type rather than on the data, because the data cannot tell a `DATE`
4011/// from an `INTEGER` and that is the whole reason the two are kept apart.
4012fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
4013    let signed = || data.signed_at(index);
4014    let unsigned = || data.unsigned_at(index);
4015    let value = match ty {
4016        LogicalType::Boolean => match data {
4017            Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
4018            _ => None,
4019        },
4020        LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
4021        LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
4022        LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
4023        LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
4024        LogicalType::HugeInt => signed().map(Value::HugeInt),
4025        LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
4026        LogicalType::USmallInt => {
4027            unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
4028        }
4029        LogicalType::UInteger => {
4030            unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
4031        }
4032        LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
4033        LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
4034        LogicalType::Float => match data {
4035            Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
4036            _ => None,
4037        },
4038        LogicalType::Double => match data {
4039            Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
4040            _ => None,
4041        },
4042        LogicalType::Decimal { width, scale } => {
4043            signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
4044        }
4045        LogicalType::Varchar | LogicalType::Blob | LogicalType::Bit => {
4046            data.bytes_at(index).map(|bytes| bytes_as(ty, bytes))
4047        }
4048        LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
4049        LogicalType::Time => signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time),
4050        LogicalType::TimeTz => signed().and_then(|x| i64::try_from(x).ok()).map(Value::TimeTz),
4051        LogicalType::Timestamp
4052        | LogicalType::TimestampS
4053        | LogicalType::TimestampMs
4054        | LogicalType::TimestampNs => {
4055            signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
4056        }
4057        LogicalType::TimestampTz => {
4058            signed().and_then(|x| i64::try_from(x).ok()).map(Value::TimestampTz)
4059        }
4060        LogicalType::Interval => match data {
4061            Data::Interval(v) => {
4062                v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
4063            }
4064            _ => None,
4065        },
4066        _ => None,
4067    };
4068    value.unwrap_or(Value::Null)
4069}
4070
4071/// The fields a struct type names, and nothing for any other type.
4072///
4073/// Only a `STRUCT` vector has a [`Body::Fields`] body, and the two are built together, so in practice
4074/// the empty slice is unreachable and is here so that reading a field name is not a panic if that ever
4075/// stops being true. A struct vector whose type has fewer fields than it has children answers about
4076/// the fields it can name, because the zip stops at the shorter of the two.
4077fn fields_of(ty: &LogicalType) -> &[Field] {
4078    match ty {
4079        LogicalType::Struct(fields) => fields,
4080        _ => &[],
4081    }
4082}
4083
4084/// One row of a string column as a value, given what its bytes are meant to be read as.
4085///
4086/// Both forms that hold strings come through here, so a row that is a `BLOB` in a flat column is a
4087/// `BLOB` in a string view column too. Bytes that are not text in a `VARCHAR` column are a null
4088/// rather than a panic, since everything that got in went in as a string and a column that has
4089/// something else in it is a bug somewhere earlier that a read should not turn into a crash.
4090fn bytes_as(ty: &LogicalType, bytes: &[u8]) -> Value {
4091    match ty {
4092        LogicalType::Varchar => {
4093            std::str::from_utf8(bytes).map_or(Value::Null, |text| Value::Varchar(text.to_owned()))
4094        }
4095        LogicalType::Blob | LogicalType::Bit => Value::Blob(bytes.to_vec()),
4096        _ => Value::Null,
4097    }
4098}
4099
4100/// An empty run of data of the right layout for a type.
4101pub(crate) fn empty_data_for(ty: &LogicalType) -> Result<Data> {
4102    use rudb_common::PhysicalType as P;
4103    macro_rules! empties {
4104        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4105            match ty.physical() {
4106                P::Empty => Data::Empty,
4107                $(P::$variant => Data::$variant(Buffer::new()),)+
4108                P::Varlen => Data::Varlen(StringColumn::new()),
4109                other => {
4110                    return Err(Error::not_implemented(format!(
4111                        "a flat vector of {other:?} data, which arrives with the storage layer"
4112                    )));
4113                }
4114            }
4115        };
4116    }
4117    Ok(crate::for_each_layout!(fixed, empties))
4118}
4119
4120/// An empty run of the type's layout with room for `rows` values already taken.
4121///
4122/// For a caller that knows how many values are going in before the first one does, which is a
4123/// producer laying pieces end to end. Growing from empty instead reallocates once per doubling and
4124/// finishes holding a run rounded up to the next power of two, and on a row group of 122,880 values
4125/// that rounding is the last 8,192 of them carried for the life of the table.
4126///
4127/// Bytes are not reserved for a varlen run, because how many of them there are is not the number of
4128/// rows and the caller appending them is the one that can work it out.
4129///
4130/// # Errors
4131///
4132/// If the type has no flat layout, the same as [`empty_data_for`].
4133pub(crate) fn data_for(ty: &LogicalType, rows: usize) -> Result<Data> {
4134    let mut data = empty_data_for(ty)?;
4135    macro_rules! reserved {
4136        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
4137            match &mut data {
4138                Data::Empty => {}
4139                $(Data::$variant(values) => values.reserve(rows),)+
4140                Data::Varlen(values) => values.reserve_views(rows),
4141            }
4142        };
4143    }
4144    crate::for_each_layout!(fixed, reserved);
4145    Ok(data)
4146}
4147
4148/// Appends one value to a run of data, or a zero of the right shape when it is null.
4149///
4150/// The zero matters. A null still occupies a position, the validity mask is what says it is null,
4151/// and a run of data with a hole in it would put every value after the hole in the wrong place.
4152fn push_value(data: &mut Data, value: &Value) -> Result<()> {
4153    macro_rules! push {
4154        ($vec:expr, $variant:path, $zero:expr) => {
4155            match value {
4156                Value::Null => $vec.push($zero),
4157                $variant(x) => $vec.push(*x),
4158                other => {
4159                    return Err(Error::internal(format!(
4160                        "{other:?} does not belong in this vector"
4161                    )));
4162                }
4163            }
4164        };
4165    }
4166    // A decimal is stored as its unscaled integer in whatever width its precision needs, which
4167    // `LogicalType::physical` decides and which is why the same `Value::Decimal` is at home in four
4168    // different runs. The narrowing cannot fail for a value the binder produced, because the width
4169    // that chose the run is the width in the value, but it is checked rather than assumed because
4170    // an unchecked cast here would silently store a different number.
4171    macro_rules! decimal {
4172        ($vec:expr, $ty:ty, $unscaled:expr) => {
4173            match <$ty>::try_from(*$unscaled) {
4174                Ok(x) => $vec.push(x),
4175                Err(_) => {
4176                    return Err(Error::internal(format!(
4177                        "an unscaled decimal of {} does not fit the run its precision chose",
4178                        $unscaled
4179                    )));
4180                }
4181            }
4182        };
4183    }
4184    match data {
4185        Data::Empty => {}
4186        Data::Bool(v) => push!(v, Value::Boolean, false),
4187        Data::Int8(v) => push!(v, Value::TinyInt, 0),
4188        Data::Int16(v) => match value {
4189            Value::Null => v.push(0),
4190            Value::SmallInt(x) => v.push(*x),
4191            Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
4192            other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
4193        },
4194        Data::Int32(v) => match value {
4195            Value::Null => v.push(0),
4196            Value::Integer(x) | Value::Date(x) => v.push(*x),
4197            Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
4198            other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
4199        },
4200        Data::Int64(v) => match value {
4201            Value::Null => v.push(0),
4202            Value::BigInt(x)
4203            | Value::Time(x)
4204            | Value::TimeTz(x)
4205            | Value::Timestamp(x)
4206            | Value::TimestampTz(x) => v.push(*x),
4207            Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
4208            other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
4209        },
4210        Data::Int128(v) => match value {
4211            Value::Null => v.push(0),
4212            Value::HugeInt(x) => v.push(*x),
4213            Value::Decimal { unscaled, .. } => v.push(*unscaled),
4214            other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
4215        },
4216        Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
4217        Data::UInt16(v) => push!(v, Value::USmallInt, 0),
4218        Data::UInt32(v) => push!(v, Value::UInteger, 0),
4219        Data::UInt64(v) => push!(v, Value::UBigInt, 0),
4220        Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
4221        Data::Float32(v) => push!(v, Value::Float, 0.0),
4222        Data::Float64(v) => push!(v, Value::Double, 0.0),
4223        Data::Interval(v) => match value {
4224            Value::Null => v.push((0, 0, 0)),
4225            Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
4226            other => return Err(Error::internal(format!("{other:?} is not an interval"))),
4227        },
4228        Data::Varlen(column) => match value {
4229            Value::Null => {
4230                column.push("");
4231            }
4232            Value::Varchar(text) => {
4233                column.push(text);
4234            }
4235            // A blob goes in as the bytes it is. The column stores a length and some bytes either
4236            // way, so text is the reading of one rather than a different column, and a blob that
4237            // is not UTF-8 is stored exactly like one that happens to be.
4238            Value::Blob(bytes) => {
4239                column.push_bytes(bytes);
4240            }
4241            other => return Err(Error::internal(format!("{other:?} is not a string"))),
4242        },
4243    }
4244    Ok(())
4245}
4246
4247#[cfg(test)]
4248mod tests {
4249    use std::sync::Arc;
4250
4251    use rudb_common::{Field, LogicalType, Value};
4252
4253    use super::{
4254        Body, Data, FSST_PAYS_AT, Form, MAP_KEY, MAP_VALUE, NO_ROW, VECTOR_SIZE, Vector,
4255        packing_base,
4256    };
4257    use crate::buffer::Buffer;
4258    use crate::fsst::SymbolTable;
4259    use crate::string::{StringColumn, StringView};
4260    use crate::validity::Validity;
4261
4262    fn integers(values: &[i32]) -> Vector {
4263        Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec().into())).unwrap()
4264    }
4265
4266    #[test]
4267    fn unpacking_in_bulk_reads_what_a_code_at_a_time_reads_at_every_width() {
4268        let mut state = 0x5eed_0b17_u64;
4269        let mut next = || {
4270            state ^= state << 13;
4271            state ^= state >> 7;
4272            state ^= state << 17;
4273            state
4274        };
4275        let words: Vec<u64> = (0..700).map(|_| next()).collect();
4276        for width in 1..=super::PACKED_WIDTH_MAX {
4277            for offset in [0, 1, 63, 64, 65] {
4278                let packed = super::Packed { words: &words, width, base: 0, offset };
4279                for (from, rows) in [(0, 0), (0, 1), (0, 64), (3, 200), (61, 130), (128, 512)] {
4280                    let mut out = vec![u64::MAX; rows];
4281                    packed.unpack(from, &mut out);
4282                    let want: Vec<u64> = (from..from + rows).map(|row| packed.code(row)).collect();
4283                    assert_eq!(out, want, "width {width} offset {offset} from {from}");
4284                }
4285                let at = [5_usize, 9, 9, 70, 6, 200, 131];
4286                let want: Vec<u64> = at.iter().map(|&row| packed.code(row)).collect();
4287                assert_eq!(packed.codes_at(|index| at[index], at.len()), want);
4288                let far = [0_usize, 5000];
4289                let want: Vec<u64> = far.iter().map(|&row| packed.code(row)).collect();
4290                assert_eq!(packed.codes_at(|index| far[index], far.len()), want);
4291            }
4292        }
4293    }
4294
4295    /// A `Value::List` of integers, which is what a row of a list column arrives as.
4296    fn list(values: &[i32]) -> Value {
4297        Value::List {
4298            element: LogicalType::Integer,
4299            values: values.iter().map(|&v| Value::Integer(v)).collect(),
4300        }
4301    }
4302
4303    fn list_column(rows: &[Value]) -> Vector {
4304        Vector::from_values(LogicalType::list(LogicalType::Integer), rows).unwrap()
4305    }
4306
4307    #[test]
4308    fn a_list_column_is_one_child_and_a_range_per_row() {
4309        let rows = vec![list(&[1, 2, 3]), list(&[]), Value::Null, list(&[4])];
4310        let column = list_column(&rows);
4311        assert_eq!(column.form(), Form::List);
4312        assert_eq!(column.len(), 4);
4313        assert_eq!(column.logical_type(), &LogicalType::list(LogicalType::Integer));
4314        // Four rows and four elements, because a null and an empty list both contribute none.
4315        let (entries, child) = column.list_parts().expect("a list");
4316        assert_eq!(entries, [(0, 3), (3, 0), (3, 0), (3, 1)]);
4317        assert_eq!(child.len(), 4);
4318        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
4319    }
4320
4321    /// The one thing the entries cannot say on their own, so it has to be checked that the mask says
4322    /// it. An empty list is a row that is there and holds nothing, a null is a row that is not there,
4323    /// and both of them have an entry of length zero.
4324    #[test]
4325    fn an_empty_list_and_a_null_list_have_the_same_entry_and_are_different_rows() {
4326        let column = list_column(&[list(&[]), Value::Null]);
4327        let (entries, _) = column.list_parts().expect("a list");
4328        assert_eq!(entries[0].1, entries[1].1, "both entries are empty");
4329        assert!(!column.is_null_at(0), "an empty list is not null");
4330        assert!(column.is_null_at(1), "a null list is null");
4331        assert_eq!(column.value_at(0), list(&[]));
4332        assert_eq!(column.value_at(1), Value::Null);
4333    }
4334
4335    #[test]
4336    fn slicing_a_list_column_shares_the_child_rather_than_copying_it() {
4337        let rows: Vec<Value> = (0..64).map(|row| list(&[row, row + 1, row + 2])).collect();
4338        let column = list_column(&rows);
4339        let cut = column.slice(8, 4).unwrap();
4340        assert_eq!(cut.form(), Form::List);
4341        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[8..12]);
4342        // The entries are absolute positions in a child that was not cut, which is what makes the
4343        // cut eight bytes a row however long the lists are. The elements outside the range are still
4344        // there and nothing points at them.
4345        let (entries, child) = cut.list_parts().expect("a list");
4346        assert_eq!(entries[0], (24, 3));
4347        assert_eq!(child.len(), 192);
4348    }
4349
4350    #[test]
4351    fn gathering_a_list_column_permutes_the_entries_and_leaves_the_child_alone() {
4352        let rows = vec![list(&[1]), list(&[2, 2]), list(&[3, 3, 3])];
4353        let column = list_column(&rows);
4354        let picked = column.gather(&[2, 0, 2]).unwrap();
4355        assert_eq!(
4356            picked.iter().collect::<Vec<_>>(),
4357            [list(&[3, 3, 3]), list(&[1]), list(&[3, 3, 3])]
4358        );
4359        // Two of the three rows are the same row, which is the case a run of offsets cannot write
4360        // down and a start and a length can. That is the whole reason this form carries both.
4361        assert_eq!(picked.list_parts().expect("a list").1.len(), 6);
4362    }
4363
4364    #[test]
4365    fn a_gather_past_the_end_of_a_list_column_is_null_rather_than_somebody_elses_elements() {
4366        let column = list_column(&[list(&[1, 2]), list(&[3])]);
4367        let picked = column.gather(&[1, 9]).unwrap();
4368        assert_eq!(picked.value_at(0), list(&[3]));
4369        assert_eq!(picked.value_at(1), Value::Null);
4370    }
4371
4372    #[test]
4373    fn a_list_of_lists_nests_as_far_as_it_is_written() {
4374        let outer = Value::List {
4375            element: LogicalType::list(LogicalType::Integer),
4376            values: vec![list(&[1, 2]), list(&[3])],
4377        };
4378        let column = Vector::from_values(
4379            LogicalType::list(LogicalType::list(LogicalType::Integer)),
4380            std::slice::from_ref(&outer),
4381        )
4382        .unwrap();
4383        assert_eq!(column.value_at(0), outer);
4384        assert_eq!(column.list_parts().expect("a list").1.form(), Form::List);
4385    }
4386
4387    /// A list row is not bytes and not an integer, and a caller that asks for either gets nothing
4388    /// rather than the first element or a length. Both of those would be a wrong answer that a
4389    /// group by or a hash would read without complaining.
4390    #[test]
4391    fn the_scalar_readers_decline_a_list_instead_of_answering_about_its_elements() {
4392        let column = list_column(&[list(&[7])]);
4393        assert_eq!(column.signed_at(0), None);
4394        assert_eq!(column.bytes_at(0), None);
4395        assert_eq!(column.data(), None);
4396    }
4397
4398    fn pair(a: i32, b: &str) -> Value {
4399        Value::Struct(vec![
4400            ("a".to_string(), Value::Integer(a)),
4401            ("b".to_string(), Value::Varchar(b.to_string())),
4402        ])
4403    }
4404
4405    fn pair_type() -> LogicalType {
4406        LogicalType::Struct(vec![
4407            Field::new("a", LogicalType::Integer),
4408            Field::new("b", LogicalType::Varchar),
4409        ])
4410    }
4411
4412    fn pair_column(rows: &[Value]) -> Vector {
4413        Vector::from_values(pair_type(), rows).unwrap()
4414    }
4415
4416    #[test]
4417    fn a_struct_column_is_one_child_per_field_as_long_as_the_column() {
4418        let rows = vec![pair(1, "x"), pair(2, "y"), pair(3, "z")];
4419        let column = pair_column(&rows);
4420        assert_eq!(column.form(), Form::Struct);
4421        assert_eq!(column.len(), 3);
4422        assert_eq!(column.logical_type(), &pair_type());
4423        // Two children rather than two entries and a child, and both of them as long as the column,
4424        // which is the whole difference between this form and the list one.
4425        let children = column.struct_parts().expect("a struct");
4426        assert_eq!(children.len(), 2);
4427        assert_eq!(children[0].len(), 3);
4428        assert_eq!(children[1].len(), 3);
4429        assert_eq!(children[0].logical_type(), &LogicalType::Integer);
4430        assert_eq!(children[1].logical_type(), &LogicalType::Varchar);
4431        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
4432    }
4433
4434    /// Picking one field out of a struct is picking one child, which is the reason this accessor is
4435    /// public. A projection of `s.a` hands back a vector that already exists, so it costs a pointer
4436    /// rather than a pass over the rows, and that is only true while the children are full length.
4437    #[test]
4438    fn one_field_of_a_struct_column_is_a_column_that_is_already_there() {
4439        let column = pair_column(&[pair(10, "x"), pair(20, "y")]);
4440        let field = &column.struct_parts().expect("a struct")[0];
4441        assert_eq!(field.iter().collect::<Vec<_>>(), [Value::Integer(10), Value::Integer(20)]);
4442        assert_eq!(field.signed_at(1), Some(20), "the field is a scalar column and reads like one");
4443    }
4444
4445    /// A null struct is a bit in the mask at the top and nothing deeper, which is how every other type
4446    /// records a null and is what DuckDB does. The row reads as a single null rather than as a struct of
4447    /// nulls, and the fields underneath are still their own columns.
4448    #[test]
4449    fn a_null_struct_is_the_mask_at_the_top_and_not_a_struct_full_of_nulls() {
4450        let column = pair_column(&[pair(1, "x"), Value::Null]);
4451        assert!(!column.is_null_at(0));
4452        assert!(column.is_null_at(1));
4453        assert_eq!(column.value_at(1), Value::Null);
4454        // A struct row whose every field happens to be null is a different row, and it is not null.
4455        let all_null = pair_column(&[Value::Struct(vec![
4456            ("a".to_string(), Value::Null),
4457            ("b".to_string(), Value::Null),
4458        ])]);
4459        assert!(!all_null.is_null_at(0), "a struct of nulls is a row that is there");
4460        assert_ne!(all_null.value_at(0), Value::Null);
4461    }
4462
4463    #[test]
4464    fn slicing_a_struct_column_cuts_every_field_at_the_same_place() {
4465        let rows: Vec<Value> = (0..64).map(|row| pair(row, "s")).collect();
4466        let column = pair_column(&rows);
4467        let cut = column.slice(8, 4).unwrap();
4468        assert_eq!(cut.form(), Form::Struct);
4469        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[8..12]);
4470        // The cut a list column does not have to do. A list shares its child untouched because the
4471        // entries carry the range, and a struct has no entry standing between the row and the child,
4472        // so every child is four rows long here rather than sixty four.
4473        for child in cut.struct_parts().expect("a struct") {
4474            assert_eq!(child.len(), 4);
4475        }
4476    }
4477
4478    #[test]
4479    fn gathering_a_struct_column_gathers_every_field_at_the_same_positions() {
4480        let column = pair_column(&[pair(1, "x"), pair(2, "y"), pair(3, "z")]);
4481        let picked = column.gather(&[2, 0, 2]).unwrap();
4482        assert_eq!(picked.iter().collect::<Vec<_>>(), [pair(3, "z"), pair(1, "x"), pair(3, "z")]);
4483        for child in picked.struct_parts().expect("a struct") {
4484            assert_eq!(child.len(), 3, "a field is as long as the gather, not as the source");
4485        }
4486    }
4487
4488    #[test]
4489    fn a_gather_past_the_end_of_a_struct_column_is_null_in_every_field_and_at_the_top() {
4490        let column = pair_column(&[pair(1, "x"), pair(2, "y")]);
4491        let picked = column.gather(&[1, 9]).unwrap();
4492        assert_eq!(picked.value_at(0), pair(2, "y"));
4493        assert_eq!(picked.value_at(1), Value::Null);
4494        for child in picked.struct_parts().expect("a struct") {
4495            assert!(child.is_null_at(1), "a row that came from nowhere has no field value either");
4496        }
4497    }
4498
4499    /// The names are matched and not counted, because a caller holding a struct value built in a
4500    /// different order from the type's would otherwise get its columns transposed, and that is a wrong
4501    /// answer that reads as a right one.
4502    #[test]
4503    fn the_fields_of_a_struct_value_go_in_by_name_rather_than_by_position() {
4504        let swapped = Value::Struct(vec![
4505            ("b".to_string(), Value::Varchar("x".to_string())),
4506            ("a".to_string(), Value::Integer(1)),
4507        ]);
4508        let column = pair_column(&[swapped]);
4509        assert_eq!(column.value_at(0), pair(1, "x"));
4510        let wrong = Value::Struct(vec![
4511            ("a".to_string(), Value::Integer(1)),
4512            ("c".to_string(), Value::Varchar("x".to_string())),
4513        ]);
4514        let failed = Vector::from_values(pair_type(), &[wrong]);
4515        assert!(failed.is_err(), "a row with no b field is an error rather than a null b");
4516    }
4517
4518    #[test]
4519    fn a_struct_built_from_children_takes_its_field_names_from_the_caller() {
4520        let column = Vector::structure(vec![
4521            ("a".to_string(), integers(&[1, 2, 3])),
4522            ("b".to_string(), integers(&[4, 5, 6])),
4523        ])
4524        .expect("two columns of three");
4525        assert_eq!(column.len(), 3);
4526        assert_eq!(
4527            column.logical_type(),
4528            &LogicalType::Struct(vec![
4529                Field::new("a", LogicalType::Integer),
4530                Field::new("b", LogicalType::Integer),
4531            ])
4532        );
4533        assert_eq!(
4534            column.value_at(1),
4535            Value::Struct(vec![
4536                ("a".to_string(), Value::Integer(2)),
4537                ("b".to_string(), Value::Integer(5)),
4538            ])
4539        );
4540    }
4541
4542    /// The two mistakes this constructor makes easy, both refused rather than stored. A short field is
4543    /// the one that matters: it would be a struct that reads past the end of one of its own children,
4544    /// which is the same mistake `Vector::list` checks for at the other end.
4545    #[test]
4546    fn a_struct_of_uneven_children_or_of_no_children_is_refused() {
4547        let uneven = Vector::structure(vec![
4548            ("a".to_string(), integers(&[1, 2, 3])),
4549            ("b".to_string(), integers(&[4, 5])),
4550        ]);
4551        assert!(uneven.is_err(), "a field shorter than the struct");
4552        assert!(Vector::structure(vec![]).is_err(), "no field to take a length from");
4553    }
4554
4555    #[test]
4556    fn a_struct_of_lists_and_a_list_of_structs_both_nest() {
4557        let ty =
4558            LogicalType::Struct(vec![Field::new("a", LogicalType::list(LogicalType::Integer))]);
4559        let row = Value::Struct(vec![("a".to_string(), list(&[1, 2]))]);
4560        let column = Vector::from_values(ty, std::slice::from_ref(&row)).unwrap();
4561        assert_eq!(column.value_at(0), row);
4562        assert_eq!(column.struct_parts().expect("a struct")[0].form(), Form::List);
4563
4564        let outer = Value::List { element: pair_type(), values: vec![pair(1, "x"), pair(2, "y")] };
4565        let lists =
4566            Vector::from_values(LogicalType::list(pair_type()), std::slice::from_ref(&outer))
4567                .unwrap();
4568        assert_eq!(lists.value_at(0), outer);
4569        assert_eq!(lists.list_parts().expect("a list").1.form(), Form::Struct);
4570    }
4571
4572    fn tags(pairs: &[(&str, &str)]) -> Value {
4573        Value::map(
4574            LogicalType::Varchar,
4575            LogicalType::Varchar,
4576            pairs
4577                .iter()
4578                .map(|&(key, value)| {
4579                    (Value::Varchar(key.to_string()), Value::Varchar(value.to_string()))
4580                })
4581                .collect(),
4582        )
4583    }
4584
4585    fn tag_column(rows: &[Value]) -> Vector {
4586        Vector::from_values(LogicalType::map(LogicalType::Varchar, LogicalType::Varchar), rows)
4587            .unwrap()
4588    }
4589
4590    /// A map is a list of two field structs, which is the whole design, so the test that says so is
4591    /// the one that reaches through both layers and finds the pieces where each of them puts them.
4592    #[test]
4593    fn a_map_column_is_a_list_whose_child_is_a_struct_of_keys_and_values() {
4594        let rows =
4595            vec![tags(&[("a", "b"), ("c", "d")]), tags(&[]), Value::Null, tags(&[("e", "f")])];
4596        let column = tag_column(&rows);
4597        assert_eq!(column.len(), 4);
4598        assert_eq!(
4599            column.logical_type(),
4600            &LogicalType::map(LogicalType::Varchar, LogicalType::Varchar)
4601        );
4602        // The physical form is a list's, because the bytes are a list's. The logical type is what
4603        // remembers it is a map, which is the same split `LogicalType::physical` already makes.
4604        assert_eq!(column.form(), Form::List);
4605        let (entries, child) = column.list_parts().expect("the layout of a list");
4606        assert_eq!(entries, [(0, 2), (2, 0), (2, 0), (2, 1)]);
4607        assert_eq!(child.form(), Form::Struct);
4608        assert_eq!(
4609            child.logical_type(),
4610            &LogicalType::Struct(vec![
4611                Field::new(MAP_KEY, LogicalType::Varchar),
4612                Field::new(MAP_VALUE, LogicalType::Varchar),
4613            ])
4614        );
4615        // And the accessor that reaches through it hands back the two columns rather than the struct.
4616        let (entries, keys, values) = column.map_parts().expect("a map");
4617        assert_eq!(entries.len(), 4);
4618        assert_eq!(keys.text_at(0), Some("a"));
4619        assert_eq!(values.text_at(0), Some("b"));
4620        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
4621    }
4622
4623    /// The same distinction a list has, checked again here rather than assumed from the composition,
4624    /// because the empty map is the one every catalog table in D2 is full of and a null map is what a
4625    /// column with no tags at all would be.
4626    #[test]
4627    fn an_empty_map_and_a_null_map_are_different_rows() {
4628        let column = tag_column(&[tags(&[]), Value::Null]);
4629        assert!(!column.is_null_at(0), "an empty map is a row that is there");
4630        assert!(column.is_null_at(1));
4631        assert_eq!(column.value_at(0), tags(&[]));
4632        assert_eq!(column.value_at(1), Value::Null);
4633        assert_eq!(column.value_at(0).to_string(), "{}");
4634        assert_eq!(column.value_at(1).to_string(), "NULL");
4635    }
4636
4637    /// A map prints `{a=b}` and a struct prints `{'a': b}`, both measured off the pin. They share a
4638    /// layout and they cannot share a printer, which is the one thing about this composition that does
4639    /// not fall out of it.
4640    #[test]
4641    fn a_map_prints_with_equals_signs_and_a_struct_prints_with_quoted_names() {
4642        assert_eq!(tags(&[("a", "b"), ("c", "d")]).to_string(), "{a=b, c=d}");
4643        assert_eq!(pair(1, "x").to_string(), "{'a': 1, 'b': x}");
4644        let numbers = Value::map(
4645            LogicalType::Integer,
4646            LogicalType::Integer,
4647            vec![(Value::Integer(1), Value::Integer(3)), (Value::Integer(2), Value::Integer(4))],
4648        );
4649        assert_eq!(numbers.to_string(), "{1=3, 2=4}");
4650        let null_value = Value::map(
4651            LogicalType::Varchar,
4652            LogicalType::Varchar,
4653            vec![(Value::Varchar("x".to_string()), Value::Null)],
4654        );
4655        assert_eq!(null_value.to_string(), "{x=NULL}");
4656    }
4657
4658    /// A map inherits the list's cut and the list's gather, which is the payoff for storing it as one.
4659    /// Neither of these is code written for maps and both of them are worth a test that says the
4660    /// inheritance works, since the type is rewritten on the way through and a form that came back as a
4661    /// list would still read.
4662    #[test]
4663    fn cutting_and_gathering_a_map_keeps_it_a_map() {
4664        let rows: Vec<Value> =
4665            (0..16).map(|row| tags(&[("k", if row % 2 == 0 { "e" } else { "o" })])).collect();
4666        let column = tag_column(&rows);
4667
4668        let cut = column.slice(4, 3).unwrap();
4669        assert!(matches!(cut.logical_type(), LogicalType::Map(_, _)), "still a map after a cut");
4670        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[4..7]);
4671        // The child was not cut, the same as for a list, which is what makes the cut eight bytes a row.
4672        assert_eq!(cut.map_parts().expect("a map").1.len(), 16);
4673
4674        let picked = column.gather(&[3, 0, 3]).unwrap();
4675        assert!(matches!(picked.logical_type(), LogicalType::Map(_, _)));
4676        assert_eq!(
4677            picked.iter().collect::<Vec<_>>(),
4678            [rows[3].clone(), rows[0].clone(), rows[3].clone()]
4679        );
4680        let past = column.gather(&[0, 99]).unwrap();
4681        assert_eq!(past.value_at(1), Value::Null);
4682    }
4683
4684    #[test]
4685    fn a_map_built_from_two_columns_pairs_them_by_position() {
4686        let keys = Vector::from_values(
4687            LogicalType::Varchar,
4688            &[Value::Varchar("a".to_string()), Value::Varchar("c".to_string())],
4689        )
4690        .unwrap();
4691        let values = Vector::from_values(
4692            LogicalType::Varchar,
4693            &[Value::Varchar("b".to_string()), Value::Varchar("d".to_string())],
4694        )
4695        .unwrap();
4696        let column = Vector::map(vec![(0, 2), (2, 0)], keys, values).expect("two rows");
4697        assert_eq!(column.len(), 2);
4698        assert_eq!(
4699            column.logical_type(),
4700            &LogicalType::map(LogicalType::Varchar, LogicalType::Varchar)
4701        );
4702        assert_eq!(column.value_at(0), tags(&[("a", "b"), ("c", "d")]));
4703        assert_eq!(column.value_at(1), tags(&[]));
4704        // The entry check the list constructor does is the one a map gets, so an entry past the end of
4705        // the pair of columns is refused here too rather than read as somebody else's keys.
4706        let short =
4707            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("a".to_string())]).unwrap();
4708        let other =
4709            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("b".to_string())]).unwrap();
4710        assert!(Vector::map(vec![(0, 9)], short, other).is_err(), "an entry past the end");
4711    }
4712
4713    /// `map_parts` is about the logical type and `list_parts` is about the layout, so a list has to
4714    /// decline the first and a map has to answer the second. Getting that backwards would let a kernel
4715    /// written for maps read a list of two field structs as if it were one.
4716    #[test]
4717    fn a_list_is_not_a_map_however_much_its_child_looks_like_one() {
4718        let pairs = Value::List { element: pair_type(), values: vec![pair(1, "x")] };
4719        let column =
4720            Vector::from_values(LogicalType::list(pair_type()), std::slice::from_ref(&pairs))
4721                .unwrap();
4722        assert!(column.map_parts().is_none(), "a list of structs is a list");
4723        assert!(column.list_parts().is_some());
4724        let map = tag_column(&[tags(&[("a", "b")])]);
4725        assert!(map.map_parts().is_some());
4726        assert!(map.list_parts().is_some(), "a map has a list's layout and says so");
4727    }
4728
4729    /// A struct row is not bytes and not an integer, and it stays that way when it has exactly one
4730    /// integer field, which is the case where answering about the field would look reasonable and would
4731    /// be a hash keyed on the wrong thing.
4732    #[test]
4733    fn the_scalar_readers_decline_a_struct_of_one_integer_field() {
4734        let ty = LogicalType::Struct(vec![Field::new("a", LogicalType::Integer)]);
4735        let row = Value::Struct(vec![("a".to_string(), Value::Integer(7))]);
4736        let column = Vector::from_values(ty, &[row]).unwrap();
4737        assert_eq!(column.signed_at(0), None);
4738        assert_eq!(column.bytes_at(0), None);
4739        assert_eq!(column.data(), None);
4740    }
4741
4742    #[test]
4743    fn a_clustered_column_becomes_runs_and_reads_back_the_same() {
4744        let mut values = Vec::new();
4745        for (value, times) in [(7, 400), (8, 300), (7, 324)] {
4746            values.extend(std::iter::repeat_n(value, times));
4747        }
4748        let flat = integers(&values);
4749        let runs = flat.run_encoded().unwrap();
4750        assert_eq!(runs.form(), Form::Rle);
4751        assert_eq!(runs.run_parts().expect("runs").0, [400, 700, 1024]);
4752        assert_eq!(runs.len(), flat.len());
4753        assert_eq!(runs.iter().collect::<Vec<_>>(), flat.iter().collect::<Vec<_>>());
4754        assert!(
4755            runs.footprint() * 10 < flat.footprint(),
4756            "three runs against a thousand rows: {} against {}",
4757            runs.footprint(),
4758            flat.footprint()
4759        );
4760    }
4761
4762    /// The check is worth having in both directions. A form that is only ever bigger than what it
4763    /// replaced is a form that costs a pass over the column to decide not to use.
4764    #[test]
4765    fn a_column_that_does_not_repeat_is_left_flat() {
4766        let flat = integers(&(0..1024).collect::<Vec<i32>>());
4767        assert_eq!(flat.run_encoded().unwrap().form(), Form::Flat);
4768        // Two runs over four rows is exactly break even on a four byte column, and break even is
4769        // not a reason to change form.
4770        assert_eq!(integers(&[1, 1, 2, 2]).run_encoded().unwrap().form(), Form::Flat);
4771        assert_eq!(integers(&[1, 1, 1, 2, 2]).run_encoded().unwrap().form(), Form::Rle);
4772    }
4773
4774    #[test]
4775    fn two_nulls_beside_each_other_are_one_run_and_a_null_between_two_equals_is_a_break() {
4776        let mut values = vec![Value::Integer(4), Value::Integer(4)];
4777        values.extend([Value::Null, Value::Null, Value::Null]);
4778        values.extend(std::iter::repeat_n(Value::Integer(4), 5));
4779        let flat = Vector::from_values(LogicalType::Integer, &values).unwrap();
4780        let runs = flat.run_encoded().unwrap();
4781        assert_eq!(runs.run_parts().expect("runs").0, [2, 5, 10]);
4782        assert_eq!(runs.iter().collect::<Vec<_>>(), values);
4783    }
4784
4785    #[test]
4786    fn slicing_runs_keeps_them_runs_and_cuts_the_first_and_last_one_back() {
4787        let flat = integers(&[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]);
4788        let runs = flat.run_encoded().unwrap();
4789        let piece = runs.slice(3, 6).unwrap();
4790        assert_eq!(piece.form(), Form::Rle, "the form is the whole point");
4791        assert_eq!(piece.run_parts().expect("runs").0, [1, 5, 6]);
4792        assert_eq!(
4793            piece.iter().collect::<Vec<_>>(),
4794            flat.slice(3, 6).unwrap().iter().collect::<Vec<_>>()
4795        );
4796        assert_eq!(runs.slice(0, 0).unwrap().len(), 0);
4797        assert_eq!(runs.slice(0, 12).unwrap().form(), Form::Rle);
4798    }
4799
4800    #[test]
4801    fn gathering_out_of_runs_walks_to_the_values_the_way_it_walks_a_dictionary() {
4802        let mut values = vec![Value::Varchar("red".into()); 4];
4803        values.extend([Value::Null, Value::Null, Value::Null]);
4804        values.extend(vec![Value::Varchar("blue".into()); 4]);
4805        let runs =
4806            Vector::from_values(LogicalType::Varchar, &values).unwrap().run_encoded().unwrap();
4807        assert_eq!(runs.form(), Form::Rle);
4808        let picked = runs.gather(&[8, 0, 5, 2]).unwrap();
4809        assert_eq!(picked.form(), Form::Flat, "a gather copies, whatever it gathered from");
4810        assert_eq!(
4811            picked.iter().collect::<Vec<_>>(),
4812            [values[8].clone(), values[0].clone(), Value::Null, values[2].clone()]
4813        );
4814        assert_eq!(runs.text_at(1), Some("red"));
4815        assert_eq!(runs.text_at(5), None, "a null has no text");
4816        assert_eq!(runs.flatten().unwrap().iter().collect::<Vec<_>>(), values);
4817    }
4818
4819    /// A run length vector over a run length vector turns one search per row into two, and there is
4820    /// nothing in the engine that builds one, so it is refused rather than composed.
4821    #[test]
4822    fn runs_of_runs_are_refused_and_runs_of_a_dictionary_are_not() {
4823        let inner = integers(&[1, 1, 1, 1, 2]).run_encoded().unwrap();
4824        assert_eq!(inner.form(), Form::Rle);
4825        let error = Vector::runs(vec![2, 8], inner).unwrap_err();
4826        assert!(error.to_string().contains("runs of runs"), "{error}");
4827
4828        let words = Vector::from_values(
4829            LogicalType::Varchar,
4830            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
4831        )
4832        .unwrap();
4833        let dictionary = Vector::dictionary(vec![1, 0], words).unwrap();
4834        let stacked = Vector::runs(vec![4, 9], dictionary).unwrap();
4835        assert_eq!(stacked.len(), 9);
4836        assert_eq!(stacked.value_at(3), Value::Varchar("blue".into()));
4837        assert_eq!(stacked.value_at(4), Value::Varchar("red".into()));
4838    }
4839
4840    #[test]
4841    fn run_ends_have_to_increase_and_there_is_one_value_for_each_of_them() {
4842        let values = integers(&[1, 2]);
4843        assert!(Vector::runs(vec![4], values.clone()).is_err(), "two values and one run");
4844        assert!(Vector::runs(vec![4, 4], values.clone()).is_err(), "an end that repeats");
4845        assert!(Vector::runs(vec![4, 2], values.clone()).is_err(), "an end that goes backwards");
4846        assert!(Vector::runs(vec![0, 2], values.clone()).is_err(), "a first run holding no rows");
4847        assert_eq!(Vector::runs(vec![4, 9], values).unwrap().len(), 9);
4848    }
4849
4850    #[test]
4851    fn a_form_that_is_already_compact_is_left_where_it_is() {
4852        let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1000);
4853        assert_eq!(constant.run_encoded().unwrap().form(), Form::Constant);
4854        assert_eq!(Vector::sequence(0, 1, 1000).run_encoded().unwrap().form(), Form::Sequence);
4855    }
4856
4857    /// What makes one accessor cover both forms. A dictionary hands back the codes it stores and a
4858    /// run length vector works the same numbers out, and a kernel writing `values[at[row]]` reads
4859    /// the same rows out of either.
4860    #[test]
4861    fn both_forms_that_point_somewhere_hand_back_a_position_per_row() {
4862        let words = Vector::from_values(
4863            LogicalType::Varchar,
4864            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
4865        )
4866        .unwrap();
4867        let runs = Vector::runs(vec![3, 5], words.clone()).unwrap();
4868        let (at, values) = runs.positions().expect("runs point somewhere");
4869        assert_eq!(at.as_ref(), [0, 0, 0, 1, 1]);
4870        assert_eq!(values.value_at(at[3] as usize), runs.value_at(3));
4871
4872        let dictionary = Vector::dictionary(vec![1, 0, 1], words).unwrap();
4873        let (at, values) = dictionary.positions().expect("a dictionary points somewhere");
4874        assert_eq!(at.as_ref(), [1, 0, 1]);
4875        assert_eq!(values.value_at(at[0] as usize), dictionary.value_at(0));
4876
4877        assert!(integers(&[1, 2, 3]).positions().is_none(), "a flat vector points at itself");
4878        assert!(Vector::sequence(0, 1, 4).positions().is_none(), "a sequence stores nothing");
4879    }
4880
4881    #[test]
4882    fn slicing_a_dictionary_keeps_it_a_dictionary_where_gathering_would_not() {
4883        let values = Vector::from_values(
4884            LogicalType::Varchar,
4885            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
4886        )
4887        .unwrap();
4888        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
4889
4890        let piece = vector.slice(1, 3).unwrap();
4891        assert_eq!(piece.form(), Form::Dictionary, "the form is the whole point");
4892        assert_eq!(piece.len(), 3);
4893        assert_eq!(
4894            piece.iter().collect::<Vec<_>>(),
4895            [
4896                Value::Varchar("blue".into()),
4897                Value::Varchar("blue".into()),
4898                Value::Varchar("red".into())
4899            ]
4900        );
4901        assert_eq!(vector.gather(&[1, 2, 3]).unwrap().form(), Form::Flat, "which a gather loses");
4902    }
4903
4904    #[test]
4905    fn slicing_a_dictionary_shares_the_dictionary_rather_than_copying_it() {
4906        // The assertion is about the address and not about the values, because the values were
4907        // right when the dictionary was copied too. A page holds one dictionary and is cut into a
4908        // chunk of codes at a time, so copying the dictionary here is a copy of every string in it
4909        // per chunk, and on a read of a ClickBench partition it was ten percent of the cycles.
4910        let values = Vector::from_values(
4911            LogicalType::Varchar,
4912            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
4913        )
4914        .unwrap();
4915        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
4916        let Body::Dictionary { values: whole, .. } = &vector.body else {
4917            panic!("a dictionary vector holds a dictionary");
4918        };
4919
4920        let piece = vector.slice(1, 3).unwrap();
4921        let Body::Dictionary { codes, values: cut, .. } = &piece.body else {
4922            panic!("a slice of a dictionary is a dictionary");
4923        };
4924        assert!(Arc::ptr_eq(whole, cut), "the cut copied the dictionary");
4925        assert_eq!(codes.as_slice(), &[1, 1, 0], "the codes are the part that is cut");
4926
4927        // And a cut of a cut shares it too, since that is what a scan does to a page it reads twice.
4928        let again = piece.slice(1, 2).unwrap();
4929        let Body::Dictionary { values: cut, .. } = &again.body else {
4930            panic!("a slice of a slice of a dictionary is a dictionary");
4931        };
4932        assert!(Arc::ptr_eq(whole, cut), "the second cut copied the dictionary");
4933        assert_eq!(
4934            again.iter().collect::<Vec<_>>(),
4935            [Value::Varchar("blue".into()), Value::Varchar("red".into())]
4936        );
4937    }
4938
4939    /// Once the codes are a page, a cut and a clone of a coded column point at the same codes, which
4940    /// is what a scan does to every page of a dictionary encoded Parquet column.
4941    #[test]
4942    fn a_paged_dictionary_shares_its_codes_with_its_cuts_and_clones() {
4943        let values = Vector::from_values(
4944            LogicalType::Varchar,
4945            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
4946        )
4947        .unwrap();
4948        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap().into_pages();
4949        let codes = |vector: &Vector| match &vector.body {
4950            Body::Dictionary { codes, .. } => codes.as_slice().as_ptr() as usize,
4951            _ => panic!("a dictionary vector holds a dictionary"),
4952        };
4953        assert_eq!(codes(&vector.slice(1, 3).unwrap()), codes(&vector) + 4, "the cut copied");
4954        assert_eq!(codes(&vector.clone()), codes(&vector), "the clone copied");
4955        assert_eq!(
4956            vector.slice(1, 3).unwrap().iter().collect::<Vec<_>>(),
4957            [
4958                Value::Varchar("blue".into()),
4959                Value::Varchar("blue".into()),
4960                Value::Varchar("red".into())
4961            ]
4962        );
4963    }
4964
4965    #[test]
4966    fn a_slice_carries_the_nulls_that_were_in_its_range_and_not_the_others() {
4967        let vector =
4968            integers(&[1, 2, 3, 4]).with_validity(Validity::from_run(&[false, true, false, true]));
4969        let piece = vector.slice(1, 2).unwrap();
4970        assert!(piece.validity().is_valid(0));
4971        assert!(!piece.validity().is_valid(1));
4972        assert_eq!(piece.value_at(1), Value::Null);
4973    }
4974
4975    #[test]
4976    fn slicing_a_sequence_moves_its_start_rather_than_writing_the_values_out() {
4977        let vector = Vector::sequence(100, 5, 10);
4978        let piece = vector.slice(3, 4).unwrap();
4979        assert_eq!(piece.form(), Form::Sequence);
4980        assert_eq!(
4981            piece.iter().collect::<Vec<_>>(),
4982            [Value::BigInt(115), Value::BigInt(120), Value::BigInt(125), Value::BigInt(130)]
4983        );
4984    }
4985
4986    #[test]
4987    fn slicing_a_constant_is_a_shorter_constant() {
4988        let vector = Vector::constant(LogicalType::Integer, Value::Integer(9), 8);
4989        let piece = vector.slice(2, 3).unwrap();
4990        assert_eq!(piece.form(), Form::Constant);
4991        assert_eq!(piece.len(), 3);
4992        assert_eq!(piece.value_at(2), Value::Integer(9));
4993    }
4994
4995    #[test]
4996    fn slicing_the_whole_vector_hands_it_back_as_it_was() {
4997        let vector = integers(&[1, 2, 3]);
4998        assert_eq!(
4999            vector.slice(0, 3).unwrap().iter().collect::<Vec<_>>(),
5000            [Value::Integer(1), Value::Integer(2), Value::Integer(3)]
5001        );
5002    }
5003
5004    #[test]
5005    fn cutting_a_flat_body_answers_what_gathering_the_same_rows_answers() {
5006        // The cut of a flat body used to be written as a gather over the positions in the range,
5007        // and it is now a run copied out, so the two have to keep saying the same thing. Every
5008        // start and every length, with nulls in the range and out of it, since the validity is the
5009        // half of this that changed shape.
5010        let rows: Vec<i32> = (0..70).collect();
5011        let valid: Vec<bool> = (0..70).map(|row| row % 7 != 0 && row % 11 != 3).collect();
5012        let vector = integers(&rows).with_validity(Validity::from_run(&valid));
5013        for at in 0..70usize {
5014            for len in 0..=(70 - at) {
5015                let cut = vector.slice(at, len).unwrap();
5016                let positions: Vec<u32> = (at..at + len).map(|row| row as u32).collect();
5017                let gathered = vector.gather(&positions).unwrap();
5018                assert_eq!(cut.len(), len, "rows {at} to {}", at + len);
5019                assert_eq!(
5020                    cut.iter().collect::<Vec<_>>(),
5021                    gathered.iter().collect::<Vec<_>>(),
5022                    "rows {at} to {}",
5023                    at + len
5024                );
5025            }
5026        }
5027    }
5028
5029    /// The flat body used to be the one form of a vector whose cut cost an allocation and a copy,
5030    /// and it is not any more when its buffer is a run inside a page. Asserted on the address,
5031    /// because the values are the same either way and the address is the whole claim.
5032    #[test]
5033    fn cutting_a_flat_body_over_a_page_does_not_copy_it() {
5034        let page = Arc::new((0i64..64).collect::<Vec<_>>());
5035        let address = page.as_ptr() as usize;
5036        let data = Data::Int64(Buffer::from_arc(Arc::clone(&page)));
5037        let vector = Vector::flat(LogicalType::BigInt, data).unwrap();
5038        let cut = vector.slice(16, 8).unwrap();
5039        assert_eq!(cut.form(), Form::Flat);
5040        assert_eq!(cut.len(), 8);
5041        let Some(Data::Int64(run)) = cut.data() else {
5042            panic!("the layout changed under the test")
5043        };
5044        assert!(run.is_shared(), "the cut copied the run out of the page");
5045        assert_eq!(run.as_slice().as_ptr() as usize, address + 16 * 8);
5046        assert_eq!(run.as_slice(), &(16i64..24).collect::<Vec<_>>()[..]);
5047        assert_eq!(cut.value_at(0), Value::BigInt(16));
5048        // And the same cut of an owned run says the same thing, by copying it.
5049        let owned = Vector::flat(LogicalType::BigInt, Data::Int64((0i64..64).collect())).unwrap();
5050        let copied = owned.slice(16, 8).unwrap();
5051        let Some(Data::Int64(run)) = copied.data() else {
5052            panic!("the layout changed under the test")
5053        };
5054        assert!(!run.is_shared());
5055        assert_eq!(run.as_slice(), &(16i64..24).collect::<Vec<_>>()[..]);
5056    }
5057
5058    /// `into_pages` is how a producer says its values will be handed out many times. A flat body is
5059    /// the form it changes, and after it a copy of the vector is a reference count bump.
5060    #[test]
5061    fn a_vector_over_pages_is_copied_and_cut_without_its_values_moving() {
5062        let vector = integers(&[1, 2, 3, 4, 5, 6, 7, 8]).into_pages();
5063        let address = |vector: &Vector| match vector.data() {
5064            Some(Data::Int32(values)) => values.as_slice().as_ptr() as usize,
5065            _ => panic!("the layout changed under the test"),
5066        };
5067        let stored = address(&vector);
5068        assert_eq!(address(&vector.clone()), stored, "a copy moved the values");
5069        assert_eq!(address(&vector.slice(2, 4).unwrap()), stored + 2 * 4, "a cut moved the values");
5070        assert_eq!(
5071            vector.slice(2, 4).unwrap().iter().collect::<Vec<_>>(),
5072            [Value::Integer(3), Value::Integer(4), Value::Integer(5), Value::Integer(6)]
5073        );
5074        // Twice is not two pages.
5075        assert_eq!(address(&vector.clone().into_pages()), stored);
5076    }
5077
5078    /// A cut, a gather and a flatten of a string column over a page all move views and no bytes.
5079    ///
5080    /// This is the string half of the paging that `a_vector_over_pages_is_copied_and_cut_without_
5081    /// its_values_moving` checks for a fixed width column, and it is worth its own test because a
5082    /// string column is two allocations rather than one: the cut that matters is the payload
5083    /// staying where it is while the views move.
5084    #[test]
5085    fn a_string_column_over_a_page_is_cut_and_gathered_without_its_payload_moving() {
5086        let long = ["the first of the long strings", "the second one", "and a third long one here"];
5087        let mut built = StringColumn::with_capacity(long.len());
5088        for text in long {
5089            built.push(text);
5090        }
5091        let vector = Vector::flat(LogicalType::Varchar, Data::Varlen(built.into_page())).unwrap();
5092        let payload = |vector: &Vector| match vector.data() {
5093            Some(Data::Varlen(column)) => column.arena().as_ptr() as usize,
5094            _ => panic!("the layout changed under the test"),
5095        };
5096        let stored = payload(&vector);
5097        let cut = vector.slice(1, 2).unwrap();
5098        assert_eq!(payload(&cut), stored, "a cut moved the payload");
5099        assert_eq!(cut.text_at(0), Some(long[1]));
5100        assert_eq!(cut.text_at(1), Some(long[2]));
5101        let gathered = vector.gather(&[2, 0]).unwrap();
5102        assert_eq!(payload(&gathered), stored, "a gather moved the payload");
5103        assert_eq!(gathered.text_at(0), Some(long[2]));
5104        assert_eq!(gathered.text_at(1), Some(long[0]));
5105        // And the same column with its own arena still copies, because sharing an owned arena
5106        // means cloning every byte of it including the bytes nobody asked for.
5107        let mut owned = StringColumn::with_capacity(long.len());
5108        for text in long {
5109            owned.push(text);
5110        }
5111        let held = Vector::flat(LogicalType::Varchar, Data::Varlen(owned)).unwrap();
5112        let copied = held.slice(1, 2).unwrap();
5113        assert_ne!(payload(&copied), payload(&held), "an owned payload was shared");
5114        assert_eq!(copied.text_at(0), Some(long[1]));
5115    }
5116
5117    /// A flatten gives up the form and not the sharing. The views form is already views over an
5118    /// arena, so flattening one over a page is the views and nothing else, and the flat column
5119    /// that comes out reads the same strings out of the same bytes.
5120    #[test]
5121    fn flattening_string_views_over_a_page_keeps_the_page() {
5122        let mut built = StringColumn::with_capacity(2);
5123        built.push("a string too long to sit inside a view");
5124        built.push("another string that is also too long");
5125        let (views, arena) = built.into_page().into_parts();
5126        let stored = arena.as_slice().as_ptr() as usize;
5127        let vector = Vector::string_views(LogicalType::Varchar, views, Arc::new(arena)).unwrap();
5128        assert_eq!(vector.form(), Form::StringView);
5129        let flat = vector.flatten().unwrap();
5130        assert_eq!(flat.form(), Form::Flat);
5131        let Some(Data::Varlen(column)) = flat.data() else {
5132            panic!("the layout changed under the test")
5133        };
5134        assert_eq!(column.arena().as_ptr() as usize, stored, "the flatten moved the payload");
5135        assert_eq!(flat.text_at(0), Some("a string too long to sit inside a view"));
5136        assert_eq!(flat.text_at(1), Some("another string that is also too long"));
5137    }
5138
5139    /// Every form that is not flat already shares what is expensive, so this is a no op on them and
5140    /// in particular does not flatten anything. A form that came back flat would be a column that
5141    /// lost its encoding on the way into a table.
5142    #[test]
5143    fn putting_a_vector_on_pages_does_not_change_any_other_form() {
5144        let dictionary = Vector::dictionary(
5145            vec![0, 1, 0, 1],
5146            Vector::from_values(
5147                LogicalType::Varchar,
5148                &[Value::Varchar("a".into()), Value::Varchar("b".into())],
5149            )
5150            .unwrap(),
5151        )
5152        .unwrap();
5153        let cases = [
5154            Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
5155            Vector::sequence(4, 0, 1),
5156            dictionary,
5157        ];
5158        for vector in cases {
5159            let form = vector.form();
5160            let paged = vector.clone().into_pages();
5161            assert_eq!(paged.form(), form, "{form:?} changed form");
5162            assert_eq!(paged.iter().collect::<Vec<_>>(), vector.iter().collect::<Vec<_>>());
5163        }
5164    }
5165
5166    #[test]
5167    fn cutting_a_flat_string_column_answers_what_gathering_it_answers() {
5168        // The string layout is the one whose cut is still a loop, and it is also the one where a
5169        // row is a view into an arena rather than a slot, so it gets the same treatment separately.
5170        // Both inline and out of line strings, since they are copied by different paths.
5171        let rows: Vec<String> =
5172            (0..40).map(|row| "x".repeat(row % 30) + &row.to_string()).collect();
5173        let values: Vec<Value> = rows.iter().map(|row| Value::Varchar(row.clone())).collect();
5174        let vector = Vector::from_values(LogicalType::Varchar, &values).unwrap().flatten().unwrap();
5175        assert_eq!(vector.form(), Form::Flat, "the cut under test is the flat one");
5176        for at in 0..40usize {
5177            for len in 0..=(40 - at) {
5178                let cut = vector.slice(at, len).unwrap();
5179                let positions: Vec<u32> = (at..at + len).map(|row| row as u32).collect();
5180                let gathered = vector.gather(&positions).unwrap();
5181                assert_eq!(
5182                    cut.iter().collect::<Vec<_>>(),
5183                    gathered.iter().collect::<Vec<_>>(),
5184                    "rows {at} to {}",
5185                    at + len
5186                );
5187            }
5188        }
5189    }
5190
5191    #[test]
5192    fn a_slice_past_the_end_is_an_error_rather_than_a_short_vector() {
5193        let error = integers(&[1, 2, 3]).slice(2, 2).unwrap_err();
5194        assert!(error.to_string().contains("of a vector of 3"), "{error}");
5195    }
5196
5197    #[test]
5198    fn the_vector_size_is_the_one_the_design_is_built_around() {
5199        // 8192, which is four times DuckDB's 2048, measured in #480 against 1024, 2048, 4096 and
5200        // 32768. What the rest of the code assumes about it is not the value but the shape: a
5201        // multiple of 1024, which is the FastLanes unit and is what makes a validity mask a whole
5202        // number of u64 words with none of them half used.
5203        assert_eq!(VECTOR_SIZE, 8192);
5204        assert_eq!(VECTOR_SIZE % 1024, 0);
5205        assert_eq!(VECTOR_SIZE % 64, 0);
5206        assert_eq!(VECTOR_SIZE / 64, 128, "the words in a validity mask");
5207    }
5208
5209    #[test]
5210    fn a_flat_vector_reads_back_what_was_put_in_it() {
5211        let vector = integers(&[1, 2, 3]);
5212        assert_eq!(vector.form(), Form::Flat);
5213        assert_eq!(vector.len(), 3);
5214        assert_eq!(vector.value_at(1), Value::Integer(2));
5215        assert_eq!(
5216            vector.iter().collect::<Vec<_>>(),
5217            vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
5218        );
5219    }
5220
5221    #[test]
5222    fn a_vector_built_from_values_reads_the_same_values_back() {
5223        let vector = Vector::from_values(
5224            LogicalType::Varchar,
5225            &[
5226                Value::Varchar("a".to_string()),
5227                Value::Null,
5228                Value::Varchar("a string too long to sit inside a view".to_string()),
5229            ],
5230        )
5231        .expect("strings and a null");
5232        assert_eq!(vector.len(), 3);
5233        assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
5234        assert_eq!(vector.value_at(1), Value::Null);
5235        assert_eq!(
5236            vector.value_at(2),
5237            Value::Varchar("a string too long to sit inside a view".to_string())
5238        );
5239    }
5240
5241    /// A null still occupies a position. If it did not then every value after it would read back
5242    /// one place to the left, which is the kind of bug that looks like a storage bug for a week.
5243    #[test]
5244    fn a_null_in_the_middle_does_not_move_the_values_after_it() {
5245        let vector = Vector::from_values(
5246            LogicalType::Integer,
5247            &[Value::Integer(1), Value::Null, Value::Integer(3)],
5248        )
5249        .expect("integers and a null");
5250        assert_eq!(vector.value_at(2), Value::Integer(3));
5251        assert!(vector.validity().has_nulls(3), "the middle one is null");
5252    }
5253
5254    #[test]
5255    fn a_value_the_type_cannot_hold_is_refused() {
5256        let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
5257        assert!(wrong.is_err(), "a string is not an integer");
5258    }
5259
5260    #[test]
5261    fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
5262        // One comparison here against a wrong answer read out three layers later.
5263        let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1].into()));
5264        assert!(wrong.is_err());
5265        let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1].into()));
5266        assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
5267    }
5268
5269    #[test]
5270    fn a_constant_vector_costs_one_value_whatever_its_length() {
5271        let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
5272        assert_eq!(vector.form(), Form::Constant);
5273        assert_eq!(vector.len(), VECTOR_SIZE);
5274        assert_eq!(vector.value_at(0), Value::Integer(7));
5275        assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
5276        assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
5277    }
5278
5279    #[test]
5280    fn a_constant_null_is_all_invalid_without_being_told() {
5281        let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
5282        assert_eq!(vector.validity(), &Validity::AllInvalid);
5283        assert_eq!(vector.value_at(3), Value::Null);
5284    }
5285
5286    #[test]
5287    fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
5288        let vector = Vector::sequence(100, 1, VECTOR_SIZE);
5289        assert_eq!(vector.form(), Form::Sequence);
5290        assert_eq!(vector.value_at(0), Value::BigInt(100));
5291        assert_eq!(vector.value_at(923), Value::BigInt(1023));
5292        let stepped = Vector::sequence(0, 5, 4);
5293        assert_eq!(
5294            stepped.iter().collect::<Vec<_>>(),
5295            vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
5296        );
5297    }
5298
5299    #[test]
5300    fn a_dictionary_vector_reads_through_its_codes() {
5301        let mut column = StringColumn::new();
5302        column.push("red");
5303        column.push("green");
5304        let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
5305        let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
5306        assert_eq!(vector.form(), Form::Dictionary);
5307        assert_eq!(vector.logical_type(), &LogicalType::Varchar);
5308        assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
5309        assert_eq!(vector.len(), 4);
5310    }
5311
5312    /// The accessor a group by keys a string column through, which has to agree with `value_at` on
5313    /// every position or two rows holding one string end up in two groups.
5314    #[test]
5315    fn text_is_read_where_it_already_is_for_the_forms_that_store_it() {
5316        let mut column = StringColumn::new();
5317        column.push("red");
5318        column.push("green");
5319        column.push("");
5320        let flat = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
5321        for index in 0..flat.len() {
5322            assert_eq!(flat.text_at(index).map(str::to_string), text_of(&flat.value_at(index)));
5323        }
5324        let dictionary = Vector::dictionary(vec![1, 0, 1, 2], flat).unwrap();
5325        for index in 0..dictionary.len() {
5326            assert_eq!(
5327                dictionary.text_at(index).map(str::to_string),
5328                text_of(&dictionary.value_at(index))
5329            );
5330        }
5331        assert_eq!(dictionary.text_at(4), None, "past the end");
5332    }
5333
5334    /// The forms and types that have no text to hand back, which a caller answers by falling back
5335    /// to `value_at`. A blob is the one that would be a correctness bug rather than a slow path,
5336    /// since its bytes are not required to be text and it is not a `VARCHAR` either way.
5337    #[test]
5338    fn text_is_refused_where_it_is_not_stored_as_itself() {
5339        let nulls =
5340            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into()), Value::Null])
5341                .unwrap();
5342        assert_eq!(nulls.text_at(0), Some("red"));
5343        assert_eq!(nulls.text_at(1), None, "a null has no text");
5344        let constant = Vector::constant(LogicalType::Varchar, Value::Varchar("red".into()), 3);
5345        assert_eq!(constant.text_at(0), None, "a constant is not stored per position");
5346        assert_eq!(integers(&[1, 2]).text_at(0), None, "an integer is not text");
5347        let mut bytes = StringColumn::new();
5348        bytes.push("red");
5349        let blob = Vector::flat(LogicalType::Blob, Data::Varlen(bytes)).unwrap();
5350        assert_eq!(blob.text_at(0), None, "a blob is not a varchar");
5351    }
5352
5353    /// The accessor a group by keys an integer column through, which has to agree with `value_at`
5354    /// on every position or two rows holding one number end up in two groups.
5355    #[test]
5356    fn a_signed_integer_is_read_where_it_already_is_for_the_forms_that_store_it() {
5357        let flat = integers(&[7, -3, 0, 2]);
5358        for index in 0..flat.len() {
5359            assert_eq!(flat.signed_at(index), signed_of(&flat.value_at(index)), "flat {index}");
5360        }
5361        let dictionary = Vector::dictionary(vec![1, 0, 3, 2], flat).unwrap();
5362        for index in 0..dictionary.len() {
5363            assert_eq!(
5364                dictionary.signed_at(index),
5365                signed_of(&dictionary.value_at(index)),
5366                "dictionary {index}"
5367            );
5368        }
5369        assert_eq!(dictionary.signed_at(4), None, "past the end");
5370
5371        let runs = Vector::runs(vec![2, 5], integers(&[4, 9])).unwrap();
5372        for index in 0..runs.len() {
5373            assert_eq!(runs.signed_at(index), signed_of(&runs.value_at(index)), "run {index}");
5374        }
5375        let constant = Vector::constant(LogicalType::BigInt, Value::BigInt(11), 3);
5376        assert_eq!(constant.signed_at(2), Some(11));
5377        let sequence = Vector::sequence(100, 5, 4);
5378        for index in 0..sequence.len() {
5379            assert_eq!(
5380                sequence.signed_at(index),
5381                signed_of(&sequence.value_at(index)),
5382                "sequence {index}"
5383            );
5384        }
5385    }
5386
5387    /// A window of a shared page packs exactly when the same rows owned would, and a range its
5388    /// type cannot hold at the width it needs stays flat rather than failing. A load of ClickBench
5389    /// `hits` hit both: its windows were judged by their share of the page, packed at 32 bits, and
5390    /// the packed form refused a range that ran past `i32::MAX`.
5391    #[test]
5392    fn a_window_of_a_page_packs_the_way_the_same_rows_owned_do() {
5393        let wide: Vec<i32> = (0..122_880)
5394            .map(|at| if at % 2 == 0 { i32::MIN + 5 + at } else { i32::MAX - 9 - at })
5395            .collect();
5396        let narrow: Vec<i32> = (0..122_880).map(|at| 1_000 + at % 200).collect();
5397        for values in [wide, narrow] {
5398            let page = integers(&values).into_pages();
5399            let window = page.slice(0, 8_192).unwrap();
5400            let owned = integers(&values[..8_192]);
5401            let packed_window = window.bit_packed().unwrap();
5402            let packed_owned = owned.bit_packed().unwrap();
5403            assert_eq!(
5404                packed_window.packed_parts().is_some(),
5405                packed_owned.packed_parts().is_some()
5406            );
5407            for at in [0, 1, 4_095, 8_191] {
5408                assert_eq!(packed_window.value_at(at), owned.value_at(at));
5409            }
5410        }
5411    }
5412
5413    /// The forms and types that have no integer to hand back, which a caller answers by falling
5414    /// back to `value_at`.
5415    #[test]
5416    fn a_signed_integer_is_refused_where_it_is_not_stored_as_itself() {
5417        let nulls =
5418            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
5419        assert_eq!(nulls.signed_at(0), Some(4));
5420        assert_eq!(nulls.signed_at(1), None, "a null is not a number");
5421        let packed = integers(&[1, 2, 3, 1]).bit_packed().unwrap();
5422        assert_eq!(packed.signed_at(0), Some(1), "a packed integer is read in code space");
5423        let mut bytes = StringColumn::new();
5424        bytes.push("red");
5425        let text = Vector::flat(LogicalType::Varchar, Data::Varlen(bytes)).unwrap();
5426        assert_eq!(text.signed_at(0), None, "a string is not a number");
5427        let double = Vector::flat(LogicalType::Double, Data::Float64(vec![1.5].into())).unwrap();
5428        assert_eq!(double.signed_at(0), None, "a double is not a signed integer");
5429    }
5430
5431    /// The block form has to agree with the row at a time form on every position of every shape it
5432    /// answers for, because a caller picks one of the two and a group by that read two different
5433    /// numbers for one row would put that row in two groups.
5434    #[test]
5435    fn a_block_of_signed_integers_holds_what_the_row_at_a_time_accessor_hands_back() {
5436        let mut out = Vec::new();
5437        let shapes = [
5438            integers(&[7, -3, 0, 2]),
5439            Vector::flat(LogicalType::Integer, Data::Int32(vec![5, -6, 7].into())).unwrap(),
5440            Vector::flat(LogicalType::SmallInt, Data::Int16(vec![1, -2].into())).unwrap(),
5441            Vector::flat(LogicalType::TinyInt, Data::Int8(vec![-128, 127].into())).unwrap(),
5442            Vector::constant(LogicalType::BigInt, Value::BigInt(11), 3),
5443            Vector::sequence(100, 5, 4),
5444            integers(&[1, 2, 3, 1]).bit_packed().unwrap(),
5445        ];
5446        for column in &shapes {
5447            assert!(column.signed_block(&mut out), "{:?} hands over a block", column.form());
5448            assert_eq!(out.len(), column.len(), "{:?} filled the whole chunk", column.form());
5449            for (index, &held) in out.iter().enumerate() {
5450                assert_eq!(
5451                    Some(i128::from(held)),
5452                    column.signed_at(index),
5453                    "{:?} at {index}",
5454                    column.form()
5455                );
5456            }
5457        }
5458    }
5459
5460    /// What the block form will not answer for, where the caller reads the vector a row at a time
5461    /// instead. A null is not one of them: it writes whatever sits under it and the caller reads the
5462    /// null from the column.
5463    #[test]
5464    fn a_block_is_refused_for_the_shapes_it_would_have_to_gather_or_widen() {
5465        let mut out = Vec::new();
5466        let flat = integers(&[7, -3, 0, 2]);
5467        assert!(!Vector::dictionary(vec![1, 0], flat.clone()).unwrap().signed_block(&mut out));
5468        assert!(!Vector::runs(vec![2, 5], integers(&[4, 9])).unwrap().signed_block(&mut out));
5469        let wide = Vector::flat(LogicalType::HugeInt, Data::Int128(vec![1, 2].into())).unwrap();
5470        assert!(!wide.signed_block(&mut out), "a hugeint does not fit sixty four bits");
5471        let double = Vector::flat(LogicalType::Double, Data::Float64(vec![1.5].into())).unwrap();
5472        assert!(!double.signed_block(&mut out), "a double is not a signed integer");
5473        assert!(out.is_empty(), "a refusal leaves the buffer empty");
5474
5475        let nulls =
5476            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
5477        assert!(nulls.signed_block(&mut out), "a flat column with nulls still hands over");
5478        assert_eq!(out[0], 4);
5479    }
5480
5481    /// Asked once for a chunk, and it has to agree with `is_null_at` asked for every row of it.
5482    #[test]
5483    fn a_vector_says_whether_it_holds_any_null_at_all() {
5484        let flat = integers(&[7, -3, 0, 2]);
5485        assert!(flat.none_null());
5486        let nulls =
5487            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
5488        assert!(!nulls.none_null());
5489        assert!(Vector::dictionary(vec![1, 0], flat.clone()).unwrap().none_null());
5490        // The null is in the dictionary rather than in the mask, which is the case the row at a time
5491        // form reads through for and the reason this one does too.
5492        let holed = Vector::dictionary(vec![0, 0], nulls.clone()).unwrap();
5493        assert!(!holed.none_null(), "a dictionary is read through to its values");
5494        assert!(!holed.is_null_at(0), "and no code points at the null it holds");
5495        assert!(Vector::runs(vec![2, 5], integers(&[4, 9])).unwrap().none_null());
5496        assert!(!Vector::runs(vec![1, 2], nulls).unwrap().none_null());
5497        assert!(Vector::constant(LogicalType::BigInt, Value::BigInt(11), 3).none_null());
5498        assert!(!Vector::constant(LogicalType::BigInt, Value::Null, 3).none_null());
5499    }
5500
5501    /// The integer of a value, for comparing `signed_at` against `value_at` position by position.
5502    fn signed_of(value: &Value) -> Option<i128> {
5503        match value {
5504            Value::TinyInt(x) => Some(i128::from(*x)),
5505            Value::SmallInt(x) => Some(i128::from(*x)),
5506            Value::Integer(x) | Value::Date(x) => Some(i128::from(*x)),
5507            Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => Some(i128::from(*x)),
5508            Value::HugeInt(x) | Value::Decimal { unscaled: x, .. } => Some(*x),
5509            _ => None,
5510        }
5511    }
5512
5513    /// The text of a value, for comparing `text_at` against `value_at` position by position.
5514    fn text_of(value: &Value) -> Option<String> {
5515        match value {
5516            Value::Varchar(text) => Some(text.clone()),
5517            _ => None,
5518        }
5519    }
5520
5521    #[test]
5522    fn a_dictionary_code_past_the_end_is_refused() {
5523        // The alternative is a silent read of the wrong value, which is the failure mode the
5524        // entire M3 design has to be careful about.
5525        let values = integers(&[1, 2]);
5526        assert!(Vector::dictionary(vec![0, 2], values).is_err());
5527        // The check runs on the highest code rather than the first bad one, so it has to say that
5528        // no codes at all is fine even when there are no values for them to point at either.
5529        let empty = Vector::dictionary(Vec::new(), integers(&[])).expect("no codes, no values");
5530        assert_eq!(empty.len(), 0);
5531        // And a code of zero against an empty dictionary is still past the end.
5532        assert!(Vector::dictionary(vec![0], integers(&[])).is_err());
5533    }
5534
5535    #[test]
5536    fn every_form_flattens_to_the_same_values_it_reads_out() {
5537        // This is the shape of the equivalence testing in spec/16-testing.md section 16.2, in
5538        // miniature and long before there is an encoded kernel to point it at. A form that reads
5539        // out one way and flattens another is the exact bug that testing exists to catch.
5540        let mut column = StringColumn::new();
5541        column.push("alpha");
5542        column.push("beta");
5543        let dictionary = Vector::dictionary(
5544            vec![1, 0, 1],
5545            Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
5546        )
5547        .unwrap();
5548        let cases = [
5549            Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
5550            Vector::sequence(7, -2, 5),
5551            dictionary,
5552        ];
5553        for vector in cases {
5554            let flat = vector.flatten().unwrap();
5555            assert_eq!(flat.form(), Form::Flat);
5556            assert_eq!(flat.len(), vector.len());
5557            for index in 0..vector.len() {
5558                assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
5559            }
5560        }
5561    }
5562
5563    #[test]
5564    fn a_null_still_occupies_a_position_after_flattening() {
5565        // The reason push_value writes a zero for a null rather than skipping it. A run of data
5566        // with a hole in it puts every value after the hole in the wrong place, and the validity
5567        // mask is what says the position is null.
5568        let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
5569        let flat = vector.flatten().unwrap();
5570        assert_eq!(flat.value_at(0), Value::BigInt(0));
5571        assert_eq!(flat.value_at(1), Value::Null);
5572        assert_eq!(flat.value_at(2), Value::BigInt(2));
5573        assert_eq!(flat.value_at(3), Value::BigInt(3));
5574    }
5575
5576    /// A dictionary holds its nulls in the vector it points at, so its own validity is all valid
5577    /// and reading that instead of the values turns a null into whatever zero means for the type.
5578    /// A filter over a nullable column produces exactly this vector, so the bug reaches a result
5579    /// set as `LEFT JOIN` padding that comes back as zeros.
5580    #[test]
5581    fn a_null_behind_a_dictionary_survives_flattening() {
5582        let values =
5583            Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
5584        let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
5585        let flat = dictionary.flatten().unwrap();
5586        assert_eq!(flat.value_at(0), Value::Null);
5587        assert_eq!(flat.value_at(1), Value::Integer(3));
5588        assert_eq!(flat.value_at(2), Value::Null);
5589    }
5590
5591    /// The property that makes `gather` usable at all: it has to be the same function as reading the
5592    /// wanted positions one at a time, over every form, or compaction changes answers.
5593    #[test]
5594    fn gathering_reads_what_reading_one_position_at_a_time_reads() {
5595        let mut column = StringColumn::new();
5596        column.push("alpha");
5597        column.push("beta");
5598        column.push("gamma");
5599        let cases = [
5600            integers(&[10, 20, 30, 40]),
5601            integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
5602            Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
5603            Vector::sequence(100, -7, 4),
5604            Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
5605            Vector::dictionary(
5606                vec![2, 0, 1, 2],
5607                Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
5608            )
5609            .unwrap(),
5610            Vector::dictionary(
5611                vec![1, 0, 1, 0],
5612                Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
5613                    .unwrap(),
5614            )
5615            .unwrap(),
5616        ];
5617        let wanted = [3_u32, 0, 2, 2, 1];
5618        for vector in cases {
5619            let gathered = vector.gather(&wanted).unwrap();
5620            assert_eq!(gathered.len(), wanted.len());
5621            assert_eq!(gathered.logical_type(), vector.logical_type());
5622            for (slot, &index) in wanted.iter().enumerate() {
5623                assert_eq!(
5624                    gathered.value_at(slot),
5625                    vector.value_at(index as usize),
5626                    "slot {slot} of {:?}",
5627                    vector.form()
5628                );
5629            }
5630        }
5631    }
5632
5633    /// A gather past the end is not an error, because the selection that produced the indices is
5634    /// checked by its caller and the one thing that must not happen here is a read of the wrong
5635    /// value. An index nothing answers is null, which is what an outer join pad needs anyway.
5636    #[test]
5637    fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
5638        let vector = integers(&[1, 2, 3]);
5639        let gathered = vector.gather(&[2, 9]).unwrap();
5640        assert_eq!(gathered.value_at(0), Value::Integer(3));
5641        assert_eq!(gathered.value_at(1), Value::Null);
5642    }
5643
5644    /// The vector with nothing in it at all, which is what an untyped `NULL` is stored as. Every
5645    /// position asked for is past its end, so the answer is nulls and the length has to be the
5646    /// length that was asked for rather than the length that was there.
5647    #[test]
5648    fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
5649        let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
5650        let gathered = vector.gather(&[0, 1, 2]).unwrap();
5651        assert_eq!(gathered.len(), 3);
5652        assert_eq!(gathered.value_at(0), Value::Null);
5653        assert_eq!(gathered.value_at(2), Value::Null);
5654    }
5655
5656    /// Every position holds the same value, so a gather with no hole in it has nothing to copy and
5657    /// the result is the constant again rather than a run of a thousand copies of it.
5658    #[test]
5659    fn gathering_a_constant_stays_a_constant() {
5660        let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
5661        let gathered = vector.gather(&[7, 7, 99]).unwrap();
5662        assert_eq!(gathered.form(), Form::Constant);
5663        assert_eq!(gathered.len(), 3);
5664        assert_eq!(gathered.value_at(2), Value::Integer(4));
5665    }
5666
5667    /// A dictionary over a dictionary is what a second filter over an already filtered chunk builds,
5668    /// and the gather has to walk to the bottom of that chain rather than one step down it. The
5669    /// constructor composes the ordinary chain away, so the one built here is the kind it cannot,
5670    /// which is a level holding nulls of its own.
5671    #[test]
5672    fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
5673        let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
5674            .unwrap()
5675            .with_validity(Validity::from_iter(3, |index| index != 2));
5676        let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
5677        let gathered = outer.gather(&[0, 1]).unwrap();
5678        assert_eq!(gathered.form(), Form::Flat);
5679        assert_eq!(gathered.value_at(0), Value::Integer(8));
5680        assert_eq!(gathered.value_at(1), Value::Null);
5681    }
5682
5683    /// Two filters over one chunk build a dictionary over a dictionary, four conjuncts pushed down
5684    /// separately build four levels of it, and every level is a dependent load on every later read
5685    /// of every row plus a code array that cannot be freed. Composing at construction is one pass
5686    /// over the codes the range check was walking anyway.
5687    #[test]
5688    fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
5689        let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
5690        let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
5691        let (codes, values) = outer.dictionary_parts().unwrap();
5692        assert_eq!(codes, [1, 0]);
5693        assert_eq!(values.form(), Form::Flat);
5694        assert_eq!(outer.value_at(0), Value::Integer(8));
5695        assert_eq!(outer.value_at(1), Value::Integer(7));
5696    }
5697
5698    /// The invariant stated as the thing it is there for, which is that the depth does not grow with
5699    /// the number of filters. Four levels stacked one at a time are one level at the end of it.
5700    #[test]
5701    fn stacking_dictionaries_does_not_make_them_deeper() {
5702        let mut vector = integers(&[10, 20, 30, 40]);
5703        for _ in 0..4 {
5704            vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
5705        }
5706        let (codes, values) = vector.dictionary_parts().unwrap();
5707        assert_eq!(values.form(), Form::Flat);
5708        assert_eq!(codes, [0, 1, 2, 3]);
5709        assert_eq!(
5710            vector.iter().collect::<Vec<_>>(),
5711            integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
5712        );
5713    }
5714
5715    /// Composing has to carry the nulls down with it. The values hold them, the codes point at them,
5716    /// and a composed code that lands on a null position is still a null.
5717    #[test]
5718    fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
5719        let values =
5720            Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
5721        let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
5722        let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
5723        assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
5724        assert_eq!(outer.value_at(0), Value::Null);
5725        assert_eq!(outer.value_at(1), Value::Integer(3));
5726    }
5727
5728    /// The one level composition cannot go past. A dictionary that was given a validity of its own is
5729    /// saying its nulls are at that level rather than in the values, and pointing the outer codes
5730    /// straight at the values would read through the holes instead of stopping at them.
5731    #[test]
5732    fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
5733        let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
5734            .unwrap()
5735            .with_validity(Validity::from_iter(3, |index| index != 1));
5736        let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
5737        assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
5738        assert_eq!(outer.value_at(0), Value::Null);
5739        assert_eq!(outer.value_at(1), Value::Integer(3));
5740        assert_eq!(outer.value_at(2), Value::Integer(1));
5741    }
5742
5743    /// The difference between the two questions about nulls, which a group by got wrong. A filtered
5744    /// chunk is dictionary vectors, those are built with every row marked present at their own
5745    /// level, and the nulls are down in the values. So the mask says the row has a value and the
5746    /// row does not.
5747    #[test]
5748    fn a_null_behind_a_dictionary_reads_as_null_even_though_the_mask_says_otherwise() {
5749        let values = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
5750            .unwrap()
5751            .with_validity(Validity::from_iter(2, |index| index != 0));
5752        let vector = Vector::dictionary(vec![0, 1, 0], values).unwrap();
5753        assert!(vector.validity().is_valid(0), "the mask at this level says present");
5754        assert!(vector.is_null_at(0));
5755        assert!(!vector.is_null_at(1));
5756        assert!(vector.is_null_at(2));
5757        assert!(vector.is_null_at(3), "a row past the end is null");
5758    }
5759
5760    /// The same for runs, which are built the same way and keep their nulls in the same place.
5761    #[test]
5762    fn a_null_inside_a_run_reads_as_null_even_though_the_mask_says_otherwise() {
5763        let values = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
5764            .unwrap()
5765            .with_validity(Validity::from_iter(2, |index| index != 0));
5766        let vector = Vector::runs(vec![2, 3], values).unwrap();
5767        assert!(vector.validity().is_valid(0));
5768        assert!(vector.is_null_at(0));
5769        assert!(vector.is_null_at(1));
5770        assert!(!vector.is_null_at(2));
5771    }
5772
5773    /// Every other form keeps its nulls in its own mask, so the two answers agree there.
5774    #[test]
5775    fn the_forms_that_hold_their_own_nulls_answer_the_same_either_way() {
5776        let flat = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
5777            .unwrap()
5778            .with_validity(Validity::from_iter(2, |index| index != 0));
5779        let constant = Vector::constant(LogicalType::Integer, Value::Null, 2);
5780        let sequence = Vector::sequence(10, 2, 2);
5781        for vector in [flat, constant, sequence] {
5782            for row in 0..vector.len() {
5783                assert_eq!(vector.is_null_at(row), !vector.validity().is_valid(row));
5784            }
5785        }
5786    }
5787
5788    #[test]
5789    fn flattening_a_flat_vector_is_the_same_vector() {
5790        let vector = integers(&[1, 2, 3]);
5791        assert_eq!(vector.flatten().unwrap(), vector);
5792    }
5793
5794    /// The same answer as `flatten` and, for the vector that is already flat and owns its values,
5795    /// the same allocation. Asserted on the address because that is the whole claim: the values
5796    /// come back where they were rather than in a copy of themselves. A flatten through a borrow
5797    /// cannot do that, and at the top of a query it copied every column of every chunk of the
5798    /// result to hand back the bytes it was given.
5799    #[test]
5800    fn flattening_a_vector_that_owns_its_values_moves_them_rather_than_copying_them() {
5801        let vector = integers(&[1, 2, 3, 4]);
5802        let address = |vector: &Vector| match vector.data() {
5803            Some(Data::Int32(values)) => values.as_slice().as_ptr() as usize,
5804            _ => panic!("the layout changed under the test"),
5805        };
5806        let stored = address(&vector);
5807        let flat = vector.into_flat().unwrap();
5808        assert_eq!(address(&flat), stored, "the values moved");
5809        assert_eq!(
5810            flat.iter().collect::<Vec<_>>(),
5811            (1..=4).map(Value::Integer).collect::<Vec<_>>()
5812        );
5813        // And a form that is not flat is flattened, which is the case the copy is deserved in.
5814        let dictionary = Vector::dictionary(vec![1, 0, 1], integers(&[7, 8])).unwrap();
5815        let flat = dictionary.clone().into_flat().unwrap();
5816        assert_eq!(flat.form(), Form::Flat);
5817        assert_eq!(flat.iter().collect::<Vec<_>>(), dictionary.iter().collect::<Vec<_>>());
5818    }
5819
5820    #[test]
5821    fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
5822        let ty = LogicalType::decimal(9, 2).unwrap();
5823        let vector = Vector::flat(ty, Data::Int32(vec![1234].into())).unwrap();
5824        assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
5825        assert_eq!(vector.value_at(0).to_string(), "12.34");
5826    }
5827
5828    #[test]
5829    fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
5830        // The read path worked at every width and the write path only accepted the 128 bit run, so
5831        // `SELECT 2.5` produced a value nothing could store. All four widths round trip now.
5832        for (width, scale, unscaled) in
5833            [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
5834        {
5835            let ty = LogicalType::decimal(width, scale).unwrap();
5836            let value = Value::Decimal { unscaled, width, scale };
5837            let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
5838            assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
5839            assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
5840        }
5841    }
5842
5843    /// The bytes a blob holds are not required to be text, and a vector of them used to refuse the
5844    /// ones that were not. A byte array column in a Parquet file that nothing annotated is a blob,
5845    /// which is what ClickHouse writes and what ten of the ClickBench queries compare against, so
5846    /// this is the path those take rather than a corner of the type system.
5847    #[test]
5848    fn a_blob_holds_bytes_that_are_not_text() {
5849        let bytes = |raw: &[u8]| Value::Blob(raw.to_vec());
5850        let values = [
5851            bytes(b"a\xffb"),
5852            bytes(b"\x00\x01\x02"),
5853            Value::Null,
5854            bytes(b"\xed\xa0\x80 and long enough to leave the view"),
5855            bytes(b""),
5856        ];
5857        let vector = Vector::from_values(LogicalType::Blob, &values).unwrap();
5858        for (index, value) in values.iter().enumerate() {
5859            assert_eq!(&vector.value_at(index), value, "row {index}");
5860        }
5861    }
5862
5863    #[test]
5864    fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
5865        // Only reachable by hand, since a value's width is what picked the run. Truncating here
5866        // would store a different number and say nothing about it.
5867        let ty = LogicalType::decimal(4, 1).unwrap();
5868        let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
5869        let error = Vector::from_values(ty, &[value]).unwrap_err();
5870        assert!(error.to_string().contains("does not fit"), "{error}");
5871    }
5872
5873    #[test]
5874    fn a_flat_vector_costs_its_values_and_a_constant_costs_one() {
5875        let flat = integers(&[1; 1000]);
5876        assert!(
5877            flat.footprint() >= 4000,
5878            "a thousand i32 are four thousand bytes: {}",
5879            flat.footprint()
5880        );
5881        // The forms that compute their values rather than storing them cost nothing per value,
5882        // which is the point of having them and is what the memory limit should see.
5883        let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1_000_000);
5884        assert!(constant.footprint() < 200, "a constant is one value: {}", constant.footprint());
5885        let sequence = Vector::sequence(0, 1, 1_000_000);
5886        assert!(sequence.footprint() < 200, "a sequence is two numbers: {}", sequence.footprint());
5887    }
5888
5889    #[test]
5890    fn a_gather_off_a_dictionary_answers_the_same_nulls_either_way_round() {
5891        let words = [Value::Varchar("north".into()), Value::Null, Value::Varchar("south".into())];
5892        let plain: Vec<Value> =
5893            ["north", "east", "south"].iter().map(|word| Value::Varchar((*word).into())).collect();
5894        let clean = Arc::new(Vector::from_values(LogicalType::Varchar, &plain).unwrap());
5895        let dirty = Arc::new(Vector::from_values(LogicalType::Varchar, &words).unwrap());
5896        let codes = vec![0, 1, 2, 0, 1, 2];
5897        let sources = [
5898            Vector::stable_dictionary(codes.clone(), Arc::clone(&clean)).unwrap(),
5899            Vector::stable_dictionary(codes.clone(), Arc::clone(&dirty)).unwrap(),
5900            Vector::stable_dictionary(codes, Arc::clone(&clean))
5901                .unwrap()
5902                .with_validity(Validity::from_run(&[true, true, false, true, true, true])),
5903        ];
5904        // What a gather says about a row has to be what the column it came out of says about the
5905        // row it was taken from, whichever of the two ways the nulls are reached: the mask over the
5906        // codes, or the value a code stands for. The fast answer is only allowed when neither has
5907        // any, and an index past the end is null in both readings.
5908        for source in &sources {
5909            let picks: Vec<u32> = vec![5, 0, 3, 2, 1, 99, 4];
5910            let taken = source.gather(&picks).unwrap();
5911            for (row, &pick) in picks.iter().enumerate() {
5912                assert_eq!(
5913                    taken.is_null_at(row),
5914                    source.is_null_at(pick as usize),
5915                    "row {row} of a gather of {picks:?}"
5916                );
5917            }
5918        }
5919    }
5920
5921    #[test]
5922    fn a_dictionary_read_by_many_cuts_is_counted_about_once_between_them() {
5923        let strings: Vec<Value> = (0..2000)
5924            .map(|at| Value::Varchar(format!("a value well past the inline limit, number {at}")))
5925            .collect();
5926        let values = Arc::new(Vector::from_values(LogicalType::Varchar, &strings).unwrap());
5927        let dictionary = values.footprint();
5928        let cuts: Vec<Vector> = (0..500)
5929            .map(|_| Vector::stable_dictionary(vec![0; 8], Arc::clone(&values)).unwrap())
5930            .collect();
5931        let together: usize = cuts.iter().map(Vector::footprint).sum();
5932        // Five hundred chunks cut out of one page hold one dictionary, and what they say they hold
5933        // has to be about one dictionary. Before this it was five hundred of them, which is a
5934        // reading that grows with the answer and refuses a query holding a gigabyte a budget of
5935        // twenty five.
5936        assert!(
5937            together < dictionary * 2,
5938            "five hundred cuts are not five hundred dictionaries: {together} against {dictionary}"
5939        );
5940        assert!(
5941            together > dictionary / 2,
5942            "the dictionary is still counted: {together} against {dictionary}"
5943        );
5944    }
5945
5946    #[test]
5947    fn a_string_vector_costs_the_bytes_of_its_long_strings() {
5948        let short =
5949            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into())]).unwrap();
5950        let long = "a string well past the sixteen bytes a view holds inline".to_string();
5951        let spilled =
5952            Vector::from_values(LogicalType::Varchar, &[Value::Varchar(long.clone())]).unwrap();
5953        assert!(
5954            spilled.footprint() >= short.footprint() + long.len(),
5955            "the arena is counted: {} against {}",
5956            spilled.footprint(),
5957            short.footprint()
5958        );
5959    }
5960
5961    /// The cases worth checking are the widths where a code straddles a word boundary, which is
5962    /// every width that does not divide sixty four, and the two ends of the range.
5963    #[test]
5964    fn a_narrow_column_packs_and_reads_back_the_same_at_every_width() {
5965        for width in 1..=20u32 {
5966            let span = (1i64 << width) - 1;
5967            let values: Vec<i64> =
5968                (0..1000).map(|row| 1_000_000 + (row * 7919) % (span + 1)).collect();
5969            let flat =
5970                Vector::flat(LogicalType::BigInt, Data::Int64(values.clone().into())).unwrap();
5971            let packed = flat.bit_packed().unwrap();
5972            assert_eq!(packed.len(), flat.len());
5973            assert_eq!(
5974                packed.iter().collect::<Vec<_>>(),
5975                flat.iter().collect::<Vec<_>>(),
5976                "width {width} read back differently"
5977            );
5978        }
5979    }
5980
5981    #[test]
5982    fn the_width_is_the_bits_the_range_needs_and_not_the_bits_the_type_has() {
5983        let values: Vec<i32> = (0..1024).map(|row| 40 + (row * 2560) / 1023).collect();
5984        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
5985        let packed = flat.bit_packed().unwrap();
5986        assert_eq!(packed.form(), Form::BitPacked);
5987        let parts = packed.packed_parts().expect("packed");
5988        assert_eq!(parts.width(), 12, "0 to 2560 is twelve bits");
5989        assert_eq!(parts.base(), 40);
5990        assert!(
5991            packed.footprint() * 2 < flat.footprint(),
5992            "twelve bits against thirty two: {} against {}",
5993            packed.footprint(),
5994            flat.footprint()
5995        );
5996    }
5997
5998    /// The check is worth having in both directions, the way the run length one is. A form that is
5999    /// only ever bigger than what it replaced costs a pass over the column to decide not to use.
6000    #[test]
6001    fn a_column_that_uses_its_whole_type_is_left_flat() {
6002        let values: Vec<i32> = (0..1024).map(|row| row * 2_000_000 - 1_000_000_000).collect();
6003        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
6004        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
6005    }
6006
6007    /// The column that would not write. A thousand values just under `i32::MAX` need ten bits, and
6008    /// based at the smallest of them those ten bits could say a number an `INTEGER` cannot hold, so
6009    /// the range check refused the column and `CREATE TABLE` came back with an internal error. The
6010    /// base is what moves, not the check: it drops to where the widest code the width allows is the
6011    /// largest value the type has.
6012    #[test]
6013    fn a_column_against_the_top_of_its_type_packs_rather_than_being_refused() {
6014        let values: Vec<i32> = (0..4096).map(|row| i32::MAX - (row % 1000)).collect();
6015        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.clone().into())).unwrap();
6016        let packed = flat.bit_packed().unwrap();
6017        assert_eq!(packed.form(), Form::BitPacked);
6018        let parts = packed.packed_parts().expect("packed");
6019        assert_eq!(parts.width(), 10, "a thousand values apart is ten bits");
6020        assert_eq!(
6021            parts.base() + i128::from(u64::MAX >> (64 - parts.width())),
6022            i128::from(i32::MAX),
6023            "the widest code the width allows is the largest value the type holds"
6024        );
6025        assert_eq!(
6026            packed.iter().collect::<Vec<_>>(),
6027            flat.iter().collect::<Vec<_>>(),
6028            "the values came back different"
6029        );
6030    }
6031
6032    /// The other end of the same thing. A column that reaches both ends of its type needs every bit
6033    /// the type has, and the only base that leaves room for those codes is the bottom of the type.
6034    #[test]
6035    fn a_column_that_reaches_both_ends_of_its_type_bases_at_the_bottom_of_it() {
6036        let values: Vec<i32> = (0..4096)
6037            .map(|row| if row % 2 == 0 { i32::MIN + row } else { i32::MAX - row })
6038            .collect();
6039        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.clone().into())).unwrap();
6040        // Thirty two bits of codes for a thirty two bit type buys nothing, so the size check leaves
6041        // it flat. What matters is that it is left flat rather than refused.
6042        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
6043        assert_eq!(
6044            packing_base(&LogicalType::Integer, i128::from(i32::MIN), i128::from(i32::MAX), 32),
6045            Some(i128::from(i32::MIN))
6046        );
6047    }
6048
6049    /// A column of one value would pack to no bits at all, and one run is smaller than any packing
6050    /// of it, so the two forms do not fight over that column.
6051    #[test]
6052    fn a_column_of_one_value_is_left_to_the_run_length_form() {
6053        let flat = integers(&[9; 1024]);
6054        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
6055        assert_eq!(flat.run_encoded().unwrap().form(), Form::Rle);
6056    }
6057
6058    #[test]
6059    fn a_string_column_has_no_range_to_pack() {
6060        let text = Vector::from_values(
6061            LogicalType::Varchar,
6062            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
6063        )
6064        .unwrap();
6065        assert_eq!(text.bit_packed().unwrap().form(), Form::Flat);
6066    }
6067
6068    /// The cut is the reason the form carries a row to start reading at. It stays packed, it shares
6069    /// the same words, and it reads the rows the range asked for.
6070    #[test]
6071    fn a_cut_of_a_packed_column_stays_packed_and_shares_its_bits() {
6072        let values: Vec<i32> = (0..1024).map(|row| 100 + row % 300).collect();
6073        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
6074        let packed = flat.bit_packed().unwrap();
6075        let cut = packed.slice(500, 24).unwrap();
6076        assert_eq!(cut.form(), Form::BitPacked);
6077        assert_eq!(cut.len(), 24);
6078        assert_eq!(
6079            cut.iter().collect::<Vec<_>>(),
6080            flat.slice(500, 24).unwrap().iter().collect::<Vec<_>>()
6081        );
6082        assert!(
6083            cut.footprint() >= packed.footprint(),
6084            "a cut shares the words rather than copying a piece of them"
6085        );
6086    }
6087
6088    #[test]
6089    fn a_gather_of_a_packed_column_comes_out_flat_and_keeps_the_nulls() {
6090        let values: Vec<i32> = (0..64).map(|row| 10 + row).collect();
6091        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
6092        let packed =
6093            flat.bit_packed().unwrap().with_validity(Validity::from_iter(64, |row| row % 3 != 0));
6094        let taken = packed.gather(&[0, 1, 2, 3, 62]).unwrap();
6095        assert_eq!(taken.form(), Form::Flat);
6096        assert_eq!(
6097            taken.iter().collect::<Vec<_>>(),
6098            vec![
6099                Value::Null,
6100                Value::Integer(11),
6101                Value::Integer(12),
6102                Value::Null,
6103                Value::Integer(72)
6104            ]
6105        );
6106    }
6107
6108    /// The pair a comparison kernel asks for before it reads a bit. A literal inside the range has a
6109    /// code and a literal outside it does not, which answers the whole vector at once.
6110    #[test]
6111    fn a_literal_outside_the_packed_range_has_no_code() {
6112        let values: Vec<i32> = (0..256).map(|row| 1000 + row).collect();
6113        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
6114        let packed = flat.bit_packed().unwrap();
6115        let parts = packed.packed_parts().expect("packed");
6116        assert_eq!(parts.code_of(1000), Some(0));
6117        assert_eq!(parts.code_of(1100), Some(100));
6118        assert_eq!(parts.code_of(999), None);
6119        assert!(parts.ceiling() >= 1255);
6120        assert_eq!(parts.code_of(parts.ceiling() + 1), None);
6121    }
6122
6123    /// The bits arriving from a file rather than from a flat vector, which is what the form is for.
6124    #[test]
6125    fn packed_bits_can_be_handed_in_without_a_flat_vector_to_start_from() {
6126        let packed = Vector::packed(LogicalType::SmallInt, vec![0x0000_0000_0000_4321], 4, 7, 4)
6127            .expect("four codes of four bits");
6128        assert_eq!(
6129            packed.iter().collect::<Vec<_>>(),
6130            vec![Value::SmallInt(8), Value::SmallInt(9), Value::SmallInt(10), Value::SmallInt(11)]
6131        );
6132    }
6133
6134    #[test]
6135    fn packed_bits_that_could_not_hold_what_they_claim_are_refused() {
6136        assert!(Vector::packed(LogicalType::Varchar, vec![0], 4, 0, 4).is_err(), "not an integer");
6137        assert!(Vector::packed(LogicalType::Integer, vec![0], 0, 0, 4).is_err(), "no width");
6138        assert!(Vector::packed(LogicalType::Integer, vec![0], 64, 0, 4).is_err(), "too wide");
6139        assert!(Vector::packed(LogicalType::Integer, vec![0], 8, 0, 9).is_err(), "too few words");
6140        assert!(Vector::packed(LogicalType::TinyInt, vec![0], 8, 100, 8).is_err(), "would not fit");
6141    }
6142
6143    /// A column of strings long enough that the payload is in the arena rather than in the views.
6144    fn long_strings(count: usize) -> Vector {
6145        let values: Vec<Value> = (0..count)
6146            .map(|row| {
6147                Value::Varchar(format!("a string too long to sit inside a view, number {row}"))
6148            })
6149            .collect();
6150        Vector::from_values(LogicalType::Varchar, &values).unwrap()
6151    }
6152
6153    #[test]
6154    fn a_string_column_in_view_form_reads_back_the_same_strings() {
6155        let flat = long_strings(40);
6156        let shared = flat.clone().shared_text().unwrap();
6157        assert_eq!(shared.form(), Form::StringView);
6158        assert_eq!(shared.len(), 40);
6159        for row in 0..40 {
6160            assert_eq!(shared.value_at(row), flat.value_at(row), "row {row}");
6161            assert_eq!(shared.text_at(row), flat.text_at(row), "row {row}");
6162        }
6163    }
6164
6165    #[test]
6166    fn a_short_string_is_read_out_of_its_view_and_never_out_of_the_arena() {
6167        let flat = Vector::from_values(
6168            LogicalType::Varchar,
6169            &[Value::Varchar("red".into()), Value::Varchar("green".into()), Value::Null],
6170        )
6171        .unwrap();
6172        let shared = flat.shared_text().unwrap();
6173        // Nothing went to the arena, so the whole column resolves with an empty one.
6174        let (views, arena) = shared.text_parts().unwrap();
6175        assert!(arena.is_empty(), "three short strings need no arena");
6176        assert_eq!(views[0].bytes_in(arena), Some(&b"red"[..]));
6177        assert_eq!(shared.value_at(1), Value::Varchar("green".into()));
6178        assert_eq!(shared.value_at(2), Value::Null, "the validity came across");
6179    }
6180
6181    #[test]
6182    fn a_cut_of_a_view_column_shares_the_arena_rather_than_copying_the_bytes() {
6183        let shared = long_strings(64).shared_text().unwrap();
6184        let cut = shared.slice(16, 8).unwrap();
6185        assert_eq!(cut.form(), Form::StringView, "a cut of views is views");
6186        assert_eq!(cut.len(), 8);
6187        assert_eq!(cut.value_at(0), shared.value_at(16));
6188        assert_eq!(cut.value_at(7), shared.value_at(23));
6189        // The arena is the same bytes at the same address, which is the whole point of the form.
6190        let (_, whole) = shared.text_parts().unwrap();
6191        let (_, piece) = cut.text_parts().unwrap();
6192        assert_eq!(piece.as_ptr(), whole.as_ptr(), "the cut shares the page");
6193        assert_eq!(piece.len(), whole.len());
6194    }
6195
6196    #[test]
6197    fn a_flat_string_column_has_to_copy_the_bytes_its_cut_keeps() {
6198        let flat = long_strings(64);
6199        let cut = flat.slice(16, 8).unwrap();
6200        assert_eq!(cut.form(), Form::Flat);
6201        let (_, whole) = flat.text_parts().unwrap();
6202        let (_, piece) = cut.text_parts().unwrap();
6203        assert!(piece.len() < whole.len(), "the flat cut carries only what it kept");
6204    }
6205
6206    #[test]
6207    fn a_gather_of_a_view_column_keeps_the_form_and_a_flatten_copies_out_of_it() {
6208        let shared = long_strings(32).shared_text().unwrap();
6209        let picked: Vec<u32> = (0..32).step_by(3).collect();
6210        let gathered = shared.gather(&picked).unwrap();
6211        assert_eq!(gathered.form(), Form::StringView, "selecting rows moves views, not bytes");
6212        assert_eq!(gathered.len(), picked.len());
6213        for (row, &from) in picked.iter().enumerate() {
6214            assert_eq!(gathered.value_at(row), shared.value_at(from as usize), "row {row}");
6215        }
6216        let flattened = gathered.flatten().unwrap();
6217        assert_eq!(flattened.form(), Form::Flat);
6218        assert_eq!(flattened.iter().collect::<Vec<_>>(), gathered.iter().collect::<Vec<_>>());
6219        // The flatten is what narrows the bytes, so the arena it built holds only the rows it kept.
6220        let (_, narrowed) = flattened.text_parts().unwrap();
6221        let (_, whole) = shared.text_parts().unwrap();
6222        assert!(narrowed.len() < whole.len(), "flattening lets the page go");
6223    }
6224
6225    #[test]
6226    fn a_null_in_a_view_column_survives_being_gathered_and_flattened() {
6227        let shared = long_strings(8)
6228            .with_validity(Validity::from_iter(8, |row| row % 3 != 0))
6229            .shared_text()
6230            .unwrap();
6231        let gathered = shared.gather(&[0, 1, 2, 3, 4]).unwrap();
6232        let expected =
6233            [Value::Null, shared.value_at(1), shared.value_at(2), Value::Null, shared.value_at(4)];
6234        assert_eq!(gathered.iter().collect::<Vec<_>>(), expected);
6235        assert_eq!(gathered.flatten().unwrap().iter().collect::<Vec<_>>(), expected);
6236    }
6237
6238    #[test]
6239    fn both_string_forms_hand_a_kernel_the_same_views_and_the_same_bytes() {
6240        let flat = long_strings(6);
6241        let shared = flat.clone().shared_text().unwrap();
6242        let (flat_views, flat_arena) = flat.text_parts().unwrap();
6243        let (shared_views, shared_arena) = shared.text_parts().unwrap();
6244        assert_eq!(flat_views.len(), shared_views.len());
6245        for row in 0..6 {
6246            assert_eq!(
6247                flat_views[row].bytes_in(flat_arena),
6248                shared_views[row].bytes_in(shared_arena),
6249                "row {row}"
6250            );
6251        }
6252        // Nothing else answers this, which is what keeps a kernel from taking it for a string column.
6253        assert!(Vector::sequence(0, 1, 4).text_parts().is_none());
6254        assert!(integers(&[1, 2, 3]).text_parts().is_none());
6255    }
6256
6257    #[test]
6258    fn a_column_that_is_not_strings_cannot_be_held_as_views() {
6259        let views = vec![StringView::inline("red")];
6260        let arena = Arc::new(Buffer::new());
6261        let wrong = Vector::string_views(LogicalType::Integer, views, arena);
6262        assert!(wrong.is_err(), "an integer column has no views");
6263        assert_eq!(integers(&[1, 2]).shared_text().unwrap().form(), Form::Flat, "left alone");
6264    }
6265
6266    /// A column with enough repeated structure for a symbol table to find something, which is what
6267    /// a real text column has and a column of random bytes does not.
6268    fn sentences(count: usize) -> Vector {
6269        let values: Vec<Value> = (0..count)
6270            .map(|row| {
6271                Value::Varchar(format!(
6272                    "http://example.test/catalogue/section/{}/item/{row}",
6273                    row % 7
6274                ))
6275            })
6276            .collect();
6277        Vector::from_values(LogicalType::Varchar, &values).unwrap()
6278    }
6279
6280    #[test]
6281    fn a_compressed_column_reads_back_the_strings_that_went_into_it() {
6282        let flat = sentences(64);
6283        let coded = flat.clone().compressed().unwrap();
6284        assert_eq!(coded.form(), Form::Fsst, "a text column compresses");
6285        assert_eq!(coded.len(), 64);
6286        for row in 0..64 {
6287            assert_eq!(coded.value_at(row), flat.value_at(row), "row {row}");
6288        }
6289        assert_eq!(coded.flatten().unwrap(), flat, "flattening is the column it came from");
6290    }
6291
6292    #[test]
6293    fn compressing_halves_the_bytes_or_the_column_is_left_flat() {
6294        let flat = sentences(200);
6295        let coded = flat.clone().compressed().unwrap();
6296        let parts = coded.coded_parts().expect("compressed");
6297        // Read through the flat column, because the compressed one has no bytes to hand back where
6298        // they are and answers `None` to `text_at` rather than decompressing into a borrow.
6299        assert_eq!(coded.text_at(0), None, "nothing to borrow until it is flattened");
6300        let plain: usize = (0..200).map(|row| flat.text_at(row).map_or(0, str::len)).sum();
6301        let codes: usize = (0..200).map(|row| parts.row(row).map_or(0, <[u8]>::len)).sum();
6302        assert!(codes * FSST_PAYS_AT <= plain, "{codes} codes against {plain} bytes");
6303        // Text with no repeated structure in it gives a table nothing longer than a byte to find,
6304        // so the codes are the bytes and the column stays where it is rather than paying a
6305        // decompression per read to save nothing.
6306        let mut seed = 0x2545_f491_4f6c_dd1du64;
6307        let values: Vec<Value> = (0..256)
6308            .map(|_| {
6309                let mut text = String::new();
6310                while text.len() < 12 {
6311                    seed = seed.wrapping_mul(6_364_136_223_846_793_005).wrapping_add(1);
6312                    text.push(char::from(b'!' + ((seed >> 33) % 90) as u8));
6313                }
6314                Value::Varchar(text)
6315            })
6316            .collect();
6317        let noise = Vector::from_values(LogicalType::Varchar, &values).unwrap();
6318        assert_eq!(noise.compressed().unwrap().form(), Form::Flat);
6319    }
6320
6321    #[test]
6322    fn a_cut_of_a_compressed_column_shares_the_codes_and_the_table() {
6323        let coded = sentences(64).compressed().unwrap();
6324        let cut = coded.slice(8, 16).unwrap();
6325        assert_eq!(cut.form(), Form::Fsst);
6326        assert_eq!(cut.len(), 16);
6327        for row in 0..16 {
6328            assert_eq!(cut.value_at(row), coded.value_at(8 + row), "row {row}");
6329        }
6330        let (whole, piece) = (coded.coded_parts().unwrap(), cut.coded_parts().unwrap());
6331        assert_eq!(piece.row(0), whole.row(8), "the spans point into the same codes");
6332    }
6333
6334    #[test]
6335    fn a_gather_of_a_compressed_column_stays_compressed_and_keeps_the_nulls() {
6336        let coded = sentences(32)
6337            .with_validity(Validity::from_iter(32, |row| row % 5 != 2))
6338            .compressed()
6339            .unwrap();
6340        let picked: Vec<u32> = (0..32).step_by(2).collect();
6341        let gathered = coded.gather(&picked).unwrap();
6342        assert_eq!(gathered.form(), Form::Fsst, "selecting rows moves spans, not bytes");
6343        for (row, &from) in picked.iter().enumerate() {
6344            assert_eq!(gathered.value_at(row), coded.value_at(from as usize), "row {row}");
6345        }
6346        assert_eq!(
6347            gathered.flatten().unwrap().iter().collect::<Vec<_>>(),
6348            gathered.iter().collect::<Vec<_>>()
6349        );
6350    }
6351
6352    #[test]
6353    fn a_literal_lands_in_the_same_codes_the_row_holding_it_does() {
6354        let coded = sentences(40).compressed().unwrap();
6355        let parts = coded.coded_parts().expect("compressed");
6356        let text = coded.value_at(11);
6357        let Value::Varchar(text) = text else { panic!("a string column reads back strings") };
6358        assert_eq!(parts.encode(text.as_bytes()), parts.row(11).expect("row 11"));
6359        assert_ne!(parts.encode(b"something else entirely"), parts.row(11).unwrap());
6360    }
6361
6362    #[test]
6363    fn codes_that_run_past_what_is_there_are_refused() {
6364        let table = Arc::new(SymbolTable::empty());
6365        let codes = Arc::new(vec![1u8, 2, 3, 4]);
6366        let good = vec![(0u32, 2u32), (2, 4)];
6367        assert!(
6368            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), good, Arc::clone(&table))
6369                .is_ok()
6370        );
6371        let past = vec![(0u32, 9u32)];
6372        assert!(
6373            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), past, Arc::clone(&table))
6374                .is_err(),
6375            "a span past the end of the codes"
6376        );
6377        let backwards = vec![(3u32, 1u32)];
6378        assert!(
6379            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), backwards, Arc::clone(&table))
6380                .is_err(),
6381            "a span that ends before it starts"
6382        );
6383        let wrong = vec![(0u32, 2u32)];
6384        assert!(
6385            Vector::coded(LogicalType::Integer, codes, wrong, table).is_err(),
6386            "an integer column has no codes"
6387        );
6388    }
6389
6390    #[test]
6391    fn a_view_pointing_past_its_arena_is_refused_at_construction() {
6392        let long = "a string too long to sit inside a view";
6393        let arena: Arc<Buffer<u8>> = Arc::new(long.as_bytes().to_vec().into());
6394        let good = vec![StringView::over(long.as_bytes(), 0)];
6395        assert!(Vector::string_views(LogicalType::Varchar, good, Arc::clone(&arena)).is_ok());
6396        let bad = vec![StringView::over(long.as_bytes(), 4)];
6397        assert!(
6398            Vector::string_views(LogicalType::Varchar, bad, arena).is_err(),
6399            "four bytes short of what the view claims"
6400        );
6401    }
6402
6403    /// The form at its simplest: an id per row, and the row it names.
6404    #[test]
6405    fn a_gathered_vector_reads_the_source_row_its_id_names() {
6406        let source = Arc::new(integers(&[10, 20, 30, 40]));
6407        let vector = Vector::gathered(source, Arc::new(vec![3, 0, 3, 1])).unwrap();
6408        assert_eq!(vector.form(), Form::Gathered);
6409        assert_eq!(vector.len(), 4);
6410        assert_eq!(
6411            vector.iter().collect::<Vec<_>>(),
6412            vec![Value::Integer(40), Value::Integer(10), Value::Integer(40), Value::Integer(20)]
6413        );
6414    }
6415
6416    /// Section 8.2's lazy validity. The sentinel is a null and it is not in a mask anywhere, which is
6417    /// what lets a left link join gather null for an unmatched child row without allocating one.
6418    #[test]
6419    fn a_gathered_row_with_no_source_row_is_null_without_a_mask() {
6420        let source = Arc::new(integers(&[10, 20]));
6421        let vector = Vector::gathered(source, Arc::new(vec![1, NO_ROW, 0])).unwrap();
6422        assert!(!vector.validity().has_nulls(vector.len()), "the mask at this level says nothing");
6423        assert!(vector.is_null_at(1));
6424        assert!(!vector.is_null_at(0) && !vector.is_null_at(2));
6425        assert_eq!(
6426            vector.iter().collect::<Vec<_>>(),
6427            vec![Value::Integer(20), Value::Null, Value::Integer(10)]
6428        );
6429        assert!(!vector.none_null(), "a sentinel is a null and the bulk answer has to agree");
6430    }
6431
6432    /// The other half of the same rule: a null in the source is a null here, the way a dictionary's
6433    /// nulls live in its values. Two ways for a row to be null and one answer from `is_null_at`.
6434    #[test]
6435    fn a_gather_of_a_null_source_row_is_null() {
6436        let source = Arc::new(
6437            Vector::from_values(LogicalType::Integer, &[Value::Integer(7), Value::Null]).unwrap(),
6438        );
6439        let vector = Vector::gathered(source, Arc::new(vec![1, 0, 1])).unwrap();
6440        assert!(vector.is_null_at(0) && vector.is_null_at(2));
6441        assert_eq!(vector.value_at(1), Value::Integer(7));
6442        assert!(!vector.none_null());
6443    }
6444
6445    /// An id past the end of the source is the one failure in this form that reads whatever happens
6446    /// to be at that offset rather than failing, so it is refused where the vector is built.
6447    #[test]
6448    fn a_gathered_id_past_the_end_of_its_source_is_refused() {
6449        let source = Arc::new(integers(&[1, 2, 3]));
6450        assert!(Vector::gathered(Arc::clone(&source), Arc::new(vec![0, 3])).is_err());
6451        assert!(
6452            Vector::gathered(source, Arc::new(vec![0, NO_ROW])).is_ok(),
6453            "the sentinel is not an id past the end, it is the absence of one"
6454        );
6455    }
6456
6457    /// A cut is the offset and nothing else, which is what keeps a pipeline from copying the ids once
6458    /// per operator. Both ends stay shared and the rows answer the same.
6459    #[test]
6460    fn cutting_a_gather_moves_where_it_starts_and_copies_nothing() {
6461        let source = Arc::new(integers(&[10, 20, 30, 40, 50]));
6462        let rids = Arc::new(vec![4, 3, 2, 1, 0]);
6463        let vector = Vector::gathered(Arc::clone(&source), Arc::clone(&rids)).unwrap();
6464        let held = Arc::strong_count(&rids);
6465        let cut = vector.slice(1, 3).unwrap();
6466        assert_eq!(cut.form(), Form::Gathered);
6467        assert_eq!(
6468            Arc::strong_count(&rids),
6469            held + 1,
6470            "the cut shares the ids rather than copying"
6471        );
6472        assert_eq!(
6473            cut.iter().collect::<Vec<_>>(),
6474            vec![Value::Integer(40), Value::Integer(30), Value::Integer(20)]
6475        );
6476        assert_eq!(cut.gathered_parts().unwrap().1, [3, 2, 1]);
6477    }
6478
6479    /// Composition, which is why this is a body and not an operator. A filter over the output of a
6480    /// link join selects into the ids, and what comes out is one level rather than two.
6481    #[test]
6482    fn a_gather_of_a_gather_resolves_to_one_walk_over_the_source() {
6483        let source = Arc::new(integers(&[10, 20, 30, 40]));
6484        let inner = Vector::gathered(source, Arc::new(vec![3, 2, 1, 0])).unwrap();
6485        let outer = inner.gather(&[0, 3]).unwrap();
6486        assert_eq!(outer.iter().collect::<Vec<_>>(), vec![Value::Integer(40), Value::Integer(10)]);
6487        assert_ne!(outer.form(), Form::Gathered, "the walk stops at what the ids point into");
6488    }
6489
6490    /// The sentinel survives being gathered through, which it has to: a filter over a left link
6491    /// join's output keeps the unmatched rows it kept and they are still null.
6492    #[test]
6493    fn gathering_through_a_sentinel_keeps_it_null() {
6494        let source = Arc::new(integers(&[10, 20]));
6495        let inner = Vector::gathered(source, Arc::new(vec![0, NO_ROW, 1])).unwrap();
6496        let outer = inner.gather(&[1, 2, 1]).unwrap();
6497        assert_eq!(
6498            outer.iter().collect::<Vec<_>>(),
6499            vec![Value::Null, Value::Integer(20), Value::Null]
6500        );
6501    }
6502
6503    /// Section 8.2's dispatch rule, which is the whole difference between this form and a dictionary
6504    /// and is one comparison. A gather off a parent larger than the chunk does not want the
6505    /// dictionary arm of any kernel, and a gather off a source smaller than the chunk does.
6506    #[test]
6507    fn folding_over_the_source_is_worth_it_only_when_the_source_is_the_shorter_one() {
6508        let wide = Arc::new(integers(&(0..64).collect::<Vec<i32>>()));
6509        let narrow = Arc::new(integers(&[1, 2]));
6510        let off_wide = Vector::gathered(wide, Arc::new(vec![0, 1, 2])).unwrap();
6511        let off_narrow = Vector::gathered(narrow, Arc::new(vec![0, 1, 0, 1, 0])).unwrap();
6512        assert!(!off_wide.fold_over_source(), "sixty four source rows to answer three");
6513        assert!(off_narrow.fold_over_source(), "two source rows to answer five");
6514        assert!(!integers(&[1, 2]).fold_over_source(), "and every other form says no");
6515    }
6516
6517    /// Strings, which read their bytes where the source already has them rather than through a value.
6518    /// A gather of a string column is four bytes a row and no arena is touched until something asks.
6519    #[test]
6520    fn a_gathered_string_is_read_where_the_source_put_it() {
6521        let mut column = StringColumn::new();
6522        column.push("red");
6523        column.push("a string too long to sit inside a sixteen byte view");
6524        let source = Arc::new(Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap());
6525        let vector = Vector::gathered(source, Arc::new(vec![1, 0, NO_ROW])).unwrap();
6526        assert_eq!(vector.text_at(0), Some("a string too long to sit inside a sixteen byte view"));
6527        assert_eq!(vector.text_at(1), Some("red"));
6528        assert_eq!(vector.text_at(2), None);
6529        assert_eq!(vector.bytes_at(1), Some(b"red".as_slice()));
6530        assert_eq!(vector.value_at(1), Value::Varchar("red".into()));
6531    }
6532
6533    /// The integer accessor a group by keys through, which has to agree with `value_at` at every
6534    /// row or two rows holding one value land in two groups.
6535    #[test]
6536    fn the_signed_reader_of_a_gather_agrees_with_the_value_reader() {
6537        let source = Arc::new(integers(&[10, 20, 30]));
6538        let vector = Vector::gathered(source, Arc::new(vec![2, NO_ROW, 0, 1])).unwrap();
6539        for row in 0..vector.len() {
6540            let signed = vector.signed_at(row);
6541            match vector.value_at(row) {
6542                Value::Null => assert_eq!(signed, None),
6543                Value::Integer(held) => assert_eq!(signed, Some(i128::from(held))),
6544                other => panic!("an integer column answered {other}"),
6545            }
6546        }
6547    }
6548
6549    /// Flattening gives up the form, which is what it is for, and what comes out holds the values the
6550    /// gather stood for, nulls included.
6551    #[test]
6552    fn flattening_a_gather_writes_out_the_rows_it_pointed_at() {
6553        let source = Arc::new(integers(&[10, 20, 30]));
6554        let vector = Vector::gathered(source, Arc::new(vec![2, NO_ROW, 0])).unwrap();
6555        let flat = vector.flatten().unwrap();
6556        assert_eq!(flat.form(), Form::Flat);
6557        assert_eq!(
6558            flat.iter().collect::<Vec<_>>(),
6559            vec![Value::Integer(30), Value::Null, Value::Integer(10)]
6560        );
6561    }
6562
6563    /// A gather counts a share of what it shares, for the reason a dictionary does. Eight columns
6564    /// gathered off one parent are one parent between them, not eight.
6565    #[test]
6566    fn a_parent_gathered_by_many_columns_is_counted_about_once_between_them() {
6567        let source = Arc::new(integers(&(0..4096).collect::<Vec<i32>>()));
6568        let rids = Arc::new(vec![0; 64]);
6569        let alone = Vector::gathered(Arc::clone(&source), Arc::clone(&rids)).unwrap().footprint();
6570        let many = (0..8)
6571            .map(|_| Vector::gathered(Arc::clone(&source), Arc::clone(&rids)).unwrap())
6572            .collect::<Vec<_>>();
6573        let together = many.iter().map(Vector::footprint).sum::<usize>();
6574        assert!(
6575            together < alone * 2,
6576            "eight gathers off one parent reported {together} against {alone} for one"
6577        );
6578    }
6579}