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