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