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