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