Skip to main content

reifydb_core/value/column/
mod.rs

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