Skip to main content

linkrs_query/executor/streaming/chunk/
columnar_batch.rs

1//! Columnar batch accumulation for blocking operators
2//!
3//! Blocking operators (Sort/TopN) buffer all input before producing output.
4//! Instead of buffering `Vec<Vec<Value>>` rows, rows are accumulated
5//! column-major: homogeneous columns stay raw
6//! (`Vec<i64>`/`Vec<f64>`/`Vec<i32>`/`Vec<bool>`/`Vec<i64>` days/`Vec<Arc<str>>`)
7//! so that ordering operates on scalars without constructing one `Value`
8//! per row. Columns that mix kinds (or hit NULLs) degrade to
9//! [`BatchColumn::Fallback`], keeping the exact `Value` semantics of the
10//! row-based path.
11//!
12//! ## Relationship to `TypedColumn`
13//!
14//! `TypedColumn` models a fixed-kind column inside a `DataChunk` for batch
15//! expression evaluation, while `BatchColumn` models a column whose kind is
16//! decided by its first append (`BatchColumn::Empty` until then) and which
17//! supports accumulation (append/gather/permute). The two intentionally
18//! share a variant set so `append_typed` can move a chunk's typed columns
19//! into a batch without re-inspecting values; keep them in sync when adding
20//! a kind.
21//!
22//! ## Relationship to `MaterializedBatch`
23//!
24//! Other blocking operators (aggregate, distinct, materialize, window) keep
25//! their state in `linkrs_core::columnar::MaterializedBatch`, which is
26//! column-oriented but stores one `Vec<Value>` per column and therefore does
27//! not get the typed-scalar treatment. Treat `MaterializedBatch` as the
28//! spill and persistence form; the in-memory streaming fast path uses
29//! `TypedColumn` and `ColumnarBatch`.
30
31use std::sync::Arc;
32
33use crate::executor::streaming::chunk::columnar_common::column_variants;
34use crate::executor::streaming::chunk::columnar_common::EdgeHeaderColumn;
35use linkrs_core::value::decimal128::Decimal128Value;
36use linkrs_core::Value;
37
38mod collector;
39mod operations;
40
41#[cfg(test)]
42mod tests;
43
44pub use collector::ColumnarBatch;
45
46// Column-major accumulation of one output column across chunks.
47//
48// The variant set is declared once by `column_variants!` in
49// `columnar_common` and shared with `TypedColumn`; `len`, `is_empty`, and
50// `estimated_size` are generated from that list.
51// Accumulable blocking-operator state; see `columnar_common` for the list.
52column_variants!(BatchColumn, Empty);