Skip to main content

reifydb_core/value/column/buffer/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4pub mod extend;
5pub mod factory;
6pub mod filter;
7pub mod from;
8pub mod get;
9pub mod pool;
10pub mod reorder;
11pub mod scatter;
12pub mod slice;
13pub mod take;
14
15use std::fmt;
16
17use reifydb_value::{
18	util::bitvec::BitVec,
19	value::{
20		Value,
21		constraint::{bytes::MaxBytes, precision::Precision, scale::Scale},
22		container::{
23			any::AnyContainer, blob::BlobContainer, bool::BoolContainer, dictionary::DictionaryContainer,
24			identity_id::IdentityIdContainer, number::NumberContainer, temporal::TemporalContainer,
25			utf8::Utf8Container, uuid::UuidContainer,
26		},
27		date::Date,
28		datetime::DateTime,
29		decimal::Decimal,
30		duration::Duration,
31		int::Int,
32		time::Time,
33		uint::Uint,
34		uuid::{Uuid4, Uuid7},
35		value_type::ValueType,
36	},
37};
38use serde::{Deserialize, Deserializer, Serialize, Serializer};
39
40pub enum ColumnBuffer {
41	Bool(BoolContainer),
42	Float4(NumberContainer<f32>),
43	Float8(NumberContainer<f64>),
44	Int1(NumberContainer<i8>),
45	Int2(NumberContainer<i16>),
46	Int4(NumberContainer<i32>),
47	Int8(NumberContainer<i64>),
48	Int16(NumberContainer<i128>),
49	Uint1(NumberContainer<u8>),
50	Uint2(NumberContainer<u16>),
51	Uint4(NumberContainer<u32>),
52	Uint8(NumberContainer<u64>),
53	Uint16(NumberContainer<u128>),
54	Utf8 {
55		container: Utf8Container,
56		max_bytes: MaxBytes,
57	},
58	Date(TemporalContainer<Date>),
59	DateTime(TemporalContainer<DateTime>),
60	Time(TemporalContainer<Time>),
61	Duration(TemporalContainer<Duration>),
62	IdentityId(IdentityIdContainer),
63	Uuid4(UuidContainer<Uuid4>),
64	Uuid7(UuidContainer<Uuid7>),
65	Blob {
66		container: BlobContainer,
67		max_bytes: MaxBytes,
68	},
69	Int {
70		container: NumberContainer<Int>,
71		max_bytes: MaxBytes,
72	},
73	Uint {
74		container: NumberContainer<Uint>,
75		max_bytes: MaxBytes,
76	},
77	Decimal {
78		container: NumberContainer<Decimal>,
79		precision: Precision,
80		scale: Scale,
81	},
82
83	Any(AnyContainer),
84
85	DictionaryId(DictionaryContainer),
86
87	Option {
88		inner: Box<ColumnBuffer>,
89		bitvec: BitVec,
90	},
91}
92
93impl Clone for ColumnBuffer {
94	fn clone(&self) -> Self {
95		match self {
96			ColumnBuffer::Bool(c) => ColumnBuffer::Bool(c.clone()),
97			ColumnBuffer::Float4(c) => ColumnBuffer::Float4(c.clone()),
98			ColumnBuffer::Float8(c) => ColumnBuffer::Float8(c.clone()),
99			ColumnBuffer::Int1(c) => ColumnBuffer::Int1(c.clone()),
100			ColumnBuffer::Int2(c) => ColumnBuffer::Int2(c.clone()),
101			ColumnBuffer::Int4(c) => ColumnBuffer::Int4(c.clone()),
102			ColumnBuffer::Int8(c) => ColumnBuffer::Int8(c.clone()),
103			ColumnBuffer::Int16(c) => ColumnBuffer::Int16(c.clone()),
104			ColumnBuffer::Uint1(c) => ColumnBuffer::Uint1(c.clone()),
105			ColumnBuffer::Uint2(c) => ColumnBuffer::Uint2(c.clone()),
106			ColumnBuffer::Uint4(c) => ColumnBuffer::Uint4(c.clone()),
107			ColumnBuffer::Uint8(c) => ColumnBuffer::Uint8(c.clone()),
108			ColumnBuffer::Uint16(c) => ColumnBuffer::Uint16(c.clone()),
109			ColumnBuffer::Utf8 {
110				container,
111				max_bytes,
112			} => ColumnBuffer::Utf8 {
113				container: container.clone(),
114				max_bytes: *max_bytes,
115			},
116			ColumnBuffer::Date(c) => ColumnBuffer::Date(c.clone()),
117			ColumnBuffer::DateTime(c) => ColumnBuffer::DateTime(c.clone()),
118			ColumnBuffer::Time(c) => ColumnBuffer::Time(c.clone()),
119			ColumnBuffer::Duration(c) => ColumnBuffer::Duration(c.clone()),
120			ColumnBuffer::IdentityId(c) => ColumnBuffer::IdentityId(c.clone()),
121			ColumnBuffer::Uuid4(c) => ColumnBuffer::Uuid4(c.clone()),
122			ColumnBuffer::Uuid7(c) => ColumnBuffer::Uuid7(c.clone()),
123			ColumnBuffer::Blob {
124				container,
125				max_bytes,
126			} => ColumnBuffer::Blob {
127				container: container.clone(),
128				max_bytes: *max_bytes,
129			},
130			ColumnBuffer::Int {
131				container,
132				max_bytes,
133			} => ColumnBuffer::Int {
134				container: container.clone(),
135				max_bytes: *max_bytes,
136			},
137			ColumnBuffer::Uint {
138				container,
139				max_bytes,
140			} => ColumnBuffer::Uint {
141				container: container.clone(),
142				max_bytes: *max_bytes,
143			},
144			ColumnBuffer::Decimal {
145				container,
146				precision,
147				scale,
148			} => ColumnBuffer::Decimal {
149				container: container.clone(),
150				precision: *precision,
151				scale: *scale,
152			},
153			ColumnBuffer::Any(c) => ColumnBuffer::Any(c.clone()),
154			ColumnBuffer::DictionaryId(c) => ColumnBuffer::DictionaryId(c.clone()),
155			ColumnBuffer::Option {
156				inner,
157				bitvec,
158			} => ColumnBuffer::Option {
159				inner: inner.clone(),
160				bitvec: bitvec.clone(),
161			},
162		}
163	}
164}
165
166impl PartialEq for ColumnBuffer {
167	fn eq(&self, other: &Self) -> bool {
168		match (self, other) {
169			(ColumnBuffer::Bool(a), ColumnBuffer::Bool(b)) => a == b,
170			(ColumnBuffer::Float4(a), ColumnBuffer::Float4(b)) => a == b,
171			(ColumnBuffer::Float8(a), ColumnBuffer::Float8(b)) => a == b,
172			(ColumnBuffer::Int1(a), ColumnBuffer::Int1(b)) => a == b,
173			(ColumnBuffer::Int2(a), ColumnBuffer::Int2(b)) => a == b,
174			(ColumnBuffer::Int4(a), ColumnBuffer::Int4(b)) => a == b,
175			(ColumnBuffer::Int8(a), ColumnBuffer::Int8(b)) => a == b,
176			(ColumnBuffer::Int16(a), ColumnBuffer::Int16(b)) => a == b,
177			(ColumnBuffer::Uint1(a), ColumnBuffer::Uint1(b)) => a == b,
178			(ColumnBuffer::Uint2(a), ColumnBuffer::Uint2(b)) => a == b,
179			(ColumnBuffer::Uint4(a), ColumnBuffer::Uint4(b)) => a == b,
180			(ColumnBuffer::Uint8(a), ColumnBuffer::Uint8(b)) => a == b,
181			(ColumnBuffer::Uint16(a), ColumnBuffer::Uint16(b)) => a == b,
182			(
183				ColumnBuffer::Utf8 {
184					container: a,
185					max_bytes: am,
186				},
187				ColumnBuffer::Utf8 {
188					container: b,
189					max_bytes: bm,
190				},
191			) => a == b && am == bm,
192			(ColumnBuffer::Date(a), ColumnBuffer::Date(b)) => a == b,
193			(ColumnBuffer::DateTime(a), ColumnBuffer::DateTime(b)) => a == b,
194			(ColumnBuffer::Time(a), ColumnBuffer::Time(b)) => a == b,
195			(ColumnBuffer::Duration(a), ColumnBuffer::Duration(b)) => a == b,
196			(ColumnBuffer::IdentityId(a), ColumnBuffer::IdentityId(b)) => a == b,
197			(ColumnBuffer::Uuid4(a), ColumnBuffer::Uuid4(b)) => a == b,
198			(ColumnBuffer::Uuid7(a), ColumnBuffer::Uuid7(b)) => a == b,
199			(
200				ColumnBuffer::Blob {
201					container: a,
202					max_bytes: am,
203				},
204				ColumnBuffer::Blob {
205					container: b,
206					max_bytes: bm,
207				},
208			) => a == b && am == bm,
209			(
210				ColumnBuffer::Int {
211					container: a,
212					max_bytes: am,
213				},
214				ColumnBuffer::Int {
215					container: b,
216					max_bytes: bm,
217				},
218			) => a == b && am == bm,
219			(
220				ColumnBuffer::Uint {
221					container: a,
222					max_bytes: am,
223				},
224				ColumnBuffer::Uint {
225					container: b,
226					max_bytes: bm,
227				},
228			) => a == b && am == bm,
229			(
230				ColumnBuffer::Decimal {
231					container: a,
232					precision: ap,
233					scale: as_,
234				},
235				ColumnBuffer::Decimal {
236					container: b,
237					precision: bp,
238					scale: bs,
239				},
240			) => a == b && ap == bp && as_ == bs,
241			(ColumnBuffer::Any(a), ColumnBuffer::Any(b)) => a == b,
242			(ColumnBuffer::DictionaryId(a), ColumnBuffer::DictionaryId(b)) => a == b,
243			(
244				ColumnBuffer::Option {
245					inner: ai,
246					bitvec: ab,
247				},
248				ColumnBuffer::Option {
249					inner: bi,
250					bitvec: bb,
251				},
252			) => ai == bi && ab == bb,
253			_ => false,
254		}
255	}
256}
257
258impl fmt::Debug for ColumnBuffer {
259	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
260		match self {
261			ColumnBuffer::Bool(c) => f.debug_tuple("Bool").field(c).finish(),
262			ColumnBuffer::Float4(c) => f.debug_tuple("Float4").field(c).finish(),
263			ColumnBuffer::Float8(c) => f.debug_tuple("Float8").field(c).finish(),
264			ColumnBuffer::Int1(c) => f.debug_tuple("Int1").field(c).finish(),
265			ColumnBuffer::Int2(c) => f.debug_tuple("Int2").field(c).finish(),
266			ColumnBuffer::Int4(c) => f.debug_tuple("Int4").field(c).finish(),
267			ColumnBuffer::Int8(c) => f.debug_tuple("Int8").field(c).finish(),
268			ColumnBuffer::Int16(c) => f.debug_tuple("Int16").field(c).finish(),
269			ColumnBuffer::Uint1(c) => f.debug_tuple("Uint1").field(c).finish(),
270			ColumnBuffer::Uint2(c) => f.debug_tuple("Uint2").field(c).finish(),
271			ColumnBuffer::Uint4(c) => f.debug_tuple("Uint4").field(c).finish(),
272			ColumnBuffer::Uint8(c) => f.debug_tuple("Uint8").field(c).finish(),
273			ColumnBuffer::Uint16(c) => f.debug_tuple("Uint16").field(c).finish(),
274			ColumnBuffer::Utf8 {
275				container,
276				max_bytes,
277			} => f.debug_struct("Utf8").field("container", container).field("max_bytes", max_bytes).finish(),
278			ColumnBuffer::Date(c) => f.debug_tuple("Date").field(c).finish(),
279			ColumnBuffer::DateTime(c) => f.debug_tuple("DateTime").field(c).finish(),
280			ColumnBuffer::Time(c) => f.debug_tuple("Time").field(c).finish(),
281			ColumnBuffer::Duration(c) => f.debug_tuple("Duration").field(c).finish(),
282			ColumnBuffer::IdentityId(c) => f.debug_tuple("IdentityId").field(c).finish(),
283			ColumnBuffer::Uuid4(c) => f.debug_tuple("Uuid4").field(c).finish(),
284			ColumnBuffer::Uuid7(c) => f.debug_tuple("Uuid7").field(c).finish(),
285			ColumnBuffer::Blob {
286				container,
287				max_bytes,
288			} => f.debug_struct("Blob").field("container", container).field("max_bytes", max_bytes).finish(),
289			ColumnBuffer::Int {
290				container,
291				max_bytes,
292			} => f.debug_struct("Int").field("container", container).field("max_bytes", max_bytes).finish(),
293			ColumnBuffer::Uint {
294				container,
295				max_bytes,
296			} => f.debug_struct("Uint").field("container", container).field("max_bytes", max_bytes).finish(),
297			ColumnBuffer::Decimal {
298				container,
299				precision,
300				scale,
301			} => f.debug_struct("Decimal")
302				.field("container", container)
303				.field("precision", precision)
304				.field("scale", scale)
305				.finish(),
306			ColumnBuffer::Any(c) => f.debug_tuple("Any").field(c).finish(),
307			ColumnBuffer::DictionaryId(c) => f.debug_tuple("DictionaryId").field(c).finish(),
308			ColumnBuffer::Option {
309				inner,
310				bitvec,
311			} => f.debug_struct("Option").field("inner", inner).field("bitvec", bitvec).finish(),
312		}
313	}
314}
315
316impl Serialize for ColumnBuffer {
317	fn serialize<Ser: Serializer>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error> {
318		#[derive(Serialize)]
319		enum Helper<'a> {
320			Bool(&'a BoolContainer),
321			Float4(&'a NumberContainer<f32>),
322			Float8(&'a NumberContainer<f64>),
323			Int1(&'a NumberContainer<i8>),
324			Int2(&'a NumberContainer<i16>),
325			Int4(&'a NumberContainer<i32>),
326			Int8(&'a NumberContainer<i64>),
327			Int16(&'a NumberContainer<i128>),
328			Uint1(&'a NumberContainer<u8>),
329			Uint2(&'a NumberContainer<u16>),
330			Uint4(&'a NumberContainer<u32>),
331			Uint8(&'a NumberContainer<u64>),
332			Uint16(&'a NumberContainer<u128>),
333			Utf8 {
334				container: &'a Utf8Container,
335				max_bytes: MaxBytes,
336			},
337			Date(&'a TemporalContainer<Date>),
338			DateTime(&'a TemporalContainer<DateTime>),
339			Time(&'a TemporalContainer<Time>),
340			Duration(&'a TemporalContainer<Duration>),
341			IdentityId(&'a IdentityIdContainer),
342			Uuid4(&'a UuidContainer<Uuid4>),
343			Uuid7(&'a UuidContainer<Uuid7>),
344			Blob {
345				container: &'a BlobContainer,
346				max_bytes: MaxBytes,
347			},
348			Int {
349				container: &'a NumberContainer<Int>,
350				max_bytes: MaxBytes,
351			},
352			Uint {
353				container: &'a NumberContainer<Uint>,
354				max_bytes: MaxBytes,
355			},
356			Decimal {
357				container: &'a NumberContainer<Decimal>,
358				precision: Precision,
359				scale: Scale,
360			},
361			Any(&'a AnyContainer),
362			DictionaryId(&'a DictionaryContainer),
363			Option {
364				inner: &'a ColumnBuffer,
365				bitvec: &'a BitVec,
366			},
367		}
368		let helper = match self {
369			ColumnBuffer::Bool(c) => Helper::Bool(c),
370			ColumnBuffer::Float4(c) => Helper::Float4(c),
371			ColumnBuffer::Float8(c) => Helper::Float8(c),
372			ColumnBuffer::Int1(c) => Helper::Int1(c),
373			ColumnBuffer::Int2(c) => Helper::Int2(c),
374			ColumnBuffer::Int4(c) => Helper::Int4(c),
375			ColumnBuffer::Int8(c) => Helper::Int8(c),
376			ColumnBuffer::Int16(c) => Helper::Int16(c),
377			ColumnBuffer::Uint1(c) => Helper::Uint1(c),
378			ColumnBuffer::Uint2(c) => Helper::Uint2(c),
379			ColumnBuffer::Uint4(c) => Helper::Uint4(c),
380			ColumnBuffer::Uint8(c) => Helper::Uint8(c),
381			ColumnBuffer::Uint16(c) => Helper::Uint16(c),
382			ColumnBuffer::Utf8 {
383				container,
384				max_bytes,
385			} => Helper::Utf8 {
386				container,
387				max_bytes: *max_bytes,
388			},
389			ColumnBuffer::Date(c) => Helper::Date(c),
390			ColumnBuffer::DateTime(c) => Helper::DateTime(c),
391			ColumnBuffer::Time(c) => Helper::Time(c),
392			ColumnBuffer::Duration(c) => Helper::Duration(c),
393			ColumnBuffer::IdentityId(c) => Helper::IdentityId(c),
394			ColumnBuffer::Uuid4(c) => Helper::Uuid4(c),
395			ColumnBuffer::Uuid7(c) => Helper::Uuid7(c),
396			ColumnBuffer::Blob {
397				container,
398				max_bytes,
399			} => Helper::Blob {
400				container,
401				max_bytes: *max_bytes,
402			},
403			ColumnBuffer::Int {
404				container,
405				max_bytes,
406			} => Helper::Int {
407				container,
408				max_bytes: *max_bytes,
409			},
410			ColumnBuffer::Uint {
411				container,
412				max_bytes,
413			} => Helper::Uint {
414				container,
415				max_bytes: *max_bytes,
416			},
417			ColumnBuffer::Decimal {
418				container,
419				precision,
420				scale,
421			} => Helper::Decimal {
422				container,
423				precision: *precision,
424				scale: *scale,
425			},
426			ColumnBuffer::Any(c) => Helper::Any(c),
427			ColumnBuffer::DictionaryId(c) => Helper::DictionaryId(c),
428			ColumnBuffer::Option {
429				inner,
430				bitvec,
431			} => Helper::Option {
432				inner: inner.as_ref(),
433				bitvec,
434			},
435		};
436		helper.serialize(serializer)
437	}
438}
439
440impl<'de> Deserialize<'de> for ColumnBuffer {
441	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
442		#[derive(Deserialize)]
443		enum Helper {
444			Bool(BoolContainer),
445			Float4(NumberContainer<f32>),
446			Float8(NumberContainer<f64>),
447			Int1(NumberContainer<i8>),
448			Int2(NumberContainer<i16>),
449			Int4(NumberContainer<i32>),
450			Int8(NumberContainer<i64>),
451			Int16(NumberContainer<i128>),
452			Uint1(NumberContainer<u8>),
453			Uint2(NumberContainer<u16>),
454			Uint4(NumberContainer<u32>),
455			Uint8(NumberContainer<u64>),
456			Uint16(NumberContainer<u128>),
457			Utf8 {
458				container: Utf8Container,
459				max_bytes: MaxBytes,
460			},
461			Date(TemporalContainer<Date>),
462			DateTime(TemporalContainer<DateTime>),
463			Time(TemporalContainer<Time>),
464			Duration(TemporalContainer<Duration>),
465			IdentityId(IdentityIdContainer),
466			Uuid4(UuidContainer<Uuid4>),
467			Uuid7(UuidContainer<Uuid7>),
468			Blob {
469				container: BlobContainer,
470				max_bytes: MaxBytes,
471			},
472			Int {
473				container: NumberContainer<Int>,
474				max_bytes: MaxBytes,
475			},
476			Uint {
477				container: NumberContainer<Uint>,
478				max_bytes: MaxBytes,
479			},
480			Decimal {
481				container: NumberContainer<Decimal>,
482				precision: Precision,
483				scale: Scale,
484			},
485			Any(AnyContainer),
486			DictionaryId(DictionaryContainer),
487			Option {
488				inner: Box<ColumnBuffer>,
489				bitvec: BitVec,
490			},
491		}
492		let helper = Helper::deserialize(deserializer)?;
493		Ok(match helper {
494			Helper::Bool(c) => ColumnBuffer::Bool(c),
495			Helper::Float4(c) => ColumnBuffer::Float4(c),
496			Helper::Float8(c) => ColumnBuffer::Float8(c),
497			Helper::Int1(c) => ColumnBuffer::Int1(c),
498			Helper::Int2(c) => ColumnBuffer::Int2(c),
499			Helper::Int4(c) => ColumnBuffer::Int4(c),
500			Helper::Int8(c) => ColumnBuffer::Int8(c),
501			Helper::Int16(c) => ColumnBuffer::Int16(c),
502			Helper::Uint1(c) => ColumnBuffer::Uint1(c),
503			Helper::Uint2(c) => ColumnBuffer::Uint2(c),
504			Helper::Uint4(c) => ColumnBuffer::Uint4(c),
505			Helper::Uint8(c) => ColumnBuffer::Uint8(c),
506			Helper::Uint16(c) => ColumnBuffer::Uint16(c),
507			Helper::Utf8 {
508				container,
509				max_bytes,
510			} => ColumnBuffer::Utf8 {
511				container,
512				max_bytes,
513			},
514			Helper::Date(c) => ColumnBuffer::Date(c),
515			Helper::DateTime(c) => ColumnBuffer::DateTime(c),
516			Helper::Time(c) => ColumnBuffer::Time(c),
517			Helper::Duration(c) => ColumnBuffer::Duration(c),
518			Helper::IdentityId(c) => ColumnBuffer::IdentityId(c),
519			Helper::Uuid4(c) => ColumnBuffer::Uuid4(c),
520			Helper::Uuid7(c) => ColumnBuffer::Uuid7(c),
521			Helper::Blob {
522				container,
523				max_bytes,
524			} => ColumnBuffer::Blob {
525				container,
526				max_bytes,
527			},
528			Helper::Int {
529				container,
530				max_bytes,
531			} => ColumnBuffer::Int {
532				container,
533				max_bytes,
534			},
535			Helper::Uint {
536				container,
537				max_bytes,
538			} => ColumnBuffer::Uint {
539				container,
540				max_bytes,
541			},
542			Helper::Decimal {
543				container,
544				precision,
545				scale,
546			} => ColumnBuffer::Decimal {
547				container,
548				precision,
549				scale,
550			},
551			Helper::Any(c) => ColumnBuffer::Any(c),
552			Helper::DictionaryId(c) => ColumnBuffer::DictionaryId(c),
553			Helper::Option {
554				inner,
555				bitvec,
556			} => ColumnBuffer::Option {
557				inner,
558				bitvec,
559			},
560		})
561	}
562}
563
564macro_rules! with_container {
565	($self:expr, |$c:ident| $body:expr) => {
566		match $self {
567			ColumnBuffer::Bool($c) => $body,
568			ColumnBuffer::Float4($c) => $body,
569			ColumnBuffer::Float8($c) => $body,
570			ColumnBuffer::Int1($c) => $body,
571			ColumnBuffer::Int2($c) => $body,
572			ColumnBuffer::Int4($c) => $body,
573			ColumnBuffer::Int8($c) => $body,
574			ColumnBuffer::Int16($c) => $body,
575			ColumnBuffer::Uint1($c) => $body,
576			ColumnBuffer::Uint2($c) => $body,
577			ColumnBuffer::Uint4($c) => $body,
578			ColumnBuffer::Uint8($c) => $body,
579			ColumnBuffer::Uint16($c) => $body,
580			ColumnBuffer::Utf8 {
581				container: $c,
582				..
583			} => $body,
584			ColumnBuffer::Date($c) => $body,
585			ColumnBuffer::DateTime($c) => $body,
586			ColumnBuffer::Time($c) => $body,
587			ColumnBuffer::Duration($c) => $body,
588			ColumnBuffer::IdentityId($c) => $body,
589			ColumnBuffer::Uuid4($c) => $body,
590			ColumnBuffer::Uuid7($c) => $body,
591			ColumnBuffer::Blob {
592				container: $c,
593				..
594			} => $body,
595			ColumnBuffer::Int {
596				container: $c,
597				..
598			} => $body,
599			ColumnBuffer::Uint {
600				container: $c,
601				..
602			} => $body,
603			ColumnBuffer::Decimal {
604				container: $c,
605				..
606			} => $body,
607			ColumnBuffer::Any($c) => $body,
608			ColumnBuffer::DictionaryId($c) => $body,
609			ColumnBuffer::Option {
610				..
611			} => {
612				unreachable!(
613					"with_container! must not be called on Option variant directly; handle it explicitly"
614				)
615			}
616		}
617	};
618}
619
620pub(crate) use with_container;
621
622impl ColumnBuffer {
623	pub fn unwrap_option(&self) -> (&ColumnBuffer, Option<&BitVec>) {
624		match self {
625			ColumnBuffer::Option {
626				inner,
627				bitvec,
628			} => (inner.as_ref(), Some(bitvec)),
629			other => (other, None),
630		}
631	}
632
633	pub fn into_unwrap_option(self) -> (ColumnBuffer, Option<BitVec>) {
634		match self {
635			ColumnBuffer::Option {
636				inner,
637				bitvec,
638			} => (*inner, Some(bitvec)),
639			other => (other, None),
640		}
641	}
642
643	pub fn get_type(&self) -> ValueType {
644		match self {
645			ColumnBuffer::Bool(_) => ValueType::Boolean,
646			ColumnBuffer::Float4(_) => ValueType::Float4,
647			ColumnBuffer::Float8(_) => ValueType::Float8,
648			ColumnBuffer::Int1(_) => ValueType::Int1,
649			ColumnBuffer::Int2(_) => ValueType::Int2,
650			ColumnBuffer::Int4(_) => ValueType::Int4,
651			ColumnBuffer::Int8(_) => ValueType::Int8,
652			ColumnBuffer::Int16(_) => ValueType::Int16,
653			ColumnBuffer::Uint1(_) => ValueType::Uint1,
654			ColumnBuffer::Uint2(_) => ValueType::Uint2,
655			ColumnBuffer::Uint4(_) => ValueType::Uint4,
656			ColumnBuffer::Uint8(_) => ValueType::Uint8,
657			ColumnBuffer::Uint16(_) => ValueType::Uint16,
658			ColumnBuffer::Utf8 {
659				..
660			} => ValueType::Utf8,
661			ColumnBuffer::Date(_) => ValueType::Date,
662			ColumnBuffer::DateTime(_) => ValueType::DateTime,
663			ColumnBuffer::Time(_) => ValueType::Time,
664			ColumnBuffer::Duration(_) => ValueType::Duration,
665			ColumnBuffer::IdentityId(_) => ValueType::IdentityId,
666			ColumnBuffer::Uuid4(_) => ValueType::Uuid4,
667			ColumnBuffer::Uuid7(_) => ValueType::Uuid7,
668			ColumnBuffer::Blob {
669				..
670			} => ValueType::Blob,
671			ColumnBuffer::Int {
672				..
673			} => ValueType::Int,
674			ColumnBuffer::Uint {
675				..
676			} => ValueType::Uint,
677			ColumnBuffer::Decimal {
678				..
679			} => ValueType::Decimal,
680			ColumnBuffer::DictionaryId(_) => ValueType::DictionaryId,
681			ColumnBuffer::Any(_) => ValueType::Any,
682			ColumnBuffer::Option {
683				inner,
684				..
685			} => ValueType::Option(Box::new(inner.get_type())),
686		}
687	}
688
689	pub fn is_defined(&self, idx: usize) -> bool {
690		match self {
691			ColumnBuffer::Bool(c) => c.is_defined(idx),
692			ColumnBuffer::Float4(c) => c.is_defined(idx),
693			ColumnBuffer::Float8(c) => c.is_defined(idx),
694			ColumnBuffer::Int1(c) => c.is_defined(idx),
695			ColumnBuffer::Int2(c) => c.is_defined(idx),
696			ColumnBuffer::Int4(c) => c.is_defined(idx),
697			ColumnBuffer::Int8(c) => c.is_defined(idx),
698			ColumnBuffer::Int16(c) => c.is_defined(idx),
699			ColumnBuffer::Uint1(c) => c.is_defined(idx),
700			ColumnBuffer::Uint2(c) => c.is_defined(idx),
701			ColumnBuffer::Uint4(c) => c.is_defined(idx),
702			ColumnBuffer::Uint8(c) => c.is_defined(idx),
703			ColumnBuffer::Uint16(c) => c.is_defined(idx),
704			ColumnBuffer::Utf8 {
705				container: c,
706				..
707			} => c.is_defined(idx),
708			ColumnBuffer::Date(c) => c.is_defined(idx),
709			ColumnBuffer::DateTime(c) => c.is_defined(idx),
710			ColumnBuffer::Time(c) => c.is_defined(idx),
711			ColumnBuffer::Duration(c) => c.is_defined(idx),
712			ColumnBuffer::IdentityId(container) => container.get(idx).is_some(),
713			ColumnBuffer::Uuid4(c) => c.is_defined(idx),
714			ColumnBuffer::Uuid7(c) => c.is_defined(idx),
715			ColumnBuffer::Blob {
716				container: c,
717				..
718			} => c.is_defined(idx),
719			ColumnBuffer::Int {
720				container: c,
721				..
722			} => c.is_defined(idx),
723			ColumnBuffer::Uint {
724				container: c,
725				..
726			} => c.is_defined(idx),
727			ColumnBuffer::Decimal {
728				container: c,
729				..
730			} => c.is_defined(idx),
731			ColumnBuffer::DictionaryId(c) => c.is_defined(idx),
732			ColumnBuffer::Any(c) => c.is_defined(idx),
733			ColumnBuffer::Option {
734				bitvec,
735				..
736			} => idx < bitvec.len() && bitvec.get(idx),
737		}
738	}
739
740	pub fn is_bool(&self) -> bool {
741		self.get_type() == ValueType::Boolean
742	}
743
744	pub fn is_float(&self) -> bool {
745		self.get_type() == ValueType::Float4 || self.get_type() == ValueType::Float8
746	}
747
748	pub fn is_utf8(&self) -> bool {
749		self.get_type() == ValueType::Utf8
750	}
751
752	pub fn is_number(&self) -> bool {
753		matches!(
754			self.get_type(),
755			ValueType::Float4
756				| ValueType::Float8 | ValueType::Int1
757				| ValueType::Int2 | ValueType::Int4
758				| ValueType::Int8 | ValueType::Int16
759				| ValueType::Uint1 | ValueType::Uint2
760				| ValueType::Uint4 | ValueType::Uint8
761				| ValueType::Uint16 | ValueType::Int
762				| ValueType::Uint | ValueType::Decimal
763		)
764	}
765
766	pub fn is_text(&self) -> bool {
767		self.get_type() == ValueType::Utf8
768	}
769
770	pub fn is_temporal(&self) -> bool {
771		matches!(self.get_type(), ValueType::Date | ValueType::DateTime | ValueType::Time | ValueType::Duration)
772	}
773
774	pub fn is_uuid(&self) -> bool {
775		matches!(self.get_type(), ValueType::Uuid4 | ValueType::Uuid7)
776	}
777}
778
779impl ColumnBuffer {
780	pub fn none_count(&self) -> usize {
781		match self {
782			ColumnBuffer::Option {
783				bitvec,
784				..
785			} => bitvec.count_zeros(),
786			_ => 0,
787		}
788	}
789}
790
791impl ColumnBuffer {
792	pub fn len(&self) -> usize {
793		match self {
794			ColumnBuffer::Option {
795				inner,
796				..
797			} => inner.len(),
798			_ => with_container!(self, |c| c.len()),
799		}
800	}
801
802	pub fn is_empty(&self) -> bool {
803		self.len() == 0
804	}
805
806	pub fn capacity(&self) -> usize {
807		match self {
808			ColumnBuffer::Option {
809				inner,
810				..
811			} => inner.capacity(),
812			_ => with_container!(self, |c| c.capacity()),
813		}
814	}
815
816	pub fn heap_size(&self) -> usize {
817		match self {
818			ColumnBuffer::Option {
819				inner,
820				bitvec,
821			} => inner.heap_size() + bitvec.len().div_ceil(8),
822			_ => with_container!(self, |c| c.heap_size()),
823		}
824	}
825
826	pub fn clear(&mut self) {
827		match self {
828			ColumnBuffer::Option {
829				inner,
830				bitvec,
831			} => {
832				inner.clear();
833				bitvec.clear();
834			}
835			_ => with_container!(self, |c| c.clear()),
836		}
837	}
838
839	pub fn as_string(&self, index: usize) -> String {
840		match self {
841			ColumnBuffer::Option {
842				inner,
843				bitvec,
844			} => {
845				if index < bitvec.len() && bitvec.get(index) {
846					inner.as_string(index)
847				} else {
848					"none".to_string()
849				}
850			}
851			_ => with_container!(self, |c| c.as_string(index)),
852		}
853	}
854}
855
856impl ColumnBuffer {
857	pub fn with_capacity(target: ValueType, capacity: usize) -> Self {
858		match target {
859			ValueType::Boolean => Self::bool_with_capacity(capacity),
860			ValueType::Float4 => Self::float4_with_capacity(capacity),
861			ValueType::Float8 => Self::float8_with_capacity(capacity),
862			ValueType::Int1 => Self::int1_with_capacity(capacity),
863			ValueType::Int2 => Self::int2_with_capacity(capacity),
864			ValueType::Int4 => Self::int4_with_capacity(capacity),
865			ValueType::Int8 => Self::int8_with_capacity(capacity),
866			ValueType::Int16 => Self::int16_with_capacity(capacity),
867			ValueType::Uint1 => Self::uint1_with_capacity(capacity),
868			ValueType::Uint2 => Self::uint2_with_capacity(capacity),
869			ValueType::Uint4 => Self::uint4_with_capacity(capacity),
870			ValueType::Uint8 => Self::uint8_with_capacity(capacity),
871			ValueType::Uint16 => Self::uint16_with_capacity(capacity),
872			ValueType::Utf8 => Self::utf8_with_capacity(capacity),
873			ValueType::Date => Self::date_with_capacity(capacity),
874			ValueType::DateTime => Self::datetime_with_capacity(capacity),
875			ValueType::Time => Self::time_with_capacity(capacity),
876			ValueType::Duration => Self::duration_with_capacity(capacity),
877			ValueType::IdentityId => Self::identity_id_with_capacity(capacity),
878			ValueType::Uuid4 => Self::uuid4_with_capacity(capacity),
879			ValueType::Uuid7 => Self::uuid7_with_capacity(capacity),
880			ValueType::Blob => Self::blob_with_capacity(capacity),
881			ValueType::Int => Self::int_with_capacity(capacity),
882			ValueType::Uint => Self::uint_with_capacity(capacity),
883			ValueType::Decimal => Self::decimal_with_capacity(capacity),
884			ValueType::DictionaryId => Self::dictionary_id_with_capacity(capacity),
885			ValueType::Option(inner) => ColumnBuffer::Option {
886				inner: Box::new(ColumnBuffer::with_capacity(*inner, capacity)),
887				bitvec: BitVec::with_capacity(capacity),
888			},
889			ValueType::Any | ValueType::List(_) | ValueType::Record(_) | ValueType::Tuple(_) => {
890				Self::any_with_capacity(capacity)
891			}
892		}
893	}
894
895	pub fn empty_like(&self, capacity: usize) -> Self {
896		let mut buffer = Self::with_capacity(self.get_type(), capacity);
897		match (self, &mut buffer) {
898			(
899				ColumnBuffer::Utf8 {
900					max_bytes: src,
901					..
902				},
903				ColumnBuffer::Utf8 {
904					max_bytes: dst,
905					..
906				},
907			)
908			| (
909				ColumnBuffer::Blob {
910					max_bytes: src,
911					..
912				},
913				ColumnBuffer::Blob {
914					max_bytes: dst,
915					..
916				},
917			)
918			| (
919				ColumnBuffer::Int {
920					max_bytes: src,
921					..
922				},
923				ColumnBuffer::Int {
924					max_bytes: dst,
925					..
926				},
927			)
928			| (
929				ColumnBuffer::Uint {
930					max_bytes: src,
931					..
932				},
933				ColumnBuffer::Uint {
934					max_bytes: dst,
935					..
936				},
937			) => *dst = *src,
938			(
939				ColumnBuffer::Decimal {
940					precision: src_precision,
941					scale: src_scale,
942					..
943				},
944				ColumnBuffer::Decimal {
945					precision: dst_precision,
946					scale: dst_scale,
947					..
948				},
949			) => {
950				*dst_precision = *src_precision;
951				*dst_scale = *src_scale;
952			}
953			(ColumnBuffer::DictionaryId(src), ColumnBuffer::DictionaryId(dst)) => {
954				if let Some(dictionary_id) = src.dictionary_id() {
955					dst.set_dictionary_id(dictionary_id);
956				}
957			}
958			(
959				ColumnBuffer::Option {
960					inner: src_inner,
961					..
962				},
963				ColumnBuffer::Option {
964					inner: dst_inner,
965					..
966				},
967			) => {
968				**dst_inner = src_inner.empty_like(capacity);
969			}
970			_ => {}
971		}
972		buffer
973	}
974
975	pub fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = Value> + 'a> {
976		Box::new((0..self.len()).map(move |i| self.get_value(i)))
977	}
978}