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/// 1024 rather than DuckDB's 2048, per `spec/04-architecture.md` section 4.3. It is the FastLanes
54/// unit, it makes a validity mask exactly 16 `u64` words, and it keeps a vector of 16 byte string
55/// views at 16 KiB, which is the size at which several of these fit in L1 together rather than
56/// evicting each other.
57pub const VECTOR_SIZE: usize = 1024;
58
59/// What the key field of a map's child struct is called.
60///
61/// A map is stored as a list of two field structs, and these are the two names. They are DuckDB's, and
62/// they are also the names the Parquet specification gives a map's repeated group, so a reader that
63/// builds one of these from a file finds the names already agreed rather than translated.
64pub const MAP_KEY: &str = "key";
65
66/// What the value field of a map's child struct is called. See [`MAP_KEY`].
67pub const MAP_VALUE: &str = "value";
68
69/// What [`Vector::map_parts`] hands back: one entry per row, then the keys and then the values.
70///
71/// A name rather than the triple written out, because the triple written out is over the complexity
72/// clippy allows and because a kernel that takes these as an argument should be able to say so in one
73/// word.
74pub type MapParts<'a> = (&'a [(u32, u32)], &'a Vector, &'a Vector);
75
76/// Which physical form a vector is in.
77///
78/// An operator asks this once per vector and then takes the path it wants, which is the one branch
79/// per vector that the whole design is willing to spend.
80///
81/// Not exhaustive, and that is a decision rather than an oversight. `Encoded` is the fifth form
82/// and it arrives at layer three with the specialization contract. If this enum were exhaustive,
83/// the day it lands is the day every kernel in the workspace stops compiling, and the pressure at
84/// that moment would be to add an arm to each of them in a hurry rather than to think about what
85/// each one should do with an encoded vector. A required fallback arm means each kernel already
86/// has a correct answer for a form it has never seen, and specializing it is then a change that
87/// can be made one kernel at a time with a benchmark next to it.
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
89#[non_exhaustive]
90pub enum Form {
91    /// One value per position.
92    Flat,
93    /// One value, repeated.
94    Constant,
95    /// A start and a step, computed rather than stored.
96    Sequence,
97    /// Codes into a smaller vector of distinct values.
98    Dictionary,
99    /// Integers stored in as many bits as the range of the column needs, offset from a base.
100    ///
101    /// The form a narrow integer column is in. A ClickBench `ResolutionWidth` is a `SMALLINT` whose
102    /// values live between 0 and 2560, which is twelve bits, so the column is three quarters of the
103    /// size it was and the pages behind it are three quarters of the reads. What it costs is a shift
104    /// and a mask per value, which is why this is worth it at storage and at rest and is not a form
105    /// anything should be building in the middle of a pipeline.
106    BitPacked,
107    /// Sixteen byte views over an arena the vector shares rather than owns.
108    ///
109    /// The form a varchar column is in once more than one vector is looking at the same page. A flat
110    /// varchar vector owns its arena, so cutting a chunk out of it copies every byte of every long
111    /// string in the range, and on ClickBench that is most of what reading `URL` costs. Sharing the
112    /// arena makes the cut the views and nothing else, the way a dictionary cut is the codes and
113    /// nothing else.
114    StringView,
115    /// Strings compressed against one symbol table, each row on its own.
116    ///
117    /// The form a text column is in at rest. FSST is about half the bytes on the ClickBench `URL`
118    /// and `Title` columns, and unlike a block compressor it keeps random access, so reading row
119    /// four million does not decompress the four million before it. What it costs is a decompression
120    /// per row read, which is why an equality filter over it is worth writing in code space: the
121    /// literal compresses once and the rows never decompress at all.
122    Fsst,
123    /// One value per run, with the row each run ends at.
124    ///
125    /// The form a clustered column is in. `hits` is written in time order, so `EventDate` is a few
126    /// hundred runs over a hundred million rows, and a sum over it is a few hundred multiplications
127    /// rather than a hundred million additions. Dictionary says which distinct values there are and
128    /// this says where they stop, and a column can want either one without wanting the other.
129    Rle,
130    /// A child vector of every element, and a start and a length per row.
131    ///
132    /// The form a `LIST` column is in, and the only form it has. The others are all ways of writing
133    /// down a column of scalars more cheaply and this is the shape a nested value has at all, so a
134    /// list vector reports this whether or not anything has tried to make it smaller. Making it
135    /// smaller happens in the child, which is an ordinary vector and can be any of the forms above.
136    ///
137    /// A `MAP` column reports this too, because a map is a list whose child is a two field struct and
138    /// the bytes really are a list's. This enum is about the physical layout, and the logical type is
139    /// what remembers the difference, which is the same division `LogicalType::physical` already makes.
140    List,
141    /// One child vector per field, each as long as the vector itself.
142    ///
143    /// The form a `STRUCT` column is in, and the only form it has, for the reason [`Form::List`] is
144    /// the only form a list has. A struct holds exactly one value per field per row rather than a run
145    /// of them, so there are no entries here and the children line up with the rows one to one, which
146    /// makes a cut a cut of every child and a gather a gather of every child. Each child is an
147    /// ordinary vector and can be in any of the forms above, so that is where a struct column gets
148    /// made smaller.
149    Struct,
150}
151
152/// The values of a flat vector, one Rust vector per physical type.
153///
154/// The variants are physical rather than logical, which is what lets `DATE` and `INTEGER` share
155/// storage and share a kernel. What a run of `i32` means is the vector's logical type's business.
156#[derive(Debug, Clone, PartialEq)]
157#[non_exhaustive]
158pub enum Data {
159    /// No values, for the type of an untyped `NULL`.
160    Empty,
161    /// One byte per value.
162    Bool(Buffer<bool>),
163    /// 8 bit signed.
164    Int8(Buffer<i8>),
165    /// 16 bit signed.
166    Int16(Buffer<i16>),
167    /// 32 bit signed.
168    Int32(Buffer<i32>),
169    /// 64 bit signed.
170    Int64(Buffer<i64>),
171    /// 128 bit signed.
172    Int128(Buffer<i128>),
173    /// 8 bit unsigned.
174    UInt8(Buffer<u8>),
175    /// 16 bit unsigned.
176    UInt16(Buffer<u16>),
177    /// 32 bit unsigned.
178    UInt32(Buffer<u32>),
179    /// 64 bit unsigned.
180    UInt64(Buffer<u64>),
181    /// 128 bit unsigned.
182    UInt128(Buffer<u128>),
183    /// IEEE 754 binary32.
184    Float32(Buffer<f32>),
185    /// IEEE 754 binary64.
186    Float64(Buffer<f64>),
187    /// The months, days and microseconds triple.
188    Interval(Buffer<(i32, i32, i64)>),
189    /// Strings, as 16 byte views plus the arena the long ones live in.
190    Varlen(StringColumn),
191}
192
193impl Data {
194    /// How many values are stored.
195    ///
196    /// The match below has no wildcard arm, and that is what makes this function the check that
197    /// keeps [`for_each_layout`](crate::for_each_layout) honest. A variant added to this enum
198    /// without being added to the `all` group fails to compile here, which is a line in a build log
199    /// rather than a layout quietly missing from six kernels.
200    #[must_use]
201    pub fn len(&self) -> usize {
202        macro_rules! lengths {
203            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
204                match self {
205                    Self::Empty => 0,
206                    $(Self::$variant(values) => values.len(),)+
207                }
208            };
209        }
210        crate::for_each_layout!(all, lengths)
211    }
212
213    /// Whether there are no values.
214    #[must_use]
215    pub fn is_empty(&self) -> bool {
216        self.len() == 0
217    }
218
219    /// How many bytes of memory these values are holding.
220    ///
221    /// One arm per layout through the same macro as [`Data::len`], for the same reason: a layout
222    /// added without a size here is a layout the memory limit would charge nothing for, and a
223    /// buffer that is free is a buffer that can be grown until the process dies.
224    #[must_use]
225    pub fn footprint(&self) -> usize {
226        macro_rules! sizes {
227            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
228                match self {
229                    Self::Empty => 0,
230                    $(Self::$variant(values) => values.footprint(),)+
231                }
232            };
233        }
234        crate::for_each_layout!(all, sizes)
235    }
236
237    /// These values held as a page, so that copying or cutting them does not copy the values.
238    ///
239    /// For a producer that is going to hand the same values out many times, which is what a stored
240    /// column is. It costs one `Arc` per layout and moves the run into it without touching a value,
241    /// and after it a write through any reader copies out rather than writing the page, which is
242    /// [`Buffer::to_mut`]. A run that is already a page comes back as it was.
243    #[must_use]
244    pub fn into_pages(self) -> Self {
245        macro_rules! paged {
246            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
247                match self {
248                    Self::Empty => Self::Empty,
249                    $(Self::$variant(values) => Self::$variant(values.into_page()),)+
250                }
251            };
252        }
253        crate::for_each_layout!(all, paged)
254    }
255
256    /// An integer at `index`, widened, for any of the signed integer layouts.
257    ///
258    /// Used by the decimal path, which needs the unscaled value out of whichever width the width
259    /// and scale picked, and by anything else that would otherwise repeat the same five arms.
260    #[must_use]
261    pub fn signed_at(&self, index: usize) -> Option<i128> {
262        macro_rules! widened {
263            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
264                match self {
265                    $(Self::$variant(v) => v.get(index).map(|&x| i128::from(x)),)+
266                    _ => None,
267                }
268            };
269        }
270        crate::for_each_layout!(signed, widened)
271    }
272
273    /// An unsigned integer at `index`, widened.
274    #[must_use]
275    pub fn unsigned_at(&self, index: usize) -> Option<u128> {
276        macro_rules! widened {
277            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
278                match self {
279                    $(Self::$variant(v) => v.get(index).map(|&x| u128::from(x)),)+
280                    _ => None,
281                }
282            };
283        }
284        crate::for_each_layout!(unsigned, widened)
285    }
286
287    /// The string at `index`, for a `Varlen`.
288    #[must_use]
289    pub fn str_at(&self, index: usize) -> Option<&str> {
290        match self {
291            Self::Varlen(column) => column.get(index),
292            _ => None,
293        }
294    }
295
296    /// The bytes at `index`, for a `Varlen`, whatever they are.
297    ///
298    /// What a `BLOB` reads through, since the bytes of one are not required to be text and
299    /// [`Self::str_at`] answers `None` for the ones that are not.
300    #[must_use]
301    pub fn bytes_at(&self, index: usize) -> Option<&[u8]> {
302        match self {
303            Self::Varlen(column) => column.bytes(index),
304            _ => None,
305        }
306    }
307}
308
309/// A type, a length, a validity representation and some data.
310#[derive(Debug, Clone, PartialEq)]
311pub struct Vector {
312    ty: LogicalType,
313    len: usize,
314    validity: Validity,
315    body: Body,
316}
317
318/// What the vector holds, which is what its form is decided by.
319#[derive(Debug, Clone, PartialEq)]
320enum Body {
321    Flat(Data),
322    Constant(Box<Value>),
323    Sequence {
324        start: i64,
325        step: i64,
326    },
327    /// The values are behind an `Arc` rather than a `Box` because slicing shares them.
328    ///
329    /// A dictionary vector is cut once per chunk and the dictionary itself is the same dictionary
330    /// every time, so a `Box` meant a copy of every value in it per cut. On the ClickBench columns
331    /// that are dictionary encoded the dictionary is larger than the chunk of codes pointing into
332    /// it, and copying it was ten percent of the cycles of reading the file.
333    ///
334    /// Nothing here mutates a dictionary in place, so sharing one is only ever a read, and the one
335    /// place that wants an owned copy of the values is [`compose`], which asks for one.
336    Dictionary {
337        codes: Vec<u32>,
338        values: Arc<Vector>,
339        stable: bool,
340    },
341    /// Integer codes of `width` bits each, packed end to end, each one an offset from `base`.
342    ///
343    /// Row `r` is the `width` bits starting at bit `(offset + r) * width`, read little end first, so
344    /// a code that straddles a word boundary has its low bits in the earlier word. `offset` is what
345    /// lets a cut of a packed column be free: the bits are not byte aligned, so a slice either
346    /// repacks or remembers where it starts, and remembering is one addition per read.
347    ///
348    /// The words are behind an `Arc` for the reason the dictionary's values are. A page is packed
349    /// once and cut into chunk sized pieces, and copying the words per cut would undo most of what
350    /// the packing saved.
351    Packed {
352        words: Arc<Vec<u64>>,
353        width: u32,
354        base: i128,
355        offset: usize,
356    },
357    /// The views of a string column, over an arena that other vectors are reading at the same time.
358    ///
359    /// The views are owned because a cut is a different run of views, and the arena is shared
360    /// because a cut is the same bytes. That split is the whole form: sixteen bytes a row move and
361    /// the payload does not, however many cuts a page is taken in.
362    ///
363    /// A row's bytes are found the same way [`StringColumn`] finds them, through
364    /// [`StringView::bytes_in`], so a short string never reads the arena at all and the two ways of
365    /// holding strings cannot answer a row differently.
366    Views {
367        views: Vec<StringView>,
368        arena: Arc<Buffer<u8>>,
369    },
370    /// Text owned by a storage source and fetched by position.
371    ExternalText {
372        source: Arc<dyn TextSource>,
373    },
374    /// The FSST codes of every row, end to end, with one symbol table over all of them.
375    ///
376    /// A span rather than a run of offsets, because a gather keeps this form and a gather puts the
377    /// rows in an order the codes are not in. Eight bytes a row either way, and the span is the one
378    /// that survives being permuted.
379    ///
380    /// The codes and the table are shared for the reason a dictionary's values are: one table is
381    /// trained per page and every chunk cut out of it points at the same one. A table is sixty five
382    /// thousand hash slots, so a table per chunk would cost more than the compression saves.
383    Coded {
384        codes: Arc<Vec<u8>>,
385        spans: Vec<(u32, u32)>,
386        table: Arc<SymbolTable>,
387    },
388    /// One value per run, with the row each run ends at, exclusive and increasing.
389    ///
390    /// Ends rather than lengths, because every reader of this wants to know which run holds a row
391    /// and ends answer that with a binary search while lengths answer it with a running total. The
392    /// two are the same information and only one of them is the one that gets asked for.
393    ///
394    /// The values are behind an `Arc` for the reason the dictionary's are: a page is cut into chunk
395    /// sized pieces and the values are the same values every time.
396    Runs {
397        ends: Vec<u32>,
398        values: Arc<Vector>,
399    },
400    /// One child vector holding every element of every row, and a start and a length per row.
401    ///
402    /// Start and length rather than the run of offsets Arrow carries, because offsets say where a
403    /// row ends by saying where the next one begins, and that is only true while the rows are in
404    /// order and none is skipped. A gather permutes the rows and a filter drops them, both of which
405    /// this form has to survive without copying the child, so each row says where its own elements
406    /// are and nothing is implied about its neighbour.
407    ///
408    /// The child is behind an `Arc` for the reason a dictionary's values are. A cut of a list column
409    /// is the entries and nothing else, so a page of lists taken in chunk sized pieces holds one
410    /// child however many pieces it is read in, and the elements outside the cut stay reachable but
411    /// unreferenced rather than being copied out.
412    ///
413    /// A null list and an empty list are different rows and this is where the difference lives. A
414    /// null is the validity mask at this level being false, the same as for any other type, and its
415    /// entry is `(start, 0)` and never read. An empty list is a valid row whose entry is `(start, 0)`
416    /// as well. So the entry alone does not say which one a row is, the mask does, which is the same
417    /// division of labour every other form here uses.
418    ///
419    /// A `MAP` is stored here too, with a [`Body::Fields`] child of `key` and `value`. Everything above
420    /// is true of it unchanged, which is the point of storing it this way: the cut, the gather and the
421    /// null rule are written once and a map inherits all three.
422    Nested {
423        entries: Vec<(u32, u32)>,
424        child: Arc<Vector>,
425    },
426    /// One child vector per field, in the order the type names them, each as long as this vector.
427    ///
428    /// No entries, which is the whole difference from [`Body::Nested`]. A list row is a run of
429    /// elements so it needs to say where its run is, and a struct row is one value per field so row
430    /// `r` of field `f` is position `r` of child `f` and there is nothing to record. That makes a cut
431    /// a cut of every child and a gather a gather of every child, both at the same positions, rather
432    /// than a rewrite of an index.
433    ///
434    /// The children are behind an `Arc` for the reason a dictionary's values are, and it pays off less
435    /// often here. A cut of a list column shares its child untouched because the entries carry the
436    /// range, and a cut of a struct column has to cut each child, so the sharing only survives the
437    /// cases where nothing moves. It is still worth having, because a struct of a hundred fields
438    /// handed between operators is a hundred pointers rather than a hundred columns.
439    ///
440    /// A null struct is the validity mask at this level being false and says nothing about the
441    /// children, which still hold whatever was put in them at that row. That is DuckDB's behaviour and
442    /// it is the reason this form cannot decide a row is null by looking down: the mask is the answer,
443    /// the same as it is for a list.
444    Fields {
445        children: Vec<Arc<Vector>>,
446    },
447}
448
449/// Random access to immutable text kept by a storage reader.
450pub trait TextSource: std::fmt::Debug + Send + Sync {
451    /// Number of values available.
452    fn len(&self) -> usize;
453    /// Whether this source has no values.
454    fn is_empty(&self) -> bool {
455        self.len() == 0
456    }
457    /// Bytes at one position, or no value when the position is outside the source.
458    fn bytes_at(&self, index: usize) -> Result<Option<&[u8]>>;
459    /// Byte length at one position without requiring the payload when the source has an index.
460    fn bytes_len_at(&self, index: usize) -> Result<Option<usize>> {
461        Ok(self.bytes_at(index)?.map(<[u8]>::len))
462    }
463    /// Resident bytes retained by this source.
464    fn footprint(&self) -> usize;
465    /// How many ranks this source's sorted value order has, when it has one.
466    ///
467    /// A rank is a position in the values sorted by their bytes, so rank zero is the smallest value
468    /// and rank `ranks() - 1` is the largest. A storage format that keeps a dictionary for a whole
469    /// column can afford to sort the distinct values once when it writes the file, and what that
470    /// buys is a binary search where a reader that only knows the values are distinct has to ask
471    /// every one of them whether it matches.
472    ///
473    /// `None` means the source does not know its order, which is the honest answer for anything
474    /// built in memory and for a file written before its format stored one. Nothing is allowed to
475    /// depend on this for correctness, only for speed.
476    ///
477    /// A source that answers with `Some` promises the ranks cover every value it has, and that
478    /// [`compare_rank`](Self::compare_rank) is consistent with an ordering in which the values are
479    /// strictly increasing. Strictly, which is to say the values are distinct, because what reads
480    /// this searches it, and a search of a run of equal values finds one of them rather than all of
481    /// them. A source that holds the same value twice must answer `None` here even though it could
482    /// sort itself perfectly well.
483    fn ranks(&self) -> Option<usize> {
484        None
485    }
486    /// How the value at `rank` compares against `wanted`.
487    ///
488    /// This is a method rather than a slice of positions the caller indexes because the answer is
489    /// the only thing a search wants, and a source that knows that can answer most probes without
490    /// reading a value at all. A file that stores the first few bytes of each value in rank order
491    /// settles every probe from those bytes except the ones where two values start the same way,
492    /// and the payload stays untouched. A caller handed positions instead would have to read a
493    /// value per probe, which for a dictionary of half a million entries spread over thirty
494    /// megabytes is a fresh block of the file every time.
495    ///
496    /// Only called for a rank below [`ranks`](Self::ranks), so the default is the error a source
497    /// that has no order should never be asked to produce.
498    fn compare_rank(&self, rank: usize, wanted: &[u8]) -> Result<Ordering> {
499        let _ = (rank, wanted);
500        Err(Error::internal("a text source without a sorted order was asked to compare a rank"))
501    }
502    /// The position of the value at `rank`, which is what a search returns once it has found one.
503    ///
504    /// Called about once per search rather than once per probe, so unlike
505    /// [`compare_rank`](Self::compare_rank) it is free to be the expensive one.
506    fn code_at_rank(&self, rank: usize) -> Result<u32> {
507        let _ = rank;
508        Err(Error::internal("a text source without a sorted order was asked for a rank"))
509    }
510    /// The rank of every value, in position order, when the source can hand the whole map over.
511    ///
512    /// This is [`code_at_rank`](Self::code_at_rank) turned round, and it is a separate method
513    /// because the two are wanted by opposite kinds of reader. A search wants one code out of a
514    /// rank and probes a handful of times, so it reads the order a block at a time and leaves the
515    /// rest alone. A min or a max over a grouped column wants a rank out of a code once per row,
516    /// and a walk of the order per row costs far more than reading the order once and turning it
517    /// round. What that buys is a comparison of two integers where the alternative is a fetch of
518    /// two strings out of a payload the size of the column.
519    ///
520    /// The slice is indexed by position and is as long as [`len`](Self::len), so a caller holding a
521    /// dictionary code indexes it directly.
522    ///
523    /// `None` from a source with no order, and from one with an order it would rather not invert.
524    /// Nothing depends on this for correctness, only for speed.
525    fn code_ranks(&self) -> Option<&[u32]> {
526        None
527    }
528    /// Whether another source presents the same values.
529    fn equal(&self, other: &dyn TextSource) -> bool {
530        self.len() == other.len()
531            && (0..self.len()).all(|index| {
532                matches!(
533                    (self.bytes_at(index), other.bytes_at(index)),
534                    (Ok(left), Ok(right)) if left == right
535                )
536            })
537    }
538}
539
540impl PartialEq for dyn TextSource {
541    fn eq(&self, other: &Self) -> bool {
542        self.equal(other)
543    }
544}
545
546impl Vector {
547    /// A flat vector of `data`, all valid.
548    ///
549    /// # Errors
550    ///
551    /// If the data's physical layout is not the one the type calls for. That check is here rather
552    /// than left to the caller because a vector whose type and layout disagree is a wrong answer
553    /// waiting to be read out, and it costs one comparison at construction to prevent.
554    pub fn flat(ty: LogicalType, data: Data) -> Result<Self> {
555        let len = data.len();
556        if !matches!(data, Data::Empty) && layout_of(&data) != ty.physical() {
557            return Err(Error::internal(format!(
558                "a {ty} vector cannot hold {:?} data",
559                layout_of(&data)
560            )));
561        }
562        Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Flat(data) })
563    }
564
565    /// A flat vector built from single values, with the nulls among them turning into validity.
566    ///
567    /// The slow way in, and the only way in that anything outside this crate has. It is what an
568    /// `INSERT`, a `VALUES` clause and a test build a column with, all of which arrive holding
569    /// values rather than a run of `i32`. Nothing on a scan path calls it: a scan produces a run of
570    /// data directly and hands it to [`Self::flat`].
571    ///
572    /// # Errors
573    ///
574    /// If a value is not one the type can hold, or if the type is one there is no vector for yet,
575    /// which today means `ARRAY` and `UNION`. A `LIST`, a `STRUCT` and a `MAP` are routed to their own
576    /// builders and come back built.
577    pub fn from_values(ty: LogicalType, values: &[Value]) -> Result<Self> {
578        match &ty {
579            LogicalType::List(element) => {
580                return Self::list_from_values(element.as_ref().clone(), values);
581            }
582            LogicalType::Struct(fields) => return Self::struct_from_values(fields, values),
583            LogicalType::Map(key, value) => {
584                return Self::map_from_values(key.as_ref().clone(), value.as_ref().clone(), values);
585            }
586            _ => {}
587        }
588        let mut data = empty_data_for(&ty)?;
589        for value in values {
590            push_value(&mut data, value)?;
591        }
592        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
593        Ok(Self { ty, len: values.len(), validity, body: Body::Flat(data) })
594    }
595
596    /// A list vector of `element`, built from one [`Value::List`] per row.
597    ///
598    /// The elements of every row go into one child vector end to end, so a row's elements are a
599    /// contiguous range of it and a row is a start and a length into it. That is what makes a cut of
600    /// this form the entries and nothing else.
601    ///
602    /// A null row contributes no elements and gets an entry of length zero, which is the same entry
603    /// an empty list gets. The two are told apart by the validity mask rather than by the entry, for
604    /// the reason written on [`Body::Nested`].
605    fn list_from_values(element: LogicalType, values: &[Value]) -> Result<Self> {
606        let mut flat = Vec::new();
607        let mut entries = Vec::with_capacity(values.len());
608        for value in values {
609            let start = u32::try_from(flat.len())
610                .map_err(|_| Error::internal("a list column with more than u32 elements in it"))?;
611            match value {
612                Value::Null => entries.push((start, 0)),
613                Value::List { values: held, .. } => {
614                    let len = u32::try_from(held.len())
615                        .map_err(|_| Error::internal("a list longer than u32"))?;
616                    flat.extend_from_slice(held);
617                    entries.push((start, len));
618                }
619                other => {
620                    return Err(Error::internal(format!(
621                        "{other:?} does not belong in a list vector"
622                    )));
623                }
624            }
625        }
626        // The element type is the column's rather than any one value's. A `Value::List` carries what
627        // it thinks it is empty of, and a column built from a row of `INTEGER[]` and a row of
628        // `[]::NULL[]` would otherwise take its type from whichever row came first.
629        let child = Self::from_values(element, &flat)?;
630        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
631        Ok(Self {
632            ty: LogicalType::list(child.ty.clone()),
633            len: values.len(),
634            validity,
635            body: Body::Nested { entries, child: Arc::new(child) },
636        })
637    }
638
639    /// A list vector over a child that already exists, one entry per row.
640    ///
641    /// What a scan and a list returning kernel build, both of which produce the elements in bulk and
642    /// then say which row each range belongs to. Every row is valid, since a caller with nulls to
643    /// record adds them with [`Self::with_validity`].
644    ///
645    /// # Errors
646    ///
647    /// If an entry runs past the end of the child, which would be a row that reads elements belonging
648    /// to nobody and is the one mistake this form makes easy.
649    pub fn list(entries: Vec<(u32, u32)>, child: Vector) -> Result<Self> {
650        let reach = child.len();
651        for &(start, len) in &entries {
652            if start as usize + len as usize > reach {
653                return Err(Error::internal(format!(
654                    "a list entry of {len} at {start} in a child of {reach}"
655                )));
656            }
657        }
658        Ok(Self {
659            ty: LogicalType::list(child.ty.clone()),
660            len: entries.len(),
661            validity: Validity::AllValid,
662            body: Body::Nested { entries, child: Arc::new(child) },
663        })
664    }
665
666    /// A struct vector of `fields`, built from one [`Value::Struct`] per row.
667    ///
668    /// One pass per field rather than one pass per row, because each field becomes its own child
669    /// vector and a child is built from a run of values of one type. So a struct of three fields over
670    /// a thousand rows is three calls to [`Self::from_values`] and not a thousand.
671    ///
672    /// The fields are matched by name and not by position. A `Value::Struct` carries its names, and a
673    /// caller that built one in a different order from the type's would otherwise get the values
674    /// silently transposed into the wrong columns, which is the kind of wrong answer that reads as
675    /// right. A row missing a field the type names is an error rather than a null for the same reason.
676    ///
677    /// A null row is a null in every child as well as a false bit in the mask here. [`Body::Fields`]
678    /// says a null struct is allowed to have readable children and that is about a struct built out of
679    /// children that already exist, where whatever is underneath is the caller's. Built from values
680    /// there is nothing underneath to keep, so the children get the null.
681    fn struct_from_values(fields: &[Field], values: &[Value]) -> Result<Self> {
682        let mut children = Vec::with_capacity(fields.len());
683        for field in fields {
684            let mut column = Vec::with_capacity(values.len());
685            for value in values {
686                column.push(match value {
687                    Value::Null => Value::Null,
688                    Value::Struct(held) => held
689                        .iter()
690                        .find(|(name, _)| *name == field.name)
691                        .map(|(_, held)| held.clone())
692                        .ok_or_else(|| {
693                            Error::internal(format!(
694                                "a struct row with no {} field in it",
695                                field.name
696                            ))
697                        })?,
698                    other => {
699                        return Err(Error::internal(format!(
700                            "{other:?} does not belong in a struct vector"
701                        )));
702                    }
703                });
704            }
705            children.push(Arc::new(Self::from_values(field.ty.clone(), &column)?));
706        }
707        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
708        Ok(Self {
709            ty: LogicalType::Struct(fields.to_vec()),
710            len: values.len(),
711            validity,
712            body: Body::Fields { children },
713        })
714    }
715
716    /// A struct vector over children that already exist, one per field.
717    ///
718    /// What a scan and a struct returning kernel build, both of which produce each field as a column
719    /// and then put them side by side. Every row is valid, since a caller with nulls to record adds
720    /// them with [`Self::with_validity`].
721    ///
722    /// # Errors
723    ///
724    /// If there are no fields, or if the children are not all the same length. The first is not a
725    /// fussy restriction: a struct vector with no children has no child to take its length from, so a
726    /// zero field struct column would be a length with nothing to check it against, and a caller that
727    /// wants a column of empty structs wants a constant vector of one.
728    pub fn structure(children: Vec<(String, Vector)>) -> Result<Self> {
729        let Some((_, first)) = children.first() else {
730            return Err(Error::internal("a struct vector of no fields, which has no length"));
731        };
732        let len = first.len();
733        for (name, child) in &children {
734            if child.len() != len {
735                return Err(Error::internal(format!(
736                    "a {} field of {} rows beside a struct of {len}",
737                    name,
738                    child.len()
739                )));
740            }
741        }
742        let fields = children
743            .iter()
744            .map(|(name, child)| Field::new(name.clone(), child.ty.clone()))
745            .collect();
746        let children = children.into_iter().map(|(_, child)| Arc::new(child)).collect();
747        Ok(Self {
748            ty: LogicalType::Struct(fields),
749            len,
750            validity: Validity::AllValid,
751            body: Body::Fields { children },
752        })
753    }
754
755    /// The children, for a struct vector, and `None` for any other form.
756    ///
757    /// The accessor a kernel over a struct column reads, and the reason field extraction is free:
758    /// picking one field out of a struct is picking one of these, so a projection of `s.a` hands back
759    /// a vector that already exists rather than reading a row at a time and rebuilding a column.
760    #[must_use]
761    pub fn struct_parts(&self) -> Option<&[Arc<Self>]> {
762        match &self.body {
763            Body::Fields { children } => Some(children),
764            _ => None,
765        }
766    }
767
768    /// A map vector, built from one [`Value::Map`] per row.
769    ///
770    /// A map is a list whose child is a two field struct of keys and values, which is what DuckDB
771    /// stores and what Arrow and Parquet store, so this is the list builder and the struct builder
772    /// composed rather than a third layout. The keys of every row go into one column end to end, the
773    /// values into another beside it, and a row is a start and a length into the pair.
774    ///
775    /// The field names are [`MAP_KEY`] and [`MAP_VALUE`] because those are the names DuckDB gives them
776    /// and the names anything reading a Parquet map field will expect to find.
777    ///
778    /// A null row and an empty map are both an entry of length zero, told apart by the validity mask,
779    /// for the reason written on [`Body::Nested`].
780    fn map_from_values(key: LogicalType, value: LogicalType, values: &[Value]) -> Result<Self> {
781        let mut keys = Vec::new();
782        let mut held = Vec::new();
783        let mut entries = Vec::with_capacity(values.len());
784        for row in values {
785            let start = u32::try_from(keys.len())
786                .map_err(|_| Error::internal("a map column with more than u32 entries in it"))?;
787            match row {
788                Value::Null => entries.push((start, 0)),
789                Value::Map { entries: pairs, .. } => {
790                    let len = u32::try_from(pairs.len())
791                        .map_err(|_| Error::internal("a map with more than u32 entries"))?;
792                    for (one, other) in pairs {
793                        keys.push(one.clone());
794                        held.push(other.clone());
795                    }
796                    entries.push((start, len));
797                }
798                other => {
799                    return Err(Error::internal(format!(
800                        "{other:?} does not belong in a map vector"
801                    )));
802                }
803            }
804        }
805        // The two types are the column's rather than any one row's, for the reason the list builder
806        // takes the element type from the column: a row that is the empty map carries whatever it was
807        // built as being empty of, and the column is not entitled to take its type from that.
808        let child = Self::structure(vec![
809            (MAP_KEY.to_string(), Self::from_values(key, &keys)?),
810            (MAP_VALUE.to_string(), Self::from_values(value, &held)?),
811        ])?;
812        let ty = LogicalType::map(
813            fields_of(&child.ty)[0].ty.clone(),
814            fields_of(&child.ty)[1].ty.clone(),
815        );
816        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
817        Ok(Self {
818            ty,
819            len: values.len(),
820            validity,
821            body: Body::Nested { entries, child: Arc::new(child) },
822        })
823    }
824
825    /// A map vector over a pair of columns that already exist, one entry per row.
826    ///
827    /// What a scan and a map returning kernel build. The keys and the values are two columns of the
828    /// same length, and each row of the map is the same range of both. Every row is valid, since a
829    /// caller with nulls to record adds them with [`Self::with_validity`].
830    ///
831    /// # Errors
832    ///
833    /// If the two columns are different lengths, or if an entry runs past the end of them.
834    pub fn map(entries: Vec<(u32, u32)>, keys: Vector, values: Vector) -> Result<Self> {
835        let key = keys.ty.clone();
836        let value = values.ty.clone();
837        let child =
838            Self::structure(vec![(MAP_KEY.to_string(), keys), (MAP_VALUE.to_string(), values)])?;
839        let mut vector = Self::list(entries, child)?;
840        vector.ty = LogicalType::map(key, value);
841        Ok(vector)
842    }
843
844    /// The entries and the two columns, for a map vector, and `None` for anything else.
845    ///
846    /// Reaches through the struct child that a map is stored as, so that a kernel over a map column
847    /// reads the keys and the values as the two columns they are rather than having to know that the
848    /// pair is spelled as a struct underneath.
849    #[must_use]
850    pub fn map_parts(&self) -> Option<MapParts<'_>> {
851        if !matches!(self.ty, LogicalType::Map(_, _)) {
852            return None;
853        }
854        let (entries, child) = self.list_parts()?;
855        let [keys, values] = child.struct_parts()? else { return None };
856        Some((entries, keys, values))
857    }
858
859    /// The entries and the child, for a list vector, and `None` for any other form.
860    ///
861    /// The accessor a kernel over a list column reads, for the reason
862    /// [`Self::dictionary_parts`] exists: `unnest` over 1024 rows wants the child once and the
863    /// entries once, and reading it through [`Self::value_at`] would build a `Value::List` per row
864    /// and then throw every one of them away.
865    ///
866    /// A map answers here as well, with the struct child it is stored as, because this is a question
867    /// about the layout and a map's layout is a list's. A caller that wants the keys and the values as
868    /// two columns wants [`Self::map_parts`], which reaches through that child.
869    #[must_use]
870    pub fn list_parts(&self) -> Option<(&[(u32, u32)], &Self)> {
871        match &self.body {
872            Body::Nested { entries, child } => Some((entries, child)),
873            _ => None,
874        }
875    }
876
877    /// A vector of `len` copies of one value.
878    ///
879    /// Costs one value regardless of the length, which is what makes a literal in a predicate free
880    /// and what makes a projection of a constant free.
881    #[must_use]
882    pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
883        let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
884        Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
885    }
886
887    /// A vector of `len` values starting at `start` and stepping by `step`.
888    ///
889    /// This is what a row identifier column is, and it costs sixteen bytes rather than eight
890    /// kilobytes. A scan that produces row ids for a later fetch produces one of these.
891    #[must_use]
892    pub fn sequence(start: i64, step: i64, len: usize) -> Self {
893        Self {
894            ty: LogicalType::BigInt,
895            len,
896            validity: Validity::AllValid,
897            body: Body::Sequence { start, step },
898        }
899    }
900
901    /// A vector of codes into a smaller vector of distinct values.
902    ///
903    /// The form the whole M3 thesis rests on. A dictionary vector handed to a group by is an
904    /// integer column, and an aggregate over one is an aggregate over integers no matter what the
905    /// logical type says.
906    ///
907    /// A dictionary over a dictionary is composed into one level here rather than left as two, so
908    /// the form has a depth of one always and a kernel that reads [`Self::dictionary_parts`] is
909    /// reading the values rather than another layer of codes. Two filters over the same chunk build
910    /// the second case and four conjuncts pushed down separately build four of it.
911    ///
912    /// The cost of leaving them stacked turned out to be a cliff rather than a slope. Every loop in
913    /// `rudb-kernels` reaches for the values behind the codes with [`Self::data`], a dictionary
914    /// pointing at a dictionary has no data to hand back, so the second level does not make the
915    /// kernels slower, it turns them off and drops the work onto the row at a time path that exists
916    /// to be correct rather than fast. Measured on server3 over a chunk of two numeric columns and a
917    /// consumer of two vectorized passes, one level reads at 3.5 nanoseconds a row and two levels at
918    /// 104, and the third and fourth levels cost almost nothing more because the first one had
919    /// already given up everything there was to give. Composing is one pass over the outer codes,
920    /// which the range check above is already making.
921    ///
922    /// The one dictionary that is not composed past is one carrying a validity of its own. A
923    /// dictionary is built all valid and only [`Self::with_validity`] can change that, so such a
924    /// vector is saying that its nulls are at this level rather than in the values it points at, and
925    /// composing past it would drop them.
926    ///
927    /// # Errors
928    ///
929    /// If any code is past the end of the value vector.
930    pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
931        Self::dictionary_over(codes, Arc::new(values))
932    }
933
934    /// The same, over a set of values somebody else is holding too.
935    ///
936    /// The body holds its values in an `Arc` either way, so a caller that already has one has
937    /// nothing to hand over but a pointer. The caller this is for is a Parquet chunk: one dictionary
938    /// page serves every data page of the chunk, and going through [`Self::dictionary`] meant
939    /// copying the whole dictionary into each page's vector on the way to putting it in an `Arc`
940    /// that then had a single holder. On a ClickBench scan that copy was sixteen percent of the
941    /// instructions the query ran.
942    ///
943    /// Composing a dictionary over a dictionary still needs the values by value, so that case takes
944    /// them out of the handle and copies if anybody else is still reading them. Nothing that shares
945    /// a dictionary builds a stacked one, so the two paths do not meet in practice.
946    ///
947    /// The range check takes the highest code rather than stopping at the first bad one. Stopping
948    /// early sounds cheaper and is not, because a loop that can exit anywhere cannot be vectorized
949    /// and a running maximum can, and the only run that would have exited early is the one about to
950    /// fail the query anyway. Every other run reads the whole of `codes` either way. It was 5.2
951    /// percent of a ClickBench scan as a `find`.
952    ///
953    /// # Errors
954    ///
955    /// If any code is past the end of the value vector.
956    pub fn dictionary_over(codes: Vec<u32>, values: Arc<Vector>) -> Result<Self> {
957        let highest = codes.iter().copied().fold(0, u32::max);
958        if !codes.is_empty() && highest as usize >= values.len() {
959            return Err(Error::internal(format!(
960                "dictionary code {highest} is past the end of a {} value dictionary",
961                values.len()
962            )));
963        }
964        let stacked = matches!(values.validity, Validity::AllValid)
965            && matches!(values.body, Body::Dictionary { .. });
966        let (codes, values) = if stacked {
967            let (codes, values) = compose(codes, Arc::unwrap_or_clone(values));
968            (codes, Arc::new(values))
969        } else {
970            (codes, values)
971        };
972        Ok(Self {
973            ty: values.ty.clone(),
974            len: codes.len(),
975            validity: Validity::AllValid,
976            body: Body::Dictionary { codes, values, stable: false },
977        })
978    }
979
980    /// A dictionary whose codes keep the same meaning across every page of its source.
981    pub fn stable_dictionary(codes: Vec<u32>, values: Arc<Vector>) -> Result<Self> {
982        let mut vector = Self::dictionary_over(codes, values)?;
983        if let Body::Dictionary { stable, .. } = &mut vector.body {
984            *stable = true;
985        }
986        Ok(vector)
987    }
988
989    /// A stable dictionary whose caller already found the largest code while decoding it.
990    pub fn stable_dictionary_validated(
991        codes: Vec<u32>,
992        values: Arc<Vector>,
993        highest: Option<u32>,
994    ) -> Result<Self> {
995        if highest.is_some_and(|code| code as usize >= values.len()) {
996            return Err(Error::internal("a stable dictionary code is past its value dictionary"));
997        }
998        Ok(Self {
999            ty: values.ty.clone(),
1000            len: codes.len(),
1001            validity: Validity::AllValid,
1002            body: Body::Dictionary { codes, values, stable: true },
1003        })
1004    }
1005
1006    /// A vector of runs, one value each, with the row each run ends at.
1007    ///
1008    /// `ends` is exclusive and strictly increasing, so run `i` covers the rows from `ends[i - 1]` to
1009    /// `ends[i]` and run zero starts at nothing. The length of the vector is the last end.
1010    ///
1011    /// The depth is one, the same way a dictionary's is, and for a sharper reason. Every kernel that
1012    /// wants runs wants the value of a run without another search, and a run length vector over a
1013    /// run length vector turns one search into two and then into three. Rather than compose, this
1014    /// refuses: nothing in the engine builds a stacked one, because [`Self::run_encoded`] only ever
1015    /// reads a flat body, so a stacked one is a caller doing something by hand and the useful answer
1016    /// is to say so rather than to quietly do a pass of work they did not ask for.
1017    ///
1018    /// A run over a dictionary is fine and is not that case. The two forms answer different
1019    /// questions and a column that is both clustered and low cardinality genuinely wants both.
1020    ///
1021    /// # Errors
1022    ///
1023    /// If there is not exactly one value per run, if the ends do not increase, or if the values are
1024    /// themselves run length encoded.
1025    pub fn runs(ends: Vec<u32>, values: Vector) -> Result<Self> {
1026        if matches!(values.body, Body::Runs { .. }) {
1027            return Err(Error::internal("runs of runs, which is two searches to read one row"));
1028        }
1029        if ends.len() != values.len() {
1030            return Err(Error::internal(format!(
1031                "{} runs and {} values to put in them",
1032                ends.len(),
1033                values.len()
1034            )));
1035        }
1036        if ends.windows(2).any(|pair| pair[0] >= pair[1]) || ends.first() == Some(&0) {
1037            return Err(Error::internal("run ends that do not increase"));
1038        }
1039        let len = ends.last().copied().unwrap_or(0) as usize;
1040        Ok(Self {
1041            ty: values.ty.clone(),
1042            len,
1043            validity: Validity::AllValid,
1044            body: Body::Runs { ends, values: Arc::new(values) },
1045        })
1046    }
1047
1048    /// The same values as runs, when there are few enough runs for that to be smaller.
1049    ///
1050    /// Costs one pass over the column to find out, which is why this is a call somebody makes rather
1051    /// than something a constructor does. The decision is the same arithmetic every time: a row in
1052    /// flat form costs one value, a run costs one value plus the four bytes of its end, so runs are
1053    /// smaller once there are fewer than about half as many runs as rows, and the narrower the
1054    /// column the more runs it takes. `RUNS_PAY_AT` is that ratio, written down rather than spelt
1055    /// into an `if`, because it is the number a sweep will want to move.
1056    ///
1057    /// Only a flat body is looked at. A constant and a sequence are already one value and two
1058    /// numbers, so there is nothing to win, and a dictionary that is also clustered is a real case
1059    /// that wants its codes run length encoded rather than its values, which is a different function
1060    /// and not this one.
1061    ///
1062    /// Two adjacent nulls are one run. Two adjacent equal values with a null between them are three,
1063    /// because the null is a value of the column as far as anything reading it is concerned.
1064    ///
1065    /// # Errors
1066    ///
1067    /// From the gather this does at the end, and nowhere else. A body that is not flat comes back
1068    /// unchanged rather than as an error, so a nested vector never reaches the part that can fail.
1069    pub fn run_encoded(&self) -> Result<Self> {
1070        let Body::Flat(data) = &self.body else {
1071            return Ok(self.clone());
1072        };
1073        let ends = boundaries(data, &self.validity, self.len);
1074        if ends.len().saturating_mul(RUNS_PAY_AT) >= self.len {
1075            return Ok(self.clone());
1076        }
1077        let starts: Vec<u32> =
1078            std::iter::once(0).chain(ends.iter().copied()).take(ends.len()).collect();
1079        Self::runs(ends, self.gather(&starts)?)
1080    }
1081
1082    /// A vector of `len` integers packed `width` bits each, every one an offset from `base`.
1083    ///
1084    /// The way in for a reader that already has the packed bits, which is what a column file holds
1085    /// and what a network frame carries. Nothing unpacks on the way in, so a scan of a packed column
1086    /// hands the bits straight to the chunk and the cost of the form is paid by whoever reads a
1087    /// value rather than by the scan.
1088    ///
1089    /// The range check is on the two ends rather than on every code, which is the whole check. A
1090    /// code is between zero and `2^width - 1` by construction, so if `base` and `base + 2^width - 1`
1091    /// both fit the column's layout then every value does, and that is two comparisons instead of
1092    /// one per row.
1093    ///
1094    /// # Errors
1095    ///
1096    /// If the type is not one of the integer layouts, if the width is not between one and
1097    /// [`PACKED_WIDTH_MAX`], if there are not enough words for the length, or if either end of the
1098    /// range would not fit the type.
1099    pub fn packed(
1100        ty: LogicalType,
1101        words: Vec<u64>,
1102        width: u32,
1103        base: i128,
1104        len: usize,
1105    ) -> Result<Self> {
1106        let Some((low, high)) = layout_range(&ty) else {
1107            return Err(Error::internal(format!("a {ty} vector has no integer layout to pack")));
1108        };
1109        if width == 0 || width > PACKED_WIDTH_MAX {
1110            return Err(Error::internal(format!(
1111                "a packed width of {width}, which is outside 1 to {PACKED_WIDTH_MAX}"
1112            )));
1113        }
1114        let needed = words_for(len, width);
1115        if words.len() < needed {
1116            return Err(Error::internal(format!(
1117                "{} words for {len} values of {width} bits, which needs {needed}",
1118                words.len()
1119            )));
1120        }
1121        let top = base + i128::from(u64::MAX >> (64 - width));
1122        if base < low || top > high {
1123            return Err(Error::internal(format!(
1124                "packed values from {base} to {top}, which a {ty} cannot hold"
1125            )));
1126        }
1127        Ok(Self {
1128            ty,
1129            len,
1130            validity: Validity::AllValid,
1131            body: Body::Packed { words: Arc::new(words), width, base, offset: 0 },
1132        })
1133    }
1134
1135    /// The same values bit packed, when the range of the column makes that smaller.
1136    ///
1137    /// Costs one pass to find the range and one to write the bits, which is why this is a call
1138    /// somebody makes rather than something a constructor does. It is the counterpart of
1139    /// [`Self::run_encoded`] and the decision has the same shape: a row flat costs the width of its
1140    /// layout, a row packed costs the bits the column's range needs, and the form is worth having
1141    /// only when the second is a good deal smaller than the first. [`PACKING_PAYS_AT`] is that
1142    /// ratio, written down rather than spelt into an `if`, because it is the number a sweep will
1143    /// want to move.
1144    ///
1145    /// Only a flat integer body is looked at. A constant and a sequence are already smaller than any
1146    /// packing of them, a dictionary's codes are the thing that would want packing rather than its
1147    /// values, and a float has no range to pack into since the bits of an `f64` are not an integer
1148    /// that arithmetic on the column agrees with.
1149    ///
1150    /// The range is taken over every slot including the null ones, which hold a zero. A column of
1151    /// large values with one null in it therefore packs a range that reaches down to zero and comes
1152    /// out wider than it needed to be. The alternative is a pass that consults the validity per slot
1153    /// to find the range and a second rule for what to write into a null slot, and this form exists
1154    /// to make reads cheap rather than to squeeze the last bit out of a sparse column.
1155    ///
1156    /// A column whose values are all the same packs to nothing at all, and rather than invent a zero
1157    /// bit code this declines and leaves it to [`Self::run_encoded`], which turns that column into
1158    /// one run and is smaller than any packing of it.
1159    ///
1160    /// # Errors
1161    ///
1162    /// If the packed bits and the length disagree, which would be a bug here rather than a caller
1163    /// doing something wrong.
1164    pub fn bit_packed(&self) -> Result<Self> {
1165        let Body::Flat(data) = &self.body else {
1166            return Ok(self.clone());
1167        };
1168        let Some((low, high)) = span_of(data, self.len) else {
1169            return Ok(self.clone());
1170        };
1171        let Some(range) = high.checked_sub(low).and_then(|range| u64::try_from(range).ok()) else {
1172            return Ok(self.clone());
1173        };
1174        let width = u64::BITS - range.leading_zeros();
1175        if width == 0 || width > PACKED_WIDTH_MAX {
1176            return Ok(self.clone());
1177        }
1178        if words_for(self.len, width) * size_of::<u64>() * PACKING_PAYS_AT > data.footprint() {
1179            return Ok(self.clone());
1180        }
1181        let words = pack(data, self.len, low, width);
1182        let packed = Self::packed(self.ty.clone(), words, width, low, self.len)?;
1183        Ok(packed.with_validity(self.validity.clone()))
1184    }
1185
1186    /// A vector of string views over an arena somebody else is holding too.
1187    ///
1188    /// The way in for a scan that has a page of strings and wants several chunks over it. Each chunk
1189    /// gets its own run of views and they all share the one arena, so the bytes are read where the
1190    /// page put them and nothing copies them.
1191    ///
1192    /// Every view is checked against the arena here rather than when a row is read. That is a pass
1193    /// over the views at construction, which is the same pass the caller just did to build them, and
1194    /// what it buys is that a row of this form cannot resolve to bytes that are not there. The check
1195    /// is on the offsets and not on the bytes, so it says nothing about whether the payload is text,
1196    /// which is the same promise a `BLOB` column makes.
1197    ///
1198    /// # Errors
1199    ///
1200    /// If the type is not one stored as views, or if a view points past the end of the arena.
1201    pub fn string_views(
1202        ty: LogicalType,
1203        views: Vec<StringView>,
1204        arena: Arc<Buffer<u8>>,
1205    ) -> Result<Self> {
1206        if ty.physical() != rudb_common::PhysicalType::Varlen {
1207            return Err(Error::internal(format!("a {ty} vector cannot hold string views")));
1208        }
1209        if views.iter().any(|view| view.bytes_in(&arena).is_none()) {
1210            return Err(Error::internal("a string view points past the end of its arena"));
1211        }
1212        let len = views.len();
1213        Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Views { views, arena } })
1214    }
1215
1216    /// A text vector whose values remain in a storage source until they are read.
1217    pub fn external_text(ty: LogicalType, source: Arc<dyn TextSource>) -> Result<Self> {
1218        if ty.physical() != rudb_common::PhysicalType::Varlen {
1219            return Err(Error::internal(format!(
1220                "a {ty} vector cannot use an external text source"
1221            )));
1222        }
1223        let len = source.len();
1224        Ok(Self { ty, len, validity: Validity::AllValid, body: Body::ExternalText { source } })
1225    }
1226
1227    /// The same strings, in a form where a cut of them does not copy the bytes.
1228    ///
1229    /// The counterpart of [`Self::run_encoded`] and [`Self::bit_packed`] for a string column, and
1230    /// the only one of the three that takes `self` by value. It has to: what it does is move the
1231    /// arena into an `Arc` so nothing copies it again, and a version taking `&self` would start by
1232    /// copying the arena once to have one to move.
1233    ///
1234    /// Anything that is not a flat string column comes back as it was, which includes a column that
1235    /// is already in this form.
1236    ///
1237    /// # Errors
1238    ///
1239    /// Nothing here fails today. The result is a `Result` because the check inside
1240    /// [`Self::string_views`] is worth running on the views this builds rather than trusting that
1241    /// this function built them right.
1242    pub fn shared_text(self) -> Result<Self> {
1243        let Body::Flat(Data::Varlen(column)) = self.body else {
1244            return Ok(self);
1245        };
1246        let (views, arena) = column.into_parts();
1247        let shared = Self::string_views(self.ty, views, Arc::new(arena))?;
1248        Ok(shared.with_validity(self.validity))
1249    }
1250
1251    /// A vector of FSST codes against a table somebody else trained.
1252    ///
1253    /// The way in for a reader that has a page of compressed strings and the table that goes with
1254    /// it. The codes are not copied and the table is not retrained, so laying several chunks over
1255    /// one page costs the spans and nothing else.
1256    ///
1257    /// # Errors
1258    ///
1259    /// If the type is not one stored as text, or if a span runs past the end of the codes.
1260    pub fn coded(
1261        ty: LogicalType,
1262        codes: Arc<Vec<u8>>,
1263        spans: Vec<(u32, u32)>,
1264        table: Arc<SymbolTable>,
1265    ) -> Result<Self> {
1266        if ty.physical() != rudb_common::PhysicalType::Varlen {
1267            return Err(Error::internal(format!("a {ty} vector cannot hold FSST codes")));
1268        }
1269        let end = u32::try_from(codes.len()).unwrap_or(u32::MAX);
1270        if spans.iter().any(|&(from, to)| from > to || to > end) {
1271            return Err(Error::internal("an FSST span runs past the end of the codes"));
1272        }
1273        let len = spans.len();
1274        Ok(Self {
1275            ty,
1276            len,
1277            validity: Validity::AllValid,
1278            body: Body::Coded { codes, spans, table },
1279        })
1280    }
1281
1282    /// The same strings, compressed against a table trained on them.
1283    ///
1284    /// The counterpart of [`Self::run_encoded`] and [`Self::bit_packed`] for a text column, and it
1285    /// takes `self` by value for the reason [`Self::shared_text`] does.
1286    ///
1287    /// The table is trained on every row rather than on a sample. A vector is at most 1024 rows, so
1288    /// the sample would be most of the column anyway, and the systematic sampling
1289    /// `spec/06-compression.md` section 6.3 asks for is a decision about a page and belongs to
1290    /// whoever is holding one.
1291    ///
1292    /// It declines unless the codes are at most half the bytes the strings are. FSST gets about that
1293    /// on text and rather less on anything already short or already random, and below that the
1294    /// decompression per row read is not bought back. A column it declines on comes back as it was.
1295    ///
1296    /// # Errors
1297    ///
1298    /// Nothing here fails today. The result is a `Result` because the checks inside [`Self::coded`]
1299    /// are worth running on what this builds rather than trusting that this built it right.
1300    pub fn compressed(self) -> Result<Self> {
1301        let Body::Flat(Data::Varlen(column)) = &self.body else {
1302            return Ok(self);
1303        };
1304        let rows: Vec<&[u8]> = (0..self.len).filter_map(|row| column.bytes(row)).collect();
1305        if rows.len() != self.len {
1306            return Ok(self);
1307        }
1308        let plain: usize = rows.iter().map(|row| row.len()).sum();
1309        let table = SymbolTable::train(&rows);
1310        let mut codes = Vec::with_capacity(plain);
1311        let mut spans = Vec::with_capacity(self.len);
1312        for row in &rows {
1313            let from = u32::try_from(codes.len()).unwrap_or(u32::MAX);
1314            table.compress(row, &mut codes);
1315            spans.push((from, u32::try_from(codes.len()).unwrap_or(u32::MAX)));
1316        }
1317        if codes.len() * FSST_PAYS_AT > plain {
1318            return Ok(self);
1319        }
1320        let coded = Self::coded(self.ty.clone(), Arc::new(codes), spans, Arc::new(table))?;
1321        Ok(coded.with_validity(self.validity.clone()))
1322    }
1323
1324    /// The same vector with a different validity.
1325    #[must_use]
1326    pub fn with_validity(mut self, validity: Validity) -> Self {
1327        self.validity = validity;
1328        self
1329    }
1330
1331    /// What kind of values these are.
1332    #[must_use]
1333    pub fn logical_type(&self) -> &LogicalType {
1334        &self.ty
1335    }
1336
1337    /// How many values there are.
1338    #[must_use]
1339    pub fn len(&self) -> usize {
1340        self.len
1341    }
1342
1343    /// Whether there are no values.
1344    #[must_use]
1345    pub fn is_empty(&self) -> bool {
1346        self.len == 0
1347    }
1348
1349    /// How many bytes of memory this vector is holding.
1350    ///
1351    /// What the memory limit charges for it. A constant and a sequence hold one value and two
1352    /// numbers however long they are, which is the point of both forms, so the number here is the
1353    /// form's cost and not the column's width times its length.
1354    ///
1355    /// A dictionary counts its values in full, and two vectors sharing one dictionary each report
1356    /// all of it. That over counts, deliberately: working out that two operators are looking at the
1357    /// same `Arc` means threading identity through the accounting, and a limit that over counts
1358    /// refuses a query that would have fit while a limit that under counts lets one through that
1359    /// does not. The first is a worse answer to give and the second is a worse thing to be.
1360    #[must_use]
1361    pub fn footprint(&self) -> usize {
1362        let body = match &self.body {
1363            Body::Flat(data) => data.footprint(),
1364            Body::Constant(value) => value.footprint(),
1365            Body::Sequence { .. } => 0,
1366            Body::Dictionary { codes, values, .. } => {
1367                codes.capacity() * size_of::<u32>() + values.footprint()
1368            }
1369            Body::Packed { words, .. } => words.capacity() * size_of::<u64>(),
1370            // The arena counts in full in every vector sharing it, for the reason a shared
1371            // dictionary does: over counting refuses a query that would have fit and under counting
1372            // admits one that does not, and the first is the better way to be wrong.
1373            Body::Views { views, arena } => {
1374                views.capacity() * size_of::<StringView>() + arena.footprint()
1375            }
1376            Body::ExternalText { source } => source.footprint(),
1377            // The table counts in full in every vector sharing it, the way a shared arena and a
1378            // shared dictionary do. It is the largest of the three and the most shared of them, so
1379            // this is the one place the over counting is worth saying out loud: a page of a hundred
1380            // chunks reports its table a hundred times.
1381            Body::Coded { codes, spans, table } => {
1382                codes.capacity() + spans.capacity() * size_of::<(u32, u32)>() + table.footprint()
1383            }
1384            Body::Runs { ends, values } => ends.capacity() * size_of::<u32>() + values.footprint(),
1385            // The child counts in full in every vector sharing it, the way a shared dictionary and a
1386            // shared arena do, and for the same reason.
1387            Body::Nested { entries, child } => {
1388                entries.capacity() * size_of::<(u32, u32)>() + child.footprint()
1389            }
1390            // Every child in full, the way the list child counts. A struct is as wide as its fields
1391            // are, so this is the one body whose cost is a sum over children rather than one number,
1392            // and a struct of a hundred narrow fields costs what the hundred columns cost.
1393            Body::Fields { children } => {
1394                children.capacity() * size_of::<Arc<Self>>()
1395                    + children.iter().map(|child| child.footprint()).sum::<usize>()
1396            }
1397        };
1398        size_of::<Self>() + self.validity.footprint() + body
1399    }
1400
1401    /// Which of the values are not null, at this level and no deeper.
1402    ///
1403    /// This is not the same question as [`Self::is_null_at`] and the difference has already cost
1404    /// one wrong answer. A dictionary and a run length vector keep their nulls in the values they
1405    /// point at rather than in a mask of their own, so both are built with every row marked present
1406    /// here and a row whose value is null reads as valid. A caller that wants to know whether a row
1407    /// is null wants the other one. A caller that wants the mask of a flat column, to copy it or to
1408    /// count it, wants this one.
1409    #[must_use]
1410    pub fn validity(&self) -> &Validity {
1411        &self.validity
1412    }
1413
1414    /// Whether the row at `index` is null, in whichever form the vector is in.
1415    ///
1416    /// Reads through a dictionary or a run to the value it stands for, which is where those two
1417    /// forms keep their nulls, and answers from the mask for every other form. A row past the end
1418    /// is null, the same answer [`Self::value_at`] gives it.
1419    #[must_use]
1420    pub fn is_null_at(&self, index: usize) -> bool {
1421        if index >= self.len || !self.validity.is_valid(index) {
1422            return true;
1423        }
1424        match &self.body {
1425            Body::Dictionary { codes, values, .. } => match codes.get(index) {
1426                Some(&code) => values.is_null_at(code as usize),
1427                None => true,
1428            },
1429            Body::Runs { ends, values } => match run_holding(ends, index) {
1430                Some(run) => values.is_null_at(run),
1431                None => true,
1432            },
1433            _ => false,
1434        }
1435    }
1436
1437    /// Which physical form this vector is in.
1438    #[must_use]
1439    pub fn form(&self) -> Form {
1440        match self.body {
1441            Body::Flat(_) => Form::Flat,
1442            Body::Constant(_) => Form::Constant,
1443            Body::Sequence { .. } => Form::Sequence,
1444            Body::Dictionary { .. } => Form::Dictionary,
1445            Body::Packed { .. } => Form::BitPacked,
1446            Body::Views { .. } => Form::StringView,
1447            Body::ExternalText { .. } => Form::StringView,
1448            Body::Coded { .. } => Form::Fsst,
1449            Body::Runs { .. } => Form::Rle,
1450            Body::Nested { .. } => Form::List,
1451            Body::Fields { .. } => Form::Struct,
1452        }
1453    }
1454
1455    /// The data, for a flat vector, and `None` for any other form.
1456    ///
1457    /// A kernel that wants a slice asks for it and takes the flat path if it gets one. A kernel
1458    /// that can do better on a constant or a dictionary checks [`Self::form`] first.
1459    #[must_use]
1460    pub fn data(&self) -> Option<&Data> {
1461        match &self.body {
1462            Body::Flat(data) => Some(data),
1463            _ => None,
1464        }
1465    }
1466
1467    /// The one value, for a constant vector, and `None` for any other form.
1468    ///
1469    /// A kernel comparing a column against a literal wants the literal once rather than 1024
1470    /// times, and [`Self::value_at`] on a constant clones it on every call because it has to be
1471    /// able to hand back a `Value` for any form. This is the accessor that lets the specialized
1472    /// path hoist the clone out of the loop.
1473    #[must_use]
1474    pub fn constant_value(&self) -> Option<&Value> {
1475        match &self.body {
1476            Body::Constant(value) => Some(value.as_ref()),
1477            _ => None,
1478        }
1479    }
1480
1481    /// The codes and the values, for a dictionary vector, and `None` for any other form.
1482    ///
1483    /// The reason a kernel needs this rather than reading the dictionary through
1484    /// [`Self::value_at`] is the entire argument for the form existing. A filter against a
1485    /// dictionary column of 1024 rows and 40 distinct values is 40 comparisons and 1024 lookups,
1486    /// not 1024 comparisons, and there is no way to write that loop without seeing the codes.
1487    ///
1488    /// Note what the validity of the returned vector means. A dictionary keeps its nulls in the
1489    /// vector it points at, and the dictionary's own validity says nothing about them, so a caller
1490    /// deciding whether row `i` is null has to ask the value vector about `codes[i]` rather than
1491    /// asking this vector about `i`. [`Self::flatten`] has the same note on it for the same
1492    /// reason, because getting this wrong is a null that survives being selected and comes out as
1493    /// a zero.
1494    #[must_use]
1495    pub fn dictionary_parts(&self) -> Option<(&[u32], &Self)> {
1496        match &self.body {
1497            Body::Dictionary { codes, values, .. } => Some((codes, values.as_ref())),
1498            _ => None,
1499        }
1500    }
1501
1502    /// The codes and the shared dictionary handle for a dictionary vector.
1503    ///
1504    /// Storage readers use the identity of this handle to prove that codes from separate pages
1505    /// belong to one table-wide dictionary. Kernels that only read values should continue to use
1506    /// [`Self::dictionary_parts`].
1507    #[must_use]
1508    pub fn shared_dictionary_parts(&self) -> Option<(&[u32], &Arc<Self>)> {
1509        match &self.body {
1510            Body::Dictionary { codes, values, .. } => Some((codes, values)),
1511            _ => None,
1512        }
1513    }
1514
1515    /// Stable codes and their shared values, when storage guarantees one code space across pages.
1516    #[must_use]
1517    pub fn stable_dictionary_parts(&self) -> Option<(&[u32], &Arc<Self>)> {
1518        match &self.body {
1519            Body::Dictionary { codes, values, stable: true } => Some((codes, values)),
1520            _ => None,
1521        }
1522    }
1523
1524    /// The run ends and the run values, for a run length vector, and `None` for any other form.
1525    ///
1526    /// The ends are exclusive and increasing, and there is exactly one value per run, so a kernel
1527    /// that wants to walk this walks the pairs and never asks which run a row is in. That is the
1528    /// whole argument for the form: an aggregate over a clustered column is one multiply per run
1529    /// instead of one add per row, and there is no way to write that loop without seeing the ends.
1530    ///
1531    /// The nulls are in the values, the way a dictionary's are, so a caller deciding whether row `i`
1532    /// is null asks the value vector about the run rather than asking this vector about `i`.
1533    #[must_use]
1534    pub fn run_parts(&self) -> Option<(&[u32], &Self)> {
1535        match &self.body {
1536            Body::Runs { ends, values } => Some((ends, values.as_ref())),
1537            _ => None,
1538        }
1539    }
1540
1541    /// Where each row's value is, for the two forms that keep their values somewhere else.
1542    ///
1543    /// A dictionary and a run length vector are the same shape seen from a kernel: a run of
1544    /// positions and a vector to read them out of. The difference is that a dictionary stores the
1545    /// positions and a run length vector works them out, and a kernel writing `values[at[row]]` does
1546    /// not care which. So every specialization written against [`Self::dictionary_parts`] covers
1547    /// both forms by asking this instead, and the day a third form with an indirection arrives it
1548    /// covers that one too without any of those kernels being reopened.
1549    ///
1550    /// The run length side costs an allocation of one position per row and a pass to fill it, which
1551    /// is the same four bytes a row a dictionary was already carrying and is paid once per kernel
1552    /// call rather than once per row. That is the price of this being one accessor rather than a
1553    /// second arm in eighteen kernels, and it is not the last word: a kernel that wants a run at a
1554    /// time reads [`Self::run_parts`] and pays nothing, which is the specialization this makes it
1555    /// possible to skip writing until a sweep says it is worth it.
1556    #[must_use]
1557    pub fn positions(&self) -> Option<(Cow<'_, [u32]>, &Self)> {
1558        match &self.body {
1559            Body::Dictionary { codes, values, .. } => Some((Cow::Borrowed(codes), values.as_ref())),
1560            Body::Runs { ends, values } => {
1561                let mut at = Vec::with_capacity(self.len);
1562                for (run, &stop) in ends.iter().enumerate() {
1563                    let run = u32::try_from(run).unwrap_or(u32::MAX);
1564                    at.resize(stop as usize, run);
1565                }
1566                Some((Cow::Owned(at), values.as_ref()))
1567            }
1568            _ => None,
1569        }
1570    }
1571
1572    /// The bits and what they mean, for a bit packed vector, and `None` for any other form.
1573    ///
1574    /// What a kernel needs to stay in code space. A comparison against a literal is the case that
1575    /// pays: `column > 900` over a column packed from a base of 40 is `code > 860`, which is the
1576    /// same shift and mask the read was going to do anyway and no unpacking at all, and a literal
1577    /// outside the packed range answers the whole vector without reading a bit of it. None of that
1578    /// can be written without seeing the width and the base.
1579    #[must_use]
1580    pub fn packed_parts(&self) -> Option<Packed<'_>> {
1581        match &self.body {
1582            Body::Packed { words, width, base, offset } => {
1583                Some(Packed { words, width: *width, base: *base, offset: *offset })
1584            }
1585            _ => None,
1586        }
1587    }
1588
1589    /// The views and the arena, for either form that stores strings, and `None` for the rest.
1590    ///
1591    /// This is to the two string forms what [`Self::positions`] is to the two forms that point
1592    /// somewhere else. A flat varchar column owns its arena and a string view column shares one, and
1593    /// a kernel reading a row wants the view and the bytes either way, so every specialization
1594    /// written against this covers both forms and neither has to be reopened when a third way of
1595    /// holding an arena arrives.
1596    ///
1597    /// The arena is whatever the long strings live in, which for a column over a page is the page,
1598    /// including the parts of it no view points at. Only the views say which bytes are a row.
1599    #[must_use]
1600    pub fn text_parts(&self) -> Option<(&[StringView], &[u8])> {
1601        match &self.body {
1602            Body::Flat(Data::Varlen(column)) => Some((column.views(), column.arena())),
1603            Body::Views { views, arena } => Some((views, arena)),
1604            _ => None,
1605        }
1606    }
1607
1608    /// The codes and the table, for an FSST vector, and `None` for any other form.
1609    ///
1610    /// What a kernel needs to stay in code space. An equality filter is the case that pays, and it
1611    /// pays completely: the literal is compressed once against the same table and after that a row
1612    /// matches exactly when its code bytes match, because compressing is a function and so is
1613    /// decompressing. No row is decompressed at all. An ordering comparison cannot do that, since a
1614    /// symbol code says nothing about where its symbol sorts, so those decompress and say so.
1615    #[must_use]
1616    pub fn coded_parts(&self) -> Option<Coded<'_>> {
1617        match &self.body {
1618            Body::Coded { codes, spans, table } => Some(Coded { codes, spans, table }),
1619            _ => None,
1620        }
1621    }
1622
1623    /// The start and the step, for a sequence vector, and `None` for any other form.
1624    #[must_use]
1625    pub fn sequence_parts(&self) -> Option<(i64, i64)> {
1626        match self.body {
1627            Body::Sequence { start, step } => Some((start, step)),
1628            _ => None,
1629        }
1630    }
1631
1632    /// The value at `index`, as a single value.
1633    ///
1634    /// This is the slow path on purpose. It is what a result set is read out with and what a test
1635    /// asserts on, and an operator that calls it per row is an operator that has already lost the
1636    /// argument the vector interface exists to win.
1637    #[must_use]
1638    pub fn value_at(&self, index: usize) -> Value {
1639        if index >= self.len || !self.validity.is_valid(index) {
1640            return Value::Null;
1641        }
1642        match &self.body {
1643            Body::Constant(value) => value.as_ref().clone(),
1644            Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
1645            Body::Dictionary { codes, values, .. } => match codes.get(index) {
1646                Some(&code) => values.value_at(code as usize),
1647                None => Value::Null,
1648            },
1649            Body::Runs { ends, values } => match run_holding(ends, index) {
1650                Some(run) => values.value_at(run),
1651                None => Value::Null,
1652            },
1653            // One value unpacked into a run of one, so that what a packed value means is decided in
1654            // the same place a flat one is rather than in a second copy of the type mapping that
1655            // could drift from it. It allocates, which this path is allowed to do and the typed
1656            // unpack in `copied` is not, and it is the reason anything about to read a packed
1657            // column a row at a time should flatten it once instead.
1658            Body::Packed { words, width, base, offset } => {
1659                unpack(&self.ty, words, *offset, *width, *base, &[index])
1660                    .map_or(Value::Null, |data| value_from(&self.ty, &data, 0))
1661            }
1662            // The bytes are where the arena has them, and what they are read as is the logical
1663            // type's business, so this hands the row to the same reader a flat column goes through
1664            // rather than deciding here that a `BLOB` is a string.
1665            Body::Views { views, arena } => {
1666                match views.get(index).and_then(|v| v.bytes_in(arena)) {
1667                    Some(bytes) => bytes_as(&self.ty, bytes),
1668                    None => Value::Null,
1669                }
1670            }
1671            Body::ExternalText { source } => source
1672                .bytes_at(index)
1673                .ok()
1674                .flatten()
1675                .map_or(Value::Null, |bytes| bytes_as(&self.ty, bytes)),
1676            // One row decompressed on its own, which is the property the form is chosen for. It
1677            // allocates, which this path is allowed to do, and it is the reason anything about to
1678            // read a compressed column a row at a time should flatten it once instead.
1679            Body::Coded { codes, spans, table } => {
1680                match spans.get(index).and_then(|&(from, to)| {
1681                    let mut out = Vec::new();
1682                    table.decompress(codes.get(from as usize..to as usize)?, &mut out).ok()?;
1683                    Some(out)
1684                }) {
1685                    Some(bytes) => bytes_as(&self.ty, &bytes),
1686                    None => Value::Null,
1687                }
1688            }
1689            // A row's elements are read out of the child one at a time, which is the slow path this
1690            // whole function is and is why a kernel over a list column reads `list_parts` instead.
1691            // The element type comes from the child rather than from this vector's type, so a list
1692            // whose child was built narrower than the column claims still hands back what is in it.
1693            //
1694            // A map is stored in this body too, so which value comes out is decided by the logical
1695            // type rather than by the body. That is the one place the composition shows: the bytes of
1696            // a map really are the bytes of a list of two field structs, and the only thing that
1697            // remembers it is a map is the type.
1698            Body::Nested { entries, child } => match (entries.get(index), &self.ty) {
1699                (Some(&(start, len)), LogicalType::Map(key, value)) => {
1700                    let pairs = child.struct_parts().unwrap_or_default();
1701                    Value::map(
1702                        key.as_ref().clone(),
1703                        value.as_ref().clone(),
1704                        (start..start + len)
1705                            .filter_map(|at| {
1706                                let [keys, values] = pairs else { return None };
1707                                Some((keys.value_at(at as usize), values.value_at(at as usize)))
1708                            })
1709                            .collect(),
1710                    )
1711                }
1712                (Some(&(start, len)), _) => Value::List {
1713                    element: child.ty.clone(),
1714                    values: (start..start + len).map(|at| child.value_at(at as usize)).collect(),
1715                },
1716                (None, _) => Value::Null,
1717            },
1718            // One value read out of each child at the same position, which is the slow path this whole
1719            // function is and is why a kernel over a struct column reads `struct_parts` instead. The
1720            // names come from this vector's type rather than from the children, because a child is a
1721            // vector and a vector has no name, and the type is where the field order is written down.
1722            Body::Fields { children } => Value::Struct(
1723                fields_of(&self.ty)
1724                    .iter()
1725                    .zip(children)
1726                    .map(|(field, child)| (field.name.clone(), child.value_at(index)))
1727                    .collect(),
1728            ),
1729            Body::Flat(data) => value_from(&self.ty, data, index),
1730        }
1731    }
1732
1733    /// The value at `index`, preserving storage read and validation failures.
1734    pub fn try_value_at(&self, index: usize) -> Result<Value> {
1735        if index >= self.len || !self.validity.is_valid(index) {
1736            return Ok(Value::Null);
1737        }
1738        match &self.body {
1739            Body::ExternalText { source } => {
1740                Ok(source.bytes_at(index)?.map_or(Value::Null, |bytes| bytes_as(&self.ty, bytes)))
1741            }
1742            Body::Dictionary { codes, values, .. } => match codes.get(index) {
1743                Some(&code) => values.try_value_at(code as usize),
1744                None => Ok(Value::Null),
1745            },
1746            Body::Runs { ends, values } => match run_holding(ends, index) {
1747                Some(run) => values.try_value_at(run),
1748                None => Ok(Value::Null),
1749            },
1750            Body::Nested { entries, child } => match (entries.get(index), &self.ty) {
1751                (Some(&(start, len)), LogicalType::Map(key, value)) => {
1752                    let pairs = child.struct_parts().unwrap_or_default();
1753                    let [keys, values] = pairs else { return Ok(Value::Null) };
1754                    let mut entries = Vec::with_capacity(len as usize);
1755                    for at in start..start + len {
1756                        entries.push((
1757                            keys.try_value_at(at as usize)?,
1758                            values.try_value_at(at as usize)?,
1759                        ));
1760                    }
1761                    Ok(Value::map(key.as_ref().clone(), value.as_ref().clone(), entries))
1762                }
1763                (Some(&(start, len)), _) => {
1764                    let mut values = Vec::with_capacity(len as usize);
1765                    for at in start..start + len {
1766                        values.push(child.try_value_at(at as usize)?);
1767                    }
1768                    Ok(Value::List { element: child.ty.clone(), values })
1769                }
1770                (None, _) => Ok(Value::Null),
1771            },
1772            Body::Fields { children } => {
1773                let mut values = Vec::with_capacity(children.len());
1774                for (field, child) in fields_of(&self.ty).iter().zip(children) {
1775                    values.push((field.name.clone(), child.try_value_at(index)?));
1776                }
1777                Ok(Value::Struct(values))
1778            }
1779            _ => Ok(self.value_at(index)),
1780        }
1781    }
1782
1783    /// The text at `index`, borrowed rather than copied.
1784    ///
1785    /// [`Self::value_at`] on a `VARCHAR` column allocates a `String` per call, and a group by that
1786    /// reads a string column keys on one string per input row. This hands back the bytes where they
1787    /// already are, so a caller with somewhere to put them does not go to the allocator at all.
1788    ///
1789    /// `None` for a null, for an index past the end, for a column that is not `VARCHAR`, and for the
1790    /// constant and sequence forms, whose values are not stored per position. A caller that gets
1791    /// `None` has to fall back to [`Self::value_at`], which is correct for all of those.
1792    #[must_use]
1793    pub fn text_at(&self, index: usize) -> Option<&str> {
1794        if self.ty != LogicalType::Varchar || index >= self.len || !self.validity.is_valid(index) {
1795            return None;
1796        }
1797        match &self.body {
1798            Body::Flat(data) => data.str_at(index),
1799            Body::Dictionary { codes, values, .. } => {
1800                values.text_at(usize::try_from(*codes.get(index)?).ok()?)
1801            }
1802            Body::Runs { ends, values } => values.text_at(run_holding(ends, index)?),
1803            Body::Views { views, arena } => {
1804                std::str::from_utf8(views.get(index)?.bytes_in(arena)?).ok()
1805            }
1806            Body::ExternalText { source } => {
1807                std::str::from_utf8(source.bytes_at(index).ok().flatten()?).ok()
1808            }
1809            _ => None,
1810        }
1811    }
1812
1813    /// The variable length bytes at `index`, borrowed without validating or copying them.
1814    ///
1815    /// String data is validated when it enters a vector. Hashing and equality only need its bytes,
1816    /// so those kernels should not pay for UTF-8 validation again on every read.
1817    #[must_use]
1818    pub fn bytes_at(&self, index: usize) -> Option<&[u8]> {
1819        if index >= self.len || !self.validity.is_valid(index) {
1820            return None;
1821        }
1822        match &self.body {
1823            Body::Constant(value) => match value.as_ref() {
1824                Value::Varchar(text) => Some(text.as_bytes()),
1825                Value::Blob(bytes) => Some(bytes),
1826                _ => None,
1827            },
1828            Body::Dictionary { codes, values, .. } => {
1829                values.bytes_at(usize::try_from(*codes.get(index)?).ok()?)
1830            }
1831            Body::Runs { ends, values } => values.bytes_at(run_holding(ends, index)?),
1832            Body::Views { views, arena } => views.get(index)?.bytes_in(arena),
1833            Body::ExternalText { source } => source.bytes_at(index).ok().flatten(),
1834            Body::Flat(data) => data.bytes_at(index),
1835            // The same `None` [`Self::text_at`] gives, for the same reason. A compressed row is not
1836            // anywhere in its plain bytes, so there is nothing here to hand back a borrow of, and a
1837            // caller that gets `None` goes to `value_at` and gets the row decompressed into a value.
1838            // A list row is `None` for a nearer reason: it is not bytes at all, and a caller wanting
1839            // its elements wants [`Self::list_parts`] rather than a borrow of one row.
1840            Body::Coded { .. }
1841            | Body::Sequence { .. }
1842            | Body::Packed { .. }
1843            | Body::Nested { .. }
1844            | Body::Fields { .. } => None,
1845        }
1846    }
1847
1848    /// Variable length bytes at `index`, preserving storage read and validation failures.
1849    pub fn try_bytes_at(&self, index: usize) -> Result<Option<&[u8]>> {
1850        if index >= self.len || !self.validity.is_valid(index) {
1851            return Ok(None);
1852        }
1853        match &self.body {
1854            Body::Constant(value) => Ok(match value.as_ref() {
1855                Value::Varchar(text) => Some(text.as_bytes()),
1856                Value::Blob(bytes) => Some(bytes.as_slice()),
1857                _ => None,
1858            }),
1859            Body::Dictionary { codes, values, .. } => match codes.get(index) {
1860                Some(&code) => values.try_bytes_at(code as usize),
1861                None => Ok(None),
1862            },
1863            Body::Runs { ends, values } => match run_holding(ends, index) {
1864                Some(run) => values.try_bytes_at(run),
1865                None => Ok(None),
1866            },
1867            Body::Views { views, arena } => {
1868                Ok(views.get(index).and_then(|view| view.bytes_in(arena)))
1869            }
1870            Body::ExternalText { source } => source.bytes_at(index),
1871            Body::Flat(data) => Ok(data.bytes_at(index)),
1872            Body::Coded { .. }
1873            | Body::Sequence { .. }
1874            | Body::Packed { .. }
1875            | Body::Nested { .. }
1876            | Body::Fields { .. } => Ok(None),
1877        }
1878    }
1879
1880    /// Variable length byte count at `index`, preserving storage failures.
1881    pub fn try_bytes_len_at(&self, index: usize) -> Result<Option<usize>> {
1882        if index >= self.len || !self.validity.is_valid(index) {
1883            return Ok(None);
1884        }
1885        match &self.body {
1886            Body::Dictionary { codes, values, .. } => match codes.get(index) {
1887                Some(&code) => values.try_bytes_len_at(code as usize),
1888                None => Ok(None),
1889            },
1890            Body::Runs { ends, values } => match run_holding(ends, index) {
1891                Some(run) => values.try_bytes_len_at(run),
1892                None => Ok(None),
1893            },
1894            Body::ExternalText { source } => source.bytes_len_at(index),
1895            _ => Ok(self.bytes_at(index).map(<[u8]>::len)),
1896        }
1897    }
1898
1899    /// How many ranks this vector's values have in sorted order, when whatever holds them knows.
1900    ///
1901    /// See [`TextSource::ranks`] for what a rank is and what a source promises by answering with
1902    /// one. Only a vector whose values come from storage can answer, because only storage is in a
1903    /// position to have sorted them once and written the answer down.
1904    #[must_use]
1905    pub fn ranks(&self) -> Option<usize> {
1906        match &self.body {
1907            Body::ExternalText { source } => source.ranks(),
1908            _ => None,
1909        }
1910    }
1911
1912    /// How the value at `rank` compares against `wanted`. See [`TextSource::compare_rank`].
1913    pub fn compare_rank(&self, rank: usize, wanted: &[u8]) -> Result<Ordering> {
1914        match &self.body {
1915            Body::ExternalText { source } => source.compare_rank(rank, wanted),
1916            _ => {
1917                Err(Error::internal("a vector without a sorted order was asked to compare a rank"))
1918            }
1919        }
1920    }
1921
1922    /// The position of the value at `rank`. See [`TextSource::code_at_rank`].
1923    pub fn code_at_rank(&self, rank: usize) -> Result<u32> {
1924        match &self.body {
1925            Body::ExternalText { source } => source.code_at_rank(rank),
1926            _ => Err(Error::internal("a vector without a sorted order was asked for a rank")),
1927        }
1928    }
1929
1930    /// The rank of every value, indexed by position. See [`TextSource::code_ranks`].
1931    #[must_use]
1932    pub fn code_ranks(&self) -> Option<&[u32]> {
1933        match &self.body {
1934            Body::ExternalText { source } => source.code_ranks(),
1935            _ => None,
1936        }
1937    }
1938
1939    /// Text at `index`, preserving storage read, validation and UTF-8 failures.
1940    pub fn try_text_at(&self, index: usize) -> Result<Option<&str>> {
1941        if self.ty != LogicalType::Varchar {
1942            return Ok(None);
1943        }
1944        self.try_bytes_at(index)?
1945            .map(|bytes| {
1946                std::str::from_utf8(bytes).map_err(|error| {
1947                    Error::conversion(format!("invalid UTF-8 in VARCHAR: {error}"))
1948                })
1949            })
1950            .transpose()
1951    }
1952
1953    /// Read every storage-backed value reachable through this vector.
1954    pub fn validate_external(&self) -> Result<()> {
1955        match &self.body {
1956            Body::ExternalText { source } => {
1957                for index in 0..source.len() {
1958                    source.bytes_at(index)?;
1959                }
1960            }
1961            Body::Dictionary { codes, values, .. } => {
1962                for &code in codes {
1963                    values.try_bytes_at(code as usize)?;
1964                }
1965            }
1966            Body::Runs { values, .. } => values.validate_external()?,
1967            Body::Nested { child, .. } => child.validate_external()?,
1968            Body::Fields { children } => {
1969                for child in children {
1970                    child.validate_external()?;
1971                }
1972            }
1973            _ => {}
1974        }
1975        Ok(())
1976    }
1977
1978    /// The signed integer at `index`, widened, read without building a [`Value`].
1979    ///
1980    /// The integer sibling of [`Self::bytes_at`], and it is here for the same caller. A group by on
1981    /// an integer column compares one key per input row against the group it probed, and doing that
1982    /// through [`Self::value_at`] built and dropped a sixty four byte value a row at a time for a
1983    /// number that was already sitting in the column.
1984    ///
1985    /// Widened to `i128` because that is what [`Data::signed_at`] hands back underneath, and one
1986    /// method that covers every signed width is worth more than five that do not. A caller that
1987    /// wants a narrower type narrows it, which is a range check against a value in a register.
1988    ///
1989    /// The types this answers for are the ones whose flat data is read through `signed_at`, so the
1990    /// five signed integer widths and the decimal, date, time and timestamp types that are stored
1991    /// in them. A decimal answers with its unscaled value, which is the number the column holds.
1992    ///
1993    /// `None` for a null, for an index past the end, for a column of any other type, and for the
1994    /// compressed form. Packed integers stay in code space and answer `base + code` directly. A
1995    /// caller that gets `None` falls back to [`Self::value_at`], which is correct for the remaining
1996    /// forms.
1997    #[must_use]
1998    pub fn signed_at(&self, index: usize) -> Option<i128> {
1999        if index >= self.len || !self.validity.is_valid(index) {
2000            return None;
2001        }
2002        match &self.body {
2003            Body::Flat(data) => data.signed_at(index),
2004            Body::Constant(value) => match value.as_ref() {
2005                Value::TinyInt(x) => Some(i128::from(*x)),
2006                Value::SmallInt(x) => Some(i128::from(*x)),
2007                Value::Integer(x) | Value::Date(x) => Some(i128::from(*x)),
2008                Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => Some(i128::from(*x)),
2009                Value::HugeInt(x) | Value::Decimal { unscaled: x, .. } => Some(*x),
2010                _ => None,
2011            },
2012            // The same arithmetic [`Self::value_at`] does on a sequence, so the two agree about a
2013            // sequence that runs off the end of the width it is stored in.
2014            Body::Sequence { start, step } => {
2015                Some(i128::from(start.wrapping_add(step.wrapping_mul(index as i64))))
2016            }
2017            Body::Dictionary { codes, values, .. } => {
2018                values.signed_at(usize::try_from(*codes.get(index)?).ok()?)
2019            }
2020            Body::Runs { ends, values } => values.signed_at(run_holding(ends, index)?),
2021            Body::Packed { words, width, base, offset } => Some(
2022                *base + i128::from(code_at(words, (*offset + index) * *width as usize, *width)),
2023            ),
2024            // The same `None` [`Self::bytes_at`] gives, for the same reason. A compressed row is not
2025            // an integer anywhere until it has been unpacked, and a caller that gets
2026            // `None` goes to `value_at` and gets the row unpacked into a value. A list row is not an
2027            // integer in any form, however many integers are in it, and a struct row is not one even
2028            // when it has exactly one integer field, since the row is the struct and not the field.
2029            Body::Coded { .. }
2030            | Body::Views { .. }
2031            | Body::ExternalText { .. }
2032            | Body::Nested { .. }
2033            | Body::Fields { .. } => None,
2034        }
2035    }
2036
2037    /// Every value in order, as single values.
2038    pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
2039        (0..self.len).map(|index| self.value_at(index))
2040    }
2041
2042    /// This vector with its payload held as a page, so that copying or cutting it is free.
2043    ///
2044    /// For a producer that means to hand the same values out many times, which is what a stored
2045    /// column is. A flat body is the form this changes, because it is the only one that owns a run
2046    /// of values a copy would have to copy. Every other form already shares what is expensive and
2047    /// owns only what a cut has to rewrite, so it comes back as it was: a dictionary shares its
2048    /// values, a packed body shares its words, a string body shares its arena, an FSST body shares
2049    /// its codes and its table, and a constant and a sequence have nothing to share.
2050    ///
2051    /// Not recursive into a nested column's children, because a `LIST` or a `STRUCT` holds its
2052    /// children behind an `Arc` already.
2053    #[must_use]
2054    pub fn into_pages(self) -> Self {
2055        let body = match self.body {
2056            Body::Flat(data) => Body::Flat(data.into_pages()),
2057            other => other,
2058        };
2059        Self { body, ..self }
2060    }
2061
2062    /// A contiguous run of the values, in the form they are already in.
2063    ///
2064    /// This is the cut [`Self::gather`] cannot do. A gather walks a dictionary to its leaf and
2065    /// copies, so gathering a piece of a dictionary encoded column hands back a flat one, and a
2066    /// caller that only wanted the first thousand rows of a page has silently paid for a copy and
2067    /// thrown the dictionary away. A group by over a dictionary encoded column is the case that
2068    /// cares, and it is most of ClickBench.
2069    ///
2070    /// So each form is cut as itself. A dictionary keeps its dictionary and slices its codes, a
2071    /// sequence stays arithmetic with its start moved along, a constant stays a shorter constant,
2072    /// and a flat body is a window into its page when it has one and a copy of its range when it
2073    /// does not, which [`Self::into_pages`] is how a producer decides.
2074    ///
2075    /// The dictionary itself is shared rather than copied, so a cut is the codes and nothing else.
2076    /// It used to be copied, and on a read of a ClickBench partition that copy was ten percent of
2077    /// the cycles: a page holds one dictionary and is cut into chunk sized pieces, so the whole
2078    /// dictionary was copied once per chunk to be read the same way each time.
2079    ///
2080    /// # Errors
2081    ///
2082    /// If the range runs past the end of the vector, or if the type has no flat layout and the
2083    /// body is one that has to be copied.
2084    pub fn slice(&self, at: usize, len: usize) -> Result<Self> {
2085        let end = at.checked_add(len).ok_or_else(|| Error::internal("a slice that wraps"))?;
2086        if end > self.len {
2087            return Err(Error::internal(format!("rows {at} to {end} of a vector of {}", self.len)));
2088        }
2089        if at == 0 && len == self.len {
2090            return Ok(self.clone());
2091        }
2092        let validity = self.validity.slice(at, len);
2093        let body = match &self.body {
2094            Body::Constant(value) => Body::Constant(value.clone()),
2095            Body::Sequence { start, step } => {
2096                Body::Sequence { start: start + step * at as i64, step: *step }
2097            }
2098            Body::Dictionary { codes, values, stable } => Body::Dictionary {
2099                codes: codes[at..end].to_vec(),
2100                values: Arc::clone(values),
2101                stable: *stable,
2102            },
2103            // The bits are not byte aligned, so a cut either repacks them or moves the row the
2104            // reading starts at. Moving it is one addition and repacking is a pass, and a page is
2105            // cut into chunk sized pieces often enough that the difference is the form.
2106            Body::Packed { words, width, base, offset } => Body::Packed {
2107                words: Arc::clone(words),
2108                width: *width,
2109                base: *base,
2110                offset: offset + at,
2111            },
2112            // The cut a flat string column cannot do. Sixteen bytes a row move and the payload stays
2113            // where the page put it, so taking a chunk out of a column of long strings costs the
2114            // same as taking one out of a column of integers. A flat varchar body copies every byte
2115            // of every long string in the range instead, which is the measurement written down in
2116            // `Chunk::compact`: compaction loses on a varchar column, and this is the half of the
2117            // reason that is about cutting rather than about selecting.
2118            Body::Views { views, arena } => {
2119                Body::Views { views: views[at..end].to_vec(), arena: Arc::clone(arena) }
2120            }
2121            // The spans are absolute positions in the shared codes, so a cut is a run of them and
2122            // nothing has to be rebased. One page of compressed strings, one table, and as many
2123            // chunks over it as the reader wants.
2124            Body::Coded { codes, spans, table } => Body::Coded {
2125                codes: Arc::clone(codes),
2126                spans: spans[at..end].to_vec(),
2127                table: Arc::clone(table),
2128            },
2129            // Only the runs the range touches survive, the first and last of them cut back to where
2130            // the range starts and stops, and every end moved to be relative to the new row zero. A
2131            // cut of a hundred rows out of a column of a hundred million is a handful of runs, which
2132            // is the reason this form is worth cutting as itself rather than copying out.
2133            Body::Runs { ends, values } if len > 0 => {
2134                let first = run_holding(ends, at).unwrap_or(0);
2135                let last = run_holding(ends, end - 1).unwrap_or(first);
2136                let cut: Vec<u32> = ends[first..=last]
2137                    .iter()
2138                    .map(|&stop| stop.min(end as u32) - at as u32)
2139                    .collect();
2140                let values = values.slice(first, last - first + 1)?;
2141                Body::Runs { ends: cut, values: Arc::new(values) }
2142            }
2143            // An empty cut has no run to point at and an empty run length body would be a vector of
2144            // no runs claiming a length, so it comes back as the empty flat vector instead.
2145            Body::Runs { .. } => return self.gather(&[]),
2146            // The entries are absolute positions in the shared child, so a cut is a run of them and
2147            // nothing has to be rebased, the same as a cut of FSST spans. The elements outside the
2148            // range stay in the child unreferenced, which is the trade this form makes: a chunk cut
2149            // out of a page of lists moves eight bytes a row and copies no elements at all.
2150            Body::Nested { entries, child } => {
2151                Body::Nested { entries: entries[at..end].to_vec(), child: Arc::clone(child) }
2152            }
2153            // Every child cut at the same place, because a struct row is one value per field at the
2154            // same position in each and there is no entry standing between the row and the child to
2155            // rewrite instead. So this is the one nested form whose cut is not free, and what it costs
2156            // is whatever cutting each field costs, which for a field of string views is sixteen bytes
2157            // a row and for a field of packed integers is one addition.
2158            Body::Fields { children } => Body::Fields {
2159                children: children
2160                    .iter()
2161                    .map(|child| child.slice(at, len).map(Arc::new))
2162                    .collect::<Result<Vec<_>>>()?,
2163            },
2164            Body::ExternalText { source } => {
2165                let mut out = StringColumn::with_capacity(len);
2166                for index in at..end {
2167                    out.push_bytes(source.bytes_at(index)?.unwrap_or_default());
2168                }
2169                Body::Flat(Data::Varlen(out))
2170            }
2171            // The one form with nowhere to point, so its range is copied out. A run and not a
2172            // gather: this used to build a vector of the positions `at..end` and hand it to
2173            // `gather`, which then built a vector of `usize` from it, a vector of `bool` beside
2174            // that, and read the values back one bounds checked index at a time. That is five
2175            // passes and three allocations to say `memcpy`, and on a scan it was the largest thing
2176            // in the program after the aggregation itself, because every chunk of every column of
2177            // every page comes through here.
2178            Body::Flat(data) => Body::Flat(run_of(data, at, end)),
2179        };
2180        Ok(Self { ty: self.ty.clone(), len, validity, body })
2181    }
2182
2183    /// The same values in flat form.
2184    ///
2185    /// Flattening a vector that is already flat is free. Flattening any other form costs a copy,
2186    /// which is exactly why the other forms exist and why nothing on the hot path should call
2187    /// this. It is here for the operators that genuinely cannot do better and for the tests that
2188    /// check the other forms against it.
2189    ///
2190    /// A call that copies counts itself against [`Cause::Flatten`], because a flatten on a hot path
2191    /// is the most expensive thing in this crate and the only way to find one is to have the number.
2192    /// A call on a vector that is already flat does not count, since it neither copies nor gives
2193    /// anything up.
2194    ///
2195    /// # Errors
2196    ///
2197    /// If the type is one there is no vector for yet, which today means `ARRAY` and `UNION`. A `LIST`
2198    /// and a `MAP` flatten to themselves and a `STRUCT` to a struct of flattened fields, since none of
2199    /// the three has a data slice in any form and there is nothing flatter to become.
2200    pub fn flatten(&self) -> Result<Self> {
2201        if let Body::Flat(_) = self.body {
2202            return Ok(self.clone());
2203        }
2204        slow::took(Cause::Flatten);
2205        self.copied((0..self.len).collect(), false)
2206    }
2207
2208    /// The values at the given positions, copied, in a form that does not point back at this vector.
2209    ///
2210    /// This is the copying counterpart to [`Self::dictionary`], and the two are the two halves of
2211    /// the decision `spec/07-execution.md` section 7.1 describes. Which half is right is measured
2212    /// rather than argued, and [`Chunk::compact`](crate::Chunk::compact) is where the measurement
2213    /// is written down.
2214    ///
2215    /// A dictionary chain is walked to its leaf first and the codes composed on the way down, so the
2216    /// copy runs once over the data rather than once per level, and a position that is null at any
2217    /// level comes out null here. The copy is a typed loop per physical layout rather than a `Value`
2218    /// per row, which is the whole point of it and is what [`Self::flatten`] now goes through too.
2219    ///
2220    /// # Errors
2221    ///
2222    /// If the type is one there is no vector for yet, which today means `ARRAY` and `UNION`. A `LIST`
2223    /// and a `MAP` gather by permuting their entries and a `STRUCT` by gathering every field.
2224    pub fn gather(&self, indices: &[u32]) -> Result<Self> {
2225        self.copied(indices.iter().map(|&index| index as usize).collect(), true)
2226    }
2227
2228    /// The copy both [`Self::gather`] and [`Self::flatten`] are.
2229    ///
2230    /// `forms_stay` is the one thing the two want differently. A gather of a constant is a shorter
2231    /// constant and copying it out would be a thousand writes of the same value for nothing, and a
2232    /// gather of string views is a shorter run of views over the same arena rather than a copy of
2233    /// the bytes. Flattening promises flat form to a caller that is about to read the data slice, so
2234    /// for that one both of them have to be written out.
2235    fn copied(&self, at: Vec<usize>, forms_stay: bool) -> Result<Self> {
2236        let rows = at.len();
2237        if forms_stay {
2238            if let Body::Dictionary { codes, values, stable: true } = &self.body {
2239                let validity = Validity::from_iter(rows, |row| {
2240                    at.get(row).is_some_and(|&index| index < self.len && !self.is_null_at(index))
2241                });
2242                let gathered =
2243                    at.iter().map(|&index| codes.get(index).copied().unwrap_or(0)).collect();
2244                return Ok(
2245                    Self::stable_dictionary(gathered, Arc::clone(values))?.with_validity(validity)
2246                );
2247            }
2248        }
2249        let (at, leaf) = self.resolve(at);
2250        let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
2251        let validity = Validity::from_run(&live);
2252        let body = match &leaf.body {
2253            // The same gather the arm below is, for a type that has no flat layout to be written out
2254            // into. It goes through the nested builders rather than through a run of data, because they
2255            // are the one place that knows a row of a list column is a range of a child and a row of a
2256            // struct column is one position in each of several, and a second copy of that here would
2257            // be a second thing to keep in step with them.
2258            Body::Constant(value)
2259                if matches!(
2260                    self.ty,
2261                    LogicalType::List(_) | LogicalType::Struct(_) | LogicalType::Map(_, _)
2262                ) =>
2263            {
2264                if forms_stay && matches!(validity, Validity::AllValid) {
2265                    return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
2266                }
2267                let rows: Vec<Value> = at
2268                    .iter()
2269                    .map(
2270                        |&index| {
2271                            if index == NOWHERE { Value::Null } else { value.as_ref().clone() }
2272                        },
2273                    )
2274                    .collect();
2275                return Self::from_values(self.ty.clone(), &rows);
2276            }
2277            // Every position holds the same value, so the only thing the gather can change is the
2278            // length and which positions are null. A gather with no null in it is still a constant.
2279            Body::Constant(value) => {
2280                if forms_stay && matches!(validity, Validity::AllValid) {
2281                    return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
2282                }
2283                let mut data = empty_data_for(&self.ty)?;
2284                for &index in &at {
2285                    push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
2286                }
2287                Body::Flat(data)
2288            }
2289            // A sequence is arithmetic rather than storage, so the gather is the arithmetic done at
2290            // the positions asked for, and a null writes the zero every other layout writes.
2291            Body::Sequence { start, step } => Body::Flat(Data::Int64(
2292                at.iter()
2293                    .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
2294                    .collect(),
2295            )),
2296            // A flat body with no values is the untyped null, so every position asked for is null
2297            // whatever was asked for. Going through the copy would build a run of no values and
2298            // call it `rows` long, which is a vector whose length and data disagree.
2299            Body::Flat(Data::Empty) => {
2300                return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
2301            }
2302            Body::Flat(data) => Body::Flat(copy_of(data, &at)),
2303            // The one form whose copy is arithmetic rather than a move of bytes. It goes through a
2304            // typed loop per layout the way the flat copy does, because the alternative is a `Value`
2305            // per row and this is the path a flatten of a scanned column takes.
2306            Body::Packed { words, width, base, offset } => {
2307                Body::Flat(unpack(&self.ty, words, *offset, *width, *base, &at)?)
2308            }
2309            // A gather keeps the form, which is what makes selecting rows out of a string column
2310            // cost sixteen bytes a row instead of the bytes of the strings. The arena it shares is
2311            // the whole arena and not the part the kept rows point at, so a selection that throws
2312            // most of a page away goes on holding the page. That is the trade the form is: a cut and
2313            // a filter are cheap and the memory comes back when the last vector over the page goes,
2314            // and a caller that wants the bytes narrowed asks for a flatten.
2315            Body::Views { views, arena } if forms_stay => Body::Views {
2316                views: at
2317                    .iter()
2318                    .map(|&index| views.get(index).copied().unwrap_or_else(StringView::empty))
2319                    .collect(),
2320                arena: Arc::clone(arena),
2321            },
2322            // Flattening promises a data slice, so the bytes are copied out into an arena of their
2323            // own and the shared one is let go of. The total is known before any of it is copied,
2324            // the way the flat copy works it out, so the new arena is one allocation.
2325            Body::Views { views, arena } => {
2326                let mut out = StringColumn::with_capacity(at.len());
2327                out.reserve_bytes(
2328                    at.iter()
2329                        .filter_map(|&index| views.get(index))
2330                        .filter(|view| !view.is_inline())
2331                        .map(StringView::len)
2332                        .sum(),
2333                );
2334                for &index in &at {
2335                    let bytes = views.get(index).and_then(|view| view.bytes_in(arena));
2336                    out.push_bytes(bytes.unwrap_or_default());
2337                }
2338                Body::Flat(Data::Varlen(out))
2339            }
2340            Body::ExternalText { source } => {
2341                let mut out = StringColumn::with_capacity(at.len());
2342                for &index in &at {
2343                    out.push_bytes(source.bytes_at(index)?.unwrap_or_default());
2344                }
2345                Body::Flat(Data::Varlen(out))
2346            }
2347            // A gather keeps the form, because the codes do not move and a span survives being put
2348            // in an order the codes are not in. A position that resolved to nowhere gets the empty
2349            // span, which decompresses to no bytes, which is the zero every other layout writes.
2350            Body::Coded { codes, spans, table } if forms_stay => Body::Coded {
2351                codes: Arc::clone(codes),
2352                spans: at
2353                    .iter()
2354                    .map(|&index| spans.get(index).copied().unwrap_or((0, 0)))
2355                    .collect(),
2356                table: Arc::clone(table),
2357            },
2358            // Flattening decompresses, which is the price of the data slice it promises. The scratch
2359            // buffer is reused across rows, so this is one allocation for the whole column rather
2360            // than one per row the way reading it a value at a time would be.
2361            Body::Coded { codes, spans, table } => {
2362                let mut out = StringColumn::with_capacity(at.len());
2363                let mut scratch = Vec::new();
2364                for &index in &at {
2365                    scratch.clear();
2366                    let span = spans
2367                        .get(index)
2368                        .and_then(|&(from, to)| codes.get(from as usize..to as usize));
2369                    if let Some(span) = span {
2370                        table.decompress(span, &mut scratch)?;
2371                    }
2372                    out.push_bytes(&scratch);
2373                }
2374                Body::Flat(Data::Varlen(out))
2375            }
2376            // The entries move and the child does not, which is the same trade the string forms
2377            // make and is why a gather of a list column costs eight bytes a row however long the
2378            // lists are. A position that resolved to nowhere gets a zero length entry, and the mask
2379            // already says it is null, so the entry is never read.
2380            //
2381            // This arm ignores `forms_stay`, unlike every arm above it, because there is nothing
2382            // flatter for a list to become. The other forms are all cheaper ways of writing down a
2383            // column of scalars and flattening gives up the saving to hand back a data slice, and a
2384            // list has no data slice in any form, so a flatten of one is this and a caller reading it
2385            // goes through `list_parts` either way.
2386            Body::Nested { entries, child } => Body::Nested {
2387                entries: at
2388                    .iter()
2389                    .map(|&index| entries.get(index).copied().unwrap_or((0, 0)))
2390                    .collect(),
2391                child: Arc::clone(child),
2392            },
2393            // Every child gathered at the same positions, for the reason the cut cuts every child:
2394            // there are no entries to permute instead, so the permutation happens once per field. The
2395            // positions handed down are the resolved ones, sentinel and all, so a row that resolved to
2396            // nowhere comes back null in each field as well as null here.
2397            //
2398            // `forms_stay` is passed straight through rather than ignored, which is the opposite of
2399            // what the list arm does, and the difference is real. There is nothing flatter for a list
2400            // to become, and a struct is only as flat as its fields are, so a flatten of a struct
2401            // column is a flatten of each field and a caller that asked for data slices gets them.
2402            Body::Fields { children } => Body::Fields {
2403                children: children
2404                    .iter()
2405                    .map(|child| child.copied(at.clone(), forms_stay).map(Arc::new))
2406                    .collect::<Result<Vec<_>>>()?,
2407            },
2408            // Unreachable, because `resolve` walks past both of the forms that point at another
2409            // vector and stops at the first body that does not.
2410            Body::Dictionary { .. } | Body::Runs { .. } => {
2411                return Err(Error::internal(
2412                    "a form that points somewhere survived being resolved",
2413                ));
2414            }
2415        };
2416        Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
2417    }
2418
2419    /// Where each wanted position lives in the first body that is not a dictionary, and that body.
2420    ///
2421    /// A position that is null anywhere on the way down, or past the end of anything on the way
2422    /// down, comes back as [`NOWHERE`]. That single sentinel is what keeps the copy loop from
2423    /// carrying a validity mask alongside the positions it is already walking.
2424    fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
2425        let mut source = self;
2426        loop {
2427            for slot in &mut at {
2428                if *slot >= source.len || !source.validity.is_valid(*slot) {
2429                    *slot = NOWHERE;
2430                }
2431            }
2432            source = match &source.body {
2433                Body::Dictionary { codes, values, .. } => {
2434                    for slot in &mut at {
2435                        *slot = match codes.get(*slot) {
2436                            Some(&code) => code as usize,
2437                            None => NOWHERE,
2438                        };
2439                    }
2440                    values.as_ref()
2441                }
2442                // A run length body is a dictionary whose code is worked out from the position
2443                // rather than stored, so the walk down is the same walk with a search where the
2444                // lookup was. `NOWHERE` searches for nothing and stays `NOWHERE`.
2445                Body::Runs { ends, values } => {
2446                    for slot in &mut at {
2447                        *slot = run_holding(ends, *slot).unwrap_or(NOWHERE);
2448                    }
2449                    values.as_ref()
2450                }
2451                _ => return (at, source),
2452            };
2453        }
2454    }
2455}
2456
2457/// So that a kernel can take its operands as either a list of vectors or a list of references.
2458///
2459/// A caller that built a `Vec<Vector>` and a caller whose operands are already somewhere else, in a
2460/// chunk or in an evaluator's scratch, want the same kernel. Without this the second kind has to
2461/// clone every operand into a `Vec` to satisfy the signature, and a clone of a vector is a copy of
2462/// the whole column, so the type would be charging real memory traffic for nothing.
2463impl AsRef<Vector> for Vector {
2464    fn as_ref(&self) -> &Vector {
2465        self
2466    }
2467}
2468
2469/// The bits of a packed vector and what they mean, for a kernel that wants to stay in code space.
2470///
2471/// Borrowed from the vector rather than owning anything, so getting one costs nothing and a kernel
2472/// that finds it cannot use them has given up nothing by asking.
2473#[derive(Debug, Clone, Copy)]
2474pub struct Packed<'a> {
2475    words: &'a [u64],
2476    width: u32,
2477    base: i128,
2478    offset: usize,
2479}
2480
2481impl Packed<'_> {
2482    /// Packed words. A persisted vector also records [`Self::offset`].
2483    #[must_use]
2484    pub fn words(&self) -> &[u64] {
2485        self.words
2486    }
2487
2488    /// Bit offset, in rows, of the first value.
2489    #[must_use]
2490    pub fn offset(&self) -> usize {
2491        self.offset
2492    }
2493
2494    /// How many bits one code takes, between one and [`PACKED_WIDTH_MAX`].
2495    #[must_use]
2496    pub fn width(&self) -> u32 {
2497        self.width
2498    }
2499
2500    /// What zero means, so that the value of a row is the base plus its code.
2501    #[must_use]
2502    pub fn base(&self) -> i128 {
2503        self.base
2504    }
2505
2506    /// The largest value this vector can be holding, whatever it is actually holding.
2507    ///
2508    /// With [`Self::base`] this is the pair a comparison kernel wants first. A literal outside the
2509    /// two answers every row of the vector the same way, which is a whole chunk decided without a
2510    /// bit being read, and that is the case a zone map would have caught if there were one here.
2511    #[must_use]
2512    pub fn ceiling(&self) -> i128 {
2513        self.base + i128::from(u64::MAX >> (u64::BITS - self.width))
2514    }
2515
2516    /// The code of row `row`, which is its value minus [`Self::base`].
2517    ///
2518    /// Out of range rows read as zero rather than panicking, the way every other accessor in this
2519    /// file answers for a row that is not there.
2520    #[must_use]
2521    pub fn code(&self, row: usize) -> u64 {
2522        code_at(self.words, (self.offset + row) * self.width as usize, self.width)
2523    }
2524
2525    /// Which code a value would have, and `None` for a value this vector cannot be holding.
2526    ///
2527    /// The translation a comparison does once per vector so that it does not have to unpack once per
2528    /// row. `None` is the useful answer rather than a failure: it says the literal is outside the
2529    /// packed range, so every row compares against it the same way.
2530    #[must_use]
2531    pub fn code_of(&self, value: i128) -> Option<u64> {
2532        u64::try_from(value.checked_sub(self.base)?).ok().filter(|&code| code <= self.mask())
2533    }
2534
2535    /// The largest code the width allows.
2536    fn mask(&self) -> u64 {
2537        u64::MAX >> (u64::BITS - self.width)
2538    }
2539}
2540
2541/// The widest a packed code is allowed to be.
2542///
2543/// Sixty three rather than sixty four so that a mask is `u64::MAX >> (64 - width)` with no shift of
2544/// a whole word in it, and reading a code is one branch on whether it straddles rather than two. A
2545/// sixty four bit code saves nothing anyway, since it is the layout it came from.
2546pub const PACKED_WIDTH_MAX: u32 = 63;
2547
2548/// How much smaller packing has to be before it is worth the shift and the mask on every read.
2549///
2550/// Two, so a column packs when the bits come to half the flat size or less. A column that would save
2551/// a tenth stays flat, because a tenth of a column is not worth turning every read of it into
2552/// arithmetic, and the whole argument for the form is that a narrow column saves most of itself.
2553pub const PACKING_PAYS_AT: usize = 2;
2554
2555/// How much smaller compressing has to be before it is worth a decompression on every read.
2556///
2557/// Two, the same rule packing follows and for the same reason. FSST gets about that on text, so a
2558/// column of English or of URLs compresses and a column of short codes or of random bytes does not,
2559/// which is the right answer for both.
2560pub const FSST_PAYS_AT: usize = 2;
2561
2562/// The codes of a compressed column and the table they are against.
2563///
2564/// Handed out by [`Vector::coded_parts`] so a kernel can work in code space. Nothing here
2565/// decompresses, which is the point: [`Self::encode`] puts the literal into the same space the rows
2566/// are already in, and after that an equality test is a byte slice comparison.
2567#[derive(Debug, Clone, Copy)]
2568pub struct Coded<'a> {
2569    codes: &'a [u8],
2570    spans: &'a [(u32, u32)],
2571    table: &'a SymbolTable,
2572}
2573
2574impl Coded<'_> {
2575    /// The table every row in this vector is compressed against.
2576    #[must_use]
2577    pub fn table(&self) -> &SymbolTable {
2578        self.table
2579    }
2580
2581    /// The code bytes of one row, still compressed.
2582    #[must_use]
2583    pub fn row(&self, row: usize) -> Option<&[u8]> {
2584        let &(from, to) = self.spans.get(row)?;
2585        self.codes.get(from as usize..to as usize)
2586    }
2587
2588    /// Some bytes in the code space this vector is in.
2589    ///
2590    /// The literal side of an equality filter. Compressing is a function of the table and the bytes,
2591    /// so two strings compress to the same codes exactly when they are the same string, and an
2592    /// equality test on the codes is an equality test on the strings with no decompression in it.
2593    #[must_use]
2594    pub fn encode(&self, bytes: &[u8]) -> Vec<u8> {
2595        let mut out = Vec::with_capacity(bytes.len());
2596        self.table.compress(bytes, &mut out);
2597        out
2598    }
2599}
2600
2601/// How many words hold `len` codes of `width` bits.
2602fn words_for(len: usize, width: u32) -> usize {
2603    (len * width as usize).div_ceil(u64::BITS as usize)
2604}
2605
2606/// The lowest and highest value a type's layout can hold, and `None` for a type with no integer one.
2607///
2608/// This is also the test of whether a type can be packed at all, and it is the only one, so the
2609/// layouts listed here and the layouts [`pack`] and [`unpack`] know how to walk are the same list
2610/// from the same macro and cannot drift apart.
2611fn layout_range(ty: &LogicalType) -> Option<(i128, i128)> {
2612    use rudb_common::PhysicalType as P;
2613    macro_rules! ranges {
2614        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
2615            match ty.physical() {
2616                $(P::$variant => Some((i128::from(<$native>::MIN), i128::from(<$native>::MAX))),)+
2617                _ => None,
2618            }
2619        };
2620    }
2621    crate::for_each_layout!(exact, ranges)
2622}
2623
2624/// The lowest and highest value in the first `len` slots of a run of integer data.
2625///
2626/// `None` for data that is not integers, which is what says a column cannot be packed. The null
2627/// slots are in the span, holding whatever zero was written into them, which
2628/// [`Vector::bit_packed`] says more about.
2629fn span_of(data: &Data, len: usize) -> Option<(i128, i128)> {
2630    macro_rules! spans {
2631        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
2632            match data {
2633                $(Data::$variant(values) => {
2634                    let mut low = i128::MAX;
2635                    let mut high = i128::MIN;
2636                    for &value in values.as_slice().iter().take(len) {
2637                        let value = i128::from(value);
2638                        low = low.min(value);
2639                        high = high.max(value);
2640                    }
2641                    (low <= high).then_some((low, high))
2642                })+
2643                _ => None,
2644            }
2645        };
2646    }
2647    crate::for_each_layout!(exact, spans)
2648}
2649
2650/// The first `len` values of a run of integer data, written out as codes of `width` bits from `base`.
2651fn pack(data: &Data, len: usize, base: i128, width: u32) -> Vec<u64> {
2652    let mut words = vec![0u64; words_for(len, width)];
2653    macro_rules! packing {
2654        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
2655            match data {
2656                $(Data::$variant(values) => {
2657                    for (row, &value) in values.as_slice().iter().take(len).enumerate() {
2658                        // In range because `base` and `width` came from the span of this same run.
2659                        let code = u64::try_from(i128::from(value) - base).unwrap_or(0);
2660                        write_code(&mut words, row * width as usize, width, code);
2661                    }
2662                })+
2663                _ => {}
2664            }
2665        };
2666    }
2667    crate::for_each_layout!(exact, packing);
2668    words
2669}
2670
2671/// The codes at the given rows, unpacked into the flat layout the type calls for.
2672///
2673/// A row of [`NOWHERE`] writes the layout's zero, which is the rule [`copy_of`] follows for the same
2674/// reason: every layout here is a parallel array to a validity mask, so a null takes a slot.
2675///
2676/// # Errors
2677///
2678/// If the type has no flat layout, which a packed vector cannot have and which is checked when one
2679/// is built, so an error here is a bug rather than a caller mistake.
2680fn unpack(
2681    ty: &LogicalType,
2682    words: &[u64],
2683    offset: usize,
2684    width: u32,
2685    base: i128,
2686    at: &[usize],
2687) -> Result<Data> {
2688    let mut out = empty_data_for(ty)?;
2689    let value_of = |row: usize| {
2690        if row == NOWHERE {
2691            return None;
2692        }
2693        Some(base + i128::from(code_at(words, (offset + row) * width as usize, width)))
2694    };
2695    macro_rules! unpacking {
2696        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
2697            match &mut out {
2698                $(Data::$variant(values) => {
2699                    values.reserve(at.len());
2700                    for &row in at {
2701                        // In range because both ends of it were checked when the vector was built.
2702                        let value = value_of(row)
2703                            .and_then(|value| <$native>::try_from(value).ok())
2704                            .unwrap_or($zero);
2705                        values.push(value);
2706                    }
2707                })+
2708                _ => {
2709                    return Err(Error::internal(format!(
2710                        "a {ty} vector was packed, which no integer layout allows"
2711                    )));
2712                }
2713            }
2714        };
2715    }
2716    crate::for_each_layout!(exact, unpacking);
2717    Ok(out)
2718}
2719
2720/// The `width` bits starting at `bit`, low end first.
2721///
2722/// Zero for bits past the end of the words, which keeps a read of a row that is not there from
2723/// panicking and matches what every other accessor here does with one.
2724fn code_at(words: &[u64], bit: usize, width: u32) -> u64 {
2725    let word = bit / u64::BITS as usize;
2726    let shift = (bit % u64::BITS as usize) as u32;
2727    let mask = u64::MAX >> (u64::BITS - width);
2728    let low = words.get(word).copied().unwrap_or(0) >> shift;
2729    let taken = u64::BITS - shift;
2730    if taken >= width {
2731        return low & mask;
2732    }
2733    // The code straddles two words, and `taken` is under the width here so it is under sixty four,
2734    // which is what makes the shift below one the hardware will do rather than one it refuses.
2735    let high = words.get(word + 1).copied().unwrap_or(0) << taken;
2736    (low | high) & mask
2737}
2738
2739/// Writes `width` bits of `code` starting at `bit`, over words that started out zero.
2740fn write_code(words: &mut [u64], bit: usize, width: u32, code: u64) {
2741    let word = bit / u64::BITS as usize;
2742    let shift = (bit % u64::BITS as usize) as u32;
2743    words[word] |= code << shift;
2744    let taken = u64::BITS - shift;
2745    if taken < width {
2746        words[word + 1] |= code >> taken;
2747    }
2748}
2749
2750/// One level of dictionary out of however many levels were handed to [`Vector::dictionary`].
2751///
2752/// Every dictionary in the system is built through that constructor and every one of them comes
2753/// through here first, so the invariant this maintains is that the vector a dictionary points at is
2754/// never itself a dictionary that could have been composed away. That makes the work a single `if`
2755/// rather than a loop: the inner vector was already composed when it was built, so composing the
2756/// outer codes through it leaves the result no deeper than the inner vector already was.
2757///
2758/// The codes are indexed rather than fetched with `get`, because the caller has already walked the
2759/// whole outer array to check that every code is in range and the inner array is exactly as long as
2760/// the vector those codes were checked against.
2761fn compose(codes: Vec<u32>, values: Vector) -> (Vec<u32>, Vector) {
2762    // A dictionary carrying a validity of its own is one whose nulls live at this level rather than
2763    // in the values, which is the one thing composition cannot carry down with it.
2764    if !matches!(values.validity, Validity::AllValid) {
2765        return (codes, values);
2766    }
2767    let Vector { ty, len, validity, body } = values;
2768    match body {
2769        Body::Dictionary { codes: inner, values: leaf, .. } => {
2770            debug_assert!(
2771                !matches!(leaf.body, Body::Dictionary { .. })
2772                    || !matches!(leaf.validity, Validity::AllValid),
2773                "a dictionary was stacked on a dictionary without going through the constructor"
2774            );
2775            // The leaf is shared, so taking it out of the `Arc` copies it when something else is
2776            // still holding the same dictionary. That is the rare path: a dictionary over a
2777            // dictionary only arrives from a caller that built one that way, and the cut that made
2778            // sharing worth doing produces neither.
2779            (codes.iter().map(|&code| inner[code as usize]).collect(), Arc::unwrap_or_clone(leaf))
2780        }
2781        body => (codes, Vector { ty, len, validity, body }),
2782    }
2783}
2784
2785/// How many rows a run has to cover on average before run length encoding is smaller.
2786///
2787/// A run costs its value plus the four bytes of its end, so on a four byte column a run of two rows
2788/// breaks even and a run of three wins. Wider columns win sooner and narrower ones later, and this
2789/// is the one ratio for all of them because a threshold per width is a table that has to be right
2790/// nine times rather than once. It is a constant with a name so that the sweep that eventually moves
2791/// it has something to move.
2792const RUNS_PAY_AT: usize = 2;
2793
2794/// Which run holds `row`, given ends that are exclusive and increasing.
2795///
2796/// A binary search rather than a scan, because the callers that ask this are the ones that are not
2797/// walking the runs in order: a single value read out of a result set, or a gather at scattered
2798/// positions. Anything walking in order should be reading [`Vector::run_parts`] instead, which is
2799/// what the form is for.
2800fn run_holding(ends: &[u32], row: usize) -> Option<usize> {
2801    let row = u32::try_from(row).ok()?;
2802    let run = match ends.binary_search(&row) {
2803        // The ends are exclusive, so landing exactly on one means the row is the first of the next.
2804        Ok(at) => at + 1,
2805        Err(at) => at,
2806    };
2807    (run < ends.len()).then_some(run)
2808}
2809
2810/// The row each run ends at, for a flat body read alongside the validity that goes with it.
2811///
2812/// Two adjacent nulls are one run, because a reader of either gets a null and cannot tell them
2813/// apart. A null between two equal values is three runs for the same reason, since the null is a
2814/// value of the column as far as anything reading it is concerned.
2815///
2816/// The comparison is per layout rather than per `Value`, which is the whole reason this is a macro.
2817/// A `Value` a row would allocate a string per row on a `VARCHAR` column and would be the exact
2818/// defect `cargo xtask rowloop` exists to fail the build on.
2819fn boundaries(data: &Data, validity: &Validity, len: usize) -> Vec<u32> {
2820    if len == 0 {
2821        return Vec::new();
2822    }
2823    let breaks = |ends: &mut Vec<u32>, mut differs: Box<dyn FnMut(usize, usize) -> bool + '_>| {
2824        for row in 1..len {
2825            let same = match (validity.is_valid(row), validity.is_valid(row - 1)) {
2826                (false, false) => true,
2827                (true, true) => !differs(row, row - 1),
2828                _ => false,
2829            };
2830            if !same {
2831                ends.push(u32::try_from(row).unwrap_or(u32::MAX));
2832            }
2833        }
2834        ends.push(u32::try_from(len).unwrap_or(u32::MAX));
2835    };
2836    let mut ends = Vec::new();
2837    macro_rules! walked {
2838        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
2839            match data {
2840                // No values at all, so every row is the same null and the column is one run.
2841                Data::Empty => ends.push(u32::try_from(len).unwrap_or(u32::MAX)),
2842                $(Data::$variant(values) => {
2843                    breaks(&mut ends, Box::new(|a, b| values.get(a) != values.get(b)));
2844                })+
2845                Data::Varlen(values) => {
2846                    breaks(&mut ends, Box::new(|a, b| values.bytes(a) != values.bytes(b)));
2847                }
2848            }
2849        };
2850    }
2851    crate::for_each_layout!(fixed, walked);
2852    ends
2853}
2854
2855/// The position of a value that is not anywhere, because it is null or out of range.
2856///
2857/// `usize::MAX` rather than an `Option<usize>`, because the copy loop's bounds check rejects it for
2858/// free and an `Option` would put a second branch next to the one already there.
2859pub(crate) const NOWHERE: usize = usize::MAX;
2860
2861/// A run of data copied at the given positions, with a zero wherever the position is [`NOWHERE`].
2862///
2863/// A zero and not a skip, because every layout here is a parallel array to a validity mask and a
2864/// short one would put every value after the first null at the wrong index. It is the same rule
2865/// [`push_value`] follows for a null.
2866/// A contiguous run of a flat body, copied out.
2867///
2868/// The counterpart to [`copy_of`] for the one case that is a range rather than a set of positions,
2869/// which is what [`Vector::slice`] asks for. Every fixed width layout is one `memcpy` and the
2870/// string layout is a run of views and their bytes, where `copy_of` is a bounds checked index and a
2871/// null test per row.
2872///
2873/// The caller has already checked that `end` is inside the vector, and a body whose data is shorter
2874/// than its vector claims is a bug elsewhere, so a short run is clamped rather than reported.
2875///
2876/// A fixed width run over a buffer that is a window into a page does not copy anything, because
2877/// [`Buffer::slice`] moves the offset instead. That is the case a scan over stored memory is in, and
2878/// it is why the flat body is no longer the one form of a vector whose cut costs an allocation.
2879fn run_of(data: &Data, at: usize, end: usize) -> Data {
2880    macro_rules! run {
2881        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
2882            match data {
2883                Data::Empty => Data::Empty,
2884                $(Data::$variant(values) => {
2885                    let held = values.len();
2886                    let from = at.min(held);
2887                    let to = end.max(from).min(held);
2888                    if to == end {
2889                        // The whole run is there, so this is a window on a shared page and a copy on
2890                        // an owned one, decided inside the buffer rather than here.
2891                        Data::$variant(values.slice(from, end - from))
2892                    } else {
2893                        let values = values.as_slice();
2894                        let mut out = Buffer::with_capacity(end - at);
2895                        out.extend_from_slice(&values[from..to]);
2896                        // A body shorter than the rows asked for pads with the zero every layout
2897                        // uses for a null, which is the answer `copy_of` gives for a position past
2898                        // the end.
2899                        // row at a time: never runs on a vector whose data matches its length.
2900                        for _ in to..end {
2901                            out.push($zero);
2902                        }
2903                        Data::$variant(out)
2904                    }
2905                })+
2906                // A view says where its bytes are, so a run of rows is not a run of bytes and this
2907                // is the one layout whose cut is still a loop. The total is known before any of it
2908                // is copied, so the arena is one allocation.
2909                Data::Varlen(values) => {
2910                    let views = values.views();
2911                    let mut out = StringColumn::with_capacity(end - at);
2912                    out.reserve_bytes(
2913                        views
2914                            .get(at.min(views.len())..end.min(views.len()))
2915                            .unwrap_or(&[])
2916                            .iter()
2917                            .filter(|view| !view.is_inline())
2918                            .map(StringView::len)
2919                            .sum(),
2920                    );
2921                    // row at a time: see above, the bytes of consecutive rows need not be next to
2922                    // each other.
2923                    for index in at..end {
2924                        out.push_from(values, index);
2925                    }
2926                    Data::Varlen(out)
2927                }
2928            }
2929        };
2930    }
2931    crate::for_each_layout!(fixed, run)
2932}
2933
2934pub(crate) fn copy_of(data: &Data, at: &[usize]) -> Data {
2935    macro_rules! copied {
2936        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
2937            match data {
2938                Data::Empty => Data::Empty,
2939                $(Data::$variant(values) => {
2940                    let mut out = Buffer::with_capacity(at.len());
2941                    for &index in at {
2942                        // One bounds check rather than a null test and a bounds check, because
2943                        // `NOWHERE` is past the end of every slice there can be.
2944                        out.push(values.get(index).copied().unwrap_or($zero));
2945                    }
2946                    Data::$variant(out)
2947                })+
2948                // The one layout where a gather is a copy of bytes rather than a copy of fixed
2949                // width slots, and the reason compaction is a decision rather than a default on a
2950                // string column.
2951                Data::Varlen(values) => {
2952                    let mut out = StringColumn::with_capacity(at.len());
2953                    // The bytes are known before any of them are copied, because a view carries its
2954                    // length and the wanted positions are already in hand, so the arena is one
2955                    // allocation rather than a run of doublings that each copy what the last one
2956                    // copied.
2957                    let views = values.views();
2958                    out.reserve_bytes(
2959                        at.iter()
2960                            .filter_map(|&index| views.get(index))
2961                            .filter(|view| !view.is_inline())
2962                            .map(StringView::len)
2963                            .sum(),
2964                    );
2965                    for &index in at {
2966                        out.push_from(values, index);
2967                    }
2968                    Data::Varlen(out)
2969                }
2970            }
2971        };
2972    }
2973    crate::for_each_layout!(fixed, copied)
2974}
2975
2976/// The physical layout a run of data is in, for the check that it matches its type.
2977///
2978/// The two enums name their variants the same way on purpose, so this is one generated arm rather
2979/// than sixteen chances to pair the wrong two up.
2980pub(crate) fn layout_of(data: &Data) -> rudb_common::PhysicalType {
2981    use rudb_common::PhysicalType as P;
2982    macro_rules! layouts {
2983        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
2984            match data {
2985                Data::Empty => P::Empty,
2986                $(Data::$variant(_) => P::$variant,)+
2987            }
2988        };
2989    }
2990    crate::for_each_layout!(all, layouts)
2991}
2992
2993/// One value out of a run of data, given what the run means.
2994///
2995/// The match is on the logical type rather than on the data, because the data cannot tell a `DATE`
2996/// from an `INTEGER` and that is the whole reason the two are kept apart.
2997fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
2998    let signed = || data.signed_at(index);
2999    let unsigned = || data.unsigned_at(index);
3000    let value = match ty {
3001        LogicalType::Boolean => match data {
3002            Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
3003            _ => None,
3004        },
3005        LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
3006        LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
3007        LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
3008        LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
3009        LogicalType::HugeInt => signed().map(Value::HugeInt),
3010        LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
3011        LogicalType::USmallInt => {
3012            unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
3013        }
3014        LogicalType::UInteger => {
3015            unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
3016        }
3017        LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
3018        LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
3019        LogicalType::Float => match data {
3020            Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
3021            _ => None,
3022        },
3023        LogicalType::Double => match data {
3024            Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
3025            _ => None,
3026        },
3027        LogicalType::Decimal { width, scale } => {
3028            signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
3029        }
3030        LogicalType::Varchar | LogicalType::Blob | LogicalType::Bit => {
3031            data.bytes_at(index).map(|bytes| bytes_as(ty, bytes))
3032        }
3033        LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
3034        LogicalType::Time => signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time),
3035        LogicalType::TimeTz => signed().and_then(|x| i64::try_from(x).ok()).map(Value::TimeTz),
3036        LogicalType::Timestamp
3037        | LogicalType::TimestampS
3038        | LogicalType::TimestampMs
3039        | LogicalType::TimestampNs => {
3040            signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
3041        }
3042        LogicalType::TimestampTz => {
3043            signed().and_then(|x| i64::try_from(x).ok()).map(Value::TimestampTz)
3044        }
3045        LogicalType::Interval => match data {
3046            Data::Interval(v) => {
3047                v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
3048            }
3049            _ => None,
3050        },
3051        _ => None,
3052    };
3053    value.unwrap_or(Value::Null)
3054}
3055
3056/// The fields a struct type names, and nothing for any other type.
3057///
3058/// Only a `STRUCT` vector has a [`Body::Fields`] body, and the two are built together, so in practice
3059/// the empty slice is unreachable and is here so that reading a field name is not a panic if that ever
3060/// stops being true. A struct vector whose type has fewer fields than it has children answers about
3061/// the fields it can name, because the zip stops at the shorter of the two.
3062fn fields_of(ty: &LogicalType) -> &[Field] {
3063    match ty {
3064        LogicalType::Struct(fields) => fields,
3065        _ => &[],
3066    }
3067}
3068
3069/// One row of a string column as a value, given what its bytes are meant to be read as.
3070///
3071/// Both forms that hold strings come through here, so a row that is a `BLOB` in a flat column is a
3072/// `BLOB` in a string view column too. Bytes that are not text in a `VARCHAR` column are a null
3073/// rather than a panic, since everything that got in went in as a string and a column that has
3074/// something else in it is a bug somewhere earlier that a read should not turn into a crash.
3075fn bytes_as(ty: &LogicalType, bytes: &[u8]) -> Value {
3076    match ty {
3077        LogicalType::Varchar => {
3078            std::str::from_utf8(bytes).map_or(Value::Null, |text| Value::Varchar(text.to_owned()))
3079        }
3080        LogicalType::Blob | LogicalType::Bit => Value::Blob(bytes.to_vec()),
3081        _ => Value::Null,
3082    }
3083}
3084
3085/// An empty run of data of the right layout for a type.
3086pub(crate) fn empty_data_for(ty: &LogicalType) -> Result<Data> {
3087    use rudb_common::PhysicalType as P;
3088    macro_rules! empties {
3089        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
3090            match ty.physical() {
3091                P::Empty => Data::Empty,
3092                $(P::$variant => Data::$variant(Buffer::new()),)+
3093                P::Varlen => Data::Varlen(StringColumn::new()),
3094                other => {
3095                    return Err(Error::not_implemented(format!(
3096                        "a flat vector of {other:?} data, which arrives with the storage layer"
3097                    )));
3098                }
3099            }
3100        };
3101    }
3102    Ok(crate::for_each_layout!(fixed, empties))
3103}
3104
3105/// Appends one value to a run of data, or a zero of the right shape when it is null.
3106///
3107/// The zero matters. A null still occupies a position, the validity mask is what says it is null,
3108/// and a run of data with a hole in it would put every value after the hole in the wrong place.
3109fn push_value(data: &mut Data, value: &Value) -> Result<()> {
3110    macro_rules! push {
3111        ($vec:expr, $variant:path, $zero:expr) => {
3112            match value {
3113                Value::Null => $vec.push($zero),
3114                $variant(x) => $vec.push(*x),
3115                other => {
3116                    return Err(Error::internal(format!(
3117                        "{other:?} does not belong in this vector"
3118                    )));
3119                }
3120            }
3121        };
3122    }
3123    // A decimal is stored as its unscaled integer in whatever width its precision needs, which
3124    // `LogicalType::physical` decides and which is why the same `Value::Decimal` is at home in four
3125    // different runs. The narrowing cannot fail for a value the binder produced, because the width
3126    // that chose the run is the width in the value, but it is checked rather than assumed because
3127    // an unchecked cast here would silently store a different number.
3128    macro_rules! decimal {
3129        ($vec:expr, $ty:ty, $unscaled:expr) => {
3130            match <$ty>::try_from(*$unscaled) {
3131                Ok(x) => $vec.push(x),
3132                Err(_) => {
3133                    return Err(Error::internal(format!(
3134                        "an unscaled decimal of {} does not fit the run its precision chose",
3135                        $unscaled
3136                    )));
3137                }
3138            }
3139        };
3140    }
3141    match data {
3142        Data::Empty => {}
3143        Data::Bool(v) => push!(v, Value::Boolean, false),
3144        Data::Int8(v) => push!(v, Value::TinyInt, 0),
3145        Data::Int16(v) => match value {
3146            Value::Null => v.push(0),
3147            Value::SmallInt(x) => v.push(*x),
3148            Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
3149            other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
3150        },
3151        Data::Int32(v) => match value {
3152            Value::Null => v.push(0),
3153            Value::Integer(x) | Value::Date(x) => v.push(*x),
3154            Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
3155            other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
3156        },
3157        Data::Int64(v) => match value {
3158            Value::Null => v.push(0),
3159            Value::BigInt(x)
3160            | Value::Time(x)
3161            | Value::TimeTz(x)
3162            | Value::Timestamp(x)
3163            | Value::TimestampTz(x) => v.push(*x),
3164            Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
3165            other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
3166        },
3167        Data::Int128(v) => match value {
3168            Value::Null => v.push(0),
3169            Value::HugeInt(x) => v.push(*x),
3170            Value::Decimal { unscaled, .. } => v.push(*unscaled),
3171            other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
3172        },
3173        Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
3174        Data::UInt16(v) => push!(v, Value::USmallInt, 0),
3175        Data::UInt32(v) => push!(v, Value::UInteger, 0),
3176        Data::UInt64(v) => push!(v, Value::UBigInt, 0),
3177        Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
3178        Data::Float32(v) => push!(v, Value::Float, 0.0),
3179        Data::Float64(v) => push!(v, Value::Double, 0.0),
3180        Data::Interval(v) => match value {
3181            Value::Null => v.push((0, 0, 0)),
3182            Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
3183            other => return Err(Error::internal(format!("{other:?} is not an interval"))),
3184        },
3185        Data::Varlen(column) => match value {
3186            Value::Null => {
3187                column.push("");
3188            }
3189            Value::Varchar(text) => {
3190                column.push(text);
3191            }
3192            // A blob goes in as the bytes it is. The column stores a length and some bytes either
3193            // way, so text is the reading of one rather than a different column, and a blob that
3194            // is not UTF-8 is stored exactly like one that happens to be.
3195            Value::Blob(bytes) => {
3196                column.push_bytes(bytes);
3197            }
3198            other => return Err(Error::internal(format!("{other:?} is not a string"))),
3199        },
3200    }
3201    Ok(())
3202}
3203
3204#[cfg(test)]
3205mod tests {
3206    use std::sync::Arc;
3207
3208    use rudb_common::{Field, LogicalType, Value};
3209
3210    use super::{Body, Data, FSST_PAYS_AT, Form, MAP_KEY, MAP_VALUE, VECTOR_SIZE, Vector};
3211    use crate::buffer::Buffer;
3212    use crate::fsst::SymbolTable;
3213    use crate::string::{StringColumn, StringView};
3214    use crate::validity::Validity;
3215
3216    fn integers(values: &[i32]) -> Vector {
3217        Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec().into())).unwrap()
3218    }
3219
3220    /// A `Value::List` of integers, which is what a row of a list column arrives as.
3221    fn list(values: &[i32]) -> Value {
3222        Value::List {
3223            element: LogicalType::Integer,
3224            values: values.iter().map(|&v| Value::Integer(v)).collect(),
3225        }
3226    }
3227
3228    fn list_column(rows: &[Value]) -> Vector {
3229        Vector::from_values(LogicalType::list(LogicalType::Integer), rows).unwrap()
3230    }
3231
3232    #[test]
3233    fn a_list_column_is_one_child_and_a_range_per_row() {
3234        let rows = vec![list(&[1, 2, 3]), list(&[]), Value::Null, list(&[4])];
3235        let column = list_column(&rows);
3236        assert_eq!(column.form(), Form::List);
3237        assert_eq!(column.len(), 4);
3238        assert_eq!(column.logical_type(), &LogicalType::list(LogicalType::Integer));
3239        // Four rows and four elements, because a null and an empty list both contribute none.
3240        let (entries, child) = column.list_parts().expect("a list");
3241        assert_eq!(entries, [(0, 3), (3, 0), (3, 0), (3, 1)]);
3242        assert_eq!(child.len(), 4);
3243        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
3244    }
3245
3246    /// The one thing the entries cannot say on their own, so it has to be checked that the mask says
3247    /// it. An empty list is a row that is there and holds nothing, a null is a row that is not there,
3248    /// and both of them have an entry of length zero.
3249    #[test]
3250    fn an_empty_list_and_a_null_list_have_the_same_entry_and_are_different_rows() {
3251        let column = list_column(&[list(&[]), Value::Null]);
3252        let (entries, _) = column.list_parts().expect("a list");
3253        assert_eq!(entries[0].1, entries[1].1, "both entries are empty");
3254        assert!(!column.is_null_at(0), "an empty list is not null");
3255        assert!(column.is_null_at(1), "a null list is null");
3256        assert_eq!(column.value_at(0), list(&[]));
3257        assert_eq!(column.value_at(1), Value::Null);
3258    }
3259
3260    #[test]
3261    fn slicing_a_list_column_shares_the_child_rather_than_copying_it() {
3262        let rows: Vec<Value> = (0..64).map(|row| list(&[row, row + 1, row + 2])).collect();
3263        let column = list_column(&rows);
3264        let cut = column.slice(8, 4).unwrap();
3265        assert_eq!(cut.form(), Form::List);
3266        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[8..12]);
3267        // The entries are absolute positions in a child that was not cut, which is what makes the
3268        // cut eight bytes a row however long the lists are. The elements outside the range are still
3269        // there and nothing points at them.
3270        let (entries, child) = cut.list_parts().expect("a list");
3271        assert_eq!(entries[0], (24, 3));
3272        assert_eq!(child.len(), 192);
3273    }
3274
3275    #[test]
3276    fn gathering_a_list_column_permutes_the_entries_and_leaves_the_child_alone() {
3277        let rows = vec![list(&[1]), list(&[2, 2]), list(&[3, 3, 3])];
3278        let column = list_column(&rows);
3279        let picked = column.gather(&[2, 0, 2]).unwrap();
3280        assert_eq!(
3281            picked.iter().collect::<Vec<_>>(),
3282            [list(&[3, 3, 3]), list(&[1]), list(&[3, 3, 3])]
3283        );
3284        // Two of the three rows are the same row, which is the case a run of offsets cannot write
3285        // down and a start and a length can. That is the whole reason this form carries both.
3286        assert_eq!(picked.list_parts().expect("a list").1.len(), 6);
3287    }
3288
3289    #[test]
3290    fn a_gather_past_the_end_of_a_list_column_is_null_rather_than_somebody_elses_elements() {
3291        let column = list_column(&[list(&[1, 2]), list(&[3])]);
3292        let picked = column.gather(&[1, 9]).unwrap();
3293        assert_eq!(picked.value_at(0), list(&[3]));
3294        assert_eq!(picked.value_at(1), Value::Null);
3295    }
3296
3297    #[test]
3298    fn a_list_of_lists_nests_as_far_as_it_is_written() {
3299        let outer = Value::List {
3300            element: LogicalType::list(LogicalType::Integer),
3301            values: vec![list(&[1, 2]), list(&[3])],
3302        };
3303        let column = Vector::from_values(
3304            LogicalType::list(LogicalType::list(LogicalType::Integer)),
3305            std::slice::from_ref(&outer),
3306        )
3307        .unwrap();
3308        assert_eq!(column.value_at(0), outer);
3309        assert_eq!(column.list_parts().expect("a list").1.form(), Form::List);
3310    }
3311
3312    /// A list row is not bytes and not an integer, and a caller that asks for either gets nothing
3313    /// rather than the first element or a length. Both of those would be a wrong answer that a
3314    /// group by or a hash would read without complaining.
3315    #[test]
3316    fn the_scalar_readers_decline_a_list_instead_of_answering_about_its_elements() {
3317        let column = list_column(&[list(&[7])]);
3318        assert_eq!(column.signed_at(0), None);
3319        assert_eq!(column.bytes_at(0), None);
3320        assert_eq!(column.data(), None);
3321    }
3322
3323    fn pair(a: i32, b: &str) -> Value {
3324        Value::Struct(vec![
3325            ("a".to_string(), Value::Integer(a)),
3326            ("b".to_string(), Value::Varchar(b.to_string())),
3327        ])
3328    }
3329
3330    fn pair_type() -> LogicalType {
3331        LogicalType::Struct(vec![
3332            Field::new("a", LogicalType::Integer),
3333            Field::new("b", LogicalType::Varchar),
3334        ])
3335    }
3336
3337    fn pair_column(rows: &[Value]) -> Vector {
3338        Vector::from_values(pair_type(), rows).unwrap()
3339    }
3340
3341    #[test]
3342    fn a_struct_column_is_one_child_per_field_as_long_as_the_column() {
3343        let rows = vec![pair(1, "x"), pair(2, "y"), pair(3, "z")];
3344        let column = pair_column(&rows);
3345        assert_eq!(column.form(), Form::Struct);
3346        assert_eq!(column.len(), 3);
3347        assert_eq!(column.logical_type(), &pair_type());
3348        // Two children rather than two entries and a child, and both of them as long as the column,
3349        // which is the whole difference between this form and the list one.
3350        let children = column.struct_parts().expect("a struct");
3351        assert_eq!(children.len(), 2);
3352        assert_eq!(children[0].len(), 3);
3353        assert_eq!(children[1].len(), 3);
3354        assert_eq!(children[0].logical_type(), &LogicalType::Integer);
3355        assert_eq!(children[1].logical_type(), &LogicalType::Varchar);
3356        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
3357    }
3358
3359    /// Picking one field out of a struct is picking one child, which is the reason this accessor is
3360    /// public. A projection of `s.a` hands back a vector that already exists, so it costs a pointer
3361    /// rather than a pass over the rows, and that is only true while the children are full length.
3362    #[test]
3363    fn one_field_of_a_struct_column_is_a_column_that_is_already_there() {
3364        let column = pair_column(&[pair(10, "x"), pair(20, "y")]);
3365        let field = &column.struct_parts().expect("a struct")[0];
3366        assert_eq!(field.iter().collect::<Vec<_>>(), [Value::Integer(10), Value::Integer(20)]);
3367        assert_eq!(field.signed_at(1), Some(20), "the field is a scalar column and reads like one");
3368    }
3369
3370    /// A null struct is a bit in the mask at the top and nothing deeper, which is how every other type
3371    /// records a null and is what DuckDB does. The row reads as a single null rather than as a struct of
3372    /// nulls, and the fields underneath are still their own columns.
3373    #[test]
3374    fn a_null_struct_is_the_mask_at_the_top_and_not_a_struct_full_of_nulls() {
3375        let column = pair_column(&[pair(1, "x"), Value::Null]);
3376        assert!(!column.is_null_at(0));
3377        assert!(column.is_null_at(1));
3378        assert_eq!(column.value_at(1), Value::Null);
3379        // A struct row whose every field happens to be null is a different row, and it is not null.
3380        let all_null = pair_column(&[Value::Struct(vec![
3381            ("a".to_string(), Value::Null),
3382            ("b".to_string(), Value::Null),
3383        ])]);
3384        assert!(!all_null.is_null_at(0), "a struct of nulls is a row that is there");
3385        assert_ne!(all_null.value_at(0), Value::Null);
3386    }
3387
3388    #[test]
3389    fn slicing_a_struct_column_cuts_every_field_at_the_same_place() {
3390        let rows: Vec<Value> = (0..64).map(|row| pair(row, "s")).collect();
3391        let column = pair_column(&rows);
3392        let cut = column.slice(8, 4).unwrap();
3393        assert_eq!(cut.form(), Form::Struct);
3394        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[8..12]);
3395        // The cut a list column does not have to do. A list shares its child untouched because the
3396        // entries carry the range, and a struct has no entry standing between the row and the child,
3397        // so every child is four rows long here rather than sixty four.
3398        for child in cut.struct_parts().expect("a struct") {
3399            assert_eq!(child.len(), 4);
3400        }
3401    }
3402
3403    #[test]
3404    fn gathering_a_struct_column_gathers_every_field_at_the_same_positions() {
3405        let column = pair_column(&[pair(1, "x"), pair(2, "y"), pair(3, "z")]);
3406        let picked = column.gather(&[2, 0, 2]).unwrap();
3407        assert_eq!(picked.iter().collect::<Vec<_>>(), [pair(3, "z"), pair(1, "x"), pair(3, "z")]);
3408        for child in picked.struct_parts().expect("a struct") {
3409            assert_eq!(child.len(), 3, "a field is as long as the gather, not as the source");
3410        }
3411    }
3412
3413    #[test]
3414    fn a_gather_past_the_end_of_a_struct_column_is_null_in_every_field_and_at_the_top() {
3415        let column = pair_column(&[pair(1, "x"), pair(2, "y")]);
3416        let picked = column.gather(&[1, 9]).unwrap();
3417        assert_eq!(picked.value_at(0), pair(2, "y"));
3418        assert_eq!(picked.value_at(1), Value::Null);
3419        for child in picked.struct_parts().expect("a struct") {
3420            assert!(child.is_null_at(1), "a row that came from nowhere has no field value either");
3421        }
3422    }
3423
3424    /// The names are matched and not counted, because a caller holding a struct value built in a
3425    /// different order from the type's would otherwise get its columns transposed, and that is a wrong
3426    /// answer that reads as a right one.
3427    #[test]
3428    fn the_fields_of_a_struct_value_go_in_by_name_rather_than_by_position() {
3429        let swapped = Value::Struct(vec![
3430            ("b".to_string(), Value::Varchar("x".to_string())),
3431            ("a".to_string(), Value::Integer(1)),
3432        ]);
3433        let column = pair_column(&[swapped]);
3434        assert_eq!(column.value_at(0), pair(1, "x"));
3435        let wrong = Value::Struct(vec![
3436            ("a".to_string(), Value::Integer(1)),
3437            ("c".to_string(), Value::Varchar("x".to_string())),
3438        ]);
3439        let failed = Vector::from_values(pair_type(), &[wrong]);
3440        assert!(failed.is_err(), "a row with no b field is an error rather than a null b");
3441    }
3442
3443    #[test]
3444    fn a_struct_built_from_children_takes_its_field_names_from_the_caller() {
3445        let column = Vector::structure(vec![
3446            ("a".to_string(), integers(&[1, 2, 3])),
3447            ("b".to_string(), integers(&[4, 5, 6])),
3448        ])
3449        .expect("two columns of three");
3450        assert_eq!(column.len(), 3);
3451        assert_eq!(
3452            column.logical_type(),
3453            &LogicalType::Struct(vec![
3454                Field::new("a", LogicalType::Integer),
3455                Field::new("b", LogicalType::Integer),
3456            ])
3457        );
3458        assert_eq!(
3459            column.value_at(1),
3460            Value::Struct(vec![
3461                ("a".to_string(), Value::Integer(2)),
3462                ("b".to_string(), Value::Integer(5)),
3463            ])
3464        );
3465    }
3466
3467    /// The two mistakes this constructor makes easy, both refused rather than stored. A short field is
3468    /// the one that matters: it would be a struct that reads past the end of one of its own children,
3469    /// which is the same mistake `Vector::list` checks for at the other end.
3470    #[test]
3471    fn a_struct_of_uneven_children_or_of_no_children_is_refused() {
3472        let uneven = Vector::structure(vec![
3473            ("a".to_string(), integers(&[1, 2, 3])),
3474            ("b".to_string(), integers(&[4, 5])),
3475        ]);
3476        assert!(uneven.is_err(), "a field shorter than the struct");
3477        assert!(Vector::structure(vec![]).is_err(), "no field to take a length from");
3478    }
3479
3480    #[test]
3481    fn a_struct_of_lists_and_a_list_of_structs_both_nest() {
3482        let ty =
3483            LogicalType::Struct(vec![Field::new("a", LogicalType::list(LogicalType::Integer))]);
3484        let row = Value::Struct(vec![("a".to_string(), list(&[1, 2]))]);
3485        let column = Vector::from_values(ty, std::slice::from_ref(&row)).unwrap();
3486        assert_eq!(column.value_at(0), row);
3487        assert_eq!(column.struct_parts().expect("a struct")[0].form(), Form::List);
3488
3489        let outer = Value::List { element: pair_type(), values: vec![pair(1, "x"), pair(2, "y")] };
3490        let lists =
3491            Vector::from_values(LogicalType::list(pair_type()), std::slice::from_ref(&outer))
3492                .unwrap();
3493        assert_eq!(lists.value_at(0), outer);
3494        assert_eq!(lists.list_parts().expect("a list").1.form(), Form::Struct);
3495    }
3496
3497    fn tags(pairs: &[(&str, &str)]) -> Value {
3498        Value::map(
3499            LogicalType::Varchar,
3500            LogicalType::Varchar,
3501            pairs
3502                .iter()
3503                .map(|&(key, value)| {
3504                    (Value::Varchar(key.to_string()), Value::Varchar(value.to_string()))
3505                })
3506                .collect(),
3507        )
3508    }
3509
3510    fn tag_column(rows: &[Value]) -> Vector {
3511        Vector::from_values(LogicalType::map(LogicalType::Varchar, LogicalType::Varchar), rows)
3512            .unwrap()
3513    }
3514
3515    /// A map is a list of two field structs, which is the whole design, so the test that says so is
3516    /// the one that reaches through both layers and finds the pieces where each of them puts them.
3517    #[test]
3518    fn a_map_column_is_a_list_whose_child_is_a_struct_of_keys_and_values() {
3519        let rows =
3520            vec![tags(&[("a", "b"), ("c", "d")]), tags(&[]), Value::Null, tags(&[("e", "f")])];
3521        let column = tag_column(&rows);
3522        assert_eq!(column.len(), 4);
3523        assert_eq!(
3524            column.logical_type(),
3525            &LogicalType::map(LogicalType::Varchar, LogicalType::Varchar)
3526        );
3527        // The physical form is a list's, because the bytes are a list's. The logical type is what
3528        // remembers it is a map, which is the same split `LogicalType::physical` already makes.
3529        assert_eq!(column.form(), Form::List);
3530        let (entries, child) = column.list_parts().expect("the layout of a list");
3531        assert_eq!(entries, [(0, 2), (2, 0), (2, 0), (2, 1)]);
3532        assert_eq!(child.form(), Form::Struct);
3533        assert_eq!(
3534            child.logical_type(),
3535            &LogicalType::Struct(vec![
3536                Field::new(MAP_KEY, LogicalType::Varchar),
3537                Field::new(MAP_VALUE, LogicalType::Varchar),
3538            ])
3539        );
3540        // And the accessor that reaches through it hands back the two columns rather than the struct.
3541        let (entries, keys, values) = column.map_parts().expect("a map");
3542        assert_eq!(entries.len(), 4);
3543        assert_eq!(keys.text_at(0), Some("a"));
3544        assert_eq!(values.text_at(0), Some("b"));
3545        assert_eq!(column.iter().collect::<Vec<_>>(), rows);
3546    }
3547
3548    /// The same distinction a list has, checked again here rather than assumed from the composition,
3549    /// because the empty map is the one every catalog table in D2 is full of and a null map is what a
3550    /// column with no tags at all would be.
3551    #[test]
3552    fn an_empty_map_and_a_null_map_are_different_rows() {
3553        let column = tag_column(&[tags(&[]), Value::Null]);
3554        assert!(!column.is_null_at(0), "an empty map is a row that is there");
3555        assert!(column.is_null_at(1));
3556        assert_eq!(column.value_at(0), tags(&[]));
3557        assert_eq!(column.value_at(1), Value::Null);
3558        assert_eq!(column.value_at(0).to_string(), "{}");
3559        assert_eq!(column.value_at(1).to_string(), "NULL");
3560    }
3561
3562    /// A map prints `{a=b}` and a struct prints `{'a': b}`, both measured off the pin. They share a
3563    /// layout and they cannot share a printer, which is the one thing about this composition that does
3564    /// not fall out of it.
3565    #[test]
3566    fn a_map_prints_with_equals_signs_and_a_struct_prints_with_quoted_names() {
3567        assert_eq!(tags(&[("a", "b"), ("c", "d")]).to_string(), "{a=b, c=d}");
3568        assert_eq!(pair(1, "x").to_string(), "{'a': 1, 'b': x}");
3569        let numbers = Value::map(
3570            LogicalType::Integer,
3571            LogicalType::Integer,
3572            vec![(Value::Integer(1), Value::Integer(3)), (Value::Integer(2), Value::Integer(4))],
3573        );
3574        assert_eq!(numbers.to_string(), "{1=3, 2=4}");
3575        let null_value = Value::map(
3576            LogicalType::Varchar,
3577            LogicalType::Varchar,
3578            vec![(Value::Varchar("x".to_string()), Value::Null)],
3579        );
3580        assert_eq!(null_value.to_string(), "{x=NULL}");
3581    }
3582
3583    /// A map inherits the list's cut and the list's gather, which is the payoff for storing it as one.
3584    /// Neither of these is code written for maps and both of them are worth a test that says the
3585    /// inheritance works, since the type is rewritten on the way through and a form that came back as a
3586    /// list would still read.
3587    #[test]
3588    fn cutting_and_gathering_a_map_keeps_it_a_map() {
3589        let rows: Vec<Value> =
3590            (0..16).map(|row| tags(&[("k", if row % 2 == 0 { "e" } else { "o" })])).collect();
3591        let column = tag_column(&rows);
3592
3593        let cut = column.slice(4, 3).unwrap();
3594        assert!(matches!(cut.logical_type(), LogicalType::Map(_, _)), "still a map after a cut");
3595        assert_eq!(cut.iter().collect::<Vec<_>>(), rows[4..7]);
3596        // The child was not cut, the same as for a list, which is what makes the cut eight bytes a row.
3597        assert_eq!(cut.map_parts().expect("a map").1.len(), 16);
3598
3599        let picked = column.gather(&[3, 0, 3]).unwrap();
3600        assert!(matches!(picked.logical_type(), LogicalType::Map(_, _)));
3601        assert_eq!(
3602            picked.iter().collect::<Vec<_>>(),
3603            [rows[3].clone(), rows[0].clone(), rows[3].clone()]
3604        );
3605        let past = column.gather(&[0, 99]).unwrap();
3606        assert_eq!(past.value_at(1), Value::Null);
3607    }
3608
3609    #[test]
3610    fn a_map_built_from_two_columns_pairs_them_by_position() {
3611        let keys = Vector::from_values(
3612            LogicalType::Varchar,
3613            &[Value::Varchar("a".to_string()), Value::Varchar("c".to_string())],
3614        )
3615        .unwrap();
3616        let values = Vector::from_values(
3617            LogicalType::Varchar,
3618            &[Value::Varchar("b".to_string()), Value::Varchar("d".to_string())],
3619        )
3620        .unwrap();
3621        let column = Vector::map(vec![(0, 2), (2, 0)], keys, values).expect("two rows");
3622        assert_eq!(column.len(), 2);
3623        assert_eq!(
3624            column.logical_type(),
3625            &LogicalType::map(LogicalType::Varchar, LogicalType::Varchar)
3626        );
3627        assert_eq!(column.value_at(0), tags(&[("a", "b"), ("c", "d")]));
3628        assert_eq!(column.value_at(1), tags(&[]));
3629        // The entry check the list constructor does is the one a map gets, so an entry past the end of
3630        // the pair of columns is refused here too rather than read as somebody else's keys.
3631        let short =
3632            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("a".to_string())]).unwrap();
3633        let other =
3634            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("b".to_string())]).unwrap();
3635        assert!(Vector::map(vec![(0, 9)], short, other).is_err(), "an entry past the end");
3636    }
3637
3638    /// `map_parts` is about the logical type and `list_parts` is about the layout, so a list has to
3639    /// decline the first and a map has to answer the second. Getting that backwards would let a kernel
3640    /// written for maps read a list of two field structs as if it were one.
3641    #[test]
3642    fn a_list_is_not_a_map_however_much_its_child_looks_like_one() {
3643        let pairs = Value::List { element: pair_type(), values: vec![pair(1, "x")] };
3644        let column =
3645            Vector::from_values(LogicalType::list(pair_type()), std::slice::from_ref(&pairs))
3646                .unwrap();
3647        assert!(column.map_parts().is_none(), "a list of structs is a list");
3648        assert!(column.list_parts().is_some());
3649        let map = tag_column(&[tags(&[("a", "b")])]);
3650        assert!(map.map_parts().is_some());
3651        assert!(map.list_parts().is_some(), "a map has a list's layout and says so");
3652    }
3653
3654    /// A struct row is not bytes and not an integer, and it stays that way when it has exactly one
3655    /// integer field, which is the case where answering about the field would look reasonable and would
3656    /// be a hash keyed on the wrong thing.
3657    #[test]
3658    fn the_scalar_readers_decline_a_struct_of_one_integer_field() {
3659        let ty = LogicalType::Struct(vec![Field::new("a", LogicalType::Integer)]);
3660        let row = Value::Struct(vec![("a".to_string(), Value::Integer(7))]);
3661        let column = Vector::from_values(ty, &[row]).unwrap();
3662        assert_eq!(column.signed_at(0), None);
3663        assert_eq!(column.bytes_at(0), None);
3664        assert_eq!(column.data(), None);
3665    }
3666
3667    #[test]
3668    fn a_clustered_column_becomes_runs_and_reads_back_the_same() {
3669        let mut values = Vec::new();
3670        for (value, times) in [(7, 400), (8, 300), (7, 324)] {
3671            values.extend(std::iter::repeat_n(value, times));
3672        }
3673        let flat = integers(&values);
3674        let runs = flat.run_encoded().unwrap();
3675        assert_eq!(runs.form(), Form::Rle);
3676        assert_eq!(runs.run_parts().expect("runs").0, [400, 700, 1024]);
3677        assert_eq!(runs.len(), flat.len());
3678        assert_eq!(runs.iter().collect::<Vec<_>>(), flat.iter().collect::<Vec<_>>());
3679        assert!(
3680            runs.footprint() * 10 < flat.footprint(),
3681            "three runs against a thousand rows: {} against {}",
3682            runs.footprint(),
3683            flat.footprint()
3684        );
3685    }
3686
3687    /// The check is worth having in both directions. A form that is only ever bigger than what it
3688    /// replaced is a form that costs a pass over the column to decide not to use.
3689    #[test]
3690    fn a_column_that_does_not_repeat_is_left_flat() {
3691        let flat = integers(&(0..1024).collect::<Vec<i32>>());
3692        assert_eq!(flat.run_encoded().unwrap().form(), Form::Flat);
3693        // Two runs over four rows is exactly break even on a four byte column, and break even is
3694        // not a reason to change form.
3695        assert_eq!(integers(&[1, 1, 2, 2]).run_encoded().unwrap().form(), Form::Flat);
3696        assert_eq!(integers(&[1, 1, 1, 2, 2]).run_encoded().unwrap().form(), Form::Rle);
3697    }
3698
3699    #[test]
3700    fn two_nulls_beside_each_other_are_one_run_and_a_null_between_two_equals_is_a_break() {
3701        let mut values = vec![Value::Integer(4), Value::Integer(4)];
3702        values.extend([Value::Null, Value::Null, Value::Null]);
3703        values.extend(std::iter::repeat_n(Value::Integer(4), 5));
3704        let flat = Vector::from_values(LogicalType::Integer, &values).unwrap();
3705        let runs = flat.run_encoded().unwrap();
3706        assert_eq!(runs.run_parts().expect("runs").0, [2, 5, 10]);
3707        assert_eq!(runs.iter().collect::<Vec<_>>(), values);
3708    }
3709
3710    #[test]
3711    fn slicing_runs_keeps_them_runs_and_cuts_the_first_and_last_one_back() {
3712        let flat = integers(&[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]);
3713        let runs = flat.run_encoded().unwrap();
3714        let piece = runs.slice(3, 6).unwrap();
3715        assert_eq!(piece.form(), Form::Rle, "the form is the whole point");
3716        assert_eq!(piece.run_parts().expect("runs").0, [1, 5, 6]);
3717        assert_eq!(
3718            piece.iter().collect::<Vec<_>>(),
3719            flat.slice(3, 6).unwrap().iter().collect::<Vec<_>>()
3720        );
3721        assert_eq!(runs.slice(0, 0).unwrap().len(), 0);
3722        assert_eq!(runs.slice(0, 12).unwrap().form(), Form::Rle);
3723    }
3724
3725    #[test]
3726    fn gathering_out_of_runs_walks_to_the_values_the_way_it_walks_a_dictionary() {
3727        let mut values = vec![Value::Varchar("red".into()); 4];
3728        values.extend([Value::Null, Value::Null, Value::Null]);
3729        values.extend(vec![Value::Varchar("blue".into()); 4]);
3730        let runs =
3731            Vector::from_values(LogicalType::Varchar, &values).unwrap().run_encoded().unwrap();
3732        assert_eq!(runs.form(), Form::Rle);
3733        let picked = runs.gather(&[8, 0, 5, 2]).unwrap();
3734        assert_eq!(picked.form(), Form::Flat, "a gather copies, whatever it gathered from");
3735        assert_eq!(
3736            picked.iter().collect::<Vec<_>>(),
3737            [values[8].clone(), values[0].clone(), Value::Null, values[2].clone()]
3738        );
3739        assert_eq!(runs.text_at(1), Some("red"));
3740        assert_eq!(runs.text_at(5), None, "a null has no text");
3741        assert_eq!(runs.flatten().unwrap().iter().collect::<Vec<_>>(), values);
3742    }
3743
3744    /// A run length vector over a run length vector turns one search per row into two, and there is
3745    /// nothing in the engine that builds one, so it is refused rather than composed.
3746    #[test]
3747    fn runs_of_runs_are_refused_and_runs_of_a_dictionary_are_not() {
3748        let inner = integers(&[1, 1, 1, 1, 2]).run_encoded().unwrap();
3749        assert_eq!(inner.form(), Form::Rle);
3750        let error = Vector::runs(vec![2, 8], inner).unwrap_err();
3751        assert!(error.to_string().contains("runs of runs"), "{error}");
3752
3753        let words = Vector::from_values(
3754            LogicalType::Varchar,
3755            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
3756        )
3757        .unwrap();
3758        let dictionary = Vector::dictionary(vec![1, 0], words).unwrap();
3759        let stacked = Vector::runs(vec![4, 9], dictionary).unwrap();
3760        assert_eq!(stacked.len(), 9);
3761        assert_eq!(stacked.value_at(3), Value::Varchar("blue".into()));
3762        assert_eq!(stacked.value_at(4), Value::Varchar("red".into()));
3763    }
3764
3765    #[test]
3766    fn run_ends_have_to_increase_and_there_is_one_value_for_each_of_them() {
3767        let values = integers(&[1, 2]);
3768        assert!(Vector::runs(vec![4], values.clone()).is_err(), "two values and one run");
3769        assert!(Vector::runs(vec![4, 4], values.clone()).is_err(), "an end that repeats");
3770        assert!(Vector::runs(vec![4, 2], values.clone()).is_err(), "an end that goes backwards");
3771        assert!(Vector::runs(vec![0, 2], values.clone()).is_err(), "a first run holding no rows");
3772        assert_eq!(Vector::runs(vec![4, 9], values).unwrap().len(), 9);
3773    }
3774
3775    #[test]
3776    fn a_form_that_is_already_compact_is_left_where_it_is() {
3777        let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1000);
3778        assert_eq!(constant.run_encoded().unwrap().form(), Form::Constant);
3779        assert_eq!(Vector::sequence(0, 1, 1000).run_encoded().unwrap().form(), Form::Sequence);
3780    }
3781
3782    /// What makes one accessor cover both forms. A dictionary hands back the codes it stores and a
3783    /// run length vector works the same numbers out, and a kernel writing `values[at[row]]` reads
3784    /// the same rows out of either.
3785    #[test]
3786    fn both_forms_that_point_somewhere_hand_back_a_position_per_row() {
3787        let words = Vector::from_values(
3788            LogicalType::Varchar,
3789            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
3790        )
3791        .unwrap();
3792        let runs = Vector::runs(vec![3, 5], words.clone()).unwrap();
3793        let (at, values) = runs.positions().expect("runs point somewhere");
3794        assert_eq!(at.as_ref(), [0, 0, 0, 1, 1]);
3795        assert_eq!(values.value_at(at[3] as usize), runs.value_at(3));
3796
3797        let dictionary = Vector::dictionary(vec![1, 0, 1], words).unwrap();
3798        let (at, values) = dictionary.positions().expect("a dictionary points somewhere");
3799        assert_eq!(at.as_ref(), [1, 0, 1]);
3800        assert_eq!(values.value_at(at[0] as usize), dictionary.value_at(0));
3801
3802        assert!(integers(&[1, 2, 3]).positions().is_none(), "a flat vector points at itself");
3803        assert!(Vector::sequence(0, 1, 4).positions().is_none(), "a sequence stores nothing");
3804    }
3805
3806    #[test]
3807    fn slicing_a_dictionary_keeps_it_a_dictionary_where_gathering_would_not() {
3808        let values = Vector::from_values(
3809            LogicalType::Varchar,
3810            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
3811        )
3812        .unwrap();
3813        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
3814
3815        let piece = vector.slice(1, 3).unwrap();
3816        assert_eq!(piece.form(), Form::Dictionary, "the form is the whole point");
3817        assert_eq!(piece.len(), 3);
3818        assert_eq!(
3819            piece.iter().collect::<Vec<_>>(),
3820            [
3821                Value::Varchar("blue".into()),
3822                Value::Varchar("blue".into()),
3823                Value::Varchar("red".into())
3824            ]
3825        );
3826        assert_eq!(vector.gather(&[1, 2, 3]).unwrap().form(), Form::Flat, "which a gather loses");
3827    }
3828
3829    #[test]
3830    fn slicing_a_dictionary_shares_the_dictionary_rather_than_copying_it() {
3831        // The assertion is about the address and not about the values, because the values were
3832        // right when the dictionary was copied too. A page holds one dictionary and is cut into a
3833        // chunk of codes at a time, so copying the dictionary here is a copy of every string in it
3834        // per chunk, and on a read of a ClickBench partition it was ten percent of the cycles.
3835        let values = Vector::from_values(
3836            LogicalType::Varchar,
3837            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
3838        )
3839        .unwrap();
3840        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
3841        let Body::Dictionary { values: whole, .. } = &vector.body else {
3842            panic!("a dictionary vector holds a dictionary");
3843        };
3844
3845        let piece = vector.slice(1, 3).unwrap();
3846        let Body::Dictionary { codes, values: cut, .. } = &piece.body else {
3847            panic!("a slice of a dictionary is a dictionary");
3848        };
3849        assert!(Arc::ptr_eq(whole, cut), "the cut copied the dictionary");
3850        assert_eq!(codes, &[1, 1, 0], "the codes are the part that is cut");
3851
3852        // And a cut of a cut shares it too, since that is what a scan does to a page it reads twice.
3853        let again = piece.slice(1, 2).unwrap();
3854        let Body::Dictionary { values: cut, .. } = &again.body else {
3855            panic!("a slice of a slice of a dictionary is a dictionary");
3856        };
3857        assert!(Arc::ptr_eq(whole, cut), "the second cut copied the dictionary");
3858        assert_eq!(
3859            again.iter().collect::<Vec<_>>(),
3860            [Value::Varchar("blue".into()), Value::Varchar("red".into())]
3861        );
3862    }
3863
3864    #[test]
3865    fn a_slice_carries_the_nulls_that_were_in_its_range_and_not_the_others() {
3866        let vector =
3867            integers(&[1, 2, 3, 4]).with_validity(Validity::from_run(&[false, true, false, true]));
3868        let piece = vector.slice(1, 2).unwrap();
3869        assert!(piece.validity().is_valid(0));
3870        assert!(!piece.validity().is_valid(1));
3871        assert_eq!(piece.value_at(1), Value::Null);
3872    }
3873
3874    #[test]
3875    fn slicing_a_sequence_moves_its_start_rather_than_writing_the_values_out() {
3876        let vector = Vector::sequence(100, 5, 10);
3877        let piece = vector.slice(3, 4).unwrap();
3878        assert_eq!(piece.form(), Form::Sequence);
3879        assert_eq!(
3880            piece.iter().collect::<Vec<_>>(),
3881            [Value::BigInt(115), Value::BigInt(120), Value::BigInt(125), Value::BigInt(130)]
3882        );
3883    }
3884
3885    #[test]
3886    fn slicing_a_constant_is_a_shorter_constant() {
3887        let vector = Vector::constant(LogicalType::Integer, Value::Integer(9), 8);
3888        let piece = vector.slice(2, 3).unwrap();
3889        assert_eq!(piece.form(), Form::Constant);
3890        assert_eq!(piece.len(), 3);
3891        assert_eq!(piece.value_at(2), Value::Integer(9));
3892    }
3893
3894    #[test]
3895    fn slicing_the_whole_vector_hands_it_back_as_it_was() {
3896        let vector = integers(&[1, 2, 3]);
3897        assert_eq!(
3898            vector.slice(0, 3).unwrap().iter().collect::<Vec<_>>(),
3899            [Value::Integer(1), Value::Integer(2), Value::Integer(3)]
3900        );
3901    }
3902
3903    #[test]
3904    fn cutting_a_flat_body_answers_what_gathering_the_same_rows_answers() {
3905        // The cut of a flat body used to be written as a gather over the positions in the range,
3906        // and it is now a run copied out, so the two have to keep saying the same thing. Every
3907        // start and every length, with nulls in the range and out of it, since the validity is the
3908        // half of this that changed shape.
3909        let rows: Vec<i32> = (0..70).collect();
3910        let valid: Vec<bool> = (0..70).map(|row| row % 7 != 0 && row % 11 != 3).collect();
3911        let vector = integers(&rows).with_validity(Validity::from_run(&valid));
3912        for at in 0..70usize {
3913            for len in 0..=(70 - at) {
3914                let cut = vector.slice(at, len).unwrap();
3915                let positions: Vec<u32> = (at..at + len).map(|row| row as u32).collect();
3916                let gathered = vector.gather(&positions).unwrap();
3917                assert_eq!(cut.len(), len, "rows {at} to {}", at + len);
3918                assert_eq!(
3919                    cut.iter().collect::<Vec<_>>(),
3920                    gathered.iter().collect::<Vec<_>>(),
3921                    "rows {at} to {}",
3922                    at + len
3923                );
3924            }
3925        }
3926    }
3927
3928    /// The flat body used to be the one form of a vector whose cut cost an allocation and a copy,
3929    /// and it is not any more when its buffer is a run inside a page. Asserted on the address,
3930    /// because the values are the same either way and the address is the whole claim.
3931    #[test]
3932    fn cutting_a_flat_body_over_a_page_does_not_copy_it() {
3933        let page = Arc::new((0i64..64).collect::<Vec<_>>());
3934        let address = page.as_ptr() as usize;
3935        let data = Data::Int64(Buffer::from_arc(Arc::clone(&page)));
3936        let vector = Vector::flat(LogicalType::BigInt, data).unwrap();
3937        let cut = vector.slice(16, 8).unwrap();
3938        assert_eq!(cut.form(), Form::Flat);
3939        assert_eq!(cut.len(), 8);
3940        let Some(Data::Int64(run)) = cut.data() else {
3941            panic!("the layout changed under the test")
3942        };
3943        assert!(run.is_shared(), "the cut copied the run out of the page");
3944        assert_eq!(run.as_slice().as_ptr() as usize, address + 16 * 8);
3945        assert_eq!(run.as_slice(), &(16i64..24).collect::<Vec<_>>()[..]);
3946        assert_eq!(cut.value_at(0), Value::BigInt(16));
3947        // And the same cut of an owned run says the same thing, by copying it.
3948        let owned = Vector::flat(LogicalType::BigInt, Data::Int64((0i64..64).collect())).unwrap();
3949        let copied = owned.slice(16, 8).unwrap();
3950        let Some(Data::Int64(run)) = copied.data() else {
3951            panic!("the layout changed under the test")
3952        };
3953        assert!(!run.is_shared());
3954        assert_eq!(run.as_slice(), &(16i64..24).collect::<Vec<_>>()[..]);
3955    }
3956
3957    /// `into_pages` is how a producer says its values will be handed out many times. A flat body is
3958    /// the form it changes, and after it a copy of the vector is a reference count bump.
3959    #[test]
3960    fn a_vector_over_pages_is_copied_and_cut_without_its_values_moving() {
3961        let vector = integers(&[1, 2, 3, 4, 5, 6, 7, 8]).into_pages();
3962        let address = |vector: &Vector| match vector.data() {
3963            Some(Data::Int32(values)) => values.as_slice().as_ptr() as usize,
3964            _ => panic!("the layout changed under the test"),
3965        };
3966        let stored = address(&vector);
3967        assert_eq!(address(&vector.clone()), stored, "a copy moved the values");
3968        assert_eq!(address(&vector.slice(2, 4).unwrap()), stored + 2 * 4, "a cut moved the values");
3969        assert_eq!(
3970            vector.slice(2, 4).unwrap().iter().collect::<Vec<_>>(),
3971            [Value::Integer(3), Value::Integer(4), Value::Integer(5), Value::Integer(6)]
3972        );
3973        // Twice is not two pages.
3974        assert_eq!(address(&vector.clone().into_pages()), stored);
3975    }
3976
3977    /// Every form that is not flat already shares what is expensive, so this is a no op on them and
3978    /// in particular does not flatten anything. A form that came back flat would be a column that
3979    /// lost its encoding on the way into a table.
3980    #[test]
3981    fn putting_a_vector_on_pages_does_not_change_any_other_form() {
3982        let dictionary = Vector::dictionary(
3983            vec![0, 1, 0, 1],
3984            Vector::from_values(
3985                LogicalType::Varchar,
3986                &[Value::Varchar("a".into()), Value::Varchar("b".into())],
3987            )
3988            .unwrap(),
3989        )
3990        .unwrap();
3991        let cases = [
3992            Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
3993            Vector::sequence(4, 0, 1),
3994            dictionary,
3995        ];
3996        for vector in cases {
3997            let form = vector.form();
3998            let paged = vector.clone().into_pages();
3999            assert_eq!(paged.form(), form, "{form:?} changed form");
4000            assert_eq!(paged.iter().collect::<Vec<_>>(), vector.iter().collect::<Vec<_>>());
4001        }
4002    }
4003
4004    #[test]
4005    fn cutting_a_flat_string_column_answers_what_gathering_it_answers() {
4006        // The string layout is the one whose cut is still a loop, and it is also the one where a
4007        // row is a view into an arena rather than a slot, so it gets the same treatment separately.
4008        // Both inline and out of line strings, since they are copied by different paths.
4009        let rows: Vec<String> =
4010            (0..40).map(|row| "x".repeat(row % 30) + &row.to_string()).collect();
4011        let values: Vec<Value> = rows.iter().map(|row| Value::Varchar(row.clone())).collect();
4012        let vector = Vector::from_values(LogicalType::Varchar, &values).unwrap().flatten().unwrap();
4013        assert_eq!(vector.form(), Form::Flat, "the cut under test is the flat one");
4014        for at in 0..40usize {
4015            for len in 0..=(40 - at) {
4016                let cut = vector.slice(at, len).unwrap();
4017                let positions: Vec<u32> = (at..at + len).map(|row| row as u32).collect();
4018                let gathered = vector.gather(&positions).unwrap();
4019                assert_eq!(
4020                    cut.iter().collect::<Vec<_>>(),
4021                    gathered.iter().collect::<Vec<_>>(),
4022                    "rows {at} to {}",
4023                    at + len
4024                );
4025            }
4026        }
4027    }
4028
4029    #[test]
4030    fn a_slice_past_the_end_is_an_error_rather_than_a_short_vector() {
4031        let error = integers(&[1, 2, 3]).slice(2, 2).unwrap_err();
4032        assert!(error.to_string().contains("of a vector of 3"), "{error}");
4033    }
4034
4035    #[test]
4036    fn the_vector_size_is_the_one_the_design_is_built_around() {
4037        // 1024 and not DuckDB's 2048. A validity mask is 16 u64 words and a vector of string views
4038        // is 16 KiB, both of which are consequences of this number rather than coincidences.
4039        assert_eq!(VECTOR_SIZE, 1024);
4040        assert_eq!(VECTOR_SIZE / 64, 16);
4041    }
4042
4043    #[test]
4044    fn a_flat_vector_reads_back_what_was_put_in_it() {
4045        let vector = integers(&[1, 2, 3]);
4046        assert_eq!(vector.form(), Form::Flat);
4047        assert_eq!(vector.len(), 3);
4048        assert_eq!(vector.value_at(1), Value::Integer(2));
4049        assert_eq!(
4050            vector.iter().collect::<Vec<_>>(),
4051            vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
4052        );
4053    }
4054
4055    #[test]
4056    fn a_vector_built_from_values_reads_the_same_values_back() {
4057        let vector = Vector::from_values(
4058            LogicalType::Varchar,
4059            &[
4060                Value::Varchar("a".to_string()),
4061                Value::Null,
4062                Value::Varchar("a string too long to sit inside a view".to_string()),
4063            ],
4064        )
4065        .expect("strings and a null");
4066        assert_eq!(vector.len(), 3);
4067        assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
4068        assert_eq!(vector.value_at(1), Value::Null);
4069        assert_eq!(
4070            vector.value_at(2),
4071            Value::Varchar("a string too long to sit inside a view".to_string())
4072        );
4073    }
4074
4075    /// A null still occupies a position. If it did not then every value after it would read back
4076    /// one place to the left, which is the kind of bug that looks like a storage bug for a week.
4077    #[test]
4078    fn a_null_in_the_middle_does_not_move_the_values_after_it() {
4079        let vector = Vector::from_values(
4080            LogicalType::Integer,
4081            &[Value::Integer(1), Value::Null, Value::Integer(3)],
4082        )
4083        .expect("integers and a null");
4084        assert_eq!(vector.value_at(2), Value::Integer(3));
4085        assert!(vector.validity().has_nulls(3), "the middle one is null");
4086    }
4087
4088    #[test]
4089    fn a_value_the_type_cannot_hold_is_refused() {
4090        let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
4091        assert!(wrong.is_err(), "a string is not an integer");
4092    }
4093
4094    #[test]
4095    fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
4096        // One comparison here against a wrong answer read out three layers later.
4097        let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1].into()));
4098        assert!(wrong.is_err());
4099        let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1].into()));
4100        assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
4101    }
4102
4103    #[test]
4104    fn a_constant_vector_costs_one_value_whatever_its_length() {
4105        let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
4106        assert_eq!(vector.form(), Form::Constant);
4107        assert_eq!(vector.len(), VECTOR_SIZE);
4108        assert_eq!(vector.value_at(0), Value::Integer(7));
4109        assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
4110        assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
4111    }
4112
4113    #[test]
4114    fn a_constant_null_is_all_invalid_without_being_told() {
4115        let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
4116        assert_eq!(vector.validity(), &Validity::AllInvalid);
4117        assert_eq!(vector.value_at(3), Value::Null);
4118    }
4119
4120    #[test]
4121    fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
4122        let vector = Vector::sequence(100, 1, VECTOR_SIZE);
4123        assert_eq!(vector.form(), Form::Sequence);
4124        assert_eq!(vector.value_at(0), Value::BigInt(100));
4125        assert_eq!(vector.value_at(923), Value::BigInt(1023));
4126        let stepped = Vector::sequence(0, 5, 4);
4127        assert_eq!(
4128            stepped.iter().collect::<Vec<_>>(),
4129            vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
4130        );
4131    }
4132
4133    #[test]
4134    fn a_dictionary_vector_reads_through_its_codes() {
4135        let mut column = StringColumn::new();
4136        column.push("red");
4137        column.push("green");
4138        let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
4139        let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
4140        assert_eq!(vector.form(), Form::Dictionary);
4141        assert_eq!(vector.logical_type(), &LogicalType::Varchar);
4142        assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
4143        assert_eq!(vector.len(), 4);
4144    }
4145
4146    /// The accessor a group by keys a string column through, which has to agree with `value_at` on
4147    /// every position or two rows holding one string end up in two groups.
4148    #[test]
4149    fn text_is_read_where_it_already_is_for_the_forms_that_store_it() {
4150        let mut column = StringColumn::new();
4151        column.push("red");
4152        column.push("green");
4153        column.push("");
4154        let flat = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
4155        for index in 0..flat.len() {
4156            assert_eq!(flat.text_at(index).map(str::to_string), text_of(&flat.value_at(index)));
4157        }
4158        let dictionary = Vector::dictionary(vec![1, 0, 1, 2], flat).unwrap();
4159        for index in 0..dictionary.len() {
4160            assert_eq!(
4161                dictionary.text_at(index).map(str::to_string),
4162                text_of(&dictionary.value_at(index))
4163            );
4164        }
4165        assert_eq!(dictionary.text_at(4), None, "past the end");
4166    }
4167
4168    /// The forms and types that have no text to hand back, which a caller answers by falling back
4169    /// to `value_at`. A blob is the one that would be a correctness bug rather than a slow path,
4170    /// since its bytes are not required to be text and it is not a `VARCHAR` either way.
4171    #[test]
4172    fn text_is_refused_where_it_is_not_stored_as_itself() {
4173        let nulls =
4174            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into()), Value::Null])
4175                .unwrap();
4176        assert_eq!(nulls.text_at(0), Some("red"));
4177        assert_eq!(nulls.text_at(1), None, "a null has no text");
4178        let constant = Vector::constant(LogicalType::Varchar, Value::Varchar("red".into()), 3);
4179        assert_eq!(constant.text_at(0), None, "a constant is not stored per position");
4180        assert_eq!(integers(&[1, 2]).text_at(0), None, "an integer is not text");
4181        let mut bytes = StringColumn::new();
4182        bytes.push("red");
4183        let blob = Vector::flat(LogicalType::Blob, Data::Varlen(bytes)).unwrap();
4184        assert_eq!(blob.text_at(0), None, "a blob is not a varchar");
4185    }
4186
4187    /// The accessor a group by keys an integer column through, which has to agree with `value_at`
4188    /// on every position or two rows holding one number end up in two groups.
4189    #[test]
4190    fn a_signed_integer_is_read_where_it_already_is_for_the_forms_that_store_it() {
4191        let flat = integers(&[7, -3, 0, 2]);
4192        for index in 0..flat.len() {
4193            assert_eq!(flat.signed_at(index), signed_of(&flat.value_at(index)), "flat {index}");
4194        }
4195        let dictionary = Vector::dictionary(vec![1, 0, 3, 2], flat).unwrap();
4196        for index in 0..dictionary.len() {
4197            assert_eq!(
4198                dictionary.signed_at(index),
4199                signed_of(&dictionary.value_at(index)),
4200                "dictionary {index}"
4201            );
4202        }
4203        assert_eq!(dictionary.signed_at(4), None, "past the end");
4204
4205        let runs = Vector::runs(vec![2, 5], integers(&[4, 9])).unwrap();
4206        for index in 0..runs.len() {
4207            assert_eq!(runs.signed_at(index), signed_of(&runs.value_at(index)), "run {index}");
4208        }
4209        let constant = Vector::constant(LogicalType::BigInt, Value::BigInt(11), 3);
4210        assert_eq!(constant.signed_at(2), Some(11));
4211        let sequence = Vector::sequence(100, 5, 4);
4212        for index in 0..sequence.len() {
4213            assert_eq!(
4214                sequence.signed_at(index),
4215                signed_of(&sequence.value_at(index)),
4216                "sequence {index}"
4217            );
4218        }
4219    }
4220
4221    /// The forms and types that have no integer to hand back, which a caller answers by falling
4222    /// back to `value_at`.
4223    #[test]
4224    fn a_signed_integer_is_refused_where_it_is_not_stored_as_itself() {
4225        let nulls =
4226            Vector::from_values(LogicalType::BigInt, &[Value::BigInt(4), Value::Null]).unwrap();
4227        assert_eq!(nulls.signed_at(0), Some(4));
4228        assert_eq!(nulls.signed_at(1), None, "a null is not a number");
4229        let packed = integers(&[1, 2, 3, 1]).bit_packed().unwrap();
4230        assert_eq!(packed.signed_at(0), Some(1), "a packed integer is read in code space");
4231        let mut bytes = StringColumn::new();
4232        bytes.push("red");
4233        let text = Vector::flat(LogicalType::Varchar, Data::Varlen(bytes)).unwrap();
4234        assert_eq!(text.signed_at(0), None, "a string is not a number");
4235        let double = Vector::flat(LogicalType::Double, Data::Float64(vec![1.5].into())).unwrap();
4236        assert_eq!(double.signed_at(0), None, "a double is not a signed integer");
4237    }
4238
4239    /// The integer of a value, for comparing `signed_at` against `value_at` position by position.
4240    fn signed_of(value: &Value) -> Option<i128> {
4241        match value {
4242            Value::TinyInt(x) => Some(i128::from(*x)),
4243            Value::SmallInt(x) => Some(i128::from(*x)),
4244            Value::Integer(x) | Value::Date(x) => Some(i128::from(*x)),
4245            Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => Some(i128::from(*x)),
4246            Value::HugeInt(x) | Value::Decimal { unscaled: x, .. } => Some(*x),
4247            _ => None,
4248        }
4249    }
4250
4251    /// The text of a value, for comparing `text_at` against `value_at` position by position.
4252    fn text_of(value: &Value) -> Option<String> {
4253        match value {
4254            Value::Varchar(text) => Some(text.clone()),
4255            _ => None,
4256        }
4257    }
4258
4259    #[test]
4260    fn a_dictionary_code_past_the_end_is_refused() {
4261        // The alternative is a silent read of the wrong value, which is the failure mode the
4262        // entire M3 design has to be careful about.
4263        let values = integers(&[1, 2]);
4264        assert!(Vector::dictionary(vec![0, 2], values).is_err());
4265        // The check runs on the highest code rather than the first bad one, so it has to say that
4266        // no codes at all is fine even when there are no values for them to point at either.
4267        let empty = Vector::dictionary(Vec::new(), integers(&[])).expect("no codes, no values");
4268        assert_eq!(empty.len(), 0);
4269        // And a code of zero against an empty dictionary is still past the end.
4270        assert!(Vector::dictionary(vec![0], integers(&[])).is_err());
4271    }
4272
4273    #[test]
4274    fn every_form_flattens_to_the_same_values_it_reads_out() {
4275        // This is the shape of the equivalence testing in spec/16-testing.md section 16.2, in
4276        // miniature and long before there is an encoded kernel to point it at. A form that reads
4277        // out one way and flattens another is the exact bug that testing exists to catch.
4278        let mut column = StringColumn::new();
4279        column.push("alpha");
4280        column.push("beta");
4281        let dictionary = Vector::dictionary(
4282            vec![1, 0, 1],
4283            Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
4284        )
4285        .unwrap();
4286        let cases = [
4287            Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
4288            Vector::sequence(7, -2, 5),
4289            dictionary,
4290        ];
4291        for vector in cases {
4292            let flat = vector.flatten().unwrap();
4293            assert_eq!(flat.form(), Form::Flat);
4294            assert_eq!(flat.len(), vector.len());
4295            for index in 0..vector.len() {
4296                assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
4297            }
4298        }
4299    }
4300
4301    #[test]
4302    fn a_null_still_occupies_a_position_after_flattening() {
4303        // The reason push_value writes a zero for a null rather than skipping it. A run of data
4304        // with a hole in it puts every value after the hole in the wrong place, and the validity
4305        // mask is what says the position is null.
4306        let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
4307        let flat = vector.flatten().unwrap();
4308        assert_eq!(flat.value_at(0), Value::BigInt(0));
4309        assert_eq!(flat.value_at(1), Value::Null);
4310        assert_eq!(flat.value_at(2), Value::BigInt(2));
4311        assert_eq!(flat.value_at(3), Value::BigInt(3));
4312    }
4313
4314    /// A dictionary holds its nulls in the vector it points at, so its own validity is all valid
4315    /// and reading that instead of the values turns a null into whatever zero means for the type.
4316    /// A filter over a nullable column produces exactly this vector, so the bug reaches a result
4317    /// set as `LEFT JOIN` padding that comes back as zeros.
4318    #[test]
4319    fn a_null_behind_a_dictionary_survives_flattening() {
4320        let values =
4321            Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
4322        let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
4323        let flat = dictionary.flatten().unwrap();
4324        assert_eq!(flat.value_at(0), Value::Null);
4325        assert_eq!(flat.value_at(1), Value::Integer(3));
4326        assert_eq!(flat.value_at(2), Value::Null);
4327    }
4328
4329    /// The property that makes `gather` usable at all: it has to be the same function as reading the
4330    /// wanted positions one at a time, over every form, or compaction changes answers.
4331    #[test]
4332    fn gathering_reads_what_reading_one_position_at_a_time_reads() {
4333        let mut column = StringColumn::new();
4334        column.push("alpha");
4335        column.push("beta");
4336        column.push("gamma");
4337        let cases = [
4338            integers(&[10, 20, 30, 40]),
4339            integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
4340            Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
4341            Vector::sequence(100, -7, 4),
4342            Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
4343            Vector::dictionary(
4344                vec![2, 0, 1, 2],
4345                Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
4346            )
4347            .unwrap(),
4348            Vector::dictionary(
4349                vec![1, 0, 1, 0],
4350                Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
4351                    .unwrap(),
4352            )
4353            .unwrap(),
4354        ];
4355        let wanted = [3_u32, 0, 2, 2, 1];
4356        for vector in cases {
4357            let gathered = vector.gather(&wanted).unwrap();
4358            assert_eq!(gathered.len(), wanted.len());
4359            assert_eq!(gathered.logical_type(), vector.logical_type());
4360            for (slot, &index) in wanted.iter().enumerate() {
4361                assert_eq!(
4362                    gathered.value_at(slot),
4363                    vector.value_at(index as usize),
4364                    "slot {slot} of {:?}",
4365                    vector.form()
4366                );
4367            }
4368        }
4369    }
4370
4371    /// A gather past the end is not an error, because the selection that produced the indices is
4372    /// checked by its caller and the one thing that must not happen here is a read of the wrong
4373    /// value. An index nothing answers is null, which is what an outer join pad needs anyway.
4374    #[test]
4375    fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
4376        let vector = integers(&[1, 2, 3]);
4377        let gathered = vector.gather(&[2, 9]).unwrap();
4378        assert_eq!(gathered.value_at(0), Value::Integer(3));
4379        assert_eq!(gathered.value_at(1), Value::Null);
4380    }
4381
4382    /// The vector with nothing in it at all, which is what an untyped `NULL` is stored as. Every
4383    /// position asked for is past its end, so the answer is nulls and the length has to be the
4384    /// length that was asked for rather than the length that was there.
4385    #[test]
4386    fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
4387        let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
4388        let gathered = vector.gather(&[0, 1, 2]).unwrap();
4389        assert_eq!(gathered.len(), 3);
4390        assert_eq!(gathered.value_at(0), Value::Null);
4391        assert_eq!(gathered.value_at(2), Value::Null);
4392    }
4393
4394    /// Every position holds the same value, so a gather with no hole in it has nothing to copy and
4395    /// the result is the constant again rather than a run of a thousand copies of it.
4396    #[test]
4397    fn gathering_a_constant_stays_a_constant() {
4398        let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
4399        let gathered = vector.gather(&[7, 7, 99]).unwrap();
4400        assert_eq!(gathered.form(), Form::Constant);
4401        assert_eq!(gathered.len(), 3);
4402        assert_eq!(gathered.value_at(2), Value::Integer(4));
4403    }
4404
4405    /// A dictionary over a dictionary is what a second filter over an already filtered chunk builds,
4406    /// and the gather has to walk to the bottom of that chain rather than one step down it. The
4407    /// constructor composes the ordinary chain away, so the one built here is the kind it cannot,
4408    /// which is a level holding nulls of its own.
4409    #[test]
4410    fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
4411        let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
4412            .unwrap()
4413            .with_validity(Validity::from_iter(3, |index| index != 2));
4414        let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
4415        let gathered = outer.gather(&[0, 1]).unwrap();
4416        assert_eq!(gathered.form(), Form::Flat);
4417        assert_eq!(gathered.value_at(0), Value::Integer(8));
4418        assert_eq!(gathered.value_at(1), Value::Null);
4419    }
4420
4421    /// Two filters over one chunk build a dictionary over a dictionary, four conjuncts pushed down
4422    /// separately build four levels of it, and every level is a dependent load on every later read
4423    /// of every row plus a code array that cannot be freed. Composing at construction is one pass
4424    /// over the codes the range check was walking anyway.
4425    #[test]
4426    fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
4427        let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
4428        let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
4429        let (codes, values) = outer.dictionary_parts().unwrap();
4430        assert_eq!(codes, [1, 0]);
4431        assert_eq!(values.form(), Form::Flat);
4432        assert_eq!(outer.value_at(0), Value::Integer(8));
4433        assert_eq!(outer.value_at(1), Value::Integer(7));
4434    }
4435
4436    /// The invariant stated as the thing it is there for, which is that the depth does not grow with
4437    /// the number of filters. Four levels stacked one at a time are one level at the end of it.
4438    #[test]
4439    fn stacking_dictionaries_does_not_make_them_deeper() {
4440        let mut vector = integers(&[10, 20, 30, 40]);
4441        for _ in 0..4 {
4442            vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
4443        }
4444        let (codes, values) = vector.dictionary_parts().unwrap();
4445        assert_eq!(values.form(), Form::Flat);
4446        assert_eq!(codes, [0, 1, 2, 3]);
4447        assert_eq!(
4448            vector.iter().collect::<Vec<_>>(),
4449            integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
4450        );
4451    }
4452
4453    /// Composing has to carry the nulls down with it. The values hold them, the codes point at them,
4454    /// and a composed code that lands on a null position is still a null.
4455    #[test]
4456    fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
4457        let values =
4458            Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
4459        let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
4460        let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
4461        assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
4462        assert_eq!(outer.value_at(0), Value::Null);
4463        assert_eq!(outer.value_at(1), Value::Integer(3));
4464    }
4465
4466    /// The one level composition cannot go past. A dictionary that was given a validity of its own is
4467    /// saying its nulls are at that level rather than in the values, and pointing the outer codes
4468    /// straight at the values would read through the holes instead of stopping at them.
4469    #[test]
4470    fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
4471        let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
4472            .unwrap()
4473            .with_validity(Validity::from_iter(3, |index| index != 1));
4474        let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
4475        assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
4476        assert_eq!(outer.value_at(0), Value::Null);
4477        assert_eq!(outer.value_at(1), Value::Integer(3));
4478        assert_eq!(outer.value_at(2), Value::Integer(1));
4479    }
4480
4481    /// The difference between the two questions about nulls, which a group by got wrong. A filtered
4482    /// chunk is dictionary vectors, those are built with every row marked present at their own
4483    /// level, and the nulls are down in the values. So the mask says the row has a value and the
4484    /// row does not.
4485    #[test]
4486    fn a_null_behind_a_dictionary_reads_as_null_even_though_the_mask_says_otherwise() {
4487        let values = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
4488            .unwrap()
4489            .with_validity(Validity::from_iter(2, |index| index != 0));
4490        let vector = Vector::dictionary(vec![0, 1, 0], values).unwrap();
4491        assert!(vector.validity().is_valid(0), "the mask at this level says present");
4492        assert!(vector.is_null_at(0));
4493        assert!(!vector.is_null_at(1));
4494        assert!(vector.is_null_at(2));
4495        assert!(vector.is_null_at(3), "a row past the end is null");
4496    }
4497
4498    /// The same for runs, which are built the same way and keep their nulls in the same place.
4499    #[test]
4500    fn a_null_inside_a_run_reads_as_null_even_though_the_mask_says_otherwise() {
4501        let values = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
4502            .unwrap()
4503            .with_validity(Validity::from_iter(2, |index| index != 0));
4504        let vector = Vector::runs(vec![2, 3], values).unwrap();
4505        assert!(vector.validity().is_valid(0));
4506        assert!(vector.is_null_at(0));
4507        assert!(vector.is_null_at(1));
4508        assert!(!vector.is_null_at(2));
4509    }
4510
4511    /// Every other form keeps its nulls in its own mask, so the two answers agree there.
4512    #[test]
4513    fn the_forms_that_hold_their_own_nulls_answer_the_same_either_way() {
4514        let flat = Vector::flat(LogicalType::Integer, Data::Int32(vec![0, 7].into()))
4515            .unwrap()
4516            .with_validity(Validity::from_iter(2, |index| index != 0));
4517        let constant = Vector::constant(LogicalType::Integer, Value::Null, 2);
4518        let sequence = Vector::sequence(10, 2, 2);
4519        for vector in [flat, constant, sequence] {
4520            for row in 0..vector.len() {
4521                assert_eq!(vector.is_null_at(row), !vector.validity().is_valid(row));
4522            }
4523        }
4524    }
4525
4526    #[test]
4527    fn flattening_a_flat_vector_is_the_same_vector() {
4528        let vector = integers(&[1, 2, 3]);
4529        assert_eq!(vector.flatten().unwrap(), vector);
4530    }
4531
4532    #[test]
4533    fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
4534        let ty = LogicalType::decimal(9, 2).unwrap();
4535        let vector = Vector::flat(ty, Data::Int32(vec![1234].into())).unwrap();
4536        assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
4537        assert_eq!(vector.value_at(0).to_string(), "12.34");
4538    }
4539
4540    #[test]
4541    fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
4542        // The read path worked at every width and the write path only accepted the 128 bit run, so
4543        // `SELECT 2.5` produced a value nothing could store. All four widths round trip now.
4544        for (width, scale, unscaled) in
4545            [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
4546        {
4547            let ty = LogicalType::decimal(width, scale).unwrap();
4548            let value = Value::Decimal { unscaled, width, scale };
4549            let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
4550            assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
4551            assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
4552        }
4553    }
4554
4555    /// The bytes a blob holds are not required to be text, and a vector of them used to refuse the
4556    /// ones that were not. A byte array column in a Parquet file that nothing annotated is a blob,
4557    /// which is what ClickHouse writes and what ten of the ClickBench queries compare against, so
4558    /// this is the path those take rather than a corner of the type system.
4559    #[test]
4560    fn a_blob_holds_bytes_that_are_not_text() {
4561        let bytes = |raw: &[u8]| Value::Blob(raw.to_vec());
4562        let values = [
4563            bytes(b"a\xffb"),
4564            bytes(b"\x00\x01\x02"),
4565            Value::Null,
4566            bytes(b"\xed\xa0\x80 and long enough to leave the view"),
4567            bytes(b""),
4568        ];
4569        let vector = Vector::from_values(LogicalType::Blob, &values).unwrap();
4570        for (index, value) in values.iter().enumerate() {
4571            assert_eq!(&vector.value_at(index), value, "row {index}");
4572        }
4573    }
4574
4575    #[test]
4576    fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
4577        // Only reachable by hand, since a value's width is what picked the run. Truncating here
4578        // would store a different number and say nothing about it.
4579        let ty = LogicalType::decimal(4, 1).unwrap();
4580        let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
4581        let error = Vector::from_values(ty, &[value]).unwrap_err();
4582        assert!(error.to_string().contains("does not fit"), "{error}");
4583    }
4584
4585    #[test]
4586    fn a_flat_vector_costs_its_values_and_a_constant_costs_one() {
4587        let flat = integers(&[1; 1000]);
4588        assert!(
4589            flat.footprint() >= 4000,
4590            "a thousand i32 are four thousand bytes: {}",
4591            flat.footprint()
4592        );
4593        // The forms that compute their values rather than storing them cost nothing per value,
4594        // which is the point of having them and is what the memory limit should see.
4595        let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1_000_000);
4596        assert!(constant.footprint() < 200, "a constant is one value: {}", constant.footprint());
4597        let sequence = Vector::sequence(0, 1, 1_000_000);
4598        assert!(sequence.footprint() < 200, "a sequence is two numbers: {}", sequence.footprint());
4599    }
4600
4601    #[test]
4602    fn a_string_vector_costs_the_bytes_of_its_long_strings() {
4603        let short =
4604            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into())]).unwrap();
4605        let long = "a string well past the sixteen bytes a view holds inline".to_string();
4606        let spilled =
4607            Vector::from_values(LogicalType::Varchar, &[Value::Varchar(long.clone())]).unwrap();
4608        assert!(
4609            spilled.footprint() >= short.footprint() + long.len(),
4610            "the arena is counted: {} against {}",
4611            spilled.footprint(),
4612            short.footprint()
4613        );
4614    }
4615
4616    /// The cases worth checking are the widths where a code straddles a word boundary, which is
4617    /// every width that does not divide sixty four, and the two ends of the range.
4618    #[test]
4619    fn a_narrow_column_packs_and_reads_back_the_same_at_every_width() {
4620        for width in 1..=20u32 {
4621            let span = (1i64 << width) - 1;
4622            let values: Vec<i64> =
4623                (0..1000).map(|row| 1_000_000 + (row * 7919) % (span + 1)).collect();
4624            let flat =
4625                Vector::flat(LogicalType::BigInt, Data::Int64(values.clone().into())).unwrap();
4626            let packed = flat.bit_packed().unwrap();
4627            assert_eq!(packed.len(), flat.len());
4628            assert_eq!(
4629                packed.iter().collect::<Vec<_>>(),
4630                flat.iter().collect::<Vec<_>>(),
4631                "width {width} read back differently"
4632            );
4633        }
4634    }
4635
4636    #[test]
4637    fn the_width_is_the_bits_the_range_needs_and_not_the_bits_the_type_has() {
4638        let values: Vec<i32> = (0..1024).map(|row| 40 + (row * 2560) / 1023).collect();
4639        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
4640        let packed = flat.bit_packed().unwrap();
4641        assert_eq!(packed.form(), Form::BitPacked);
4642        let parts = packed.packed_parts().expect("packed");
4643        assert_eq!(parts.width(), 12, "0 to 2560 is twelve bits");
4644        assert_eq!(parts.base(), 40);
4645        assert!(
4646            packed.footprint() * 2 < flat.footprint(),
4647            "twelve bits against thirty two: {} against {}",
4648            packed.footprint(),
4649            flat.footprint()
4650        );
4651    }
4652
4653    /// The check is worth having in both directions, the way the run length one is. A form that is
4654    /// only ever bigger than what it replaced costs a pass over the column to decide not to use.
4655    #[test]
4656    fn a_column_that_uses_its_whole_type_is_left_flat() {
4657        let values: Vec<i32> = (0..1024).map(|row| row * 2_000_000 - 1_000_000_000).collect();
4658        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
4659        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
4660    }
4661
4662    /// A column of one value would pack to no bits at all, and one run is smaller than any packing
4663    /// of it, so the two forms do not fight over that column.
4664    #[test]
4665    fn a_column_of_one_value_is_left_to_the_run_length_form() {
4666        let flat = integers(&[9; 1024]);
4667        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
4668        assert_eq!(flat.run_encoded().unwrap().form(), Form::Rle);
4669    }
4670
4671    #[test]
4672    fn a_string_column_has_no_range_to_pack() {
4673        let text = Vector::from_values(
4674            LogicalType::Varchar,
4675            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
4676        )
4677        .unwrap();
4678        assert_eq!(text.bit_packed().unwrap().form(), Form::Flat);
4679    }
4680
4681    /// The cut is the reason the form carries a row to start reading at. It stays packed, it shares
4682    /// the same words, and it reads the rows the range asked for.
4683    #[test]
4684    fn a_cut_of_a_packed_column_stays_packed_and_shares_its_bits() {
4685        let values: Vec<i32> = (0..1024).map(|row| 100 + row % 300).collect();
4686        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
4687        let packed = flat.bit_packed().unwrap();
4688        let cut = packed.slice(500, 24).unwrap();
4689        assert_eq!(cut.form(), Form::BitPacked);
4690        assert_eq!(cut.len(), 24);
4691        assert_eq!(
4692            cut.iter().collect::<Vec<_>>(),
4693            flat.slice(500, 24).unwrap().iter().collect::<Vec<_>>()
4694        );
4695        assert!(
4696            cut.footprint() >= packed.footprint(),
4697            "a cut shares the words rather than copying a piece of them"
4698        );
4699    }
4700
4701    #[test]
4702    fn a_gather_of_a_packed_column_comes_out_flat_and_keeps_the_nulls() {
4703        let values: Vec<i32> = (0..64).map(|row| 10 + row).collect();
4704        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
4705        let packed =
4706            flat.bit_packed().unwrap().with_validity(Validity::from_iter(64, |row| row % 3 != 0));
4707        let taken = packed.gather(&[0, 1, 2, 3, 62]).unwrap();
4708        assert_eq!(taken.form(), Form::Flat);
4709        assert_eq!(
4710            taken.iter().collect::<Vec<_>>(),
4711            vec![
4712                Value::Null,
4713                Value::Integer(11),
4714                Value::Integer(12),
4715                Value::Null,
4716                Value::Integer(72)
4717            ]
4718        );
4719    }
4720
4721    /// The pair a comparison kernel asks for before it reads a bit. A literal inside the range has a
4722    /// code and a literal outside it does not, which answers the whole vector at once.
4723    #[test]
4724    fn a_literal_outside_the_packed_range_has_no_code() {
4725        let values: Vec<i32> = (0..256).map(|row| 1000 + row).collect();
4726        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
4727        let packed = flat.bit_packed().unwrap();
4728        let parts = packed.packed_parts().expect("packed");
4729        assert_eq!(parts.code_of(1000), Some(0));
4730        assert_eq!(parts.code_of(1100), Some(100));
4731        assert_eq!(parts.code_of(999), None);
4732        assert!(parts.ceiling() >= 1255);
4733        assert_eq!(parts.code_of(parts.ceiling() + 1), None);
4734    }
4735
4736    /// The bits arriving from a file rather than from a flat vector, which is what the form is for.
4737    #[test]
4738    fn packed_bits_can_be_handed_in_without_a_flat_vector_to_start_from() {
4739        let packed = Vector::packed(LogicalType::SmallInt, vec![0x0000_0000_0000_4321], 4, 7, 4)
4740            .expect("four codes of four bits");
4741        assert_eq!(
4742            packed.iter().collect::<Vec<_>>(),
4743            vec![Value::SmallInt(8), Value::SmallInt(9), Value::SmallInt(10), Value::SmallInt(11)]
4744        );
4745    }
4746
4747    #[test]
4748    fn packed_bits_that_could_not_hold_what_they_claim_are_refused() {
4749        assert!(Vector::packed(LogicalType::Varchar, vec![0], 4, 0, 4).is_err(), "not an integer");
4750        assert!(Vector::packed(LogicalType::Integer, vec![0], 0, 0, 4).is_err(), "no width");
4751        assert!(Vector::packed(LogicalType::Integer, vec![0], 64, 0, 4).is_err(), "too wide");
4752        assert!(Vector::packed(LogicalType::Integer, vec![0], 8, 0, 9).is_err(), "too few words");
4753        assert!(Vector::packed(LogicalType::TinyInt, vec![0], 8, 100, 8).is_err(), "would not fit");
4754    }
4755
4756    /// A column of strings long enough that the payload is in the arena rather than in the views.
4757    fn long_strings(count: usize) -> Vector {
4758        let values: Vec<Value> = (0..count)
4759            .map(|row| {
4760                Value::Varchar(format!("a string too long to sit inside a view, number {row}"))
4761            })
4762            .collect();
4763        Vector::from_values(LogicalType::Varchar, &values).unwrap()
4764    }
4765
4766    #[test]
4767    fn a_string_column_in_view_form_reads_back_the_same_strings() {
4768        let flat = long_strings(40);
4769        let shared = flat.clone().shared_text().unwrap();
4770        assert_eq!(shared.form(), Form::StringView);
4771        assert_eq!(shared.len(), 40);
4772        for row in 0..40 {
4773            assert_eq!(shared.value_at(row), flat.value_at(row), "row {row}");
4774            assert_eq!(shared.text_at(row), flat.text_at(row), "row {row}");
4775        }
4776    }
4777
4778    #[test]
4779    fn a_short_string_is_read_out_of_its_view_and_never_out_of_the_arena() {
4780        let flat = Vector::from_values(
4781            LogicalType::Varchar,
4782            &[Value::Varchar("red".into()), Value::Varchar("green".into()), Value::Null],
4783        )
4784        .unwrap();
4785        let shared = flat.shared_text().unwrap();
4786        // Nothing went to the arena, so the whole column resolves with an empty one.
4787        let (views, arena) = shared.text_parts().unwrap();
4788        assert!(arena.is_empty(), "three short strings need no arena");
4789        assert_eq!(views[0].bytes_in(arena), Some(&b"red"[..]));
4790        assert_eq!(shared.value_at(1), Value::Varchar("green".into()));
4791        assert_eq!(shared.value_at(2), Value::Null, "the validity came across");
4792    }
4793
4794    #[test]
4795    fn a_cut_of_a_view_column_shares_the_arena_rather_than_copying_the_bytes() {
4796        let shared = long_strings(64).shared_text().unwrap();
4797        let cut = shared.slice(16, 8).unwrap();
4798        assert_eq!(cut.form(), Form::StringView, "a cut of views is views");
4799        assert_eq!(cut.len(), 8);
4800        assert_eq!(cut.value_at(0), shared.value_at(16));
4801        assert_eq!(cut.value_at(7), shared.value_at(23));
4802        // The arena is the same bytes at the same address, which is the whole point of the form.
4803        let (_, whole) = shared.text_parts().unwrap();
4804        let (_, piece) = cut.text_parts().unwrap();
4805        assert_eq!(piece.as_ptr(), whole.as_ptr(), "the cut shares the page");
4806        assert_eq!(piece.len(), whole.len());
4807    }
4808
4809    #[test]
4810    fn a_flat_string_column_has_to_copy_the_bytes_its_cut_keeps() {
4811        let flat = long_strings(64);
4812        let cut = flat.slice(16, 8).unwrap();
4813        assert_eq!(cut.form(), Form::Flat);
4814        let (_, whole) = flat.text_parts().unwrap();
4815        let (_, piece) = cut.text_parts().unwrap();
4816        assert!(piece.len() < whole.len(), "the flat cut carries only what it kept");
4817    }
4818
4819    #[test]
4820    fn a_gather_of_a_view_column_keeps_the_form_and_a_flatten_copies_out_of_it() {
4821        let shared = long_strings(32).shared_text().unwrap();
4822        let picked: Vec<u32> = (0..32).step_by(3).collect();
4823        let gathered = shared.gather(&picked).unwrap();
4824        assert_eq!(gathered.form(), Form::StringView, "selecting rows moves views, not bytes");
4825        assert_eq!(gathered.len(), picked.len());
4826        for (row, &from) in picked.iter().enumerate() {
4827            assert_eq!(gathered.value_at(row), shared.value_at(from as usize), "row {row}");
4828        }
4829        let flattened = gathered.flatten().unwrap();
4830        assert_eq!(flattened.form(), Form::Flat);
4831        assert_eq!(flattened.iter().collect::<Vec<_>>(), gathered.iter().collect::<Vec<_>>());
4832        // The flatten is what narrows the bytes, so the arena it built holds only the rows it kept.
4833        let (_, narrowed) = flattened.text_parts().unwrap();
4834        let (_, whole) = shared.text_parts().unwrap();
4835        assert!(narrowed.len() < whole.len(), "flattening lets the page go");
4836    }
4837
4838    #[test]
4839    fn a_null_in_a_view_column_survives_being_gathered_and_flattened() {
4840        let shared = long_strings(8)
4841            .with_validity(Validity::from_iter(8, |row| row % 3 != 0))
4842            .shared_text()
4843            .unwrap();
4844        let gathered = shared.gather(&[0, 1, 2, 3, 4]).unwrap();
4845        let expected =
4846            [Value::Null, shared.value_at(1), shared.value_at(2), Value::Null, shared.value_at(4)];
4847        assert_eq!(gathered.iter().collect::<Vec<_>>(), expected);
4848        assert_eq!(gathered.flatten().unwrap().iter().collect::<Vec<_>>(), expected);
4849    }
4850
4851    #[test]
4852    fn both_string_forms_hand_a_kernel_the_same_views_and_the_same_bytes() {
4853        let flat = long_strings(6);
4854        let shared = flat.clone().shared_text().unwrap();
4855        let (flat_views, flat_arena) = flat.text_parts().unwrap();
4856        let (shared_views, shared_arena) = shared.text_parts().unwrap();
4857        assert_eq!(flat_views.len(), shared_views.len());
4858        for row in 0..6 {
4859            assert_eq!(
4860                flat_views[row].bytes_in(flat_arena),
4861                shared_views[row].bytes_in(shared_arena),
4862                "row {row}"
4863            );
4864        }
4865        // Nothing else answers this, which is what keeps a kernel from taking it for a string column.
4866        assert!(Vector::sequence(0, 1, 4).text_parts().is_none());
4867        assert!(integers(&[1, 2, 3]).text_parts().is_none());
4868    }
4869
4870    #[test]
4871    fn a_column_that_is_not_strings_cannot_be_held_as_views() {
4872        let views = vec![StringView::inline("red")];
4873        let arena = Arc::new(Buffer::new());
4874        let wrong = Vector::string_views(LogicalType::Integer, views, arena);
4875        assert!(wrong.is_err(), "an integer column has no views");
4876        assert_eq!(integers(&[1, 2]).shared_text().unwrap().form(), Form::Flat, "left alone");
4877    }
4878
4879    /// A column with enough repeated structure for a symbol table to find something, which is what
4880    /// a real text column has and a column of random bytes does not.
4881    fn sentences(count: usize) -> Vector {
4882        let values: Vec<Value> = (0..count)
4883            .map(|row| {
4884                Value::Varchar(format!(
4885                    "http://example.test/catalogue/section/{}/item/{row}",
4886                    row % 7
4887                ))
4888            })
4889            .collect();
4890        Vector::from_values(LogicalType::Varchar, &values).unwrap()
4891    }
4892
4893    #[test]
4894    fn a_compressed_column_reads_back_the_strings_that_went_into_it() {
4895        let flat = sentences(64);
4896        let coded = flat.clone().compressed().unwrap();
4897        assert_eq!(coded.form(), Form::Fsst, "a text column compresses");
4898        assert_eq!(coded.len(), 64);
4899        for row in 0..64 {
4900            assert_eq!(coded.value_at(row), flat.value_at(row), "row {row}");
4901        }
4902        assert_eq!(coded.flatten().unwrap(), flat, "flattening is the column it came from");
4903    }
4904
4905    #[test]
4906    fn compressing_halves_the_bytes_or_the_column_is_left_flat() {
4907        let flat = sentences(200);
4908        let coded = flat.clone().compressed().unwrap();
4909        let parts = coded.coded_parts().expect("compressed");
4910        // Read through the flat column, because the compressed one has no bytes to hand back where
4911        // they are and answers `None` to `text_at` rather than decompressing into a borrow.
4912        assert_eq!(coded.text_at(0), None, "nothing to borrow until it is flattened");
4913        let plain: usize = (0..200).map(|row| flat.text_at(row).map_or(0, str::len)).sum();
4914        let codes: usize = (0..200).map(|row| parts.row(row).map_or(0, <[u8]>::len)).sum();
4915        assert!(codes * FSST_PAYS_AT <= plain, "{codes} codes against {plain} bytes");
4916        // Text with no repeated structure in it gives a table nothing longer than a byte to find,
4917        // so the codes are the bytes and the column stays where it is rather than paying a
4918        // decompression per read to save nothing.
4919        let mut seed = 0x2545_f491_4f6c_dd1du64;
4920        let values: Vec<Value> = (0..256)
4921            .map(|_| {
4922                let mut text = String::new();
4923                while text.len() < 12 {
4924                    seed = seed.wrapping_mul(6_364_136_223_846_793_005).wrapping_add(1);
4925                    text.push(char::from(b'!' + ((seed >> 33) % 90) as u8));
4926                }
4927                Value::Varchar(text)
4928            })
4929            .collect();
4930        let noise = Vector::from_values(LogicalType::Varchar, &values).unwrap();
4931        assert_eq!(noise.compressed().unwrap().form(), Form::Flat);
4932    }
4933
4934    #[test]
4935    fn a_cut_of_a_compressed_column_shares_the_codes_and_the_table() {
4936        let coded = sentences(64).compressed().unwrap();
4937        let cut = coded.slice(8, 16).unwrap();
4938        assert_eq!(cut.form(), Form::Fsst);
4939        assert_eq!(cut.len(), 16);
4940        for row in 0..16 {
4941            assert_eq!(cut.value_at(row), coded.value_at(8 + row), "row {row}");
4942        }
4943        let (whole, piece) = (coded.coded_parts().unwrap(), cut.coded_parts().unwrap());
4944        assert_eq!(piece.row(0), whole.row(8), "the spans point into the same codes");
4945    }
4946
4947    #[test]
4948    fn a_gather_of_a_compressed_column_stays_compressed_and_keeps_the_nulls() {
4949        let coded = sentences(32)
4950            .with_validity(Validity::from_iter(32, |row| row % 5 != 2))
4951            .compressed()
4952            .unwrap();
4953        let picked: Vec<u32> = (0..32).step_by(2).collect();
4954        let gathered = coded.gather(&picked).unwrap();
4955        assert_eq!(gathered.form(), Form::Fsst, "selecting rows moves spans, not bytes");
4956        for (row, &from) in picked.iter().enumerate() {
4957            assert_eq!(gathered.value_at(row), coded.value_at(from as usize), "row {row}");
4958        }
4959        assert_eq!(
4960            gathered.flatten().unwrap().iter().collect::<Vec<_>>(),
4961            gathered.iter().collect::<Vec<_>>()
4962        );
4963    }
4964
4965    #[test]
4966    fn a_literal_lands_in_the_same_codes_the_row_holding_it_does() {
4967        let coded = sentences(40).compressed().unwrap();
4968        let parts = coded.coded_parts().expect("compressed");
4969        let text = coded.value_at(11);
4970        let Value::Varchar(text) = text else { panic!("a string column reads back strings") };
4971        assert_eq!(parts.encode(text.as_bytes()), parts.row(11).expect("row 11"));
4972        assert_ne!(parts.encode(b"something else entirely"), parts.row(11).unwrap());
4973    }
4974
4975    #[test]
4976    fn codes_that_run_past_what_is_there_are_refused() {
4977        let table = Arc::new(SymbolTable::empty());
4978        let codes = Arc::new(vec![1u8, 2, 3, 4]);
4979        let good = vec![(0u32, 2u32), (2, 4)];
4980        assert!(
4981            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), good, Arc::clone(&table))
4982                .is_ok()
4983        );
4984        let past = vec![(0u32, 9u32)];
4985        assert!(
4986            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), past, Arc::clone(&table))
4987                .is_err(),
4988            "a span past the end of the codes"
4989        );
4990        let backwards = vec![(3u32, 1u32)];
4991        assert!(
4992            Vector::coded(LogicalType::Varchar, Arc::clone(&codes), backwards, Arc::clone(&table))
4993                .is_err(),
4994            "a span that ends before it starts"
4995        );
4996        let wrong = vec![(0u32, 2u32)];
4997        assert!(
4998            Vector::coded(LogicalType::Integer, codes, wrong, table).is_err(),
4999            "an integer column has no codes"
5000        );
5001    }
5002
5003    #[test]
5004    fn a_view_pointing_past_its_arena_is_refused_at_construction() {
5005        let long = "a string too long to sit inside a view";
5006        let arena: Arc<Buffer<u8>> = Arc::new(long.as_bytes().to_vec().into());
5007        let good = vec![StringView::over(long.as_bytes(), 0)];
5008        assert!(Vector::string_views(LogicalType::Varchar, good, Arc::clone(&arena)).is_ok());
5009        let bad = vec![StringView::over(long.as_bytes(), 4)];
5010        assert!(
5011            Vector::string_views(LogicalType::Varchar, bad, arena).is_err(),
5012            "four bytes short of what the view claims"
5013        );
5014    }
5015}