reifydb_core/value/column/data/
mod.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4mod extend;
5mod factory;
6mod filter;
7mod from;
8mod get;
9mod reorder;
10mod slice;
11mod take;
12
13use reifydb_type::{
14	Date, DateTime, Decimal, Duration, Int, Time, Type, Uint, Uuid4, Uuid7, Value,
15	value::constraint::{bytes::MaxBytes, precision::Precision, scale::Scale},
16};
17use serde::{Deserialize, Serialize};
18
19use crate::{
20	BitVec,
21	value::container::{
22		AnyContainer, BlobContainer, BoolContainer, IdentityIdContainer, NumberContainer, TemporalContainer,
23		UndefinedContainer, Utf8Container, UuidContainer,
24	},
25};
26
27#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
28pub enum ColumnData {
29	Bool(BoolContainer),
30	Float4(NumberContainer<f32>),
31	Float8(NumberContainer<f64>),
32	Int1(NumberContainer<i8>),
33	Int2(NumberContainer<i16>),
34	Int4(NumberContainer<i32>),
35	Int8(NumberContainer<i64>),
36	Int16(NumberContainer<i128>),
37	Uint1(NumberContainer<u8>),
38	Uint2(NumberContainer<u16>),
39	Uint4(NumberContainer<u32>),
40	Uint8(NumberContainer<u64>),
41	Uint16(NumberContainer<u128>),
42	Utf8 {
43		container: Utf8Container,
44		max_bytes: MaxBytes,
45	},
46	Date(TemporalContainer<Date>),
47	DateTime(TemporalContainer<DateTime>),
48	Time(TemporalContainer<Time>),
49	Duration(TemporalContainer<Duration>),
50	IdentityId(IdentityIdContainer),
51	Uuid4(UuidContainer<Uuid4>),
52	Uuid7(UuidContainer<Uuid7>),
53	Blob {
54		container: BlobContainer,
55		max_bytes: MaxBytes,
56	},
57	Int {
58		container: NumberContainer<Int>,
59		max_bytes: MaxBytes,
60	},
61	Uint {
62		container: NumberContainer<Uint>,
63		max_bytes: MaxBytes,
64	},
65	Decimal {
66		container: NumberContainer<Decimal>,
67		precision: Precision,
68		scale: Scale,
69	},
70	// Container for Any type (heterogeneous values)
71	Any(AnyContainer),
72	// special case: all undefined
73	Undefined(UndefinedContainer),
74}
75
76impl ColumnData {
77	pub fn get_type(&self) -> Type {
78		match self {
79			ColumnData::Bool(_) => Type::Boolean,
80			ColumnData::Float4(_) => Type::Float4,
81			ColumnData::Float8(_) => Type::Float8,
82			ColumnData::Int1(_) => Type::Int1,
83			ColumnData::Int2(_) => Type::Int2,
84			ColumnData::Int4(_) => Type::Int4,
85			ColumnData::Int8(_) => Type::Int8,
86			ColumnData::Int16(_) => Type::Int16,
87			ColumnData::Uint1(_) => Type::Uint1,
88			ColumnData::Uint2(_) => Type::Uint2,
89			ColumnData::Uint4(_) => Type::Uint4,
90			ColumnData::Uint8(_) => Type::Uint8,
91			ColumnData::Uint16(_) => Type::Uint16,
92			ColumnData::Utf8 {
93				..
94			} => Type::Utf8,
95			ColumnData::Date(_) => Type::Date,
96			ColumnData::DateTime(_) => Type::DateTime,
97			ColumnData::Time(_) => Type::Time,
98			ColumnData::Duration(_) => Type::Duration,
99			ColumnData::IdentityId(_) => Type::IdentityId,
100			ColumnData::Uuid4(_) => Type::Uuid4,
101			ColumnData::Uuid7(_) => Type::Uuid7,
102			ColumnData::Blob {
103				..
104			} => Type::Blob,
105			ColumnData::Int {
106				..
107			} => Type::Int,
108			ColumnData::Uint {
109				..
110			} => Type::Uint,
111			ColumnData::Decimal {
112				..
113			} => Type::Decimal,
114			ColumnData::Any(_) => Type::Any,
115			ColumnData::Undefined(_) => Type::Undefined,
116		}
117	}
118
119	pub fn is_defined(&self, idx: usize) -> bool {
120		match self {
121			ColumnData::Bool(container) => container.is_defined(idx),
122			ColumnData::Float4(container) => container.is_defined(idx),
123			ColumnData::Float8(container) => container.is_defined(idx),
124			ColumnData::Int1(container) => container.is_defined(idx),
125			ColumnData::Int2(container) => container.is_defined(idx),
126			ColumnData::Int4(container) => container.is_defined(idx),
127			ColumnData::Int8(container) => container.is_defined(idx),
128			ColumnData::Int16(container) => container.is_defined(idx),
129			ColumnData::Uint1(container) => container.is_defined(idx),
130			ColumnData::Uint2(container) => container.is_defined(idx),
131			ColumnData::Uint4(container) => container.is_defined(idx),
132			ColumnData::Uint8(container) => container.is_defined(idx),
133			ColumnData::Uint16(container) => container.is_defined(idx),
134			ColumnData::Utf8 {
135				container,
136				..
137			} => container.is_defined(idx),
138			ColumnData::Date(container) => container.is_defined(idx),
139			ColumnData::DateTime(container) => container.is_defined(idx),
140			ColumnData::Time(container) => container.is_defined(idx),
141			ColumnData::Duration(container) => container.is_defined(idx),
142			ColumnData::IdentityId(container) => container.get(idx).is_some(),
143			ColumnData::Uuid4(container) => container.is_defined(idx),
144			ColumnData::Uuid7(container) => container.is_defined(idx),
145			ColumnData::Blob {
146				container,
147				..
148			} => container.is_defined(idx),
149			ColumnData::Int {
150				container,
151				..
152			} => container.is_defined(idx),
153			ColumnData::Uint {
154				container,
155				..
156			} => container.is_defined(idx),
157			ColumnData::Decimal {
158				container,
159				..
160			} => container.is_defined(idx),
161			ColumnData::Any(container) => container.is_defined(idx),
162			ColumnData::Undefined(_) => false,
163		}
164	}
165
166	pub fn is_bool(&self) -> bool {
167		self.get_type() == Type::Boolean
168	}
169
170	pub fn is_float(&self) -> bool {
171		self.get_type() == Type::Float4 || self.get_type() == Type::Float8
172	}
173
174	pub fn is_utf8(&self) -> bool {
175		self.get_type() == Type::Utf8
176	}
177
178	pub fn is_number(&self) -> bool {
179		matches!(
180			self.get_type(),
181			Type::Float4
182				| Type::Float8 | Type::Int1 | Type::Int2
183				| Type::Int4 | Type::Int8 | Type::Int16
184				| Type::Uint1 | Type::Uint2 | Type::Uint4
185				| Type::Uint8 | Type::Uint16 | Type::Int
186				| Type::Uint | Type::Decimal { .. }
187		)
188	}
189
190	pub fn is_text(&self) -> bool {
191		self.get_type() == Type::Utf8
192	}
193
194	pub fn is_temporal(&self) -> bool {
195		matches!(self.get_type(), Type::Date | Type::DateTime | Type::Time | Type::Duration)
196	}
197
198	pub fn is_uuid(&self) -> bool {
199		matches!(self.get_type(), Type::Uuid4 | Type::Uuid7)
200	}
201}
202
203impl ColumnData {
204	pub fn bitvec(&self) -> &BitVec {
205		match self {
206			ColumnData::Bool(container) => container.bitvec(),
207			ColumnData::Float4(container) => container.bitvec(),
208			ColumnData::Float8(container) => container.bitvec(),
209			ColumnData::Int1(container) => container.bitvec(),
210			ColumnData::Int2(container) => container.bitvec(),
211			ColumnData::Int4(container) => container.bitvec(),
212			ColumnData::Int8(container) => container.bitvec(),
213			ColumnData::Int16(container) => container.bitvec(),
214			ColumnData::Uint1(container) => container.bitvec(),
215			ColumnData::Uint2(container) => container.bitvec(),
216			ColumnData::Uint4(container) => container.bitvec(),
217			ColumnData::Uint8(container) => container.bitvec(),
218			ColumnData::Uint16(container) => container.bitvec(),
219			ColumnData::Utf8 {
220				container,
221				..
222			} => container.bitvec(),
223			ColumnData::Date(container) => container.bitvec(),
224			ColumnData::DateTime(container) => container.bitvec(),
225			ColumnData::Time(container) => container.bitvec(),
226			ColumnData::Duration(container) => container.bitvec(),
227			ColumnData::IdentityId(container) => container.bitvec(),
228			ColumnData::Uuid4(container) => container.bitvec(),
229			ColumnData::Uuid7(container) => container.bitvec(),
230			ColumnData::Blob {
231				container,
232				..
233			} => container.bitvec(),
234			ColumnData::Int {
235				container,
236				..
237			} => container.bitvec(),
238			ColumnData::Uint {
239				container,
240				..
241			} => container.bitvec(),
242			ColumnData::Decimal {
243				container,
244				..
245			} => container.bitvec(),
246			ColumnData::Any(container) => container.bitvec(),
247			ColumnData::Undefined(_) => unreachable!(),
248		}
249	}
250
251	pub fn undefined_count(&self) -> usize {
252		self.bitvec().count_zeros()
253	}
254}
255
256impl ColumnData {
257	pub fn with_capacity(target: Type, capacity: usize) -> Self {
258		match target {
259			Type::Boolean => Self::bool_with_capacity(capacity),
260			Type::Float4 => Self::float4_with_capacity(capacity),
261			Type::Float8 => Self::float8_with_capacity(capacity),
262			Type::Int1 => Self::int1_with_capacity(capacity),
263			Type::Int2 => Self::int2_with_capacity(capacity),
264			Type::Int4 => Self::int4_with_capacity(capacity),
265			Type::Int8 => Self::int8_with_capacity(capacity),
266			Type::Int16 => Self::int16_with_capacity(capacity),
267			Type::Uint1 => Self::uint1_with_capacity(capacity),
268			Type::Uint2 => Self::uint2_with_capacity(capacity),
269			Type::Uint4 => Self::uint4_with_capacity(capacity),
270			Type::Uint8 => Self::uint8_with_capacity(capacity),
271			Type::Uint16 => Self::uint16_with_capacity(capacity),
272			Type::Utf8 => Self::utf8_with_capacity(capacity),
273			Type::Date => Self::date_with_capacity(capacity),
274			Type::DateTime => Self::datetime_with_capacity(capacity),
275			Type::Time => Self::time_with_capacity(capacity),
276			Type::Duration => Self::duration_with_capacity(capacity),
277			Type::IdentityId => Self::identity_id_with_capacity(capacity),
278			Type::Uuid4 => Self::uuid4_with_capacity(capacity),
279			Type::Uuid7 => Self::uuid7_with_capacity(capacity),
280			Type::Blob => Self::blob_with_capacity(capacity),
281			Type::Int => Self::int_with_capacity(capacity),
282			Type::Uint => Self::uint_with_capacity(capacity),
283			Type::Decimal => Self::decimal_with_capacity(capacity),
284			Type::Undefined => ColumnData::undefined(0),
285			Type::Any => Self::any_with_capacity(capacity),
286		}
287	}
288
289	pub fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = Value> + 'a> {
290		Box::new((0..self.len()).map(move |i| self.get_value(i)))
291	}
292}
293
294impl ColumnData {
295	pub fn len(&self) -> usize {
296		match self {
297			ColumnData::Bool(container) => container.len(),
298			ColumnData::Float4(container) => container.len(),
299			ColumnData::Float8(container) => container.len(),
300			ColumnData::Int1(container) => container.len(),
301			ColumnData::Int2(container) => container.len(),
302			ColumnData::Int4(container) => container.len(),
303			ColumnData::Int8(container) => container.len(),
304			ColumnData::Int16(container) => container.len(),
305			ColumnData::Uint1(container) => container.len(),
306			ColumnData::Uint2(container) => container.len(),
307			ColumnData::Uint4(container) => container.len(),
308			ColumnData::Uint8(container) => container.len(),
309			ColumnData::Uint16(container) => container.len(),
310			ColumnData::Utf8 {
311				container,
312				..
313			} => container.len(),
314			ColumnData::Date(container) => container.len(),
315			ColumnData::DateTime(container) => container.len(),
316			ColumnData::Time(container) => container.len(),
317			ColumnData::Duration(container) => container.len(),
318			ColumnData::IdentityId(container) => container.len(),
319			ColumnData::Uuid4(container) => container.len(),
320			ColumnData::Uuid7(container) => container.len(),
321			ColumnData::Blob {
322				container,
323				..
324			} => container.len(),
325			ColumnData::Int {
326				container,
327				..
328			} => container.len(),
329			ColumnData::Uint {
330				container,
331				..
332			} => container.len(),
333			ColumnData::Decimal {
334				container,
335				..
336			} => container.len(),
337			ColumnData::Any(container) => container.len(),
338			ColumnData::Undefined(container) => container.len(),
339		}
340	}
341
342	pub fn capacity(&self) -> usize {
343		match self {
344			ColumnData::Bool(container) => container.capacity(),
345			ColumnData::Float4(container) => container.capacity(),
346			ColumnData::Float8(container) => container.capacity(),
347			ColumnData::Int1(container) => container.capacity(),
348			ColumnData::Int2(container) => container.capacity(),
349			ColumnData::Int4(container) => container.capacity(),
350			ColumnData::Int8(container) => container.capacity(),
351			ColumnData::Int16(container) => container.capacity(),
352			ColumnData::Uint1(container) => container.capacity(),
353			ColumnData::Uint2(container) => container.capacity(),
354			ColumnData::Uint4(container) => container.capacity(),
355			ColumnData::Uint8(container) => container.capacity(),
356			ColumnData::Uint16(container) => container.capacity(),
357			ColumnData::Utf8 {
358				container,
359				..
360			} => container.capacity(),
361			ColumnData::Date(container) => container.capacity(),
362			ColumnData::DateTime(container) => container.capacity(),
363			ColumnData::Time(container) => container.capacity(),
364			ColumnData::Duration(container) => container.capacity(),
365			ColumnData::IdentityId(container) => container.capacity(),
366			ColumnData::Uuid4(container) => container.capacity(),
367			ColumnData::Uuid7(container) => container.capacity(),
368			ColumnData::Blob {
369				container,
370				..
371			} => container.capacity(),
372			ColumnData::Int {
373				container,
374				..
375			} => container.capacity(),
376			ColumnData::Uint {
377				container,
378				..
379			} => container.capacity(),
380			ColumnData::Decimal {
381				container,
382				..
383			} => container.capacity(),
384			ColumnData::Any(container) => container.capacity(),
385			ColumnData::Undefined(container) => container.capacity(),
386		}
387	}
388
389	pub fn as_string(&self, index: usize) -> String {
390		match self {
391			ColumnData::Bool(container) => container.as_string(index),
392			ColumnData::Float4(container) => container.as_string(index),
393			ColumnData::Float8(container) => container.as_string(index),
394			ColumnData::Int1(container) => container.as_string(index),
395			ColumnData::Int2(container) => container.as_string(index),
396			ColumnData::Int4(container) => container.as_string(index),
397			ColumnData::Int8(container) => container.as_string(index),
398			ColumnData::Int16(container) => container.as_string(index),
399			ColumnData::Uint1(container) => container.as_string(index),
400			ColumnData::Uint2(container) => container.as_string(index),
401			ColumnData::Uint4(container) => container.as_string(index),
402			ColumnData::Uint8(container) => container.as_string(index),
403			ColumnData::Uint16(container) => container.as_string(index),
404			ColumnData::Utf8 {
405				container,
406				..
407			} => container.as_string(index),
408			ColumnData::Date(container) => container.as_string(index),
409			ColumnData::DateTime(container) => container.as_string(index),
410			ColumnData::Time(container) => container.as_string(index),
411			ColumnData::Duration(container) => container.as_string(index),
412			ColumnData::IdentityId(container) => container.as_string(index),
413			ColumnData::Uuid4(container) => container.as_string(index),
414			ColumnData::Uuid7(container) => container.as_string(index),
415			ColumnData::Blob {
416				container,
417				..
418			} => container.as_string(index),
419			ColumnData::Int {
420				container,
421				..
422			} => container.as_string(index),
423			ColumnData::Uint {
424				container,
425				..
426			} => container.as_string(index),
427			ColumnData::Decimal {
428				container,
429				..
430			} => container.as_string(index),
431			ColumnData::Any(container) => container.as_string(index),
432			ColumnData::Undefined(container) => container.as_string(index),
433		}
434	}
435}