Skip to main content

reifydb_core/value/column/data/
factory.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_type::{
5	util::bitvec::BitVec,
6	value::{
7		blob::Blob,
8		container::{
9			any::AnyContainer, blob::BlobContainer, bool::BoolContainer, dictionary::DictionaryContainer,
10			identity_id::IdentityIdContainer, number::NumberContainer, temporal::TemporalContainer,
11			utf8::Utf8Container, uuid::UuidContainer,
12		},
13		date::Date,
14		datetime::DateTime,
15		decimal::Decimal,
16		dictionary::DictionaryEntryId,
17		duration::Duration,
18		identity::IdentityId,
19		int::Int,
20		time::Time,
21		r#type::Type,
22		uint::Uint,
23		uuid::{Uuid4, Uuid7},
24	},
25};
26
27use crate::value::column::ColumnData;
28
29macro_rules! impl_number_factory {
30	($name:ident, $name_opt:ident, $name_cap:ident, $name_bv:ident, $variant:ident, $t:ty, $default:expr) => {
31		pub fn $name(data: impl IntoIterator<Item = $t>) -> Self {
32			let data = data.into_iter().collect::<Vec<_>>();
33			ColumnData::$variant(NumberContainer::from_vec(data))
34		}
35
36		pub fn $name_opt(data: impl IntoIterator<Item = Option<$t>>) -> Self {
37			let mut values = Vec::new();
38			let mut bitvec = Vec::new();
39			let mut has_none = false;
40			for opt in data {
41				match opt {
42					Some(value) => {
43						values.push(value);
44						bitvec.push(true);
45					}
46					None => {
47						values.push($default);
48						bitvec.push(false);
49						has_none = true;
50					}
51				}
52			}
53			let inner = ColumnData::$variant(NumberContainer::from_vec(values));
54			if has_none {
55				ColumnData::Option {
56					inner: Box::new(inner),
57					bitvec: BitVec::from(bitvec),
58				}
59			} else {
60				inner
61			}
62		}
63
64		pub fn $name_cap(capacity: usize) -> Self {
65			ColumnData::$variant(NumberContainer::with_capacity(capacity))
66		}
67
68		pub fn $name_bv(data: impl IntoIterator<Item = $t>, bitvec: impl Into<BitVec>) -> Self {
69			let data = data.into_iter().collect::<Vec<_>>();
70			let bitvec = bitvec.into();
71			assert_eq!(bitvec.len(), data.len());
72			let inner = ColumnData::$variant(NumberContainer::from_vec(data));
73			if bitvec.all_ones() {
74				inner
75			} else {
76				ColumnData::Option {
77					inner: Box::new(inner),
78					bitvec,
79				}
80			}
81		}
82	};
83}
84
85macro_rules! impl_temporal_factory {
86	($name:ident, $name_opt:ident, $name_cap:ident, $name_bv:ident, $variant:ident, $t:ty) => {
87		pub fn $name(data: impl IntoIterator<Item = $t>) -> Self {
88			let data = data.into_iter().collect::<Vec<_>>();
89			ColumnData::$variant(TemporalContainer::from_vec(data))
90		}
91
92		pub fn $name_opt(data: impl IntoIterator<Item = Option<$t>>) -> Self {
93			let mut values = Vec::new();
94			let mut bitvec = Vec::new();
95			let mut has_none = false;
96			for opt in data {
97				match opt {
98					Some(value) => {
99						values.push(value);
100						bitvec.push(true);
101					}
102					None => {
103						values.push(<$t>::default());
104						bitvec.push(false);
105						has_none = true;
106					}
107				}
108			}
109			let inner = ColumnData::$variant(TemporalContainer::from_vec(values));
110			if has_none {
111				ColumnData::Option {
112					inner: Box::new(inner),
113					bitvec: BitVec::from(bitvec),
114				}
115			} else {
116				inner
117			}
118		}
119
120		pub fn $name_cap(capacity: usize) -> Self {
121			ColumnData::$variant(TemporalContainer::with_capacity(capacity))
122		}
123
124		pub fn $name_bv(data: impl IntoIterator<Item = $t>, bitvec: impl Into<BitVec>) -> Self {
125			let data = data.into_iter().collect::<Vec<_>>();
126			let bitvec = bitvec.into();
127			assert_eq!(bitvec.len(), data.len());
128			let inner = ColumnData::$variant(TemporalContainer::from_vec(data));
129			if bitvec.all_ones() {
130				inner
131			} else {
132				ColumnData::Option {
133					inner: Box::new(inner),
134					bitvec,
135				}
136			}
137		}
138	};
139}
140
141macro_rules! impl_uuid_factory {
142	($name:ident, $name_opt:ident, $name_cap:ident, $name_bv:ident, $variant:ident, $t:ty) => {
143		pub fn $name(data: impl IntoIterator<Item = $t>) -> Self {
144			let data = data.into_iter().collect::<Vec<_>>();
145			ColumnData::$variant(UuidContainer::from_vec(data))
146		}
147
148		pub fn $name_opt(data: impl IntoIterator<Item = Option<$t>>) -> Self {
149			let mut values = Vec::new();
150			let mut bitvec = Vec::new();
151			let mut has_none = false;
152			for opt in data {
153				match opt {
154					Some(value) => {
155						values.push(value);
156						bitvec.push(true);
157					}
158					None => {
159						values.push(<$t>::default());
160						bitvec.push(false);
161						has_none = true;
162					}
163				}
164			}
165			let inner = ColumnData::$variant(UuidContainer::from_vec(values));
166			if has_none {
167				ColumnData::Option {
168					inner: Box::new(inner),
169					bitvec: BitVec::from(bitvec),
170				}
171			} else {
172				inner
173			}
174		}
175
176		pub fn $name_cap(capacity: usize) -> Self {
177			ColumnData::$variant(UuidContainer::with_capacity(capacity))
178		}
179
180		pub fn $name_bv(data: impl IntoIterator<Item = $t>, bitvec: impl Into<BitVec>) -> Self {
181			let data = data.into_iter().collect::<Vec<_>>();
182			let bitvec = bitvec.into();
183			assert_eq!(bitvec.len(), data.len());
184			let inner = ColumnData::$variant(UuidContainer::from_vec(data));
185			if bitvec.all_ones() {
186				inner
187			} else {
188				ColumnData::Option {
189					inner: Box::new(inner),
190					bitvec,
191				}
192			}
193		}
194	};
195}
196
197impl ColumnData {
198	pub fn bool(data: impl IntoIterator<Item = bool>) -> Self {
199		let data = data.into_iter().collect::<Vec<_>>();
200		ColumnData::Bool(BoolContainer::from_vec(data))
201	}
202
203	pub fn bool_optional(data: impl IntoIterator<Item = Option<bool>>) -> Self {
204		let mut values = Vec::new();
205		let mut bitvec = Vec::new();
206		let mut has_none = false;
207
208		for opt in data {
209			match opt {
210				Some(value) => {
211					values.push(value);
212					bitvec.push(true);
213				}
214				None => {
215					values.push(false);
216					bitvec.push(false);
217					has_none = true;
218				}
219			}
220		}
221
222		let inner = ColumnData::Bool(BoolContainer::from_vec(values));
223		if has_none {
224			ColumnData::Option {
225				inner: Box::new(inner),
226				bitvec: BitVec::from(bitvec),
227			}
228		} else {
229			inner
230		}
231	}
232
233	pub fn bool_with_capacity(capacity: usize) -> Self {
234		ColumnData::Bool(BoolContainer::with_capacity(capacity))
235	}
236
237	pub fn bool_with_bitvec(data: impl IntoIterator<Item = bool>, bitvec: impl Into<BitVec>) -> Self {
238		let data = data.into_iter().collect::<Vec<_>>();
239		let bitvec = bitvec.into();
240		assert_eq!(bitvec.len(), data.len());
241		let inner = ColumnData::Bool(BoolContainer::from_vec(data));
242		if bitvec.all_ones() {
243			inner
244		} else {
245			ColumnData::Option {
246				inner: Box::new(inner),
247				bitvec,
248			}
249		}
250	}
251
252	impl_number_factory!(float4, float4_optional, float4_with_capacity, float4_with_bitvec, Float4, f32, 0.0);
253	impl_number_factory!(float8, float8_optional, float8_with_capacity, float8_with_bitvec, Float8, f64, 0.0);
254	impl_number_factory!(int1, int1_optional, int1_with_capacity, int1_with_bitvec, Int1, i8, 0);
255	impl_number_factory!(int2, int2_optional, int2_with_capacity, int2_with_bitvec, Int2, i16, 0);
256	impl_number_factory!(int4, int4_optional, int4_with_capacity, int4_with_bitvec, Int4, i32, 0);
257	impl_number_factory!(int8, int8_optional, int8_with_capacity, int8_with_bitvec, Int8, i64, 0);
258	impl_number_factory!(int16, int16_optional, int16_with_capacity, int16_with_bitvec, Int16, i128, 0);
259	impl_number_factory!(uint1, uint1_optional, uint1_with_capacity, uint1_with_bitvec, Uint1, u8, 0);
260	impl_number_factory!(uint2, uint2_optional, uint2_with_capacity, uint2_with_bitvec, Uint2, u16, 0);
261	impl_number_factory!(uint4, uint4_optional, uint4_with_capacity, uint4_with_bitvec, Uint4, u32, 0);
262	impl_number_factory!(uint8, uint8_optional, uint8_with_capacity, uint8_with_bitvec, Uint8, u64, 0);
263	impl_number_factory!(uint16, uint16_optional, uint16_with_capacity, uint16_with_bitvec, Uint16, u128, 0);
264
265	pub fn utf8(data: impl IntoIterator<Item = impl Into<String>>) -> Self {
266		use reifydb_type::value::constraint::bytes::MaxBytes;
267		let data = data.into_iter().map(|c| c.into()).collect::<Vec<_>>();
268		ColumnData::Utf8 {
269			container: Utf8Container::from_vec(data),
270			max_bytes: MaxBytes::MAX,
271		}
272	}
273
274	pub fn utf8_optional(data: impl IntoIterator<Item = Option<String>>) -> Self {
275		use reifydb_type::value::constraint::bytes::MaxBytes;
276		let mut values = Vec::new();
277		let mut bitvec = Vec::new();
278		let mut has_none = false;
279
280		for opt in data {
281			match opt {
282				Some(value) => {
283					values.push(value);
284					bitvec.push(true);
285				}
286				None => {
287					values.push(String::new());
288					bitvec.push(false);
289					has_none = true;
290				}
291			}
292		}
293
294		let inner = ColumnData::Utf8 {
295			container: Utf8Container::from_vec(values),
296			max_bytes: MaxBytes::MAX,
297		};
298		if has_none {
299			ColumnData::Option {
300				inner: Box::new(inner),
301				bitvec: BitVec::from(bitvec),
302			}
303		} else {
304			inner
305		}
306	}
307
308	pub fn utf8_with_capacity(capacity: usize) -> Self {
309		use reifydb_type::value::constraint::bytes::MaxBytes;
310		ColumnData::Utf8 {
311			container: Utf8Container::with_capacity(capacity),
312			max_bytes: MaxBytes::MAX,
313		}
314	}
315
316	pub fn utf8_with_bitvec(data: impl IntoIterator<Item = impl Into<String>>, bitvec: impl Into<BitVec>) -> Self {
317		use reifydb_type::value::constraint::bytes::MaxBytes;
318		let data = data.into_iter().map(Into::into).collect::<Vec<_>>();
319		let bitvec = bitvec.into();
320		assert_eq!(bitvec.len(), data.len());
321		let inner = ColumnData::Utf8 {
322			container: Utf8Container::from_vec(data),
323			max_bytes: MaxBytes::MAX,
324		};
325		if bitvec.all_ones() {
326			inner
327		} else {
328			ColumnData::Option {
329				inner: Box::new(inner),
330				bitvec,
331			}
332		}
333	}
334
335	impl_temporal_factory!(date, date_optional, date_with_capacity, date_with_bitvec, Date, Date);
336	impl_temporal_factory!(
337		datetime,
338		datetime_optional,
339		datetime_with_capacity,
340		datetime_with_bitvec,
341		DateTime,
342		DateTime
343	);
344	impl_temporal_factory!(time, time_optional, time_with_capacity, time_with_bitvec, Time, Time);
345	impl_temporal_factory!(
346		duration,
347		duration_optional,
348		duration_with_capacity,
349		duration_with_bitvec,
350		Duration,
351		Duration
352	);
353
354	impl_uuid_factory!(uuid4, uuid4_optional, uuid4_with_capacity, uuid4_with_bitvec, Uuid4, Uuid4);
355	impl_uuid_factory!(uuid7, uuid7_optional, uuid7_with_capacity, uuid7_with_bitvec, Uuid7, Uuid7);
356
357	pub fn blob(data: impl IntoIterator<Item = Blob>) -> Self {
358		use reifydb_type::value::constraint::bytes::MaxBytes;
359		let data = data.into_iter().collect::<Vec<_>>();
360		ColumnData::Blob {
361			container: BlobContainer::from_vec(data),
362			max_bytes: MaxBytes::MAX,
363		}
364	}
365
366	pub fn blob_optional(data: impl IntoIterator<Item = Option<Blob>>) -> Self {
367		use reifydb_type::value::constraint::bytes::MaxBytes;
368		let mut values = Vec::new();
369		let mut bitvec = Vec::new();
370		let mut has_none = false;
371
372		for opt in data {
373			match opt {
374				Some(value) => {
375					values.push(value);
376					bitvec.push(true);
377				}
378				None => {
379					values.push(Blob::default());
380					bitvec.push(false);
381					has_none = true;
382				}
383			}
384		}
385
386		let inner = ColumnData::Blob {
387			container: BlobContainer::from_vec(values),
388			max_bytes: MaxBytes::MAX,
389		};
390		if has_none {
391			ColumnData::Option {
392				inner: Box::new(inner),
393				bitvec: BitVec::from(bitvec),
394			}
395		} else {
396			inner
397		}
398	}
399
400	pub fn blob_with_capacity(capacity: usize) -> Self {
401		use reifydb_type::value::constraint::bytes::MaxBytes;
402		ColumnData::Blob {
403			container: BlobContainer::with_capacity(capacity),
404			max_bytes: MaxBytes::MAX,
405		}
406	}
407
408	pub fn blob_with_bitvec(data: impl IntoIterator<Item = Blob>, bitvec: impl Into<BitVec>) -> Self {
409		use reifydb_type::value::constraint::bytes::MaxBytes;
410		let data = data.into_iter().collect::<Vec<_>>();
411		let bitvec = bitvec.into();
412		assert_eq!(bitvec.len(), data.len());
413		let inner = ColumnData::Blob {
414			container: BlobContainer::from_vec(data),
415			max_bytes: MaxBytes::MAX,
416		};
417		if bitvec.all_ones() {
418			inner
419		} else {
420			ColumnData::Option {
421				inner: Box::new(inner),
422				bitvec,
423			}
424		}
425	}
426
427	pub fn identity_id(identity_ids: impl IntoIterator<Item = IdentityId>) -> Self {
428		let data = identity_ids.into_iter().collect::<Vec<_>>();
429		ColumnData::IdentityId(IdentityIdContainer::from_vec(data))
430	}
431
432	pub fn identity_id_optional(identity_ids: impl IntoIterator<Item = Option<IdentityId>>) -> Self {
433		let mut values = Vec::new();
434		let mut bitvec = Vec::new();
435		let mut has_none = false;
436
437		for opt in identity_ids {
438			match opt {
439				Some(value) => {
440					values.push(value);
441					bitvec.push(true);
442				}
443				None => {
444					values.push(IdentityId::default());
445					bitvec.push(false);
446					has_none = true;
447				}
448			}
449		}
450
451		let inner = ColumnData::IdentityId(IdentityIdContainer::from_vec(values));
452		if has_none {
453			ColumnData::Option {
454				inner: Box::new(inner),
455				bitvec: BitVec::from(bitvec),
456			}
457		} else {
458			inner
459		}
460	}
461
462	pub fn identity_id_with_capacity(capacity: usize) -> Self {
463		ColumnData::IdentityId(IdentityIdContainer::with_capacity(capacity))
464	}
465
466	pub fn identity_id_with_bitvec(
467		identity_ids: impl IntoIterator<Item = IdentityId>,
468		bitvec: impl Into<BitVec>,
469	) -> Self {
470		let data = identity_ids.into_iter().collect::<Vec<_>>();
471		let bitvec = bitvec.into();
472		assert_eq!(bitvec.len(), data.len());
473		let inner = ColumnData::IdentityId(IdentityIdContainer::from_vec(data));
474		if bitvec.all_ones() {
475			inner
476		} else {
477			ColumnData::Option {
478				inner: Box::new(inner),
479				bitvec,
480			}
481		}
482	}
483
484	pub fn int(data: impl IntoIterator<Item = Int>) -> Self {
485		use reifydb_type::value::constraint::bytes::MaxBytes;
486		let data = data.into_iter().collect::<Vec<_>>();
487		ColumnData::Int {
488			container: NumberContainer::from_vec(data),
489			max_bytes: MaxBytes::MAX,
490		}
491	}
492
493	pub fn int_optional(data: impl IntoIterator<Item = Option<Int>>) -> Self {
494		use reifydb_type::value::constraint::bytes::MaxBytes;
495		let mut values = Vec::new();
496		let mut bitvec = Vec::new();
497		let mut has_none = false;
498
499		for opt in data {
500			match opt {
501				Some(value) => {
502					values.push(value);
503					bitvec.push(true);
504				}
505				None => {
506					values.push(Int::default());
507					bitvec.push(false);
508					has_none = true;
509				}
510			}
511		}
512
513		let inner = ColumnData::Int {
514			container: NumberContainer::from_vec(values),
515			max_bytes: MaxBytes::MAX,
516		};
517		if has_none {
518			ColumnData::Option {
519				inner: Box::new(inner),
520				bitvec: BitVec::from(bitvec),
521			}
522		} else {
523			inner
524		}
525	}
526
527	pub fn uint(data: impl IntoIterator<Item = Uint>) -> Self {
528		use reifydb_type::value::constraint::bytes::MaxBytes;
529		let data = data.into_iter().collect::<Vec<_>>();
530		ColumnData::Uint {
531			container: NumberContainer::from_vec(data),
532			max_bytes: MaxBytes::MAX,
533		}
534	}
535
536	pub fn uint_optional(data: impl IntoIterator<Item = Option<Uint>>) -> Self {
537		use reifydb_type::value::constraint::bytes::MaxBytes;
538		let mut values = Vec::new();
539		let mut bitvec = Vec::new();
540		let mut has_none = false;
541
542		for opt in data {
543			match opt {
544				Some(value) => {
545					values.push(value);
546					bitvec.push(true);
547				}
548				None => {
549					values.push(Uint::default());
550					bitvec.push(false);
551					has_none = true;
552				}
553			}
554		}
555
556		let inner = ColumnData::Uint {
557			container: NumberContainer::from_vec(values),
558			max_bytes: MaxBytes::MAX,
559		};
560		if has_none {
561			ColumnData::Option {
562				inner: Box::new(inner),
563				bitvec: BitVec::from(bitvec),
564			}
565		} else {
566			inner
567		}
568	}
569
570	pub fn int_with_capacity(capacity: usize) -> Self {
571		use reifydb_type::value::constraint::bytes::MaxBytes;
572		ColumnData::Int {
573			container: NumberContainer::with_capacity(capacity),
574			max_bytes: MaxBytes::MAX,
575		}
576	}
577
578	pub fn uint_with_capacity(capacity: usize) -> Self {
579		use reifydb_type::value::constraint::bytes::MaxBytes;
580		ColumnData::Uint {
581			container: NumberContainer::with_capacity(capacity),
582			max_bytes: MaxBytes::MAX,
583		}
584	}
585
586	pub fn int_with_bitvec(data: impl IntoIterator<Item = Int>, bitvec: impl Into<BitVec>) -> Self {
587		use reifydb_type::value::constraint::bytes::MaxBytes;
588		let data = data.into_iter().collect::<Vec<_>>();
589		let bitvec = bitvec.into();
590		assert_eq!(bitvec.len(), data.len());
591		let inner = ColumnData::Int {
592			container: NumberContainer::from_vec(data),
593			max_bytes: MaxBytes::MAX,
594		};
595		if bitvec.all_ones() {
596			inner
597		} else {
598			ColumnData::Option {
599				inner: Box::new(inner),
600				bitvec,
601			}
602		}
603	}
604
605	pub fn uint_with_bitvec(data: impl IntoIterator<Item = Uint>, bitvec: impl Into<BitVec>) -> Self {
606		use reifydb_type::value::constraint::bytes::MaxBytes;
607		let data = data.into_iter().collect::<Vec<_>>();
608		let bitvec = bitvec.into();
609		assert_eq!(bitvec.len(), data.len());
610		let inner = ColumnData::Uint {
611			container: NumberContainer::from_vec(data),
612			max_bytes: MaxBytes::MAX,
613		};
614		if bitvec.all_ones() {
615			inner
616		} else {
617			ColumnData::Option {
618				inner: Box::new(inner),
619				bitvec,
620			}
621		}
622	}
623
624	pub fn decimal(data: impl IntoIterator<Item = Decimal>) -> Self {
625		use reifydb_type::value::constraint::{precision::Precision, scale::Scale};
626		let data = data.into_iter().collect::<Vec<_>>();
627		ColumnData::Decimal {
628			container: NumberContainer::from_vec(data),
629			precision: Precision::MAX,
630			scale: Scale::new(0),
631		}
632	}
633
634	pub fn decimal_optional(data: impl IntoIterator<Item = Option<Decimal>>) -> Self {
635		use reifydb_type::value::constraint::{precision::Precision, scale::Scale};
636		let mut values = Vec::new();
637		let mut bitvec = Vec::new();
638		let mut has_none = false;
639
640		for opt in data {
641			match opt {
642				Some(value) => {
643					values.push(value);
644					bitvec.push(true);
645				}
646				None => {
647					values.push(Decimal::default());
648					bitvec.push(false);
649					has_none = true;
650				}
651			}
652		}
653
654		let inner = ColumnData::Decimal {
655			container: NumberContainer::from_vec(values),
656			precision: Precision::MAX,
657			scale: Scale::new(0),
658		};
659		if has_none {
660			ColumnData::Option {
661				inner: Box::new(inner),
662				bitvec: BitVec::from(bitvec),
663			}
664		} else {
665			inner
666		}
667	}
668
669	pub fn decimal_with_capacity(capacity: usize) -> Self {
670		use reifydb_type::value::constraint::{precision::Precision, scale::Scale};
671		ColumnData::Decimal {
672			container: NumberContainer::with_capacity(capacity),
673			precision: Precision::MAX,
674			scale: Scale::new(0),
675		}
676	}
677
678	pub fn decimal_with_bitvec(data: impl IntoIterator<Item = Decimal>, bitvec: impl Into<BitVec>) -> Self {
679		use reifydb_type::value::constraint::{precision::Precision, scale::Scale};
680		let data = data.into_iter().collect::<Vec<_>>();
681		let bitvec = bitvec.into();
682		assert_eq!(bitvec.len(), data.len());
683		let inner = ColumnData::Decimal {
684			container: NumberContainer::from_vec(data),
685			precision: Precision::MAX,
686			scale: Scale::new(0),
687		};
688		if bitvec.all_ones() {
689			inner
690		} else {
691			ColumnData::Option {
692				inner: Box::new(inner),
693				bitvec,
694			}
695		}
696	}
697
698	pub fn any(data: impl IntoIterator<Item = Box<reifydb_type::value::Value>>) -> Self {
699		let data = data.into_iter().collect::<Vec<_>>();
700		ColumnData::Any(AnyContainer::from_vec(data))
701	}
702
703	pub fn any_optional(data: impl IntoIterator<Item = Option<Box<reifydb_type::value::Value>>>) -> Self {
704		let mut values = Vec::new();
705		let mut bitvec = Vec::new();
706		let mut has_none = false;
707
708		for opt in data {
709			match opt {
710				Some(value) => {
711					values.push(value);
712					bitvec.push(true);
713				}
714				None => {
715					values.push(Box::new(reifydb_type::value::Value::none()));
716					bitvec.push(false);
717					has_none = true;
718				}
719			}
720		}
721
722		let inner = ColumnData::Any(AnyContainer::from_vec(values));
723		if has_none {
724			ColumnData::Option {
725				inner: Box::new(inner),
726				bitvec: BitVec::from(bitvec),
727			}
728		} else {
729			inner
730		}
731	}
732
733	pub fn any_with_capacity(capacity: usize) -> Self {
734		ColumnData::Any(AnyContainer::with_capacity(capacity))
735	}
736
737	pub fn any_with_bitvec(
738		data: impl IntoIterator<Item = Box<reifydb_type::value::Value>>,
739		bitvec: impl Into<BitVec>,
740	) -> Self {
741		let data = data.into_iter().collect::<Vec<_>>();
742		let bitvec = bitvec.into();
743		assert_eq!(bitvec.len(), data.len());
744		let inner = ColumnData::Any(AnyContainer::from_vec(data));
745		if bitvec.all_ones() {
746			inner
747		} else {
748			ColumnData::Option {
749				inner: Box::new(inner),
750				bitvec,
751			}
752		}
753	}
754
755	pub fn dictionary_id(data: impl IntoIterator<Item = DictionaryEntryId>) -> Self {
756		let data = data.into_iter().collect::<Vec<_>>();
757		ColumnData::DictionaryId(DictionaryContainer::from_vec(data))
758	}
759
760	pub fn dictionary_id_optional(data: impl IntoIterator<Item = Option<DictionaryEntryId>>) -> Self {
761		let mut values = Vec::new();
762		let mut bitvec = Vec::new();
763		let mut has_none = false;
764
765		for opt in data {
766			match opt {
767				Some(value) => {
768					values.push(value);
769					bitvec.push(true);
770				}
771				None => {
772					values.push(DictionaryEntryId::default());
773					bitvec.push(false);
774					has_none = true;
775				}
776			}
777		}
778
779		let inner = ColumnData::DictionaryId(DictionaryContainer::from_vec(values));
780		if has_none {
781			ColumnData::Option {
782				inner: Box::new(inner),
783				bitvec: BitVec::from(bitvec),
784			}
785		} else {
786			inner
787		}
788	}
789
790	pub fn dictionary_id_with_capacity(capacity: usize) -> Self {
791		ColumnData::DictionaryId(DictionaryContainer::with_capacity(capacity))
792	}
793
794	pub fn dictionary_id_with_bitvec(
795		data: impl IntoIterator<Item = DictionaryEntryId>,
796		bitvec: impl Into<BitVec>,
797	) -> Self {
798		let data = data.into_iter().collect::<Vec<_>>();
799		let bitvec = bitvec.into();
800		assert_eq!(bitvec.len(), data.len());
801		let inner = ColumnData::DictionaryId(DictionaryContainer::from_vec(data));
802		if bitvec.all_ones() {
803			inner
804		} else {
805			ColumnData::Option {
806				inner: Box::new(inner),
807				bitvec,
808			}
809		}
810	}
811
812	/// Create a single-element None of the given type (bitvec=[false]).
813	/// This preserves the column type so comparisons
814	/// see the correct inner type rather than `Option<Boolean>`.
815	pub fn typed_none(ty: &Type) -> Self {
816		match ty {
817			Type::Option(inner) => Self::typed_none(inner),
818			_ => Self::none_typed(ty.clone(), 1),
819		}
820	}
821
822	/// Create typed column data with all none values (bitvec all false).
823	/// Always returns an Option-wrapped column to avoid the *_with_bitvec
824	/// optimization that strips the Option wrapper when the bitvec is all-ones
825	/// (which is vacuously true for empty bitvecs).
826	pub fn none_typed(ty: Type, len: usize) -> Self {
827		let bitvec = BitVec::repeat(len, false);
828		let inner = match ty {
829			Type::Boolean => Self::bool(vec![false; len]),
830			Type::Float4 => Self::float4(vec![0.0f32; len]),
831			Type::Float8 => Self::float8(vec![0.0f64; len]),
832			Type::Int1 => Self::int1(vec![0i8; len]),
833			Type::Int2 => Self::int2(vec![0i16; len]),
834			Type::Int4 => Self::int4(vec![0i32; len]),
835			Type::Int8 => Self::int8(vec![0i64; len]),
836			Type::Int16 => Self::int16(vec![0i128; len]),
837			Type::Utf8 => Self::utf8(vec![String::new(); len]),
838			Type::Uint1 => Self::uint1(vec![0u8; len]),
839			Type::Uint2 => Self::uint2(vec![0u16; len]),
840			Type::Uint4 => Self::uint4(vec![0u32; len]),
841			Type::Uint8 => Self::uint8(vec![0u64; len]),
842			Type::Uint16 => Self::uint16(vec![0u128; len]),
843			Type::Date => Self::date(vec![Date::default(); len]),
844			Type::DateTime => Self::datetime(vec![DateTime::default(); len]),
845			Type::Time => Self::time(vec![Time::default(); len]),
846			Type::Duration => Self::duration(vec![Duration::default(); len]),
847			Type::Blob => Self::blob(vec![Blob::new(vec![]); len]),
848			Type::Uuid4 => Self::uuid4(vec![Uuid4::default(); len]),
849			Type::Uuid7 => Self::uuid7(vec![Uuid7::default(); len]),
850			Type::IdentityId => Self::identity_id(vec![IdentityId::default(); len]),
851			Type::Int => Self::int(vec![Int::default(); len]),
852			Type::Uint => Self::uint(vec![Uint::default(); len]),
853			Type::Decimal {
854				..
855			} => Self::decimal(vec![Decimal::from(0); len]),
856			Type::Any => Self::any(vec![Box::new(reifydb_type::value::Value::none()); len]),
857			Type::DictionaryId => Self::dictionary_id(vec![DictionaryEntryId::default(); len]),
858			Type::Option(inner) => return Self::none_typed(*inner, len),
859		};
860		ColumnData::Option {
861			inner: Box::new(inner),
862			bitvec,
863		}
864	}
865}