Skip to main content

reifydb_core/value/column/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4//! Columnar data model used by the engine and every consumer of query results.
5//!
6//! A column is a typed, possibly-nullable, possibly-dictionary-encoded buffer of values plus statistics, encoding
7//! metadata, and a none-bitmap.
8//!
9//! Invariant: a column's `RowMask` and `NoneBitmap` are always exactly aligned to its logical row count. Operations
10//! that grow or shrink the buffer must update the mask and bitmap atomically with respect to consumers; an off-by-one
11//! between length and mask silently produces wrong results in filter and aggregation paths.
12
13use std::fmt;
14
15use reifydb_value::{
16	fragment::Fragment,
17	util::bitvec::BitVec,
18	value::{
19		dictionary::DictionaryEntryId,
20		uuid::{Uuid4, Uuid7},
21		value_type::ValueType,
22	},
23};
24
25use crate::value::column::{buffer::ColumnBuffer, data::Column};
26
27pub mod buffer;
28pub mod columns;
29pub mod data;
30pub mod encoding;
31pub mod frame;
32pub mod headers;
33pub mod mask;
34pub mod nones;
35pub mod push;
36pub mod row;
37pub mod row_ref;
38pub mod stats;
39pub mod transform;
40pub mod view;
41
42pub struct ColumnWithName {
43	pub name: Fragment,
44	pub data: ColumnBuffer,
45}
46
47impl Clone for ColumnWithName {
48	fn clone(&self) -> Self {
49		Self {
50			name: self.name.clone(),
51			data: self.data.clone(),
52		}
53	}
54}
55
56impl PartialEq for ColumnWithName {
57	fn eq(&self, other: &Self) -> bool {
58		self.name == other.name && self.data == other.data
59	}
60}
61
62impl fmt::Debug for ColumnWithName {
63	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64		f.debug_struct("ColumnWithName").field("name", &self.name).field("data", &self.data).finish()
65	}
66}
67
68impl ColumnWithName {
69	pub fn new(name: impl Into<Fragment>, data: ColumnBuffer) -> Self {
70		Self {
71			name: name.into(),
72			data,
73		}
74	}
75
76	pub fn from_column(name: impl Into<Fragment>, column: Column) -> Self {
77		let buffer = column
78			.to_canonical()
79			.map(|c| c.to_buffer())
80			.unwrap_or_else(|_| panic!("ColumnWithName::from_column: to_canonical failed"));
81		Self {
82			name: name.into(),
83			data: buffer,
84		}
85	}
86
87	pub fn get_type(&self) -> ValueType {
88		self.data.get_type()
89	}
90
91	pub fn with_new_data(&self, data: ColumnBuffer) -> ColumnWithName {
92		ColumnWithName {
93			name: self.name.clone(),
94			data,
95		}
96	}
97
98	pub fn name(&self) -> &Fragment {
99		&self.name
100	}
101
102	pub fn name_owned(&self) -> Fragment {
103		self.name.clone()
104	}
105
106	pub fn data(&self) -> &ColumnBuffer {
107		&self.data
108	}
109
110	pub fn data_mut(&mut self) -> &mut ColumnBuffer {
111		&mut self.data
112	}
113
114	pub fn column(&self) -> Column {
115		Column::from_column_buffer(self.data.clone())
116	}
117
118	pub fn to_static(&self) -> ColumnWithName {
119		self.clone()
120	}
121}
122
123impl ColumnWithName {
124	pub fn int1(name: impl Into<Fragment>, data: impl IntoIterator<Item = i8>) -> Self {
125		ColumnWithName {
126			name: name.into(),
127			data: ColumnBuffer::int1(data),
128		}
129	}
130
131	pub fn int1_with_bitvec(
132		name: impl Into<Fragment>,
133		data: impl IntoIterator<Item = i8>,
134		bitvec: impl Into<BitVec>,
135	) -> Self {
136		ColumnWithName {
137			name: name.into(),
138			data: ColumnBuffer::int1_with_bitvec(data, bitvec),
139		}
140	}
141
142	pub fn int2(name: impl Into<Fragment>, data: impl IntoIterator<Item = i16>) -> Self {
143		ColumnWithName {
144			name: name.into(),
145			data: ColumnBuffer::int2(data),
146		}
147	}
148
149	pub fn int2_with_bitvec(
150		name: impl Into<Fragment>,
151		data: impl IntoIterator<Item = i16>,
152		bitvec: impl Into<BitVec>,
153	) -> Self {
154		ColumnWithName {
155			name: name.into(),
156			data: ColumnBuffer::int2_with_bitvec(data, bitvec),
157		}
158	}
159
160	pub fn int4(name: impl Into<Fragment>, data: impl IntoIterator<Item = i32>) -> Self {
161		ColumnWithName {
162			name: name.into(),
163			data: ColumnBuffer::int4(data),
164		}
165	}
166
167	pub fn int4_with_bitvec(
168		name: impl Into<Fragment>,
169		data: impl IntoIterator<Item = i32>,
170		bitvec: impl Into<BitVec>,
171	) -> Self {
172		ColumnWithName {
173			name: name.into(),
174			data: ColumnBuffer::int4_with_bitvec(data, bitvec),
175		}
176	}
177
178	pub fn int8(name: impl Into<Fragment>, data: impl IntoIterator<Item = i64>) -> Self {
179		ColumnWithName {
180			name: name.into(),
181			data: ColumnBuffer::int8(data),
182		}
183	}
184
185	pub fn int8_with_bitvec(
186		name: impl Into<Fragment>,
187		data: impl IntoIterator<Item = i64>,
188		bitvec: impl Into<BitVec>,
189	) -> Self {
190		ColumnWithName {
191			name: name.into(),
192			data: ColumnBuffer::int8_with_bitvec(data, bitvec),
193		}
194	}
195
196	pub fn int16(name: impl Into<Fragment>, data: impl IntoIterator<Item = i128>) -> Self {
197		ColumnWithName {
198			name: name.into(),
199			data: ColumnBuffer::int16(data),
200		}
201	}
202
203	pub fn int16_with_bitvec(
204		name: impl Into<Fragment>,
205		data: impl IntoIterator<Item = i128>,
206		bitvec: impl Into<BitVec>,
207	) -> Self {
208		ColumnWithName {
209			name: name.into(),
210			data: ColumnBuffer::int16_with_bitvec(data, bitvec),
211		}
212	}
213
214	pub fn uint1(name: impl Into<Fragment>, data: impl IntoIterator<Item = u8>) -> Self {
215		ColumnWithName {
216			name: name.into(),
217			data: ColumnBuffer::uint1(data),
218		}
219	}
220
221	pub fn uint1_with_bitvec(
222		name: impl Into<Fragment>,
223		data: impl IntoIterator<Item = u8>,
224		bitvec: impl Into<BitVec>,
225	) -> Self {
226		ColumnWithName {
227			name: name.into(),
228			data: ColumnBuffer::uint1_with_bitvec(data, bitvec),
229		}
230	}
231
232	pub fn uint2(name: impl Into<Fragment>, data: impl IntoIterator<Item = u16>) -> Self {
233		ColumnWithName {
234			name: name.into(),
235			data: ColumnBuffer::uint2(data),
236		}
237	}
238
239	pub fn uint2_with_bitvec(
240		name: impl Into<Fragment>,
241		data: impl IntoIterator<Item = u16>,
242		bitvec: impl Into<BitVec>,
243	) -> Self {
244		ColumnWithName {
245			name: name.into(),
246			data: ColumnBuffer::uint2_with_bitvec(data, bitvec),
247		}
248	}
249
250	pub fn uint4(name: impl Into<Fragment>, data: impl IntoIterator<Item = u32>) -> Self {
251		ColumnWithName {
252			name: name.into(),
253			data: ColumnBuffer::uint4(data),
254		}
255	}
256
257	pub fn uint4_with_bitvec(
258		name: impl Into<Fragment>,
259		data: impl IntoIterator<Item = u32>,
260		bitvec: impl Into<BitVec>,
261	) -> Self {
262		ColumnWithName {
263			name: name.into(),
264			data: ColumnBuffer::uint4_with_bitvec(data, bitvec),
265		}
266	}
267
268	pub fn uint8(name: impl Into<Fragment>, data: impl IntoIterator<Item = u64>) -> Self {
269		ColumnWithName {
270			name: name.into(),
271			data: ColumnBuffer::uint8(data),
272		}
273	}
274
275	pub fn uint8_with_bitvec(
276		name: impl Into<Fragment>,
277		data: impl IntoIterator<Item = u64>,
278		bitvec: impl Into<BitVec>,
279	) -> Self {
280		ColumnWithName {
281			name: name.into(),
282			data: ColumnBuffer::uint8_with_bitvec(data, bitvec),
283		}
284	}
285
286	pub fn uint16(name: impl Into<Fragment>, data: impl IntoIterator<Item = u128>) -> Self {
287		ColumnWithName {
288			name: name.into(),
289			data: ColumnBuffer::uint16(data),
290		}
291	}
292
293	pub fn uint16_with_bitvec(
294		name: impl Into<Fragment>,
295		data: impl IntoIterator<Item = u128>,
296		bitvec: impl Into<BitVec>,
297	) -> Self {
298		ColumnWithName {
299			name: name.into(),
300			data: ColumnBuffer::uint16_with_bitvec(data, bitvec),
301		}
302	}
303
304	pub fn float4(name: impl Into<Fragment>, data: impl IntoIterator<Item = f32>) -> Self {
305		ColumnWithName {
306			name: name.into(),
307			data: ColumnBuffer::float4(data),
308		}
309	}
310
311	pub fn float4_with_bitvec(
312		name: impl Into<Fragment>,
313		data: impl IntoIterator<Item = f32>,
314		bitvec: impl Into<BitVec>,
315	) -> Self {
316		ColumnWithName {
317			name: name.into(),
318			data: ColumnBuffer::float4_with_bitvec(data, bitvec),
319		}
320	}
321
322	pub fn float8(name: impl Into<Fragment>, data: impl IntoIterator<Item = f64>) -> Self {
323		ColumnWithName {
324			name: name.into(),
325			data: ColumnBuffer::float8(data),
326		}
327	}
328
329	pub fn float8_with_bitvec(
330		name: impl Into<Fragment>,
331		data: impl IntoIterator<Item = f64>,
332		bitvec: impl Into<BitVec>,
333	) -> Self {
334		ColumnWithName {
335			name: name.into(),
336			data: ColumnBuffer::float8_with_bitvec(data, bitvec),
337		}
338	}
339
340	pub fn bool(name: impl Into<Fragment>, data: impl IntoIterator<Item = bool>) -> Self {
341		ColumnWithName {
342			name: name.into(),
343			data: ColumnBuffer::bool(data),
344		}
345	}
346
347	pub fn bool_with_bitvec(
348		name: impl Into<Fragment>,
349		data: impl IntoIterator<Item = bool>,
350		bitvec: impl Into<BitVec>,
351	) -> Self {
352		ColumnWithName {
353			name: name.into(),
354			data: ColumnBuffer::bool_with_bitvec(data, bitvec),
355		}
356	}
357
358	pub fn utf8(name: impl Into<Fragment>, data: impl IntoIterator<Item = String>) -> Self {
359		ColumnWithName {
360			name: name.into(),
361			data: ColumnBuffer::utf8(data),
362		}
363	}
364
365	pub fn utf8_with_bitvec(
366		name: impl Into<Fragment>,
367		data: impl IntoIterator<Item = String>,
368		bitvec: impl Into<BitVec>,
369	) -> Self {
370		ColumnWithName {
371			name: name.into(),
372			data: ColumnBuffer::utf8_with_bitvec(data, bitvec),
373		}
374	}
375
376	pub fn uuid4(name: impl Into<Fragment>, data: impl IntoIterator<Item = Uuid4>) -> Self {
377		ColumnWithName {
378			name: name.into(),
379			data: ColumnBuffer::uuid4(data),
380		}
381	}
382
383	pub fn uuid4_with_bitvec(
384		name: impl Into<Fragment>,
385		data: impl IntoIterator<Item = Uuid4>,
386		bitvec: impl Into<BitVec>,
387	) -> Self {
388		ColumnWithName {
389			name: name.into(),
390			data: ColumnBuffer::uuid4_with_bitvec(data, bitvec),
391		}
392	}
393
394	pub fn uuid7(name: impl Into<Fragment>, data: impl IntoIterator<Item = Uuid7>) -> Self {
395		ColumnWithName {
396			name: name.into(),
397			data: ColumnBuffer::uuid7(data),
398		}
399	}
400
401	pub fn uuid7_with_bitvec(
402		name: impl Into<Fragment>,
403		data: impl IntoIterator<Item = Uuid7>,
404		bitvec: impl Into<BitVec>,
405	) -> Self {
406		ColumnWithName {
407			name: name.into(),
408			data: ColumnBuffer::uuid7_with_bitvec(data, bitvec),
409		}
410	}
411
412	pub fn dictionary_id(name: impl Into<Fragment>, data: impl IntoIterator<Item = DictionaryEntryId>) -> Self {
413		ColumnWithName {
414			name: name.into(),
415			data: ColumnBuffer::dictionary_id(data),
416		}
417	}
418
419	pub fn dictionary_id_with_bitvec(
420		name: impl Into<Fragment>,
421		data: impl IntoIterator<Item = DictionaryEntryId>,
422		bitvec: impl Into<BitVec>,
423	) -> Self {
424		ColumnWithName {
425			name: name.into(),
426			data: ColumnBuffer::dictionary_id_with_bitvec(data, bitvec),
427		}
428	}
429
430	pub fn undefined_typed(name: impl Into<Fragment>, ty: ValueType, row_count: usize) -> Self {
431		ColumnWithName {
432			name: name.into(),
433			data: ColumnBuffer::none_typed(ty, row_count),
434		}
435	}
436}