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 is the fifth and it is the first
10//! of the encoded ones, which arrive one at a time with the kernels that read them rather than all
11//! at once ahead of 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//! **What is not here yet.** Buffers are owned. Section 7.1 says a vector borrowed from a buffer
20//! managed page carries a pin, and there is no buffer manager until M2, so there is nothing to pin
21//! and pretending otherwise would be an interface built against an imaginary caller. Nested types
22//! are not stored yet either, for the same reason: a `LIST(STRUCT(...))` is offsets plus child
23//! column chunks, and child column chunks are storage.
24
25use std::borrow::Cow;
26use std::sync::Arc;
27
28use rudb_common::{Cause, Error, LogicalType, Result, Value, slow};
29
30use crate::buffer::Buffer;
31use crate::string::{StringColumn, StringView};
32use crate::validity::Validity;
33
34/// How many values are in a full vector.
35///
36/// 1024 rather than DuckDB's 2048, per `spec/04-architecture.md` section 4.3. It is the FastLanes
37/// unit, it makes a validity mask exactly 16 `u64` words, and it keeps a vector of 16 byte string
38/// views at 16 KiB, which is the size at which several of these fit in L1 together rather than
39/// evicting each other.
40pub const VECTOR_SIZE: usize = 1024;
41
42/// Which physical form a vector is in.
43///
44/// An operator asks this once per vector and then takes the path it wants, which is the one branch
45/// per vector that the whole design is willing to spend.
46///
47/// Not exhaustive, and that is a decision rather than an oversight. `Encoded` is the fifth form
48/// and it arrives at layer three with the specialization contract. If this enum were exhaustive,
49/// the day it lands is the day every kernel in the workspace stops compiling, and the pressure at
50/// that moment would be to add an arm to each of them in a hurry rather than to think about what
51/// each one should do with an encoded vector. A required fallback arm means each kernel already
52/// has a correct answer for a form it has never seen, and specializing it is then a change that
53/// can be made one kernel at a time with a benchmark next to it.
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
55#[non_exhaustive]
56pub enum Form {
57    /// One value per position.
58    Flat,
59    /// One value, repeated.
60    Constant,
61    /// A start and a step, computed rather than stored.
62    Sequence,
63    /// Codes into a smaller vector of distinct values.
64    Dictionary,
65    /// Integers stored in as many bits as the range of the column needs, offset from a base.
66    ///
67    /// The form a narrow integer column is in. A ClickBench `ResolutionWidth` is a `SMALLINT` whose
68    /// values live between 0 and 2560, which is twelve bits, so the column is three quarters of the
69    /// size it was and the pages behind it are three quarters of the reads. What it costs is a shift
70    /// and a mask per value, which is why this is worth it at storage and at rest and is not a form
71    /// anything should be building in the middle of a pipeline.
72    BitPacked,
73    /// One value per run, with the row each run ends at.
74    ///
75    /// The form a clustered column is in. `hits` is written in time order, so `EventDate` is a few
76    /// hundred runs over a hundred million rows, and a sum over it is a few hundred multiplications
77    /// rather than a hundred million additions. Dictionary says which distinct values there are and
78    /// this says where they stop, and a column can want either one without wanting the other.
79    Rle,
80}
81
82/// The values of a flat vector, one Rust vector per physical type.
83///
84/// The variants are physical rather than logical, which is what lets `DATE` and `INTEGER` share
85/// storage and share a kernel. What a run of `i32` means is the vector's logical type's business.
86#[derive(Debug, Clone, PartialEq)]
87#[non_exhaustive]
88pub enum Data {
89    /// No values, for the type of an untyped `NULL`.
90    Empty,
91    /// One byte per value.
92    Bool(Buffer<bool>),
93    /// 8 bit signed.
94    Int8(Buffer<i8>),
95    /// 16 bit signed.
96    Int16(Buffer<i16>),
97    /// 32 bit signed.
98    Int32(Buffer<i32>),
99    /// 64 bit signed.
100    Int64(Buffer<i64>),
101    /// 128 bit signed.
102    Int128(Buffer<i128>),
103    /// 8 bit unsigned.
104    UInt8(Buffer<u8>),
105    /// 16 bit unsigned.
106    UInt16(Buffer<u16>),
107    /// 32 bit unsigned.
108    UInt32(Buffer<u32>),
109    /// 64 bit unsigned.
110    UInt64(Buffer<u64>),
111    /// 128 bit unsigned.
112    UInt128(Buffer<u128>),
113    /// IEEE 754 binary32.
114    Float32(Buffer<f32>),
115    /// IEEE 754 binary64.
116    Float64(Buffer<f64>),
117    /// The months, days and microseconds triple.
118    Interval(Buffer<(i32, i32, i64)>),
119    /// Strings, as 16 byte views plus the arena the long ones live in.
120    Varlen(StringColumn),
121}
122
123impl Data {
124    /// How many values are stored.
125    ///
126    /// The match below has no wildcard arm, and that is what makes this function the check that
127    /// keeps [`for_each_layout`](crate::for_each_layout) honest. A variant added to this enum
128    /// without being added to the `all` group fails to compile here, which is a line in a build log
129    /// rather than a layout quietly missing from six kernels.
130    #[must_use]
131    pub fn len(&self) -> usize {
132        macro_rules! lengths {
133            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
134                match self {
135                    Self::Empty => 0,
136                    $(Self::$variant(values) => values.len(),)+
137                }
138            };
139        }
140        crate::for_each_layout!(all, lengths)
141    }
142
143    /// Whether there are no values.
144    #[must_use]
145    pub fn is_empty(&self) -> bool {
146        self.len() == 0
147    }
148
149    /// How many bytes of memory these values are holding.
150    ///
151    /// One arm per layout through the same macro as [`Data::len`], for the same reason: a layout
152    /// added without a size here is a layout the memory limit would charge nothing for, and a
153    /// buffer that is free is a buffer that can be grown until the process dies.
154    #[must_use]
155    pub fn footprint(&self) -> usize {
156        macro_rules! sizes {
157            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
158                match self {
159                    Self::Empty => 0,
160                    $(Self::$variant(values) => values.footprint(),)+
161                }
162            };
163        }
164        crate::for_each_layout!(all, sizes)
165    }
166
167    /// An integer at `index`, widened, for any of the signed integer layouts.
168    ///
169    /// Used by the decimal path, which needs the unscaled value out of whichever width the width
170    /// and scale picked, and by anything else that would otherwise repeat the same five arms.
171    #[must_use]
172    pub fn signed_at(&self, index: usize) -> Option<i128> {
173        macro_rules! widened {
174            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
175                match self {
176                    $(Self::$variant(v) => v.get(index).map(|&x| i128::from(x)),)+
177                    _ => None,
178                }
179            };
180        }
181        crate::for_each_layout!(signed, widened)
182    }
183
184    /// An unsigned integer at `index`, widened.
185    #[must_use]
186    pub fn unsigned_at(&self, index: usize) -> Option<u128> {
187        macro_rules! widened {
188            ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
189                match self {
190                    $(Self::$variant(v) => v.get(index).map(|&x| u128::from(x)),)+
191                    _ => None,
192                }
193            };
194        }
195        crate::for_each_layout!(unsigned, widened)
196    }
197
198    /// The string at `index`, for a `Varlen`.
199    #[must_use]
200    pub fn str_at(&self, index: usize) -> Option<&str> {
201        match self {
202            Self::Varlen(column) => column.get(index),
203            _ => None,
204        }
205    }
206
207    /// The bytes at `index`, for a `Varlen`, whatever they are.
208    ///
209    /// What a `BLOB` reads through, since the bytes of one are not required to be text and
210    /// [`Self::str_at`] answers `None` for the ones that are not.
211    #[must_use]
212    pub fn bytes_at(&self, index: usize) -> Option<&[u8]> {
213        match self {
214            Self::Varlen(column) => column.bytes(index),
215            _ => None,
216        }
217    }
218}
219
220/// A type, a length, a validity representation and some data.
221#[derive(Debug, Clone, PartialEq)]
222pub struct Vector {
223    ty: LogicalType,
224    len: usize,
225    validity: Validity,
226    body: Body,
227}
228
229/// What the vector holds, which is what its form is decided by.
230#[derive(Debug, Clone, PartialEq)]
231enum Body {
232    Flat(Data),
233    Constant(Box<Value>),
234    Sequence {
235        start: i64,
236        step: i64,
237    },
238    /// The values are behind an `Arc` rather than a `Box` because slicing shares them.
239    ///
240    /// A dictionary vector is cut once per chunk and the dictionary itself is the same dictionary
241    /// every time, so a `Box` meant a copy of every value in it per cut. On the ClickBench columns
242    /// that are dictionary encoded the dictionary is larger than the chunk of codes pointing into
243    /// it, and copying it was ten percent of the cycles of reading the file.
244    ///
245    /// Nothing here mutates a dictionary in place, so sharing one is only ever a read, and the one
246    /// place that wants an owned copy of the values is [`compose`], which asks for one.
247    Dictionary {
248        codes: Vec<u32>,
249        values: Arc<Vector>,
250    },
251    /// Integer codes of `width` bits each, packed end to end, each one an offset from `base`.
252    ///
253    /// Row `r` is the `width` bits starting at bit `(offset + r) * width`, read little end first, so
254    /// a code that straddles a word boundary has its low bits in the earlier word. `offset` is what
255    /// lets a cut of a packed column be free: the bits are not byte aligned, so a slice either
256    /// repacks or remembers where it starts, and remembering is one addition per read.
257    ///
258    /// The words are behind an `Arc` for the reason the dictionary's values are. A page is packed
259    /// once and cut into chunk sized pieces, and copying the words per cut would undo most of what
260    /// the packing saved.
261    Packed {
262        words: Arc<Vec<u64>>,
263        width: u32,
264        base: i128,
265        offset: usize,
266    },
267    /// One value per run, with the row each run ends at, exclusive and increasing.
268    ///
269    /// Ends rather than lengths, because every reader of this wants to know which run holds a row
270    /// and ends answer that with a binary search while lengths answer it with a running total. The
271    /// two are the same information and only one of them is the one that gets asked for.
272    ///
273    /// The values are behind an `Arc` for the reason the dictionary's are: a page is cut into chunk
274    /// sized pieces and the values are the same values every time.
275    Runs {
276        ends: Vec<u32>,
277        values: Arc<Vector>,
278    },
279}
280
281impl Vector {
282    /// A flat vector of `data`, all valid.
283    ///
284    /// # Errors
285    ///
286    /// If the data's physical layout is not the one the type calls for. That check is here rather
287    /// than left to the caller because a vector whose type and layout disagree is a wrong answer
288    /// waiting to be read out, and it costs one comparison at construction to prevent.
289    pub fn flat(ty: LogicalType, data: Data) -> Result<Self> {
290        let len = data.len();
291        if !matches!(data, Data::Empty) && layout_of(&data) != ty.physical() {
292            return Err(Error::internal(format!(
293                "a {ty} vector cannot hold {:?} data",
294                layout_of(&data)
295            )));
296        }
297        Ok(Self { ty, len, validity: Validity::AllValid, body: Body::Flat(data) })
298    }
299
300    /// A flat vector built from single values, with the nulls among them turning into validity.
301    ///
302    /// The slow way in, and the only way in that anything outside this crate has. It is what an
303    /// `INSERT`, a `VALUES` clause and a test build a column with, all of which arrive holding
304    /// values rather than a run of `i32`. Nothing on a scan path calls it: a scan produces a run of
305    /// data directly and hands it to [`Self::flat`].
306    ///
307    /// # Errors
308    ///
309    /// If a value is not one the type can hold, or if the type is one that cannot be stored flat
310    /// yet, which today means the nested types.
311    pub fn from_values(ty: LogicalType, values: &[Value]) -> Result<Self> {
312        let mut data = empty_data_for(&ty)?;
313        for value in values {
314            push_value(&mut data, value)?;
315        }
316        let validity = Validity::from_iter(values.len(), |index| !values[index].is_null());
317        Ok(Self { ty, len: values.len(), validity, body: Body::Flat(data) })
318    }
319
320    /// A vector of `len` copies of one value.
321    ///
322    /// Costs one value regardless of the length, which is what makes a literal in a predicate free
323    /// and what makes a projection of a constant free.
324    #[must_use]
325    pub fn constant(ty: LogicalType, value: Value, len: usize) -> Self {
326        let validity = if value.is_null() { Validity::AllInvalid } else { Validity::AllValid };
327        Self { ty, len, validity, body: Body::Constant(Box::new(value)) }
328    }
329
330    /// A vector of `len` values starting at `start` and stepping by `step`.
331    ///
332    /// This is what a row identifier column is, and it costs sixteen bytes rather than eight
333    /// kilobytes. A scan that produces row ids for a later fetch produces one of these.
334    #[must_use]
335    pub fn sequence(start: i64, step: i64, len: usize) -> Self {
336        Self {
337            ty: LogicalType::BigInt,
338            len,
339            validity: Validity::AllValid,
340            body: Body::Sequence { start, step },
341        }
342    }
343
344    /// A vector of codes into a smaller vector of distinct values.
345    ///
346    /// The form the whole M3 thesis rests on. A dictionary vector handed to a group by is an
347    /// integer column, and an aggregate over one is an aggregate over integers no matter what the
348    /// logical type says.
349    ///
350    /// A dictionary over a dictionary is composed into one level here rather than left as two, so
351    /// the form has a depth of one always and a kernel that reads [`Self::dictionary_parts`] is
352    /// reading the values rather than another layer of codes. Two filters over the same chunk build
353    /// the second case and four conjuncts pushed down separately build four of it.
354    ///
355    /// The cost of leaving them stacked turned out to be a cliff rather than a slope. Every loop in
356    /// `rudb-kernels` reaches for the values behind the codes with [`Self::data`], a dictionary
357    /// pointing at a dictionary has no data to hand back, so the second level does not make the
358    /// kernels slower, it turns them off and drops the work onto the row at a time path that exists
359    /// to be correct rather than fast. Measured on server3 over a chunk of two numeric columns and a
360    /// consumer of two vectorized passes, one level reads at 3.5 nanoseconds a row and two levels at
361    /// 104, and the third and fourth levels cost almost nothing more because the first one had
362    /// already given up everything there was to give. Composing is one pass over the outer codes,
363    /// which the range check above is already making.
364    ///
365    /// The one dictionary that is not composed past is one carrying a validity of its own. A
366    /// dictionary is built all valid and only [`Self::with_validity`] can change that, so such a
367    /// vector is saying that its nulls are at this level rather than in the values it points at, and
368    /// composing past it would drop them.
369    ///
370    /// # Errors
371    ///
372    /// If any code is past the end of the value vector.
373    pub fn dictionary(codes: Vec<u32>, values: Vector) -> Result<Self> {
374        if let Some(&bad) = codes.iter().find(|&&code| code as usize >= values.len()) {
375            return Err(Error::internal(format!(
376                "dictionary code {bad} is past the end of a {} value dictionary",
377                values.len()
378            )));
379        }
380        let (codes, values) = compose(codes, values);
381        Ok(Self {
382            ty: values.ty.clone(),
383            len: codes.len(),
384            validity: Validity::AllValid,
385            body: Body::Dictionary { codes, values: Arc::new(values) },
386        })
387    }
388
389    /// A vector of runs, one value each, with the row each run ends at.
390    ///
391    /// `ends` is exclusive and strictly increasing, so run `i` covers the rows from `ends[i - 1]` to
392    /// `ends[i]` and run zero starts at nothing. The length of the vector is the last end.
393    ///
394    /// The depth is one, the same way a dictionary's is, and for a sharper reason. Every kernel that
395    /// wants runs wants the value of a run without another search, and a run length vector over a
396    /// run length vector turns one search into two and then into three. Rather than compose, this
397    /// refuses: nothing in the engine builds a stacked one, because [`Self::run_encoded`] only ever
398    /// reads a flat body, so a stacked one is a caller doing something by hand and the useful answer
399    /// is to say so rather than to quietly do a pass of work they did not ask for.
400    ///
401    /// A run over a dictionary is fine and is not that case. The two forms answer different
402    /// questions and a column that is both clustered and low cardinality genuinely wants both.
403    ///
404    /// # Errors
405    ///
406    /// If there is not exactly one value per run, if the ends do not increase, or if the values are
407    /// themselves run length encoded.
408    pub fn runs(ends: Vec<u32>, values: Vector) -> Result<Self> {
409        if matches!(values.body, Body::Runs { .. }) {
410            return Err(Error::internal("runs of runs, which is two searches to read one row"));
411        }
412        if ends.len() != values.len() {
413            return Err(Error::internal(format!(
414                "{} runs and {} values to put in them",
415                ends.len(),
416                values.len()
417            )));
418        }
419        if ends.windows(2).any(|pair| pair[0] >= pair[1]) || ends.first() == Some(&0) {
420            return Err(Error::internal("run ends that do not increase"));
421        }
422        let len = ends.last().copied().unwrap_or(0) as usize;
423        Ok(Self {
424            ty: values.ty.clone(),
425            len,
426            validity: Validity::AllValid,
427            body: Body::Runs { ends, values: Arc::new(values) },
428        })
429    }
430
431    /// The same values as runs, when there are few enough runs for that to be smaller.
432    ///
433    /// Costs one pass over the column to find out, which is why this is a call somebody makes rather
434    /// than something a constructor does. The decision is the same arithmetic every time: a row in
435    /// flat form costs one value, a run costs one value plus the four bytes of its end, so runs are
436    /// smaller once there are fewer than about half as many runs as rows, and the narrower the
437    /// column the more runs it takes. `RUNS_PAY_AT` is that ratio, written down rather than spelt
438    /// into an `if`, because it is the number a sweep will want to move.
439    ///
440    /// Only a flat body is looked at. A constant and a sequence are already one value and two
441    /// numbers, so there is nothing to win, and a dictionary that is also clustered is a real case
442    /// that wants its codes run length encoded rather than its values, which is a different function
443    /// and not this one.
444    ///
445    /// Two adjacent nulls are one run. Two adjacent equal values with a null between them are three,
446    /// because the null is a value of the column as far as anything reading it is concerned.
447    ///
448    /// # Errors
449    ///
450    /// If the type has no flat layout, which today means the nested types.
451    pub fn run_encoded(&self) -> Result<Self> {
452        let Body::Flat(data) = &self.body else {
453            return Ok(self.clone());
454        };
455        let ends = boundaries(data, &self.validity, self.len);
456        if ends.len().saturating_mul(RUNS_PAY_AT) >= self.len {
457            return Ok(self.clone());
458        }
459        let starts: Vec<u32> =
460            std::iter::once(0).chain(ends.iter().copied()).take(ends.len()).collect();
461        Self::runs(ends, self.gather(&starts)?)
462    }
463
464    /// A vector of `len` integers packed `width` bits each, every one an offset from `base`.
465    ///
466    /// The way in for a reader that already has the packed bits, which is what a column file holds
467    /// and what a network frame carries. Nothing unpacks on the way in, so a scan of a packed column
468    /// hands the bits straight to the chunk and the cost of the form is paid by whoever reads a
469    /// value rather than by the scan.
470    ///
471    /// The range check is on the two ends rather than on every code, which is the whole check. A
472    /// code is between zero and `2^width - 1` by construction, so if `base` and `base + 2^width - 1`
473    /// both fit the column's layout then every value does, and that is two comparisons instead of
474    /// one per row.
475    ///
476    /// # Errors
477    ///
478    /// If the type is not one of the integer layouts, if the width is not between one and
479    /// [`PACKED_WIDTH_MAX`], if there are not enough words for the length, or if either end of the
480    /// range would not fit the type.
481    pub fn packed(
482        ty: LogicalType,
483        words: Vec<u64>,
484        width: u32,
485        base: i128,
486        len: usize,
487    ) -> Result<Self> {
488        let Some((low, high)) = layout_range(&ty) else {
489            return Err(Error::internal(format!("a {ty} vector has no integer layout to pack")));
490        };
491        if width == 0 || width > PACKED_WIDTH_MAX {
492            return Err(Error::internal(format!(
493                "a packed width of {width}, which is outside 1 to {PACKED_WIDTH_MAX}"
494            )));
495        }
496        let needed = words_for(len, width);
497        if words.len() < needed {
498            return Err(Error::internal(format!(
499                "{} words for {len} values of {width} bits, which needs {needed}",
500                words.len()
501            )));
502        }
503        let top = base + i128::from(u64::MAX >> (64 - width));
504        if base < low || top > high {
505            return Err(Error::internal(format!(
506                "packed values from {base} to {top}, which a {ty} cannot hold"
507            )));
508        }
509        Ok(Self {
510            ty,
511            len,
512            validity: Validity::AllValid,
513            body: Body::Packed { words: Arc::new(words), width, base, offset: 0 },
514        })
515    }
516
517    /// The same values bit packed, when the range of the column makes that smaller.
518    ///
519    /// Costs one pass to find the range and one to write the bits, which is why this is a call
520    /// somebody makes rather than something a constructor does. It is the counterpart of
521    /// [`Self::run_encoded`] and the decision has the same shape: a row flat costs the width of its
522    /// layout, a row packed costs the bits the column's range needs, and the form is worth having
523    /// only when the second is a good deal smaller than the first. [`PACKING_PAYS_AT`] is that
524    /// ratio, written down rather than spelt into an `if`, because it is the number a sweep will
525    /// want to move.
526    ///
527    /// Only a flat integer body is looked at. A constant and a sequence are already smaller than any
528    /// packing of them, a dictionary's codes are the thing that would want packing rather than its
529    /// values, and a float has no range to pack into since the bits of an `f64` are not an integer
530    /// that arithmetic on the column agrees with.
531    ///
532    /// The range is taken over every slot including the null ones, which hold a zero. A column of
533    /// large values with one null in it therefore packs a range that reaches down to zero and comes
534    /// out wider than it needed to be. The alternative is a pass that consults the validity per slot
535    /// to find the range and a second rule for what to write into a null slot, and this form exists
536    /// to make reads cheap rather than to squeeze the last bit out of a sparse column.
537    ///
538    /// A column whose values are all the same packs to nothing at all, and rather than invent a zero
539    /// bit code this declines and leaves it to [`Self::run_encoded`], which turns that column into
540    /// one run and is smaller than any packing of it.
541    ///
542    /// # Errors
543    ///
544    /// If the packed bits and the length disagree, which would be a bug here rather than a caller
545    /// doing something wrong.
546    pub fn bit_packed(&self) -> Result<Self> {
547        let Body::Flat(data) = &self.body else {
548            return Ok(self.clone());
549        };
550        let Some((low, high)) = span_of(data, self.len) else {
551            return Ok(self.clone());
552        };
553        let Some(range) = high.checked_sub(low).and_then(|range| u64::try_from(range).ok()) else {
554            return Ok(self.clone());
555        };
556        let width = u64::BITS - range.leading_zeros();
557        if width == 0 || width > PACKED_WIDTH_MAX {
558            return Ok(self.clone());
559        }
560        if words_for(self.len, width) * size_of::<u64>() * PACKING_PAYS_AT > data.footprint() {
561            return Ok(self.clone());
562        }
563        let words = pack(data, self.len, low, width);
564        let packed = Self::packed(self.ty.clone(), words, width, low, self.len)?;
565        Ok(packed.with_validity(self.validity.clone()))
566    }
567
568    /// The same vector with a different validity.
569    #[must_use]
570    pub fn with_validity(mut self, validity: Validity) -> Self {
571        self.validity = validity;
572        self
573    }
574
575    /// What kind of values these are.
576    #[must_use]
577    pub fn logical_type(&self) -> &LogicalType {
578        &self.ty
579    }
580
581    /// How many values there are.
582    #[must_use]
583    pub fn len(&self) -> usize {
584        self.len
585    }
586
587    /// Whether there are no values.
588    #[must_use]
589    pub fn is_empty(&self) -> bool {
590        self.len == 0
591    }
592
593    /// How many bytes of memory this vector is holding.
594    ///
595    /// What the memory limit charges for it. A constant and a sequence hold one value and two
596    /// numbers however long they are, which is the point of both forms, so the number here is the
597    /// form's cost and not the column's width times its length.
598    ///
599    /// A dictionary counts its values in full, and two vectors sharing one dictionary each report
600    /// all of it. That over counts, deliberately: working out that two operators are looking at the
601    /// same `Arc` means threading identity through the accounting, and a limit that over counts
602    /// refuses a query that would have fit while a limit that under counts lets one through that
603    /// does not. The first is a worse answer to give and the second is a worse thing to be.
604    #[must_use]
605    pub fn footprint(&self) -> usize {
606        let body = match &self.body {
607            Body::Flat(data) => data.footprint(),
608            Body::Constant(value) => value.footprint(),
609            Body::Sequence { .. } => 0,
610            Body::Dictionary { codes, values } => {
611                codes.capacity() * size_of::<u32>() + values.footprint()
612            }
613            Body::Packed { words, .. } => words.capacity() * size_of::<u64>(),
614            Body::Runs { ends, values } => ends.capacity() * size_of::<u32>() + values.footprint(),
615        };
616        size_of::<Self>() + self.validity.footprint() + body
617    }
618
619    /// Which of the values are not null.
620    #[must_use]
621    pub fn validity(&self) -> &Validity {
622        &self.validity
623    }
624
625    /// Which physical form this vector is in.
626    #[must_use]
627    pub fn form(&self) -> Form {
628        match self.body {
629            Body::Flat(_) => Form::Flat,
630            Body::Constant(_) => Form::Constant,
631            Body::Sequence { .. } => Form::Sequence,
632            Body::Dictionary { .. } => Form::Dictionary,
633            Body::Packed { .. } => Form::BitPacked,
634            Body::Runs { .. } => Form::Rle,
635        }
636    }
637
638    /// The data, for a flat vector, and `None` for any other form.
639    ///
640    /// A kernel that wants a slice asks for it and takes the flat path if it gets one. A kernel
641    /// that can do better on a constant or a dictionary checks [`Self::form`] first.
642    #[must_use]
643    pub fn data(&self) -> Option<&Data> {
644        match &self.body {
645            Body::Flat(data) => Some(data),
646            _ => None,
647        }
648    }
649
650    /// The one value, for a constant vector, and `None` for any other form.
651    ///
652    /// A kernel comparing a column against a literal wants the literal once rather than 1024
653    /// times, and [`Self::value_at`] on a constant clones it on every call because it has to be
654    /// able to hand back a `Value` for any form. This is the accessor that lets the specialized
655    /// path hoist the clone out of the loop.
656    #[must_use]
657    pub fn constant_value(&self) -> Option<&Value> {
658        match &self.body {
659            Body::Constant(value) => Some(value.as_ref()),
660            _ => None,
661        }
662    }
663
664    /// The codes and the values, for a dictionary vector, and `None` for any other form.
665    ///
666    /// The reason a kernel needs this rather than reading the dictionary through
667    /// [`Self::value_at`] is the entire argument for the form existing. A filter against a
668    /// dictionary column of 1024 rows and 40 distinct values is 40 comparisons and 1024 lookups,
669    /// not 1024 comparisons, and there is no way to write that loop without seeing the codes.
670    ///
671    /// Note what the validity of the returned vector means. A dictionary keeps its nulls in the
672    /// vector it points at, and the dictionary's own validity says nothing about them, so a caller
673    /// deciding whether row `i` is null has to ask the value vector about `codes[i]` rather than
674    /// asking this vector about `i`. [`Self::flatten`] has the same note on it for the same
675    /// reason, because getting this wrong is a null that survives being selected and comes out as
676    /// a zero.
677    #[must_use]
678    pub fn dictionary_parts(&self) -> Option<(&[u32], &Self)> {
679        match &self.body {
680            Body::Dictionary { codes, values } => Some((codes, values.as_ref())),
681            _ => None,
682        }
683    }
684
685    /// The run ends and the run values, for a run length vector, and `None` for any other form.
686    ///
687    /// The ends are exclusive and increasing, and there is exactly one value per run, so a kernel
688    /// that wants to walk this walks the pairs and never asks which run a row is in. That is the
689    /// whole argument for the form: an aggregate over a clustered column is one multiply per run
690    /// instead of one add per row, and there is no way to write that loop without seeing the ends.
691    ///
692    /// The nulls are in the values, the way a dictionary's are, so a caller deciding whether row `i`
693    /// is null asks the value vector about the run rather than asking this vector about `i`.
694    #[must_use]
695    pub fn run_parts(&self) -> Option<(&[u32], &Self)> {
696        match &self.body {
697            Body::Runs { ends, values } => Some((ends, values.as_ref())),
698            _ => None,
699        }
700    }
701
702    /// Where each row's value is, for the two forms that keep their values somewhere else.
703    ///
704    /// A dictionary and a run length vector are the same shape seen from a kernel: a run of
705    /// positions and a vector to read them out of. The difference is that a dictionary stores the
706    /// positions and a run length vector works them out, and a kernel writing `values[at[row]]` does
707    /// not care which. So every specialization written against [`Self::dictionary_parts`] covers
708    /// both forms by asking this instead, and the day a third form with an indirection arrives it
709    /// covers that one too without any of those kernels being reopened.
710    ///
711    /// The run length side costs an allocation of one position per row and a pass to fill it, which
712    /// is the same four bytes a row a dictionary was already carrying and is paid once per kernel
713    /// call rather than once per row. That is the price of this being one accessor rather than a
714    /// second arm in eighteen kernels, and it is not the last word: a kernel that wants a run at a
715    /// time reads [`Self::run_parts`] and pays nothing, which is the specialization this makes it
716    /// possible to skip writing until a sweep says it is worth it.
717    #[must_use]
718    pub fn positions(&self) -> Option<(Cow<'_, [u32]>, &Self)> {
719        match &self.body {
720            Body::Dictionary { codes, values } => Some((Cow::Borrowed(codes), values.as_ref())),
721            Body::Runs { ends, values } => {
722                let mut at = Vec::with_capacity(self.len);
723                for (run, &stop) in ends.iter().enumerate() {
724                    let run = u32::try_from(run).unwrap_or(u32::MAX);
725                    at.resize(stop as usize, run);
726                }
727                Some((Cow::Owned(at), values.as_ref()))
728            }
729            _ => None,
730        }
731    }
732
733    /// The bits and what they mean, for a bit packed vector, and `None` for any other form.
734    ///
735    /// What a kernel needs to stay in code space. A comparison against a literal is the case that
736    /// pays: `column > 900` over a column packed from a base of 40 is `code > 860`, which is the
737    /// same shift and mask the read was going to do anyway and no unpacking at all, and a literal
738    /// outside the packed range answers the whole vector without reading a bit of it. None of that
739    /// can be written without seeing the width and the base.
740    #[must_use]
741    pub fn packed_parts(&self) -> Option<Packed<'_>> {
742        match &self.body {
743            Body::Packed { words, width, base, offset } => {
744                Some(Packed { words, width: *width, base: *base, offset: *offset })
745            }
746            _ => None,
747        }
748    }
749
750    /// The start and the step, for a sequence vector, and `None` for any other form.
751    #[must_use]
752    pub fn sequence_parts(&self) -> Option<(i64, i64)> {
753        match self.body {
754            Body::Sequence { start, step } => Some((start, step)),
755            _ => None,
756        }
757    }
758
759    /// The value at `index`, as a single value.
760    ///
761    /// This is the slow path on purpose. It is what a result set is read out with and what a test
762    /// asserts on, and an operator that calls it per row is an operator that has already lost the
763    /// argument the vector interface exists to win.
764    #[must_use]
765    pub fn value_at(&self, index: usize) -> Value {
766        if index >= self.len || !self.validity.is_valid(index) {
767            return Value::Null;
768        }
769        match &self.body {
770            Body::Constant(value) => value.as_ref().clone(),
771            Body::Sequence { start, step } => Value::BigInt(start + step * index as i64),
772            Body::Dictionary { codes, values } => match codes.get(index) {
773                Some(&code) => values.value_at(code as usize),
774                None => Value::Null,
775            },
776            Body::Runs { ends, values } => match run_holding(ends, index) {
777                Some(run) => values.value_at(run),
778                None => Value::Null,
779            },
780            // One value unpacked into a run of one, so that what a packed value means is decided in
781            // the same place a flat one is rather than in a second copy of the type mapping that
782            // could drift from it. It allocates, which this path is allowed to do and the typed
783            // unpack in `copied` is not, and it is the reason anything about to read a packed
784            // column a row at a time should flatten it once instead.
785            Body::Packed { words, width, base, offset } => {
786                unpack(&self.ty, words, *offset, *width, *base, &[index])
787                    .map_or(Value::Null, |data| value_from(&self.ty, &data, 0))
788            }
789            Body::Flat(data) => value_from(&self.ty, data, index),
790        }
791    }
792
793    /// The text at `index`, borrowed rather than copied.
794    ///
795    /// [`Self::value_at`] on a `VARCHAR` column allocates a `String` per call, and a group by that
796    /// reads a string column keys on one string per input row. This hands back the bytes where they
797    /// already are, so a caller with somewhere to put them does not go to the allocator at all.
798    ///
799    /// `None` for a null, for an index past the end, for a column that is not `VARCHAR`, and for the
800    /// constant and sequence forms, whose values are not stored per position. A caller that gets
801    /// `None` has to fall back to [`Self::value_at`], which is correct for all of those.
802    #[must_use]
803    pub fn text_at(&self, index: usize) -> Option<&str> {
804        if self.ty != LogicalType::Varchar || index >= self.len || !self.validity.is_valid(index) {
805            return None;
806        }
807        match &self.body {
808            Body::Flat(data) => data.str_at(index),
809            Body::Dictionary { codes, values } => {
810                values.text_at(usize::try_from(*codes.get(index)?).ok()?)
811            }
812            Body::Runs { ends, values } => values.text_at(run_holding(ends, index)?),
813            _ => None,
814        }
815    }
816
817    /// Every value in order, as single values.
818    pub fn iter(&self) -> impl Iterator<Item = Value> + '_ {
819        (0..self.len).map(|index| self.value_at(index))
820    }
821
822    /// A contiguous run of the values, in the form they are already in.
823    ///
824    /// This is the cut [`Self::gather`] cannot do. A gather walks a dictionary to its leaf and
825    /// copies, so gathering a piece of a dictionary encoded column hands back a flat one, and a
826    /// caller that only wanted the first thousand rows of a page has silently paid for a copy and
827    /// thrown the dictionary away. A group by over a dictionary encoded column is the case that
828    /// cares, and it is most of ClickBench.
829    ///
830    /// So each form is cut as itself. A dictionary keeps its dictionary and slices its codes, a
831    /// sequence stays arithmetic with its start moved along, a constant stays a shorter constant,
832    /// and a flat body is the one that genuinely has to copy its range.
833    ///
834    /// The dictionary itself is shared rather than copied, so a cut is the codes and nothing else.
835    /// It used to be copied, and on a read of a ClickBench partition that copy was ten percent of
836    /// the cycles: a page holds one dictionary and is cut into chunk sized pieces, so the whole
837    /// dictionary was copied once per chunk to be read the same way each time.
838    ///
839    /// # Errors
840    ///
841    /// If the range runs past the end of the vector, or if the type has no flat layout and the
842    /// body is one that has to be copied.
843    pub fn slice(&self, at: usize, len: usize) -> Result<Self> {
844        let end = at.checked_add(len).ok_or_else(|| Error::internal("a slice that wraps"))?;
845        if end > self.len {
846            return Err(Error::internal(format!("rows {at} to {end} of a vector of {}", self.len)));
847        }
848        if at == 0 && len == self.len {
849            return Ok(self.clone());
850        }
851        let validity = Validity::from_iter(len, |row| self.validity.is_valid(at + row));
852        let body = match &self.body {
853            Body::Constant(value) => Body::Constant(value.clone()),
854            Body::Sequence { start, step } => {
855                Body::Sequence { start: start + step * at as i64, step: *step }
856            }
857            Body::Dictionary { codes, values } => {
858                Body::Dictionary { codes: codes[at..end].to_vec(), values: Arc::clone(values) }
859            }
860            // The bits are not byte aligned, so a cut either repacks them or moves the row the
861            // reading starts at. Moving it is one addition and repacking is a pass, and a page is
862            // cut into chunk sized pieces often enough that the difference is the form.
863            Body::Packed { words, width, base, offset } => Body::Packed {
864                words: Arc::clone(words),
865                width: *width,
866                base: *base,
867                offset: offset + at,
868            },
869            // Only the runs the range touches survive, the first and last of them cut back to where
870            // the range starts and stops, and every end moved to be relative to the new row zero. A
871            // cut of a hundred rows out of a column of a hundred million is a handful of runs, which
872            // is the reason this form is worth cutting as itself rather than copying out.
873            Body::Runs { ends, values } if len > 0 => {
874                let first = run_holding(ends, at).unwrap_or(0);
875                let last = run_holding(ends, end - 1).unwrap_or(first);
876                let cut: Vec<u32> = ends[first..=last]
877                    .iter()
878                    .map(|&stop| stop.min(end as u32) - at as u32)
879                    .collect();
880                let values = values.slice(first, last - first + 1)?;
881                Body::Runs { ends: cut, values: Arc::new(values) }
882            }
883            // An empty cut has no run to point at and an empty run length body would be a vector of
884            // no runs claiming a length, so it comes back as the empty flat vector instead.
885            Body::Runs { .. } => return self.gather(&[]),
886            // The one form with nowhere to point, so its range is copied out. A gather is the
887            // right tool here and does no more than this would: a flat body has no dictionary
888            // under it for the gather to flatten.
889            Body::Flat(_) => {
890                let indices: Vec<u32> =
891                    (at..end).map(|row| u32::try_from(row).unwrap_or(u32::MAX)).collect();
892                return self.gather(&indices);
893            }
894        };
895        Ok(Self { ty: self.ty.clone(), len, validity, body })
896    }
897
898    /// The same values in flat form.
899    ///
900    /// Flattening a vector that is already flat is free. Flattening any other form costs a copy,
901    /// which is exactly why the other forms exist and why nothing on the hot path should call
902    /// this. It is here for the operators that genuinely cannot do better and for the tests that
903    /// check the other forms against it.
904    ///
905    /// A call that copies counts itself against [`Cause::Flatten`], because a flatten on a hot path
906    /// is the most expensive thing in this crate and the only way to find one is to have the number.
907    /// A call on a vector that is already flat does not count, since it neither copies nor gives
908    /// anything up.
909    ///
910    /// # Errors
911    ///
912    /// If the type is one this crate cannot store flat yet, which today means the nested types.
913    pub fn flatten(&self) -> Result<Self> {
914        if let Body::Flat(_) = self.body {
915            return Ok(self.clone());
916        }
917        slow::took(Cause::Flatten);
918        self.copied((0..self.len).collect(), false)
919    }
920
921    /// The values at the given positions, copied, in a form that does not point back at this vector.
922    ///
923    /// This is the copying counterpart to [`Self::dictionary`], and the two are the two halves of
924    /// the decision `spec/07-execution.md` section 7.1 describes. Which half is right is measured
925    /// rather than argued, and [`Chunk::compact`](crate::Chunk::compact) is where the measurement
926    /// is written down.
927    ///
928    /// A dictionary chain is walked to its leaf first and the codes composed on the way down, so the
929    /// copy runs once over the data rather than once per level, and a position that is null at any
930    /// level comes out null here. The copy is a typed loop per physical layout rather than a `Value`
931    /// per row, which is the whole point of it and is what [`Self::flatten`] now goes through too.
932    ///
933    /// # Errors
934    ///
935    /// If the type has no flat layout, which today means the nested types.
936    pub fn gather(&self, indices: &[u32]) -> Result<Self> {
937        self.copied(indices.iter().map(|&index| index as usize).collect(), true)
938    }
939
940    /// The copy both [`Self::gather`] and [`Self::flatten`] are.
941    ///
942    /// `constants_stay` is the one thing the two want differently. A gather of a constant is a
943    /// shorter constant and copying it out would be a thousand writes of the same value for nothing,
944    /// but flattening promises flat form to a caller that is about to read the data slice, so for
945    /// that one the constant has to be written out.
946    fn copied(&self, at: Vec<usize>, constants_stay: bool) -> Result<Self> {
947        let rows = at.len();
948        let (at, leaf) = self.resolve(at);
949        let live: Vec<bool> = at.iter().map(|&index| index != NOWHERE).collect();
950        let validity = Validity::from_run(&live);
951        let body = match &leaf.body {
952            // Every position holds the same value, so the only thing the gather can change is the
953            // length and which positions are null. A gather with no null in it is still a constant.
954            Body::Constant(value) => {
955                if constants_stay && matches!(validity, Validity::AllValid) {
956                    return Ok(Self::constant(self.ty.clone(), value.as_ref().clone(), rows));
957                }
958                let mut data = empty_data_for(&self.ty)?;
959                for &index in &at {
960                    push_value(&mut data, if index == NOWHERE { &Value::Null } else { value })?;
961                }
962                Body::Flat(data)
963            }
964            // A sequence is arithmetic rather than storage, so the gather is the arithmetic done at
965            // the positions asked for, and a null writes the zero every other layout writes.
966            Body::Sequence { start, step } => Body::Flat(Data::Int64(
967                at.iter()
968                    .map(|&index| if index == NOWHERE { 0 } else { start + step * index as i64 })
969                    .collect(),
970            )),
971            // A flat body with no values is the untyped null, so every position asked for is null
972            // whatever was asked for. Going through the copy would build a run of no values and
973            // call it `rows` long, which is a vector whose length and data disagree.
974            Body::Flat(Data::Empty) => {
975                return Ok(Self::constant(self.ty.clone(), Value::Null, rows));
976            }
977            Body::Flat(data) => Body::Flat(copy_of(data, &at)),
978            // The one form whose copy is arithmetic rather than a move of bytes. It goes through a
979            // typed loop per layout the way the flat copy does, because the alternative is a `Value`
980            // per row and this is the path a flatten of a scanned column takes.
981            Body::Packed { words, width, base, offset } => {
982                Body::Flat(unpack(&self.ty, words, *offset, *width, *base, &at)?)
983            }
984            // Unreachable, because `resolve` walks past both of the forms that point at another
985            // vector and stops at the first body that does not.
986            Body::Dictionary { .. } | Body::Runs { .. } => {
987                return Err(Error::internal(
988                    "a form that points somewhere survived being resolved",
989                ));
990            }
991        };
992        Ok(Self { ty: self.ty.clone(), len: rows, validity, body })
993    }
994
995    /// Where each wanted position lives in the first body that is not a dictionary, and that body.
996    ///
997    /// A position that is null anywhere on the way down, or past the end of anything on the way
998    /// down, comes back as [`NOWHERE`]. That single sentinel is what keeps the copy loop from
999    /// carrying a validity mask alongside the positions it is already walking.
1000    fn resolve(&self, mut at: Vec<usize>) -> (Vec<usize>, &Self) {
1001        let mut source = self;
1002        loop {
1003            for slot in &mut at {
1004                if *slot >= source.len || !source.validity.is_valid(*slot) {
1005                    *slot = NOWHERE;
1006                }
1007            }
1008            source = match &source.body {
1009                Body::Dictionary { codes, values } => {
1010                    for slot in &mut at {
1011                        *slot = match codes.get(*slot) {
1012                            Some(&code) => code as usize,
1013                            None => NOWHERE,
1014                        };
1015                    }
1016                    values.as_ref()
1017                }
1018                // A run length body is a dictionary whose code is worked out from the position
1019                // rather than stored, so the walk down is the same walk with a search where the
1020                // lookup was. `NOWHERE` searches for nothing and stays `NOWHERE`.
1021                Body::Runs { ends, values } => {
1022                    for slot in &mut at {
1023                        *slot = run_holding(ends, *slot).unwrap_or(NOWHERE);
1024                    }
1025                    values.as_ref()
1026                }
1027                _ => return (at, source),
1028            };
1029        }
1030    }
1031}
1032
1033/// So that a kernel can take its operands as either a list of vectors or a list of references.
1034///
1035/// A caller that built a `Vec<Vector>` and a caller whose operands are already somewhere else, in a
1036/// chunk or in an evaluator's scratch, want the same kernel. Without this the second kind has to
1037/// clone every operand into a `Vec` to satisfy the signature, and a clone of a vector is a copy of
1038/// the whole column, so the type would be charging real memory traffic for nothing.
1039impl AsRef<Vector> for Vector {
1040    fn as_ref(&self) -> &Vector {
1041        self
1042    }
1043}
1044
1045/// The bits of a packed vector and what they mean, for a kernel that wants to stay in code space.
1046///
1047/// Borrowed from the vector rather than owning anything, so getting one costs nothing and a kernel
1048/// that finds it cannot use them has given up nothing by asking.
1049#[derive(Debug, Clone, Copy)]
1050pub struct Packed<'a> {
1051    words: &'a [u64],
1052    width: u32,
1053    base: i128,
1054    offset: usize,
1055}
1056
1057impl Packed<'_> {
1058    /// How many bits one code takes, between one and [`PACKED_WIDTH_MAX`].
1059    #[must_use]
1060    pub fn width(&self) -> u32 {
1061        self.width
1062    }
1063
1064    /// What zero means, so that the value of a row is the base plus its code.
1065    #[must_use]
1066    pub fn base(&self) -> i128 {
1067        self.base
1068    }
1069
1070    /// The largest value this vector can be holding, whatever it is actually holding.
1071    ///
1072    /// With [`Self::base`] this is the pair a comparison kernel wants first. A literal outside the
1073    /// two answers every row of the vector the same way, which is a whole chunk decided without a
1074    /// bit being read, and that is the case a zone map would have caught if there were one here.
1075    #[must_use]
1076    pub fn ceiling(&self) -> i128 {
1077        self.base + i128::from(u64::MAX >> (u64::BITS - self.width))
1078    }
1079
1080    /// The code of row `row`, which is its value minus [`Self::base`].
1081    ///
1082    /// Out of range rows read as zero rather than panicking, the way every other accessor in this
1083    /// file answers for a row that is not there.
1084    #[must_use]
1085    pub fn code(&self, row: usize) -> u64 {
1086        code_at(self.words, (self.offset + row) * self.width as usize, self.width)
1087    }
1088
1089    /// Which code a value would have, and `None` for a value this vector cannot be holding.
1090    ///
1091    /// The translation a comparison does once per vector so that it does not have to unpack once per
1092    /// row. `None` is the useful answer rather than a failure: it says the literal is outside the
1093    /// packed range, so every row compares against it the same way.
1094    #[must_use]
1095    pub fn code_of(&self, value: i128) -> Option<u64> {
1096        u64::try_from(value.checked_sub(self.base)?).ok().filter(|&code| code <= self.mask())
1097    }
1098
1099    /// The largest code the width allows.
1100    fn mask(&self) -> u64 {
1101        u64::MAX >> (u64::BITS - self.width)
1102    }
1103}
1104
1105/// The widest a packed code is allowed to be.
1106///
1107/// Sixty three rather than sixty four so that a mask is `u64::MAX >> (64 - width)` with no shift of
1108/// a whole word in it, and reading a code is one branch on whether it straddles rather than two. A
1109/// sixty four bit code saves nothing anyway, since it is the layout it came from.
1110pub const PACKED_WIDTH_MAX: u32 = 63;
1111
1112/// How much smaller packing has to be before it is worth the shift and the mask on every read.
1113///
1114/// Two, so a column packs when the bits come to half the flat size or less. A column that would save
1115/// a tenth stays flat, because a tenth of a column is not worth turning every read of it into
1116/// arithmetic, and the whole argument for the form is that a narrow column saves most of itself.
1117pub const PACKING_PAYS_AT: usize = 2;
1118
1119/// How many words hold `len` codes of `width` bits.
1120fn words_for(len: usize, width: u32) -> usize {
1121    (len * width as usize).div_ceil(u64::BITS as usize)
1122}
1123
1124/// The lowest and highest value a type's layout can hold, and `None` for a type with no integer one.
1125///
1126/// This is also the test of whether a type can be packed at all, and it is the only one, so the
1127/// layouts listed here and the layouts [`pack`] and [`unpack`] know how to walk are the same list
1128/// from the same macro and cannot drift apart.
1129fn layout_range(ty: &LogicalType) -> Option<(i128, i128)> {
1130    use rudb_common::PhysicalType as P;
1131    macro_rules! ranges {
1132        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1133            match ty.physical() {
1134                $(P::$variant => Some((i128::from(<$native>::MIN), i128::from(<$native>::MAX))),)+
1135                _ => None,
1136            }
1137        };
1138    }
1139    crate::for_each_layout!(exact, ranges)
1140}
1141
1142/// The lowest and highest value in the first `len` slots of a run of integer data.
1143///
1144/// `None` for data that is not integers, which is what says a column cannot be packed. The null
1145/// slots are in the span, holding whatever zero was written into them, which
1146/// [`Vector::bit_packed`] says more about.
1147fn span_of(data: &Data, len: usize) -> Option<(i128, i128)> {
1148    macro_rules! spans {
1149        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1150            match data {
1151                $(Data::$variant(values) => {
1152                    let mut low = i128::MAX;
1153                    let mut high = i128::MIN;
1154                    for &value in values.as_slice().iter().take(len) {
1155                        let value = i128::from(value);
1156                        low = low.min(value);
1157                        high = high.max(value);
1158                    }
1159                    (low <= high).then_some((low, high))
1160                })+
1161                _ => None,
1162            }
1163        };
1164    }
1165    crate::for_each_layout!(exact, spans)
1166}
1167
1168/// The first `len` values of a run of integer data, written out as codes of `width` bits from `base`.
1169fn pack(data: &Data, len: usize, base: i128, width: u32) -> Vec<u64> {
1170    let mut words = vec![0u64; words_for(len, width)];
1171    macro_rules! packing {
1172        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1173            match data {
1174                $(Data::$variant(values) => {
1175                    for (row, &value) in values.as_slice().iter().take(len).enumerate() {
1176                        // In range because `base` and `width` came from the span of this same run.
1177                        let code = u64::try_from(i128::from(value) - base).unwrap_or(0);
1178                        write_code(&mut words, row * width as usize, width, code);
1179                    }
1180                })+
1181                _ => {}
1182            }
1183        };
1184    }
1185    crate::for_each_layout!(exact, packing);
1186    words
1187}
1188
1189/// The codes at the given rows, unpacked into the flat layout the type calls for.
1190///
1191/// A row of [`NOWHERE`] writes the layout's zero, which is the rule [`copy_of`] follows for the same
1192/// reason: every layout here is a parallel array to a validity mask, so a null takes a slot.
1193///
1194/// # Errors
1195///
1196/// If the type has no flat layout, which a packed vector cannot have and which is checked when one
1197/// is built, so an error here is a bug rather than a caller mistake.
1198fn unpack(
1199    ty: &LogicalType,
1200    words: &[u64],
1201    offset: usize,
1202    width: u32,
1203    base: i128,
1204    at: &[usize],
1205) -> Result<Data> {
1206    let mut out = empty_data_for(ty)?;
1207    let value_of = |row: usize| {
1208        if row == NOWHERE {
1209            return None;
1210        }
1211        Some(base + i128::from(code_at(words, (offset + row) * width as usize, width)))
1212    };
1213    macro_rules! unpacking {
1214        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1215            match &mut out {
1216                $(Data::$variant(values) => {
1217                    values.reserve(at.len());
1218                    for &row in at {
1219                        // In range because both ends of it were checked when the vector was built.
1220                        let value = value_of(row)
1221                            .and_then(|value| <$native>::try_from(value).ok())
1222                            .unwrap_or($zero);
1223                        values.push(value);
1224                    }
1225                })+
1226                _ => {
1227                    return Err(Error::internal(format!(
1228                        "a {ty} vector was packed, which no integer layout allows"
1229                    )));
1230                }
1231            }
1232        };
1233    }
1234    crate::for_each_layout!(exact, unpacking);
1235    Ok(out)
1236}
1237
1238/// The `width` bits starting at `bit`, low end first.
1239///
1240/// Zero for bits past the end of the words, which keeps a read of a row that is not there from
1241/// panicking and matches what every other accessor here does with one.
1242fn code_at(words: &[u64], bit: usize, width: u32) -> u64 {
1243    let word = bit / u64::BITS as usize;
1244    let shift = (bit % u64::BITS as usize) as u32;
1245    let mask = u64::MAX >> (u64::BITS - width);
1246    let low = words.get(word).copied().unwrap_or(0) >> shift;
1247    let taken = u64::BITS - shift;
1248    if taken >= width {
1249        return low & mask;
1250    }
1251    // The code straddles two words, and `taken` is under the width here so it is under sixty four,
1252    // which is what makes the shift below one the hardware will do rather than one it refuses.
1253    let high = words.get(word + 1).copied().unwrap_or(0) << taken;
1254    (low | high) & mask
1255}
1256
1257/// Writes `width` bits of `code` starting at `bit`, over words that started out zero.
1258fn write_code(words: &mut [u64], bit: usize, width: u32, code: u64) {
1259    let word = bit / u64::BITS as usize;
1260    let shift = (bit % u64::BITS as usize) as u32;
1261    words[word] |= code << shift;
1262    let taken = u64::BITS - shift;
1263    if taken < width {
1264        words[word + 1] |= code >> taken;
1265    }
1266}
1267
1268/// One level of dictionary out of however many levels were handed to [`Vector::dictionary`].
1269///
1270/// Every dictionary in the system is built through that constructor and every one of them comes
1271/// through here first, so the invariant this maintains is that the vector a dictionary points at is
1272/// never itself a dictionary that could have been composed away. That makes the work a single `if`
1273/// rather than a loop: the inner vector was already composed when it was built, so composing the
1274/// outer codes through it leaves the result no deeper than the inner vector already was.
1275///
1276/// The codes are indexed rather than fetched with `get`, because the caller has already walked the
1277/// whole outer array to check that every code is in range and the inner array is exactly as long as
1278/// the vector those codes were checked against.
1279fn compose(codes: Vec<u32>, values: Vector) -> (Vec<u32>, Vector) {
1280    // A dictionary carrying a validity of its own is one whose nulls live at this level rather than
1281    // in the values, which is the one thing composition cannot carry down with it.
1282    if !matches!(values.validity, Validity::AllValid) {
1283        return (codes, values);
1284    }
1285    let Vector { ty, len, validity, body } = values;
1286    match body {
1287        Body::Dictionary { codes: inner, values: leaf } => {
1288            debug_assert!(
1289                !matches!(leaf.body, Body::Dictionary { .. })
1290                    || !matches!(leaf.validity, Validity::AllValid),
1291                "a dictionary was stacked on a dictionary without going through the constructor"
1292            );
1293            // The leaf is shared, so taking it out of the `Arc` copies it when something else is
1294            // still holding the same dictionary. That is the rare path: a dictionary over a
1295            // dictionary only arrives from a caller that built one that way, and the cut that made
1296            // sharing worth doing produces neither.
1297            (codes.iter().map(|&code| inner[code as usize]).collect(), Arc::unwrap_or_clone(leaf))
1298        }
1299        body => (codes, Vector { ty, len, validity, body }),
1300    }
1301}
1302
1303/// How many rows a run has to cover on average before run length encoding is smaller.
1304///
1305/// A run costs its value plus the four bytes of its end, so on a four byte column a run of two rows
1306/// breaks even and a run of three wins. Wider columns win sooner and narrower ones later, and this
1307/// is the one ratio for all of them because a threshold per width is a table that has to be right
1308/// nine times rather than once. It is a constant with a name so that the sweep that eventually moves
1309/// it has something to move.
1310const RUNS_PAY_AT: usize = 2;
1311
1312/// Which run holds `row`, given ends that are exclusive and increasing.
1313///
1314/// A binary search rather than a scan, because the callers that ask this are the ones that are not
1315/// walking the runs in order: a single value read out of a result set, or a gather at scattered
1316/// positions. Anything walking in order should be reading [`Vector::run_parts`] instead, which is
1317/// what the form is for.
1318fn run_holding(ends: &[u32], row: usize) -> Option<usize> {
1319    let row = u32::try_from(row).ok()?;
1320    let run = match ends.binary_search(&row) {
1321        // The ends are exclusive, so landing exactly on one means the row is the first of the next.
1322        Ok(at) => at + 1,
1323        Err(at) => at,
1324    };
1325    (run < ends.len()).then_some(run)
1326}
1327
1328/// The row each run ends at, for a flat body read alongside the validity that goes with it.
1329///
1330/// Two adjacent nulls are one run, because a reader of either gets a null and cannot tell them
1331/// apart. A null between two equal values is three runs for the same reason, since the null is a
1332/// value of the column as far as anything reading it is concerned.
1333///
1334/// The comparison is per layout rather than per `Value`, which is the whole reason this is a macro.
1335/// A `Value` a row would allocate a string per row on a `VARCHAR` column and would be the exact
1336/// defect `cargo xtask rowloop` exists to fail the build on.
1337fn boundaries(data: &Data, validity: &Validity, len: usize) -> Vec<u32> {
1338    if len == 0 {
1339        return Vec::new();
1340    }
1341    let breaks = |ends: &mut Vec<u32>, mut differs: Box<dyn FnMut(usize, usize) -> bool + '_>| {
1342        for row in 1..len {
1343            let same = match (validity.is_valid(row), validity.is_valid(row - 1)) {
1344                (false, false) => true,
1345                (true, true) => !differs(row, row - 1),
1346                _ => false,
1347            };
1348            if !same {
1349                ends.push(u32::try_from(row).unwrap_or(u32::MAX));
1350            }
1351        }
1352        ends.push(u32::try_from(len).unwrap_or(u32::MAX));
1353    };
1354    let mut ends = Vec::new();
1355    macro_rules! walked {
1356        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1357            match data {
1358                // No values at all, so every row is the same null and the column is one run.
1359                Data::Empty => ends.push(u32::try_from(len).unwrap_or(u32::MAX)),
1360                $(Data::$variant(values) => {
1361                    breaks(&mut ends, Box::new(|a, b| values.get(a) != values.get(b)));
1362                })+
1363                Data::Varlen(values) => {
1364                    breaks(&mut ends, Box::new(|a, b| values.bytes(a) != values.bytes(b)));
1365                }
1366            }
1367        };
1368    }
1369    crate::for_each_layout!(fixed, walked);
1370    ends
1371}
1372
1373/// The position of a value that is not anywhere, because it is null or out of range.
1374///
1375/// `usize::MAX` rather than an `Option<usize>`, because the copy loop's bounds check rejects it for
1376/// free and an `Option` would put a second branch next to the one already there.
1377const NOWHERE: usize = usize::MAX;
1378
1379/// A run of data copied at the given positions, with a zero wherever the position is [`NOWHERE`].
1380///
1381/// A zero and not a skip, because every layout here is a parallel array to a validity mask and a
1382/// short one would put every value after the first null at the wrong index. It is the same rule
1383/// [`push_value`] follows for a null.
1384fn copy_of(data: &Data, at: &[usize]) -> Data {
1385    macro_rules! copied {
1386        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1387            match data {
1388                Data::Empty => Data::Empty,
1389                $(Data::$variant(values) => {
1390                    let mut out = Buffer::with_capacity(at.len());
1391                    for &index in at {
1392                        // One bounds check rather than a null test and a bounds check, because
1393                        // `NOWHERE` is past the end of every slice there can be.
1394                        out.push(values.get(index).copied().unwrap_or($zero));
1395                    }
1396                    Data::$variant(out)
1397                })+
1398                // The one layout where a gather is a copy of bytes rather than a copy of fixed
1399                // width slots, and the reason compaction is a decision rather than a default on a
1400                // string column.
1401                Data::Varlen(values) => {
1402                    let mut out = StringColumn::with_capacity(at.len());
1403                    // The bytes are known before any of them are copied, because a view carries its
1404                    // length and the wanted positions are already in hand, so the arena is one
1405                    // allocation rather than a run of doublings that each copy what the last one
1406                    // copied.
1407                    let views = values.views();
1408                    out.reserve_bytes(
1409                        at.iter()
1410                            .filter_map(|&index| views.get(index))
1411                            .filter(|view| !view.is_inline())
1412                            .map(StringView::len)
1413                            .sum(),
1414                    );
1415                    for &index in at {
1416                        out.push_from(values, index);
1417                    }
1418                    Data::Varlen(out)
1419                }
1420            }
1421        };
1422    }
1423    crate::for_each_layout!(fixed, copied)
1424}
1425
1426/// The physical layout a run of data is in, for the check that it matches its type.
1427///
1428/// The two enums name their variants the same way on purpose, so this is one generated arm rather
1429/// than sixteen chances to pair the wrong two up.
1430fn layout_of(data: &Data) -> rudb_common::PhysicalType {
1431    use rudb_common::PhysicalType as P;
1432    macro_rules! layouts {
1433        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1434            match data {
1435                Data::Empty => P::Empty,
1436                $(Data::$variant(_) => P::$variant,)+
1437            }
1438        };
1439    }
1440    crate::for_each_layout!(all, layouts)
1441}
1442
1443/// One value out of a run of data, given what the run means.
1444///
1445/// The match is on the logical type rather than on the data, because the data cannot tell a `DATE`
1446/// from an `INTEGER` and that is the whole reason the two are kept apart.
1447fn value_from(ty: &LogicalType, data: &Data, index: usize) -> Value {
1448    let signed = || data.signed_at(index);
1449    let unsigned = || data.unsigned_at(index);
1450    let value = match ty {
1451        LogicalType::Boolean => match data {
1452            Data::Bool(v) => v.get(index).map(|&x| Value::Boolean(x)),
1453            _ => None,
1454        },
1455        LogicalType::TinyInt => signed().and_then(|x| i8::try_from(x).ok()).map(Value::TinyInt),
1456        LogicalType::SmallInt => signed().and_then(|x| i16::try_from(x).ok()).map(Value::SmallInt),
1457        LogicalType::Integer => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Integer),
1458        LogicalType::BigInt => signed().and_then(|x| i64::try_from(x).ok()).map(Value::BigInt),
1459        LogicalType::HugeInt => signed().map(Value::HugeInt),
1460        LogicalType::UTinyInt => unsigned().and_then(|x| u8::try_from(x).ok()).map(Value::UTinyInt),
1461        LogicalType::USmallInt => {
1462            unsigned().and_then(|x| u16::try_from(x).ok()).map(Value::USmallInt)
1463        }
1464        LogicalType::UInteger => {
1465            unsigned().and_then(|x| u32::try_from(x).ok()).map(Value::UInteger)
1466        }
1467        LogicalType::UBigInt => unsigned().and_then(|x| u64::try_from(x).ok()).map(Value::UBigInt),
1468        LogicalType::UHugeInt => unsigned().map(Value::UHugeInt),
1469        LogicalType::Float => match data {
1470            Data::Float32(v) => v.get(index).map(|&x| Value::Float(x)),
1471            _ => None,
1472        },
1473        LogicalType::Double => match data {
1474            Data::Float64(v) => v.get(index).map(|&x| Value::Double(x)),
1475            _ => None,
1476        },
1477        LogicalType::Decimal { width, scale } => {
1478            signed().map(|unscaled| Value::Decimal { unscaled, width: *width, scale: *scale })
1479        }
1480        LogicalType::Varchar => data.str_at(index).map(|s| Value::Varchar(s.to_string())),
1481        LogicalType::Blob | LogicalType::Bit => {
1482            data.bytes_at(index).map(|bytes| Value::Blob(bytes.to_vec()))
1483        }
1484        LogicalType::Date => signed().and_then(|x| i32::try_from(x).ok()).map(Value::Date),
1485        LogicalType::Time | LogicalType::TimeTz => {
1486            signed().and_then(|x| i64::try_from(x).ok()).map(Value::Time)
1487        }
1488        LogicalType::Timestamp
1489        | LogicalType::TimestampS
1490        | LogicalType::TimestampMs
1491        | LogicalType::TimestampNs
1492        | LogicalType::TimestampTz => {
1493            signed().and_then(|x| i64::try_from(x).ok()).map(Value::Timestamp)
1494        }
1495        LogicalType::Interval => match data {
1496            Data::Interval(v) => {
1497                v.get(index).map(|&(months, days, micros)| Value::Interval { months, days, micros })
1498            }
1499            _ => None,
1500        },
1501        _ => None,
1502    };
1503    value.unwrap_or(Value::Null)
1504}
1505
1506/// An empty run of data of the right layout for a type.
1507fn empty_data_for(ty: &LogicalType) -> Result<Data> {
1508    use rudb_common::PhysicalType as P;
1509    macro_rules! empties {
1510        ($(($variant:ident, $native:ty, $zero:expr)),+ $(,)?) => {
1511            match ty.physical() {
1512                P::Empty => Data::Empty,
1513                $(P::$variant => Data::$variant(Buffer::new()),)+
1514                P::Varlen => Data::Varlen(StringColumn::new()),
1515                other => {
1516                    return Err(Error::not_implemented(format!(
1517                        "a flat vector of {other:?} data, which arrives with the storage layer"
1518                    )));
1519                }
1520            }
1521        };
1522    }
1523    Ok(crate::for_each_layout!(fixed, empties))
1524}
1525
1526/// Appends one value to a run of data, or a zero of the right shape when it is null.
1527///
1528/// The zero matters. A null still occupies a position, the validity mask is what says it is null,
1529/// and a run of data with a hole in it would put every value after the hole in the wrong place.
1530fn push_value(data: &mut Data, value: &Value) -> Result<()> {
1531    macro_rules! push {
1532        ($vec:expr, $variant:path, $zero:expr) => {
1533            match value {
1534                Value::Null => $vec.push($zero),
1535                $variant(x) => $vec.push(*x),
1536                other => {
1537                    return Err(Error::internal(format!(
1538                        "{other:?} does not belong in this vector"
1539                    )));
1540                }
1541            }
1542        };
1543    }
1544    // A decimal is stored as its unscaled integer in whatever width its precision needs, which
1545    // `LogicalType::physical` decides and which is why the same `Value::Decimal` is at home in four
1546    // different runs. The narrowing cannot fail for a value the binder produced, because the width
1547    // that chose the run is the width in the value, but it is checked rather than assumed because
1548    // an unchecked cast here would silently store a different number.
1549    macro_rules! decimal {
1550        ($vec:expr, $ty:ty, $unscaled:expr) => {
1551            match <$ty>::try_from(*$unscaled) {
1552                Ok(x) => $vec.push(x),
1553                Err(_) => {
1554                    return Err(Error::internal(format!(
1555                        "an unscaled decimal of {} does not fit the run its precision chose",
1556                        $unscaled
1557                    )));
1558                }
1559            }
1560        };
1561    }
1562    match data {
1563        Data::Empty => {}
1564        Data::Bool(v) => push!(v, Value::Boolean, false),
1565        Data::Int8(v) => push!(v, Value::TinyInt, 0),
1566        Data::Int16(v) => match value {
1567            Value::Null => v.push(0),
1568            Value::SmallInt(x) => v.push(*x),
1569            Value::Decimal { unscaled, .. } => decimal!(v, i16, unscaled),
1570            other => return Err(Error::internal(format!("{other:?} is not a 16 bit value"))),
1571        },
1572        Data::Int32(v) => match value {
1573            Value::Null => v.push(0),
1574            Value::Integer(x) | Value::Date(x) => v.push(*x),
1575            Value::Decimal { unscaled, .. } => decimal!(v, i32, unscaled),
1576            other => return Err(Error::internal(format!("{other:?} is not a 32 bit value"))),
1577        },
1578        Data::Int64(v) => match value {
1579            Value::Null => v.push(0),
1580            Value::BigInt(x) | Value::Time(x) | Value::Timestamp(x) => v.push(*x),
1581            Value::Decimal { unscaled, .. } => decimal!(v, i64, unscaled),
1582            other => return Err(Error::internal(format!("{other:?} is not a 64 bit value"))),
1583        },
1584        Data::Int128(v) => match value {
1585            Value::Null => v.push(0),
1586            Value::HugeInt(x) => v.push(*x),
1587            Value::Decimal { unscaled, .. } => v.push(*unscaled),
1588            other => return Err(Error::internal(format!("{other:?} is not a 128 bit value"))),
1589        },
1590        Data::UInt8(v) => push!(v, Value::UTinyInt, 0),
1591        Data::UInt16(v) => push!(v, Value::USmallInt, 0),
1592        Data::UInt32(v) => push!(v, Value::UInteger, 0),
1593        Data::UInt64(v) => push!(v, Value::UBigInt, 0),
1594        Data::UInt128(v) => push!(v, Value::UHugeInt, 0),
1595        Data::Float32(v) => push!(v, Value::Float, 0.0),
1596        Data::Float64(v) => push!(v, Value::Double, 0.0),
1597        Data::Interval(v) => match value {
1598            Value::Null => v.push((0, 0, 0)),
1599            Value::Interval { months, days, micros } => v.push((*months, *days, *micros)),
1600            other => return Err(Error::internal(format!("{other:?} is not an interval"))),
1601        },
1602        Data::Varlen(column) => match value {
1603            Value::Null => {
1604                column.push("");
1605            }
1606            Value::Varchar(text) => {
1607                column.push(text);
1608            }
1609            // A blob goes in as the bytes it is. The column stores a length and some bytes either
1610            // way, so text is the reading of one rather than a different column, and a blob that
1611            // is not UTF-8 is stored exactly like one that happens to be.
1612            Value::Blob(bytes) => {
1613                column.push_bytes(bytes);
1614            }
1615            other => return Err(Error::internal(format!("{other:?} is not a string"))),
1616        },
1617    }
1618    Ok(())
1619}
1620
1621#[cfg(test)]
1622mod tests {
1623    use std::sync::Arc;
1624
1625    use rudb_common::{LogicalType, Value};
1626
1627    use super::{Body, Data, Form, VECTOR_SIZE, Vector};
1628    use crate::string::StringColumn;
1629    use crate::validity::Validity;
1630
1631    fn integers(values: &[i32]) -> Vector {
1632        Vector::flat(LogicalType::Integer, Data::Int32(values.to_vec().into())).unwrap()
1633    }
1634
1635    #[test]
1636    fn a_clustered_column_becomes_runs_and_reads_back_the_same() {
1637        let mut values = Vec::new();
1638        for (value, times) in [(7, 400), (8, 300), (7, 324)] {
1639            values.extend(std::iter::repeat_n(value, times));
1640        }
1641        let flat = integers(&values);
1642        let runs = flat.run_encoded().unwrap();
1643        assert_eq!(runs.form(), Form::Rle);
1644        assert_eq!(runs.run_parts().expect("runs").0, [400, 700, 1024]);
1645        assert_eq!(runs.len(), flat.len());
1646        assert_eq!(runs.iter().collect::<Vec<_>>(), flat.iter().collect::<Vec<_>>());
1647        assert!(
1648            runs.footprint() * 10 < flat.footprint(),
1649            "three runs against a thousand rows: {} against {}",
1650            runs.footprint(),
1651            flat.footprint()
1652        );
1653    }
1654
1655    /// The check is worth having in both directions. A form that is only ever bigger than what it
1656    /// replaced is a form that costs a pass over the column to decide not to use.
1657    #[test]
1658    fn a_column_that_does_not_repeat_is_left_flat() {
1659        let flat = integers(&(0..1024).collect::<Vec<i32>>());
1660        assert_eq!(flat.run_encoded().unwrap().form(), Form::Flat);
1661        // Two runs over four rows is exactly break even on a four byte column, and break even is
1662        // not a reason to change form.
1663        assert_eq!(integers(&[1, 1, 2, 2]).run_encoded().unwrap().form(), Form::Flat);
1664        assert_eq!(integers(&[1, 1, 1, 2, 2]).run_encoded().unwrap().form(), Form::Rle);
1665    }
1666
1667    #[test]
1668    fn two_nulls_beside_each_other_are_one_run_and_a_null_between_two_equals_is_a_break() {
1669        let mut values = vec![Value::Integer(4), Value::Integer(4)];
1670        values.extend([Value::Null, Value::Null, Value::Null]);
1671        values.extend(std::iter::repeat_n(Value::Integer(4), 5));
1672        let flat = Vector::from_values(LogicalType::Integer, &values).unwrap();
1673        let runs = flat.run_encoded().unwrap();
1674        assert_eq!(runs.run_parts().expect("runs").0, [2, 5, 10]);
1675        assert_eq!(runs.iter().collect::<Vec<_>>(), values);
1676    }
1677
1678    #[test]
1679    fn slicing_runs_keeps_them_runs_and_cuts_the_first_and_last_one_back() {
1680        let flat = integers(&[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]);
1681        let runs = flat.run_encoded().unwrap();
1682        let piece = runs.slice(3, 6).unwrap();
1683        assert_eq!(piece.form(), Form::Rle, "the form is the whole point");
1684        assert_eq!(piece.run_parts().expect("runs").0, [1, 5, 6]);
1685        assert_eq!(
1686            piece.iter().collect::<Vec<_>>(),
1687            flat.slice(3, 6).unwrap().iter().collect::<Vec<_>>()
1688        );
1689        assert_eq!(runs.slice(0, 0).unwrap().len(), 0);
1690        assert_eq!(runs.slice(0, 12).unwrap().form(), Form::Rle);
1691    }
1692
1693    #[test]
1694    fn gathering_out_of_runs_walks_to_the_values_the_way_it_walks_a_dictionary() {
1695        let mut values = vec![Value::Varchar("red".into()); 4];
1696        values.extend([Value::Null, Value::Null, Value::Null]);
1697        values.extend(vec![Value::Varchar("blue".into()); 4]);
1698        let runs =
1699            Vector::from_values(LogicalType::Varchar, &values).unwrap().run_encoded().unwrap();
1700        assert_eq!(runs.form(), Form::Rle);
1701        let picked = runs.gather(&[8, 0, 5, 2]).unwrap();
1702        assert_eq!(picked.form(), Form::Flat, "a gather copies, whatever it gathered from");
1703        assert_eq!(
1704            picked.iter().collect::<Vec<_>>(),
1705            [values[8].clone(), values[0].clone(), Value::Null, values[2].clone()]
1706        );
1707        assert_eq!(runs.text_at(1), Some("red"));
1708        assert_eq!(runs.text_at(5), None, "a null has no text");
1709        assert_eq!(runs.flatten().unwrap().iter().collect::<Vec<_>>(), values);
1710    }
1711
1712    /// A run length vector over a run length vector turns one search per row into two, and there is
1713    /// nothing in the engine that builds one, so it is refused rather than composed.
1714    #[test]
1715    fn runs_of_runs_are_refused_and_runs_of_a_dictionary_are_not() {
1716        let inner = integers(&[1, 1, 1, 1, 2]).run_encoded().unwrap();
1717        assert_eq!(inner.form(), Form::Rle);
1718        let error = Vector::runs(vec![2, 8], inner).unwrap_err();
1719        assert!(error.to_string().contains("runs of runs"), "{error}");
1720
1721        let words = Vector::from_values(
1722            LogicalType::Varchar,
1723            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
1724        )
1725        .unwrap();
1726        let dictionary = Vector::dictionary(vec![1, 0], words).unwrap();
1727        let stacked = Vector::runs(vec![4, 9], dictionary).unwrap();
1728        assert_eq!(stacked.len(), 9);
1729        assert_eq!(stacked.value_at(3), Value::Varchar("blue".into()));
1730        assert_eq!(stacked.value_at(4), Value::Varchar("red".into()));
1731    }
1732
1733    #[test]
1734    fn run_ends_have_to_increase_and_there_is_one_value_for_each_of_them() {
1735        let values = integers(&[1, 2]);
1736        assert!(Vector::runs(vec![4], values.clone()).is_err(), "two values and one run");
1737        assert!(Vector::runs(vec![4, 4], values.clone()).is_err(), "an end that repeats");
1738        assert!(Vector::runs(vec![4, 2], values.clone()).is_err(), "an end that goes backwards");
1739        assert!(Vector::runs(vec![0, 2], values.clone()).is_err(), "a first run holding no rows");
1740        assert_eq!(Vector::runs(vec![4, 9], values).unwrap().len(), 9);
1741    }
1742
1743    #[test]
1744    fn a_form_that_is_already_compact_is_left_where_it_is() {
1745        let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1000);
1746        assert_eq!(constant.run_encoded().unwrap().form(), Form::Constant);
1747        assert_eq!(Vector::sequence(0, 1, 1000).run_encoded().unwrap().form(), Form::Sequence);
1748    }
1749
1750    /// What makes one accessor cover both forms. A dictionary hands back the codes it stores and a
1751    /// run length vector works the same numbers out, and a kernel writing `values[at[row]]` reads
1752    /// the same rows out of either.
1753    #[test]
1754    fn both_forms_that_point_somewhere_hand_back_a_position_per_row() {
1755        let words = Vector::from_values(
1756            LogicalType::Varchar,
1757            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
1758        )
1759        .unwrap();
1760        let runs = Vector::runs(vec![3, 5], words.clone()).unwrap();
1761        let (at, values) = runs.positions().expect("runs point somewhere");
1762        assert_eq!(at.as_ref(), [0, 0, 0, 1, 1]);
1763        assert_eq!(values.value_at(at[3] as usize), runs.value_at(3));
1764
1765        let dictionary = Vector::dictionary(vec![1, 0, 1], words).unwrap();
1766        let (at, values) = dictionary.positions().expect("a dictionary points somewhere");
1767        assert_eq!(at.as_ref(), [1, 0, 1]);
1768        assert_eq!(values.value_at(at[0] as usize), dictionary.value_at(0));
1769
1770        assert!(integers(&[1, 2, 3]).positions().is_none(), "a flat vector points at itself");
1771        assert!(Vector::sequence(0, 1, 4).positions().is_none(), "a sequence stores nothing");
1772    }
1773
1774    #[test]
1775    fn slicing_a_dictionary_keeps_it_a_dictionary_where_gathering_would_not() {
1776        let values = Vector::from_values(
1777            LogicalType::Varchar,
1778            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
1779        )
1780        .unwrap();
1781        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
1782
1783        let piece = vector.slice(1, 3).unwrap();
1784        assert_eq!(piece.form(), Form::Dictionary, "the form is the whole point");
1785        assert_eq!(piece.len(), 3);
1786        assert_eq!(
1787            piece.iter().collect::<Vec<_>>(),
1788            [
1789                Value::Varchar("blue".into()),
1790                Value::Varchar("blue".into()),
1791                Value::Varchar("red".into())
1792            ]
1793        );
1794        assert_eq!(vector.gather(&[1, 2, 3]).unwrap().form(), Form::Flat, "which a gather loses");
1795    }
1796
1797    #[test]
1798    fn slicing_a_dictionary_shares_the_dictionary_rather_than_copying_it() {
1799        // The assertion is about the address and not about the values, because the values were
1800        // right when the dictionary was copied too. A page holds one dictionary and is cut into a
1801        // chunk of codes at a time, so copying the dictionary here is a copy of every string in it
1802        // per chunk, and on a read of a ClickBench partition it was ten percent of the cycles.
1803        let values = Vector::from_values(
1804            LogicalType::Varchar,
1805            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
1806        )
1807        .unwrap();
1808        let vector = Vector::dictionary(vec![0, 1, 1, 0, 1], values).unwrap();
1809        let Body::Dictionary { values: whole, .. } = &vector.body else {
1810            panic!("a dictionary vector holds a dictionary");
1811        };
1812
1813        let piece = vector.slice(1, 3).unwrap();
1814        let Body::Dictionary { codes, values: cut } = &piece.body else {
1815            panic!("a slice of a dictionary is a dictionary");
1816        };
1817        assert!(Arc::ptr_eq(whole, cut), "the cut copied the dictionary");
1818        assert_eq!(codes, &[1, 1, 0], "the codes are the part that is cut");
1819
1820        // And a cut of a cut shares it too, since that is what a scan does to a page it reads twice.
1821        let again = piece.slice(1, 2).unwrap();
1822        let Body::Dictionary { values: cut, .. } = &again.body else {
1823            panic!("a slice of a slice of a dictionary is a dictionary");
1824        };
1825        assert!(Arc::ptr_eq(whole, cut), "the second cut copied the dictionary");
1826        assert_eq!(
1827            again.iter().collect::<Vec<_>>(),
1828            [Value::Varchar("blue".into()), Value::Varchar("red".into())]
1829        );
1830    }
1831
1832    #[test]
1833    fn a_slice_carries_the_nulls_that_were_in_its_range_and_not_the_others() {
1834        let vector =
1835            integers(&[1, 2, 3, 4]).with_validity(Validity::from_run(&[false, true, false, true]));
1836        let piece = vector.slice(1, 2).unwrap();
1837        assert!(piece.validity().is_valid(0));
1838        assert!(!piece.validity().is_valid(1));
1839        assert_eq!(piece.value_at(1), Value::Null);
1840    }
1841
1842    #[test]
1843    fn slicing_a_sequence_moves_its_start_rather_than_writing_the_values_out() {
1844        let vector = Vector::sequence(100, 5, 10);
1845        let piece = vector.slice(3, 4).unwrap();
1846        assert_eq!(piece.form(), Form::Sequence);
1847        assert_eq!(
1848            piece.iter().collect::<Vec<_>>(),
1849            [Value::BigInt(115), Value::BigInt(120), Value::BigInt(125), Value::BigInt(130)]
1850        );
1851    }
1852
1853    #[test]
1854    fn slicing_a_constant_is_a_shorter_constant() {
1855        let vector = Vector::constant(LogicalType::Integer, Value::Integer(9), 8);
1856        let piece = vector.slice(2, 3).unwrap();
1857        assert_eq!(piece.form(), Form::Constant);
1858        assert_eq!(piece.len(), 3);
1859        assert_eq!(piece.value_at(2), Value::Integer(9));
1860    }
1861
1862    #[test]
1863    fn slicing_the_whole_vector_hands_it_back_as_it_was() {
1864        let vector = integers(&[1, 2, 3]);
1865        assert_eq!(
1866            vector.slice(0, 3).unwrap().iter().collect::<Vec<_>>(),
1867            [Value::Integer(1), Value::Integer(2), Value::Integer(3)]
1868        );
1869    }
1870
1871    #[test]
1872    fn a_slice_past_the_end_is_an_error_rather_than_a_short_vector() {
1873        let error = integers(&[1, 2, 3]).slice(2, 2).unwrap_err();
1874        assert!(error.to_string().contains("of a vector of 3"), "{error}");
1875    }
1876
1877    #[test]
1878    fn the_vector_size_is_the_one_the_design_is_built_around() {
1879        // 1024 and not DuckDB's 2048. A validity mask is 16 u64 words and a vector of string views
1880        // is 16 KiB, both of which are consequences of this number rather than coincidences.
1881        assert_eq!(VECTOR_SIZE, 1024);
1882        assert_eq!(VECTOR_SIZE / 64, 16);
1883    }
1884
1885    #[test]
1886    fn a_flat_vector_reads_back_what_was_put_in_it() {
1887        let vector = integers(&[1, 2, 3]);
1888        assert_eq!(vector.form(), Form::Flat);
1889        assert_eq!(vector.len(), 3);
1890        assert_eq!(vector.value_at(1), Value::Integer(2));
1891        assert_eq!(
1892            vector.iter().collect::<Vec<_>>(),
1893            vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)]
1894        );
1895    }
1896
1897    #[test]
1898    fn a_vector_built_from_values_reads_the_same_values_back() {
1899        let vector = Vector::from_values(
1900            LogicalType::Varchar,
1901            &[
1902                Value::Varchar("a".to_string()),
1903                Value::Null,
1904                Value::Varchar("a string too long to sit inside a view".to_string()),
1905            ],
1906        )
1907        .expect("strings and a null");
1908        assert_eq!(vector.len(), 3);
1909        assert_eq!(vector.value_at(0), Value::Varchar("a".to_string()));
1910        assert_eq!(vector.value_at(1), Value::Null);
1911        assert_eq!(
1912            vector.value_at(2),
1913            Value::Varchar("a string too long to sit inside a view".to_string())
1914        );
1915    }
1916
1917    /// A null still occupies a position. If it did not then every value after it would read back
1918    /// one place to the left, which is the kind of bug that looks like a storage bug for a week.
1919    #[test]
1920    fn a_null_in_the_middle_does_not_move_the_values_after_it() {
1921        let vector = Vector::from_values(
1922            LogicalType::Integer,
1923            &[Value::Integer(1), Value::Null, Value::Integer(3)],
1924        )
1925        .expect("integers and a null");
1926        assert_eq!(vector.value_at(2), Value::Integer(3));
1927        assert!(vector.validity().has_nulls(3), "the middle one is null");
1928    }
1929
1930    #[test]
1931    fn a_value_the_type_cannot_hold_is_refused() {
1932        let wrong = Vector::from_values(LogicalType::Integer, &[Value::Varchar("x".to_string())]);
1933        assert!(wrong.is_err(), "a string is not an integer");
1934    }
1935
1936    #[test]
1937    fn a_type_that_does_not_match_its_layout_is_refused_at_construction() {
1938        // One comparison here against a wrong answer read out three layers later.
1939        let wrong = Vector::flat(LogicalType::Varchar, Data::Int32(vec![1].into()));
1940        assert!(wrong.is_err());
1941        let right = Vector::flat(LogicalType::Date, Data::Int32(vec![1].into()));
1942        assert!(right.is_ok(), "a date is stored in an i32 and that has to be allowed");
1943    }
1944
1945    #[test]
1946    fn a_constant_vector_costs_one_value_whatever_its_length() {
1947        let vector = Vector::constant(LogicalType::Integer, Value::Integer(7), VECTOR_SIZE);
1948        assert_eq!(vector.form(), Form::Constant);
1949        assert_eq!(vector.len(), VECTOR_SIZE);
1950        assert_eq!(vector.value_at(0), Value::Integer(7));
1951        assert_eq!(vector.value_at(VECTOR_SIZE - 1), Value::Integer(7));
1952        assert_eq!(vector.value_at(VECTOR_SIZE), Value::Null, "past the end is null, not a panic");
1953    }
1954
1955    #[test]
1956    fn a_constant_null_is_all_invalid_without_being_told() {
1957        let vector = Vector::constant(LogicalType::Integer, Value::Null, 8);
1958        assert_eq!(vector.validity(), &Validity::AllInvalid);
1959        assert_eq!(vector.value_at(3), Value::Null);
1960    }
1961
1962    #[test]
1963    fn a_sequence_vector_is_sixteen_bytes_of_row_identifiers() {
1964        let vector = Vector::sequence(100, 1, VECTOR_SIZE);
1965        assert_eq!(vector.form(), Form::Sequence);
1966        assert_eq!(vector.value_at(0), Value::BigInt(100));
1967        assert_eq!(vector.value_at(923), Value::BigInt(1023));
1968        let stepped = Vector::sequence(0, 5, 4);
1969        assert_eq!(
1970            stepped.iter().collect::<Vec<_>>(),
1971            vec![Value::BigInt(0), Value::BigInt(5), Value::BigInt(10), Value::BigInt(15)]
1972        );
1973    }
1974
1975    #[test]
1976    fn a_dictionary_vector_reads_through_its_codes() {
1977        let mut column = StringColumn::new();
1978        column.push("red");
1979        column.push("green");
1980        let values = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
1981        let vector = Vector::dictionary(vec![0, 1, 1, 0], values).unwrap();
1982        assert_eq!(vector.form(), Form::Dictionary);
1983        assert_eq!(vector.logical_type(), &LogicalType::Varchar);
1984        assert_eq!(vector.value_at(2), Value::Varchar("green".into()));
1985        assert_eq!(vector.len(), 4);
1986    }
1987
1988    /// The accessor a group by keys a string column through, which has to agree with `value_at` on
1989    /// every position or two rows holding one string end up in two groups.
1990    #[test]
1991    fn text_is_read_where_it_already_is_for_the_forms_that_store_it() {
1992        let mut column = StringColumn::new();
1993        column.push("red");
1994        column.push("green");
1995        column.push("");
1996        let flat = Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap();
1997        for index in 0..flat.len() {
1998            assert_eq!(flat.text_at(index).map(str::to_string), text_of(&flat.value_at(index)));
1999        }
2000        let dictionary = Vector::dictionary(vec![1, 0, 1, 2], flat).unwrap();
2001        for index in 0..dictionary.len() {
2002            assert_eq!(
2003                dictionary.text_at(index).map(str::to_string),
2004                text_of(&dictionary.value_at(index))
2005            );
2006        }
2007        assert_eq!(dictionary.text_at(4), None, "past the end");
2008    }
2009
2010    /// The forms and types that have no text to hand back, which a caller answers by falling back
2011    /// to `value_at`. A blob is the one that would be a correctness bug rather than a slow path,
2012    /// since its bytes are not required to be text and it is not a `VARCHAR` either way.
2013    #[test]
2014    fn text_is_refused_where_it_is_not_stored_as_itself() {
2015        let nulls =
2016            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into()), Value::Null])
2017                .unwrap();
2018        assert_eq!(nulls.text_at(0), Some("red"));
2019        assert_eq!(nulls.text_at(1), None, "a null has no text");
2020        let constant = Vector::constant(LogicalType::Varchar, Value::Varchar("red".into()), 3);
2021        assert_eq!(constant.text_at(0), None, "a constant is not stored per position");
2022        assert_eq!(integers(&[1, 2]).text_at(0), None, "an integer is not text");
2023        let mut bytes = StringColumn::new();
2024        bytes.push("red");
2025        let blob = Vector::flat(LogicalType::Blob, Data::Varlen(bytes)).unwrap();
2026        assert_eq!(blob.text_at(0), None, "a blob is not a varchar");
2027    }
2028
2029    /// The text of a value, for comparing `text_at` against `value_at` position by position.
2030    fn text_of(value: &Value) -> Option<String> {
2031        match value {
2032            Value::Varchar(text) => Some(text.clone()),
2033            _ => None,
2034        }
2035    }
2036
2037    #[test]
2038    fn a_dictionary_code_past_the_end_is_refused() {
2039        // The alternative is a silent read of the wrong value, which is the failure mode the
2040        // entire M3 design has to be careful about.
2041        let values = integers(&[1, 2]);
2042        assert!(Vector::dictionary(vec![0, 2], values).is_err());
2043    }
2044
2045    #[test]
2046    fn every_form_flattens_to_the_same_values_it_reads_out() {
2047        // This is the shape of the equivalence testing in spec/16-testing.md section 16.2, in
2048        // miniature and long before there is an encoded kernel to point it at. A form that reads
2049        // out one way and flattens another is the exact bug that testing exists to catch.
2050        let mut column = StringColumn::new();
2051        column.push("alpha");
2052        column.push("beta");
2053        let dictionary = Vector::dictionary(
2054            vec![1, 0, 1],
2055            Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
2056        )
2057        .unwrap();
2058        let cases = [
2059            Vector::constant(LogicalType::Integer, Value::Integer(3), 5),
2060            Vector::sequence(7, -2, 5),
2061            dictionary,
2062        ];
2063        for vector in cases {
2064            let flat = vector.flatten().unwrap();
2065            assert_eq!(flat.form(), Form::Flat);
2066            assert_eq!(flat.len(), vector.len());
2067            for index in 0..vector.len() {
2068                assert_eq!(flat.value_at(index), vector.value_at(index), "at {index}");
2069            }
2070        }
2071    }
2072
2073    #[test]
2074    fn a_null_still_occupies_a_position_after_flattening() {
2075        // The reason push_value writes a zero for a null rather than skipping it. A run of data
2076        // with a hole in it puts every value after the hole in the wrong place, and the validity
2077        // mask is what says the position is null.
2078        let vector = Vector::sequence(0, 1, 4).with_validity(Validity::from_iter(4, |i| i != 1));
2079        let flat = vector.flatten().unwrap();
2080        assert_eq!(flat.value_at(0), Value::BigInt(0));
2081        assert_eq!(flat.value_at(1), Value::Null);
2082        assert_eq!(flat.value_at(2), Value::BigInt(2));
2083        assert_eq!(flat.value_at(3), Value::BigInt(3));
2084    }
2085
2086    /// A dictionary holds its nulls in the vector it points at, so its own validity is all valid
2087    /// and reading that instead of the values turns a null into whatever zero means for the type.
2088    /// A filter over a nullable column produces exactly this vector, so the bug reaches a result
2089    /// set as `LEFT JOIN` padding that comes back as zeros.
2090    #[test]
2091    fn a_null_behind_a_dictionary_survives_flattening() {
2092        let values =
2093            Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
2094        let dictionary = Vector::dictionary(vec![1, 0, 1], values).unwrap();
2095        let flat = dictionary.flatten().unwrap();
2096        assert_eq!(flat.value_at(0), Value::Null);
2097        assert_eq!(flat.value_at(1), Value::Integer(3));
2098        assert_eq!(flat.value_at(2), Value::Null);
2099    }
2100
2101    /// The property that makes `gather` usable at all: it has to be the same function as reading the
2102    /// wanted positions one at a time, over every form, or compaction changes answers.
2103    #[test]
2104    fn gathering_reads_what_reading_one_position_at_a_time_reads() {
2105        let mut column = StringColumn::new();
2106        column.push("alpha");
2107        column.push("beta");
2108        column.push("gamma");
2109        let cases = [
2110            integers(&[10, 20, 30, 40]),
2111            integers(&[10, 20, 30, 40]).with_validity(Validity::from_iter(4, |i| i != 2)),
2112            Vector::constant(LogicalType::Integer, Value::Integer(9), 4),
2113            Vector::sequence(100, -7, 4),
2114            Vector::sequence(100, -7, 4).with_validity(Validity::from_iter(4, |i| i % 2 == 0)),
2115            Vector::dictionary(
2116                vec![2, 0, 1, 2],
2117                Vector::flat(LogicalType::Varchar, Data::Varlen(column)).unwrap(),
2118            )
2119            .unwrap(),
2120            Vector::dictionary(
2121                vec![1, 0, 1, 0],
2122                Vector::from_values(LogicalType::Integer, &[Value::Integer(5), Value::Null])
2123                    .unwrap(),
2124            )
2125            .unwrap(),
2126        ];
2127        let wanted = [3_u32, 0, 2, 2, 1];
2128        for vector in cases {
2129            let gathered = vector.gather(&wanted).unwrap();
2130            assert_eq!(gathered.len(), wanted.len());
2131            assert_eq!(gathered.logical_type(), vector.logical_type());
2132            for (slot, &index) in wanted.iter().enumerate() {
2133                assert_eq!(
2134                    gathered.value_at(slot),
2135                    vector.value_at(index as usize),
2136                    "slot {slot} of {:?}",
2137                    vector.form()
2138                );
2139            }
2140        }
2141    }
2142
2143    /// A gather past the end is not an error, because the selection that produced the indices is
2144    /// checked by its caller and the one thing that must not happen here is a read of the wrong
2145    /// value. An index nothing answers is null, which is what an outer join pad needs anyway.
2146    #[test]
2147    fn gathering_a_position_that_is_not_there_is_a_null_and_not_a_wrong_value() {
2148        let vector = integers(&[1, 2, 3]);
2149        let gathered = vector.gather(&[2, 9]).unwrap();
2150        assert_eq!(gathered.value_at(0), Value::Integer(3));
2151        assert_eq!(gathered.value_at(1), Value::Null);
2152    }
2153
2154    /// The vector with nothing in it at all, which is what an untyped `NULL` is stored as. Every
2155    /// position asked for is past its end, so the answer is nulls and the length has to be the
2156    /// length that was asked for rather than the length that was there.
2157    #[test]
2158    fn gathering_from_a_vector_of_no_values_is_that_many_nulls() {
2159        let vector = Vector::flat(LogicalType::Null, Data::Empty).unwrap();
2160        let gathered = vector.gather(&[0, 1, 2]).unwrap();
2161        assert_eq!(gathered.len(), 3);
2162        assert_eq!(gathered.value_at(0), Value::Null);
2163        assert_eq!(gathered.value_at(2), Value::Null);
2164    }
2165
2166    /// Every position holds the same value, so a gather with no hole in it has nothing to copy and
2167    /// the result is the constant again rather than a run of a thousand copies of it.
2168    #[test]
2169    fn gathering_a_constant_stays_a_constant() {
2170        let vector = Vector::constant(LogicalType::Integer, Value::Integer(4), 100);
2171        let gathered = vector.gather(&[7, 7, 99]).unwrap();
2172        assert_eq!(gathered.form(), Form::Constant);
2173        assert_eq!(gathered.len(), 3);
2174        assert_eq!(gathered.value_at(2), Value::Integer(4));
2175    }
2176
2177    /// A dictionary over a dictionary is what a second filter over an already filtered chunk builds,
2178    /// and the gather has to walk to the bottom of that chain rather than one step down it. The
2179    /// constructor composes the ordinary chain away, so the one built here is the kind it cannot,
2180    /// which is a level holding nulls of its own.
2181    #[test]
2182    fn gathering_walks_a_dictionary_over_a_dictionary_to_the_values() {
2183        let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9]))
2184            .unwrap()
2185            .with_validity(Validity::from_iter(3, |index| index != 2));
2186        let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
2187        let gathered = outer.gather(&[0, 1]).unwrap();
2188        assert_eq!(gathered.form(), Form::Flat);
2189        assert_eq!(gathered.value_at(0), Value::Integer(8));
2190        assert_eq!(gathered.value_at(1), Value::Null);
2191    }
2192
2193    /// Two filters over one chunk build a dictionary over a dictionary, four conjuncts pushed down
2194    /// separately build four levels of it, and every level is a dependent load on every later read
2195    /// of every row plus a code array that cannot be freed. Composing at construction is one pass
2196    /// over the codes the range check was walking anyway.
2197    #[test]
2198    fn a_dictionary_over_a_dictionary_is_composed_into_one_level() {
2199        let inner = Vector::dictionary(vec![2, 1, 0], integers(&[7, 8, 9])).unwrap();
2200        let outer = Vector::dictionary(vec![1, 2], inner).unwrap();
2201        let (codes, values) = outer.dictionary_parts().unwrap();
2202        assert_eq!(codes, [1, 0]);
2203        assert_eq!(values.form(), Form::Flat);
2204        assert_eq!(outer.value_at(0), Value::Integer(8));
2205        assert_eq!(outer.value_at(1), Value::Integer(7));
2206    }
2207
2208    /// The invariant stated as the thing it is there for, which is that the depth does not grow with
2209    /// the number of filters. Four levels stacked one at a time are one level at the end of it.
2210    #[test]
2211    fn stacking_dictionaries_does_not_make_them_deeper() {
2212        let mut vector = integers(&[10, 20, 30, 40]);
2213        for _ in 0..4 {
2214            vector = Vector::dictionary(vec![3, 2, 1, 0], vector).unwrap();
2215        }
2216        let (codes, values) = vector.dictionary_parts().unwrap();
2217        assert_eq!(values.form(), Form::Flat);
2218        assert_eq!(codes, [0, 1, 2, 3]);
2219        assert_eq!(
2220            vector.iter().collect::<Vec<_>>(),
2221            integers(&[10, 20, 30, 40]).iter().collect::<Vec<_>>()
2222        );
2223    }
2224
2225    /// Composing has to carry the nulls down with it. The values hold them, the codes point at them,
2226    /// and a composed code that lands on a null position is still a null.
2227    #[test]
2228    fn composing_a_dictionary_keeps_the_nulls_its_values_hold() {
2229        let values =
2230            Vector::from_values(LogicalType::Integer, &[Value::Integer(3), Value::Null]).unwrap();
2231        let inner = Vector::dictionary(vec![1, 0, 1], values).unwrap();
2232        let outer = Vector::dictionary(vec![0, 1], inner).unwrap();
2233        assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Flat);
2234        assert_eq!(outer.value_at(0), Value::Null);
2235        assert_eq!(outer.value_at(1), Value::Integer(3));
2236    }
2237
2238    /// The one level composition cannot go past. A dictionary that was given a validity of its own is
2239    /// saying its nulls are at that level rather than in the values, and pointing the outer codes
2240    /// straight at the values would read through the holes instead of stopping at them.
2241    #[test]
2242    fn a_dictionary_holding_its_own_nulls_is_not_composed_past() {
2243        let inner = Vector::dictionary(vec![0, 1, 2], integers(&[1, 2, 3]))
2244            .unwrap()
2245            .with_validity(Validity::from_iter(3, |index| index != 1));
2246        let outer = Vector::dictionary(vec![1, 2, 0], inner).unwrap();
2247        assert_eq!(outer.dictionary_parts().unwrap().1.form(), Form::Dictionary);
2248        assert_eq!(outer.value_at(0), Value::Null);
2249        assert_eq!(outer.value_at(1), Value::Integer(3));
2250        assert_eq!(outer.value_at(2), Value::Integer(1));
2251    }
2252
2253    #[test]
2254    fn flattening_a_flat_vector_is_the_same_vector() {
2255        let vector = integers(&[1, 2, 3]);
2256        assert_eq!(vector.flatten().unwrap(), vector);
2257    }
2258
2259    #[test]
2260    fn a_decimal_reads_its_width_and_scale_from_the_type_and_not_the_data() {
2261        let ty = LogicalType::decimal(9, 2).unwrap();
2262        let vector = Vector::flat(ty, Data::Int32(vec![1234].into())).unwrap();
2263        assert_eq!(vector.value_at(0), Value::Decimal { unscaled: 1234, width: 9, scale: 2 });
2264        assert_eq!(vector.value_at(0).to_string(), "12.34");
2265    }
2266
2267    #[test]
2268    fn a_decimal_writes_into_whichever_of_the_four_runs_its_precision_chose() {
2269        // The read path worked at every width and the write path only accepted the 128 bit run, so
2270        // `SELECT 2.5` produced a value nothing could store. All four widths round trip now.
2271        for (width, scale, unscaled) in
2272            [(4u8, 1u8, 25i128), (9, 2, 1234), (18, 3, 123_456), (38, 4, 1_234_567)]
2273        {
2274            let ty = LogicalType::decimal(width, scale).unwrap();
2275            let value = Value::Decimal { unscaled, width, scale };
2276            let vector = Vector::from_values(ty, &[value.clone(), Value::Null]).unwrap();
2277            assert_eq!(vector.value_at(0), value, "a decimal of width {width}");
2278            assert_eq!(vector.value_at(1), Value::Null, "a null decimal of width {width}");
2279        }
2280    }
2281
2282    /// The bytes a blob holds are not required to be text, and a vector of them used to refuse the
2283    /// ones that were not. A byte array column in a Parquet file that nothing annotated is a blob,
2284    /// which is what ClickHouse writes and what ten of the ClickBench queries compare against, so
2285    /// this is the path those take rather than a corner of the type system.
2286    #[test]
2287    fn a_blob_holds_bytes_that_are_not_text() {
2288        let bytes = |raw: &[u8]| Value::Blob(raw.to_vec());
2289        let values = [
2290            bytes(b"a\xffb"),
2291            bytes(b"\x00\x01\x02"),
2292            Value::Null,
2293            bytes(b"\xed\xa0\x80 and long enough to leave the view"),
2294            bytes(b""),
2295        ];
2296        let vector = Vector::from_values(LogicalType::Blob, &values).unwrap();
2297        for (index, value) in values.iter().enumerate() {
2298            assert_eq!(&vector.value_at(index), value, "row {index}");
2299        }
2300    }
2301
2302    #[test]
2303    fn a_decimal_too_wide_for_the_run_its_type_chose_is_an_error_and_not_a_wrong_number() {
2304        // Only reachable by hand, since a value's width is what picked the run. Truncating here
2305        // would store a different number and say nothing about it.
2306        let ty = LogicalType::decimal(4, 1).unwrap();
2307        let value = Value::Decimal { unscaled: 1_000_000, width: 4, scale: 1 };
2308        let error = Vector::from_values(ty, &[value]).unwrap_err();
2309        assert!(error.to_string().contains("does not fit"), "{error}");
2310    }
2311
2312    #[test]
2313    fn a_flat_vector_costs_its_values_and_a_constant_costs_one() {
2314        let flat = integers(&[1; 1000]);
2315        assert!(
2316            flat.footprint() >= 4000,
2317            "a thousand i32 are four thousand bytes: {}",
2318            flat.footprint()
2319        );
2320        // The forms that compute their values rather than storing them cost nothing per value,
2321        // which is the point of having them and is what the memory limit should see.
2322        let constant = Vector::constant(LogicalType::Integer, Value::Integer(1), 1_000_000);
2323        assert!(constant.footprint() < 200, "a constant is one value: {}", constant.footprint());
2324        let sequence = Vector::sequence(0, 1, 1_000_000);
2325        assert!(sequence.footprint() < 200, "a sequence is two numbers: {}", sequence.footprint());
2326    }
2327
2328    #[test]
2329    fn a_string_vector_costs_the_bytes_of_its_long_strings() {
2330        let short =
2331            Vector::from_values(LogicalType::Varchar, &[Value::Varchar("red".into())]).unwrap();
2332        let long = "a string well past the sixteen bytes a view holds inline".to_string();
2333        let spilled =
2334            Vector::from_values(LogicalType::Varchar, &[Value::Varchar(long.clone())]).unwrap();
2335        assert!(
2336            spilled.footprint() >= short.footprint() + long.len(),
2337            "the arena is counted: {} against {}",
2338            spilled.footprint(),
2339            short.footprint()
2340        );
2341    }
2342
2343    /// The cases worth checking are the widths where a code straddles a word boundary, which is
2344    /// every width that does not divide sixty four, and the two ends of the range.
2345    #[test]
2346    fn a_narrow_column_packs_and_reads_back_the_same_at_every_width() {
2347        for width in 1..=20u32 {
2348            let span = (1i64 << width) - 1;
2349            let values: Vec<i64> =
2350                (0..1000).map(|row| 1_000_000 + (row * 7919) % (span + 1)).collect();
2351            let flat =
2352                Vector::flat(LogicalType::BigInt, Data::Int64(values.clone().into())).unwrap();
2353            let packed = flat.bit_packed().unwrap();
2354            assert_eq!(packed.len(), flat.len());
2355            assert_eq!(
2356                packed.iter().collect::<Vec<_>>(),
2357                flat.iter().collect::<Vec<_>>(),
2358                "width {width} read back differently"
2359            );
2360        }
2361    }
2362
2363    #[test]
2364    fn the_width_is_the_bits_the_range_needs_and_not_the_bits_the_type_has() {
2365        let values: Vec<i32> = (0..1024).map(|row| 40 + (row * 2560) / 1023).collect();
2366        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
2367        let packed = flat.bit_packed().unwrap();
2368        assert_eq!(packed.form(), Form::BitPacked);
2369        let parts = packed.packed_parts().expect("packed");
2370        assert_eq!(parts.width(), 12, "0 to 2560 is twelve bits");
2371        assert_eq!(parts.base(), 40);
2372        assert!(
2373            packed.footprint() * 2 < flat.footprint(),
2374            "twelve bits against thirty two: {} against {}",
2375            packed.footprint(),
2376            flat.footprint()
2377        );
2378    }
2379
2380    /// The check is worth having in both directions, the way the run length one is. A form that is
2381    /// only ever bigger than what it replaced costs a pass over the column to decide not to use.
2382    #[test]
2383    fn a_column_that_uses_its_whole_type_is_left_flat() {
2384        let values: Vec<i32> = (0..1024).map(|row| row * 2_000_000 - 1_000_000_000).collect();
2385        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
2386        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
2387    }
2388
2389    /// A column of one value would pack to no bits at all, and one run is smaller than any packing
2390    /// of it, so the two forms do not fight over that column.
2391    #[test]
2392    fn a_column_of_one_value_is_left_to_the_run_length_form() {
2393        let flat = integers(&[9; 1024]);
2394        assert_eq!(flat.bit_packed().unwrap().form(), Form::Flat);
2395        assert_eq!(flat.run_encoded().unwrap().form(), Form::Rle);
2396    }
2397
2398    #[test]
2399    fn a_string_column_has_no_range_to_pack() {
2400        let text = Vector::from_values(
2401            LogicalType::Varchar,
2402            &[Value::Varchar("red".into()), Value::Varchar("blue".into())],
2403        )
2404        .unwrap();
2405        assert_eq!(text.bit_packed().unwrap().form(), Form::Flat);
2406    }
2407
2408    /// The cut is the reason the form carries a row to start reading at. It stays packed, it shares
2409    /// the same words, and it reads the rows the range asked for.
2410    #[test]
2411    fn a_cut_of_a_packed_column_stays_packed_and_shares_its_bits() {
2412        let values: Vec<i32> = (0..1024).map(|row| 100 + row % 300).collect();
2413        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
2414        let packed = flat.bit_packed().unwrap();
2415        let cut = packed.slice(500, 24).unwrap();
2416        assert_eq!(cut.form(), Form::BitPacked);
2417        assert_eq!(cut.len(), 24);
2418        assert_eq!(
2419            cut.iter().collect::<Vec<_>>(),
2420            flat.slice(500, 24).unwrap().iter().collect::<Vec<_>>()
2421        );
2422        assert!(
2423            cut.footprint() >= packed.footprint(),
2424            "a cut shares the words rather than copying a piece of them"
2425        );
2426    }
2427
2428    #[test]
2429    fn a_gather_of_a_packed_column_comes_out_flat_and_keeps_the_nulls() {
2430        let values: Vec<i32> = (0..64).map(|row| 10 + row).collect();
2431        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
2432        let packed =
2433            flat.bit_packed().unwrap().with_validity(Validity::from_iter(64, |row| row % 3 != 0));
2434        let taken = packed.gather(&[0, 1, 2, 3, 62]).unwrap();
2435        assert_eq!(taken.form(), Form::Flat);
2436        assert_eq!(
2437            taken.iter().collect::<Vec<_>>(),
2438            vec![
2439                Value::Null,
2440                Value::Integer(11),
2441                Value::Integer(12),
2442                Value::Null,
2443                Value::Integer(72)
2444            ]
2445        );
2446    }
2447
2448    /// The pair a comparison kernel asks for before it reads a bit. A literal inside the range has a
2449    /// code and a literal outside it does not, which answers the whole vector at once.
2450    #[test]
2451    fn a_literal_outside_the_packed_range_has_no_code() {
2452        let values: Vec<i32> = (0..256).map(|row| 1000 + row).collect();
2453        let flat = Vector::flat(LogicalType::Integer, Data::Int32(values.into())).unwrap();
2454        let packed = flat.bit_packed().unwrap();
2455        let parts = packed.packed_parts().expect("packed");
2456        assert_eq!(parts.code_of(1000), Some(0));
2457        assert_eq!(parts.code_of(1100), Some(100));
2458        assert_eq!(parts.code_of(999), None);
2459        assert!(parts.ceiling() >= 1255);
2460        assert_eq!(parts.code_of(parts.ceiling() + 1), None);
2461    }
2462
2463    /// The bits arriving from a file rather than from a flat vector, which is what the form is for.
2464    #[test]
2465    fn packed_bits_can_be_handed_in_without_a_flat_vector_to_start_from() {
2466        let packed = Vector::packed(LogicalType::SmallInt, vec![0x0000_0000_0000_4321], 4, 7, 4)
2467            .expect("four codes of four bits");
2468        assert_eq!(
2469            packed.iter().collect::<Vec<_>>(),
2470            vec![Value::SmallInt(8), Value::SmallInt(9), Value::SmallInt(10), Value::SmallInt(11)]
2471        );
2472    }
2473
2474    #[test]
2475    fn packed_bits_that_could_not_hold_what_they_claim_are_refused() {
2476        assert!(Vector::packed(LogicalType::Varchar, vec![0], 4, 0, 4).is_err(), "not an integer");
2477        assert!(Vector::packed(LogicalType::Integer, vec![0], 0, 0, 4).is_err(), "no width");
2478        assert!(Vector::packed(LogicalType::Integer, vec![0], 64, 0, 4).is_err(), "too wide");
2479        assert!(Vector::packed(LogicalType::Integer, vec![0], 8, 0, 9).is_err(), "too few words");
2480        assert!(Vector::packed(LogicalType::TinyInt, vec![0], 8, 100, 8).is_err(), "would not fit");
2481    }
2482}