Skip to main content

reifydb_core/value/column/push/
value.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use reifydb_value::{
5	util::bitvec::BitVec,
6	value::{
7		Value,
8		blob::Blob,
9		date::Date,
10		datetime::DateTime,
11		decimal::Decimal,
12		dictionary::DictionaryEntryId,
13		duration::Duration,
14		identity::IdentityId,
15		int::Int,
16		time::Time,
17		uint::Uint,
18		uuid::{Uuid4, Uuid7},
19	},
20};
21
22use crate::value::column::buffer::{ColumnBuffer, with_container};
23
24macro_rules! push_or_promote {
25	(@wrap_option $self:expr, $new_col:expr, $len:expr) => {
26		if $len > 0 {
27			let mut bitvec = BitVec::repeat($len, false);
28			bitvec.push(true);
29			*$self = ColumnBuffer::Option {
30				inner: Box::new($new_col),
31				bitvec,
32			};
33		} else {
34			*$self = $new_col;
35		}
36	};
37
38	($self:expr, $val:expr, $col_variant:ident, $factory_expr:expr) => {
39		match $self {
40			ColumnBuffer::$col_variant(_) => $self.push($val),
41			_ => unimplemented!(),
42		}
43	};
44
45	(struct $self:expr, $val:expr, $col_variant:ident, $factory_expr:expr) => {
46		match $self {
47			ColumnBuffer::$col_variant {
48				..
49			} => $self.push($val),
50			_ => unimplemented!(),
51		}
52	};
53
54	(direct $self:expr, $val:expr, $col_variant:ident, $factory_expr:expr) => {
55		match $self {
56			ColumnBuffer::$col_variant(container) => container.push($val),
57			_ => unimplemented!(),
58		}
59	};
60
61	(struct_direct $self:expr, $val:expr, $col_variant:ident, $factory_expr:expr) => {
62		match $self {
63			ColumnBuffer::$col_variant {
64				container,
65				..
66			} => container.push($val),
67			_ => unimplemented!(),
68		}
69	};
70}
71
72impl ColumnBuffer {
73	pub fn push_value(&mut self, value: Value) {
74		if let ColumnBuffer::Option {
75			inner,
76			bitvec,
77		} = self
78		{
79			if matches!(value, Value::None { .. }) {
80				with_container!(inner.as_mut(), |c| c.push_default());
81				bitvec.push(false);
82			} else if bitvec.count_ones() == 0 {
83				let len = inner.len();
84
85				let mut new_inner = match &value {
86					Value::Boolean(_) => ColumnBuffer::bool(vec![false; len]),
87					Value::Float4(_) => ColumnBuffer::float4(vec![0.0f32; len]),
88					Value::Float8(_) => ColumnBuffer::float8(vec![0.0f64; len]),
89					Value::Int1(_) => ColumnBuffer::int1(vec![0i8; len]),
90					Value::Int2(_) => ColumnBuffer::int2(vec![0i16; len]),
91					Value::Int4(_) => ColumnBuffer::int4(vec![0i32; len]),
92					Value::Int8(_) => ColumnBuffer::int8(vec![0i64; len]),
93					Value::Int16(_) => ColumnBuffer::int16(vec![0i128; len]),
94					Value::Uint1(_) => ColumnBuffer::uint1(vec![0u8; len]),
95					Value::Uint2(_) => ColumnBuffer::uint2(vec![0u16; len]),
96					Value::Uint4(_) => ColumnBuffer::uint4(vec![0u32; len]),
97					Value::Uint8(_) => ColumnBuffer::uint8(vec![0u64; len]),
98					Value::Uint16(_) => ColumnBuffer::uint16(vec![0u128; len]),
99					Value::Utf8(_) => ColumnBuffer::utf8(vec![String::new(); len]),
100					Value::Date(_) => ColumnBuffer::date(vec![Date::default(); len]),
101					Value::DateTime(_) => ColumnBuffer::datetime(vec![DateTime::default(); len]),
102					Value::Time(_) => ColumnBuffer::time(vec![Time::default(); len]),
103					Value::Duration(_) => ColumnBuffer::duration(vec![Duration::default(); len]),
104					Value::Uuid4(_) => ColumnBuffer::uuid4(vec![Uuid4::default(); len]),
105					Value::Uuid7(_) => ColumnBuffer::uuid7(vec![Uuid7::default(); len]),
106					Value::IdentityId(_) => {
107						ColumnBuffer::identity_id(vec![IdentityId::default(); len])
108					}
109					Value::DictionaryId(_) => {
110						ColumnBuffer::dictionary_id(vec![DictionaryEntryId::default(); len])
111					}
112					Value::Blob(_) => ColumnBuffer::blob(vec![Blob::default(); len]),
113					Value::Int(_) => ColumnBuffer::int(vec![Int::default(); len]),
114					Value::Uint(_) => ColumnBuffer::uint(vec![Uint::default(); len]),
115					Value::Decimal(_) => ColumnBuffer::decimal(vec![Decimal::default(); len]),
116					Value::Any(_) => ColumnBuffer::any(vec![Value::none(); len]),
117					Value::Record(_) => ColumnBuffer::any(vec![Value::none(); len]),
118					Value::Tuple(_) => ColumnBuffer::any(vec![Value::none(); len]),
119					Value::List(_) => ColumnBuffer::any(vec![Value::none(); len]),
120					Value::Type(_) => ColumnBuffer::any(vec![Value::none(); len]),
121					_ => unreachable!(),
122				};
123				new_inner.push_value(value);
124				if len > 0 {
125					let mut new_bitvec = BitVec::repeat(len, false);
126					new_bitvec.push(true);
127					*self = ColumnBuffer::Option {
128						inner: Box::new(new_inner),
129						bitvec: new_bitvec,
130					};
131				} else {
132					*self = new_inner;
133				}
134			} else {
135				inner.push_value(value);
136				bitvec.push(true);
137			}
138			return;
139		}
140		match value {
141			Value::Boolean(v) => push_or_promote!(self, v, Bool, ColumnBuffer::bool(vec![])),
142			Value::Float4(v) => push_or_promote!(self, v.value(), Float4, ColumnBuffer::float4(vec![])),
143			Value::Float8(v) => push_or_promote!(self, v.value(), Float8, ColumnBuffer::float8(vec![])),
144			Value::Int1(v) => push_or_promote!(self, v, Int1, ColumnBuffer::int1(vec![])),
145			Value::Int2(v) => push_or_promote!(self, v, Int2, ColumnBuffer::int2(vec![])),
146			Value::Int4(v) => push_or_promote!(self, v, Int4, ColumnBuffer::int4(vec![])),
147			Value::Int8(v) => push_or_promote!(self, v, Int8, ColumnBuffer::int8(vec![])),
148			Value::Int16(v) => push_or_promote!(self, v, Int16, ColumnBuffer::int16(vec![])),
149			Value::Uint1(v) => push_or_promote!(self, v, Uint1, ColumnBuffer::uint1(vec![])),
150			Value::Uint2(v) => push_or_promote!(self, v, Uint2, ColumnBuffer::uint2(vec![])),
151			Value::Uint4(v) => push_or_promote!(self, v, Uint4, ColumnBuffer::uint4(vec![])),
152			Value::Uint8(v) => push_or_promote!(self, v, Uint8, ColumnBuffer::uint8(vec![])),
153			Value::Uint16(v) => push_or_promote!(self, v, Uint16, ColumnBuffer::uint16(vec![])),
154			Value::Utf8(v) => {
155				push_or_promote!(struct self, v, Utf8, ColumnBuffer::utf8(Vec::<String>::new()))
156			}
157			Value::Date(v) => push_or_promote!(self, v, Date, ColumnBuffer::date(vec![])),
158			Value::DateTime(v) => push_or_promote!(self, v, DateTime, ColumnBuffer::datetime(vec![])),
159			Value::Time(v) => push_or_promote!(self, v, Time, ColumnBuffer::time(vec![])),
160			Value::Duration(v) => push_or_promote!(self, v, Duration, ColumnBuffer::duration(vec![])),
161			Value::Uuid4(v) => push_or_promote!(self, v, Uuid4, ColumnBuffer::uuid4(vec![])),
162			Value::Uuid7(v) => push_or_promote!(self, v, Uuid7, ColumnBuffer::uuid7(vec![])),
163			Value::IdentityId(v) => {
164				push_or_promote!(direct self, v, IdentityId, ColumnBuffer::identity_id(vec![]))
165			}
166			Value::DictionaryId(v) => {
167				push_or_promote!(direct self, v, DictionaryId, ColumnBuffer::dictionary_id(vec![]))
168			}
169			Value::Blob(v) => push_or_promote!(struct_direct self, v, Blob, ColumnBuffer::blob(vec![])),
170			Value::Int(v) => push_or_promote!(struct_direct self, v, Int, ColumnBuffer::int(vec![])),
171			Value::Uint(v) => push_or_promote!(struct_direct self, v, Uint, ColumnBuffer::uint(vec![])),
172			Value::Decimal(v) => {
173				push_or_promote!(struct_direct self, v, Decimal, ColumnBuffer::decimal(vec![]))
174			}
175			Value::None {
176				..
177			} => self.push_none(),
178			Value::Type(t) => self.push_value(Value::Any(Box::new(Value::Type(t)))),
179			Value::List(v) => self.push_value(Value::Any(Box::new(Value::List(v)))),
180			Value::Record(v) => self.push_value(Value::Any(Box::new(Value::Record(v)))),
181			Value::Tuple(v) => self.push_value(Value::Any(Box::new(Value::Tuple(v)))),
182			Value::Any(v) => match self {
183				ColumnBuffer::Any(container) => container.push(*v),
184				_ => unreachable!("Cannot push Any value to non-Any column"),
185			},
186		}
187	}
188}
189
190#[cfg(test)]
191#[allow(clippy::approx_constant)]
192pub mod tests {
193	use reifydb_runtime::context::{
194		clock::{Clock, MockClock},
195		rng::Rng,
196	};
197	use reifydb_value::value::{
198		Value,
199		date::Date,
200		datetime::DateTime,
201		dictionary::DictionaryEntryId,
202		duration::Duration,
203		identity::IdentityId,
204		ordered_f32::OrderedF32,
205		ordered_f64::OrderedF64,
206		time::Time,
207		uuid::{Uuid4, Uuid7},
208		value_type::ValueType,
209	};
210
211	use crate::value::column::ColumnBuffer;
212
213	fn test_clock_and_rng() -> (MockClock, Clock, Rng) {
214		let mock = MockClock::from_millis(1000);
215		let clock = Clock::Mock(mock.clone());
216		let rng = Rng::seeded(42);
217		(mock, clock, rng)
218	}
219
220	#[test]
221	fn test_bool() {
222		let mut col = ColumnBuffer::bool(vec![true]);
223		col.push_value(Value::Boolean(false));
224		let ColumnBuffer::Bool(container) = col else {
225			panic!("Expected Bool");
226		};
227		assert_eq!(container.data().to_vec(), vec![true, false]);
228	}
229
230	#[test]
231	fn test_undefined_bool() {
232		let mut col = ColumnBuffer::bool(vec![true]);
233		col.push_value(Value::none());
234		// Pushing none promotes the bare column to Option-wrapped.
235		assert_eq!(col.len(), 2);
236		assert!(col.is_defined(0));
237		assert!(!col.is_defined(1));
238	}
239
240	#[test]
241	fn test_push_value_to_none_bool() {
242		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 2);
243		col.push_value(Value::Boolean(true));
244		assert_eq!(col.len(), 3);
245		assert!(!col.is_defined(0));
246		assert!(!col.is_defined(1));
247		assert!(col.is_defined(2));
248		assert_eq!(col.get_value(2), Value::Boolean(true));
249	}
250
251	#[test]
252	fn test_float4() {
253		let mut col = ColumnBuffer::float4(vec![1.0]);
254		col.push_value(Value::Float4(OrderedF32::try_from(2.0).unwrap()));
255		let ColumnBuffer::Float4(container) = col else {
256			panic!("Expected Float4");
257		};
258		assert_eq!(container.data().as_slice(), &[1.0, 2.0]);
259	}
260
261	#[test]
262	fn test_undefined_float4() {
263		let mut col = ColumnBuffer::float4(vec![1.0]);
264		col.push_value(Value::none());
265		assert_eq!(col.len(), 2);
266		assert!(col.is_defined(0));
267		assert!(!col.is_defined(1));
268	}
269
270	#[test]
271	fn test_push_value_to_none_float4() {
272		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
273		col.push_value(Value::Float4(OrderedF32::try_from(3.14).unwrap()));
274		assert_eq!(col.len(), 2);
275		assert!(!col.is_defined(0));
276		assert!(col.is_defined(1));
277	}
278
279	#[test]
280	fn test_float8() {
281		let mut col = ColumnBuffer::float8(vec![1.0]);
282		col.push_value(Value::Float8(OrderedF64::try_from(2.0).unwrap()));
283		let ColumnBuffer::Float8(container) = col else {
284			panic!("Expected Float8");
285		};
286		assert_eq!(container.data().as_slice(), &[1.0, 2.0]);
287	}
288
289	#[test]
290	fn test_undefined_float8() {
291		let mut col = ColumnBuffer::float8(vec![1.0]);
292		col.push_value(Value::none());
293		assert_eq!(col.len(), 2);
294		assert!(col.is_defined(0));
295		assert!(!col.is_defined(1));
296	}
297
298	#[test]
299	fn test_push_value_to_none_float8() {
300		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
301		col.push_value(Value::Float8(OrderedF64::try_from(2.718).unwrap()));
302		assert_eq!(col.len(), 2);
303		assert!(!col.is_defined(0));
304		assert!(col.is_defined(1));
305	}
306
307	#[test]
308	fn test_int1() {
309		let mut col = ColumnBuffer::int1(vec![1]);
310		col.push_value(Value::Int1(2));
311		let ColumnBuffer::Int1(container) = col else {
312			panic!("Expected Int1");
313		};
314		assert_eq!(container.data().as_slice(), &[1, 2]);
315	}
316
317	#[test]
318	fn test_undefined_int1() {
319		let mut col = ColumnBuffer::int1(vec![1]);
320		col.push_value(Value::none());
321		assert_eq!(col.len(), 2);
322		assert!(col.is_defined(0));
323		assert!(!col.is_defined(1));
324	}
325
326	#[test]
327	fn test_push_value_to_none_int1() {
328		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
329		col.push_value(Value::Int1(5));
330		assert_eq!(col.len(), 2);
331		assert!(!col.is_defined(0));
332		assert!(col.is_defined(1));
333		assert_eq!(col.get_value(1), Value::Int1(5));
334	}
335
336	#[test]
337	fn test_int2() {
338		let mut col = ColumnBuffer::int2(vec![1]);
339		col.push_value(Value::Int2(3));
340		let ColumnBuffer::Int2(container) = col else {
341			panic!("Expected Int2");
342		};
343		assert_eq!(container.data().as_slice(), &[1, 3]);
344	}
345
346	#[test]
347	fn test_undefined_int2() {
348		let mut col = ColumnBuffer::int2(vec![1]);
349		col.push_value(Value::none());
350		assert_eq!(col.len(), 2);
351		assert!(col.is_defined(0));
352		assert!(!col.is_defined(1));
353	}
354
355	#[test]
356	fn test_push_value_to_none_int2() {
357		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
358		col.push_value(Value::Int2(10));
359		assert_eq!(col.len(), 2);
360		assert!(!col.is_defined(0));
361		assert!(col.is_defined(1));
362		assert_eq!(col.get_value(1), Value::Int2(10));
363	}
364
365	#[test]
366	fn test_int4() {
367		let mut col = ColumnBuffer::int4(vec![10]);
368		col.push_value(Value::Int4(20));
369		let ColumnBuffer::Int4(container) = col else {
370			panic!("Expected Int4");
371		};
372		assert_eq!(container.data().as_slice(), &[10, 20]);
373	}
374
375	#[test]
376	fn test_undefined_int4() {
377		let mut col = ColumnBuffer::int4(vec![10]);
378		col.push_value(Value::none());
379		assert_eq!(col.len(), 2);
380		assert!(col.is_defined(0));
381		assert!(!col.is_defined(1));
382	}
383
384	#[test]
385	fn test_push_value_to_none_int4() {
386		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
387		col.push_value(Value::Int4(20));
388		assert_eq!(col.len(), 2);
389		assert!(!col.is_defined(0));
390		assert!(col.is_defined(1));
391		assert_eq!(col.get_value(1), Value::Int4(20));
392	}
393
394	#[test]
395	fn test_int8() {
396		let mut col = ColumnBuffer::int8(vec![100]);
397		col.push_value(Value::Int8(200));
398		let ColumnBuffer::Int8(container) = col else {
399			panic!("Expected Int8");
400		};
401		assert_eq!(container.data().as_slice(), &[100, 200]);
402	}
403
404	#[test]
405	fn test_undefined_int8() {
406		let mut col = ColumnBuffer::int8(vec![100]);
407		col.push_value(Value::none());
408		assert_eq!(col.len(), 2);
409		assert!(col.is_defined(0));
410		assert!(!col.is_defined(1));
411	}
412
413	#[test]
414	fn test_push_value_to_none_int8() {
415		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
416		col.push_value(Value::Int8(30));
417		assert_eq!(col.len(), 2);
418		assert!(!col.is_defined(0));
419		assert!(col.is_defined(1));
420		assert_eq!(col.get_value(1), Value::Int8(30));
421	}
422
423	#[test]
424	fn test_int16() {
425		let mut col = ColumnBuffer::int16(vec![1000]);
426		col.push_value(Value::Int16(2000));
427		let ColumnBuffer::Int16(container) = col else {
428			panic!("Expected Int16");
429		};
430		assert_eq!(container.data().as_slice(), &[1000, 2000]);
431	}
432
433	#[test]
434	fn test_undefined_int16() {
435		let mut col = ColumnBuffer::int16(vec![1000]);
436		col.push_value(Value::none());
437		assert_eq!(col.len(), 2);
438		assert!(col.is_defined(0));
439		assert!(!col.is_defined(1));
440	}
441
442	#[test]
443	fn test_push_value_to_none_int16() {
444		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
445		col.push_value(Value::Int16(40));
446		assert_eq!(col.len(), 2);
447		assert!(!col.is_defined(0));
448		assert!(col.is_defined(1));
449		assert_eq!(col.get_value(1), Value::Int16(40));
450	}
451
452	#[test]
453	fn test_uint1() {
454		let mut col = ColumnBuffer::uint1(vec![1]);
455		col.push_value(Value::Uint1(2));
456		let ColumnBuffer::Uint1(container) = col else {
457			panic!("Expected Uint1");
458		};
459		assert_eq!(container.data().as_slice(), &[1, 2]);
460	}
461
462	#[test]
463	fn test_undefined_uint1() {
464		let mut col = ColumnBuffer::uint1(vec![1]);
465		col.push_value(Value::none());
466		assert_eq!(col.len(), 2);
467		assert!(col.is_defined(0));
468		assert!(!col.is_defined(1));
469	}
470
471	#[test]
472	fn test_push_value_to_none_uint1() {
473		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
474		col.push_value(Value::Uint1(1));
475		assert_eq!(col.len(), 2);
476		assert!(!col.is_defined(0));
477		assert!(col.is_defined(1));
478		assert_eq!(col.get_value(1), Value::Uint1(1));
479	}
480
481	#[test]
482	fn test_uint2() {
483		let mut col = ColumnBuffer::uint2(vec![10]);
484		col.push_value(Value::Uint2(20));
485		let ColumnBuffer::Uint2(container) = col else {
486			panic!("Expected Uint2");
487		};
488		assert_eq!(container.data().as_slice(), &[10, 20]);
489	}
490
491	#[test]
492	fn test_undefined_uint2() {
493		let mut col = ColumnBuffer::uint2(vec![10]);
494		col.push_value(Value::none());
495		assert_eq!(col.len(), 2);
496		assert!(col.is_defined(0));
497		assert!(!col.is_defined(1));
498	}
499
500	#[test]
501	fn test_push_value_to_none_uint2() {
502		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
503		col.push_value(Value::Uint2(2));
504		assert_eq!(col.len(), 2);
505		assert!(!col.is_defined(0));
506		assert!(col.is_defined(1));
507		assert_eq!(col.get_value(1), Value::Uint2(2));
508	}
509
510	#[test]
511	fn test_uint4() {
512		let mut col = ColumnBuffer::uint4(vec![100]);
513		col.push_value(Value::Uint4(200));
514		let ColumnBuffer::Uint4(container) = col else {
515			panic!("Expected Uint4");
516		};
517		assert_eq!(container.data().as_slice(), &[100, 200]);
518	}
519
520	#[test]
521	fn test_undefined_uint4() {
522		let mut col = ColumnBuffer::uint4(vec![100]);
523		col.push_value(Value::none());
524		assert_eq!(col.len(), 2);
525		assert!(col.is_defined(0));
526		assert!(!col.is_defined(1));
527	}
528
529	#[test]
530	fn test_push_value_to_none_uint4() {
531		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
532		col.push_value(Value::Uint4(3));
533		assert_eq!(col.len(), 2);
534		assert!(!col.is_defined(0));
535		assert!(col.is_defined(1));
536		assert_eq!(col.get_value(1), Value::Uint4(3));
537	}
538
539	#[test]
540	fn test_uint8() {
541		let mut col = ColumnBuffer::uint8(vec![1000]);
542		col.push_value(Value::Uint8(2000));
543		let ColumnBuffer::Uint8(container) = col else {
544			panic!("Expected Uint8");
545		};
546		assert_eq!(container.data().as_slice(), &[1000, 2000]);
547	}
548
549	#[test]
550	fn test_undefined_uint8() {
551		let mut col = ColumnBuffer::uint8(vec![1000]);
552		col.push_value(Value::none());
553		assert_eq!(col.len(), 2);
554		assert!(col.is_defined(0));
555		assert!(!col.is_defined(1));
556	}
557
558	#[test]
559	fn test_push_value_to_none_uint8() {
560		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
561		col.push_value(Value::Uint8(4));
562		assert_eq!(col.len(), 2);
563		assert!(!col.is_defined(0));
564		assert!(col.is_defined(1));
565		assert_eq!(col.get_value(1), Value::Uint8(4));
566	}
567
568	#[test]
569	fn test_uint16() {
570		let mut col = ColumnBuffer::uint16(vec![10000]);
571		col.push_value(Value::Uint16(20000));
572		let ColumnBuffer::Uint16(container) = col else {
573			panic!("Expected Uint16");
574		};
575		assert_eq!(container.data().as_slice(), &[10000, 20000]);
576	}
577
578	#[test]
579	fn test_undefined_uint16() {
580		let mut col = ColumnBuffer::uint16(vec![10000]);
581		col.push_value(Value::none());
582		assert_eq!(col.len(), 2);
583		assert!(col.is_defined(0));
584		assert!(!col.is_defined(1));
585	}
586
587	#[test]
588	fn test_push_value_to_none_uint16() {
589		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
590		col.push_value(Value::Uint16(5));
591		assert_eq!(col.len(), 2);
592		assert!(!col.is_defined(0));
593		assert!(col.is_defined(1));
594		assert_eq!(col.get_value(1), Value::Uint16(5));
595	}
596
597	#[test]
598	fn test_utf8() {
599		let mut col = ColumnBuffer::utf8(vec!["hello".to_string()]);
600		col.push_value(Value::Utf8("world".to_string()));
601		let ColumnBuffer::Utf8 {
602			container,
603			..
604		} = col
605		else {
606			panic!("Expected Utf8");
607		};
608		let collected: Vec<&str> = container.iter_str().collect();
609		assert_eq!(collected, vec!["hello", "world"]);
610	}
611
612	#[test]
613	fn test_undefined_utf8() {
614		let mut col = ColumnBuffer::utf8(vec!["hello".to_string()]);
615		col.push_value(Value::none());
616		assert_eq!(col.len(), 2);
617		assert!(col.is_defined(0));
618		assert!(!col.is_defined(1));
619	}
620
621	#[test]
622	fn test_push_value_to_none_utf8() {
623		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
624		col.push_value(Value::Utf8("ok".to_string()));
625		assert_eq!(col.len(), 2);
626		assert!(!col.is_defined(0));
627		assert!(col.is_defined(1));
628		assert_eq!(col.get_value(1), Value::Utf8("ok".to_string()));
629	}
630
631	#[test]
632	fn test_undefined() {
633		let mut col = ColumnBuffer::int2(vec![1]);
634		col.push_value(Value::none());
635		assert_eq!(col.len(), 2);
636		assert!(col.is_defined(0));
637		assert!(!col.is_defined(1));
638	}
639
640	#[test]
641	fn test_date() {
642		let date1 = Date::from_ymd(2023, 1, 1).unwrap();
643		let date2 = Date::from_ymd(2023, 12, 31).unwrap();
644		let mut col = ColumnBuffer::date(vec![date1]);
645		col.push_value(Value::Date(date2));
646		let ColumnBuffer::Date(container) = col else {
647			panic!("Expected Date");
648		};
649		assert_eq!(container.data().as_slice(), &[date1, date2]);
650	}
651
652	#[test]
653	fn test_undefined_date() {
654		let date1 = Date::from_ymd(2023, 1, 1).unwrap();
655		let mut col = ColumnBuffer::date(vec![date1]);
656		col.push_value(Value::none());
657		assert_eq!(col.len(), 2);
658		assert!(col.is_defined(0));
659		assert!(!col.is_defined(1));
660	}
661
662	#[test]
663	fn test_push_value_to_none_date() {
664		let date = Date::from_ymd(2023, 6, 15).unwrap();
665		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
666		col.push_value(Value::Date(date));
667		assert_eq!(col.len(), 2);
668		assert!(!col.is_defined(0));
669		assert!(col.is_defined(1));
670		assert_eq!(col.get_value(1), Value::Date(date));
671	}
672
673	#[test]
674	fn test_datetime() {
675		let dt1 = DateTime::from_epoch_secs(1672531200).unwrap(); // 2023-01-01 00:00:00 SVTC
676		let dt2 = DateTime::from_epoch_secs(1704067200).unwrap(); // 2024-01-01 00:00:00 SVTC
677		let mut col = ColumnBuffer::datetime(vec![dt1]);
678		col.push_value(Value::DateTime(dt2));
679		let ColumnBuffer::DateTime(container) = col else {
680			panic!("Expected DateTime");
681		};
682		assert_eq!(container.data().as_slice(), &[dt1, dt2]);
683	}
684
685	#[test]
686	fn test_undefined_datetime() {
687		let dt1 = DateTime::from_epoch_secs(1672531200).unwrap();
688		let mut col = ColumnBuffer::datetime(vec![dt1]);
689		col.push_value(Value::none());
690		assert_eq!(col.len(), 2);
691		assert!(col.is_defined(0));
692		assert!(!col.is_defined(1));
693	}
694
695	#[test]
696	fn test_push_value_to_none_datetime() {
697		let dt = DateTime::from_epoch_secs(1672531200).unwrap();
698		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
699		col.push_value(Value::DateTime(dt));
700		assert_eq!(col.len(), 2);
701		assert!(!col.is_defined(0));
702		assert!(col.is_defined(1));
703		assert_eq!(col.get_value(1), Value::DateTime(dt));
704	}
705
706	#[test]
707	fn test_time() {
708		let time1 = Time::from_hms(12, 30, 0).unwrap();
709		let time2 = Time::from_hms(18, 45, 30).unwrap();
710		let mut col = ColumnBuffer::time(vec![time1]);
711		col.push_value(Value::Time(time2));
712		let ColumnBuffer::Time(container) = col else {
713			panic!("Expected Time");
714		};
715		assert_eq!(container.data().as_slice(), &[time1, time2]);
716	}
717
718	#[test]
719	fn test_undefined_time() {
720		let time1 = Time::from_hms(12, 30, 0).unwrap();
721		let mut col = ColumnBuffer::time(vec![time1]);
722		col.push_value(Value::none());
723		assert_eq!(col.len(), 2);
724		assert!(col.is_defined(0));
725		assert!(!col.is_defined(1));
726	}
727
728	#[test]
729	fn test_push_value_to_none_time() {
730		let time = Time::from_hms(15, 20, 10).unwrap();
731		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
732		col.push_value(Value::Time(time));
733		assert_eq!(col.len(), 2);
734		assert!(!col.is_defined(0));
735		assert!(col.is_defined(1));
736		assert_eq!(col.get_value(1), Value::Time(time));
737	}
738
739	#[test]
740	fn test_duration() {
741		let duration1 = Duration::from_days(30).unwrap();
742		let duration2 = Duration::from_hours(24).unwrap();
743		let mut col = ColumnBuffer::duration(vec![duration1]);
744		col.push_value(Value::Duration(duration2));
745		let ColumnBuffer::Duration(container) = col else {
746			panic!("Expected Duration");
747		};
748		assert_eq!(container.data().as_slice(), &[duration1, duration2]);
749	}
750
751	#[test]
752	fn test_undefined_duration() {
753		let duration1 = Duration::from_days(30).unwrap();
754		let mut col = ColumnBuffer::duration(vec![duration1]);
755		col.push_value(Value::none());
756		assert_eq!(col.len(), 2);
757		assert!(col.is_defined(0));
758		assert!(!col.is_defined(1));
759	}
760
761	#[test]
762	fn test_push_value_to_none_duration() {
763		let duration = Duration::from_minutes(90).unwrap();
764		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
765		col.push_value(Value::Duration(duration));
766		assert_eq!(col.len(), 2);
767		assert!(!col.is_defined(0));
768		assert!(col.is_defined(1));
769		assert_eq!(col.get_value(1), Value::Duration(duration));
770	}
771
772	#[test]
773	fn test_identity_id() {
774		let (mock, clock, rng) = test_clock_and_rng();
775		let id1 = IdentityId::generate(&clock, &rng);
776		mock.advance_millis(1);
777		let id2 = IdentityId::generate(&clock, &rng);
778		let mut col = ColumnBuffer::identity_id(vec![id1]);
779		col.push_value(Value::IdentityId(id2));
780		let ColumnBuffer::IdentityId(container) = col else {
781			panic!("Expected IdentityId");
782		};
783		assert_eq!(container.data().as_slice(), &[id1, id2]);
784	}
785
786	#[test]
787	fn test_undefined_identity_id() {
788		let (_, clock, rng) = test_clock_and_rng();
789		let id1 = IdentityId::generate(&clock, &rng);
790		let mut col = ColumnBuffer::identity_id(vec![id1]);
791		col.push_value(Value::none());
792		assert_eq!(col.len(), 2);
793		assert!(col.is_defined(0));
794		assert!(!col.is_defined(1));
795	}
796
797	#[test]
798	fn test_push_value_to_none_identity_id() {
799		let (_, clock, rng) = test_clock_and_rng();
800		let id = IdentityId::generate(&clock, &rng);
801		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
802		col.push_value(Value::IdentityId(id));
803		assert_eq!(col.len(), 2);
804		assert!(!col.is_defined(0));
805		assert!(col.is_defined(1));
806		assert_eq!(col.get_value(1), Value::IdentityId(id));
807	}
808
809	#[test]
810	fn test_uuid4() {
811		let uuid1 = Uuid4::generate();
812		let uuid2 = Uuid4::generate();
813		let mut col = ColumnBuffer::uuid4(vec![uuid1]);
814		col.push_value(Value::Uuid4(uuid2));
815		let ColumnBuffer::Uuid4(container) = col else {
816			panic!("Expected Uuid4");
817		};
818		assert_eq!(container.data().as_slice(), &[uuid1, uuid2]);
819	}
820
821	#[test]
822	fn test_undefined_uuid4() {
823		let uuid1 = Uuid4::generate();
824		let mut col = ColumnBuffer::uuid4(vec![uuid1]);
825		col.push_value(Value::none());
826		assert_eq!(col.len(), 2);
827		assert!(col.is_defined(0));
828		assert!(!col.is_defined(1));
829	}
830
831	#[test]
832	fn test_push_value_to_none_uuid4() {
833		let uuid = Uuid4::generate();
834		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
835		col.push_value(Value::Uuid4(uuid));
836		assert_eq!(col.len(), 2);
837		assert!(!col.is_defined(0));
838		assert!(col.is_defined(1));
839		assert_eq!(col.get_value(1), Value::Uuid4(uuid));
840	}
841
842	#[test]
843	fn test_uuid7() {
844		let (mock, clock, rng) = test_clock_and_rng();
845		let uuid1 = Uuid7::generate(&clock, &rng);
846		mock.advance_millis(1);
847		let uuid2 = Uuid7::generate(&clock, &rng);
848		let mut col = ColumnBuffer::uuid7(vec![uuid1]);
849		col.push_value(Value::Uuid7(uuid2));
850		let ColumnBuffer::Uuid7(container) = col else {
851			panic!("Expected Uuid7");
852		};
853		assert_eq!(container.data().as_slice(), &[uuid1, uuid2]);
854	}
855
856	#[test]
857	fn test_undefined_uuid7() {
858		let (_, clock, rng) = test_clock_and_rng();
859		let uuid1 = Uuid7::generate(&clock, &rng);
860		let mut col = ColumnBuffer::uuid7(vec![uuid1]);
861		col.push_value(Value::none());
862		assert_eq!(col.len(), 2);
863		assert!(col.is_defined(0));
864		assert!(!col.is_defined(1));
865	}
866
867	#[test]
868	fn test_push_value_to_none_uuid7() {
869		let (_, clock, rng) = test_clock_and_rng();
870		let uuid = Uuid7::generate(&clock, &rng);
871		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
872		col.push_value(Value::Uuid7(uuid));
873		assert_eq!(col.len(), 2);
874		assert!(!col.is_defined(0));
875		assert!(col.is_defined(1));
876		assert_eq!(col.get_value(1), Value::Uuid7(uuid));
877	}
878
879	#[test]
880	fn test_dictionary_id() {
881		let e1 = DictionaryEntryId::U4(10);
882		let e2 = DictionaryEntryId::U4(20);
883		let mut col = ColumnBuffer::dictionary_id(vec![e1]);
884		col.push_value(Value::DictionaryId(e2));
885		let ColumnBuffer::DictionaryId(container) = col else {
886			panic!("Expected DictionaryId");
887		};
888		assert_eq!(container.data().as_slice(), &[e1, e2]);
889	}
890
891	#[test]
892	fn test_undefined_dictionary_id() {
893		let e1 = DictionaryEntryId::U4(10);
894		let mut col = ColumnBuffer::dictionary_id(vec![e1]);
895		col.push_value(Value::none());
896		assert_eq!(col.len(), 2);
897		assert!(col.is_defined(0));
898		assert!(!col.is_defined(1));
899	}
900
901	#[test]
902	fn test_push_value_to_none_dictionary_id() {
903		let e = DictionaryEntryId::U4(42);
904		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
905		col.push_value(Value::DictionaryId(e));
906		assert_eq!(col.len(), 2);
907		assert!(!col.is_defined(0));
908		assert!(col.is_defined(1));
909		assert_eq!(col.get_value(1), Value::DictionaryId(e));
910	}
911
912	#[test]
913	fn test_push_value_to_none_list() {
914		// A list arriving after only none rows must widen the column like a record does, never hit an
915		// unreachable arm.
916		let list = Value::List(vec![Value::Int4(1), Value::Int4(2)]);
917		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
918		col.push_value(list.clone());
919		assert_eq!(col.len(), 2);
920		assert!(!col.is_defined(0));
921		assert!(col.is_defined(1));
922		assert_eq!(col.get_value(1), Value::Any(Box::new(list)));
923	}
924
925	#[test]
926	fn test_push_value_to_none_type() {
927		// A type value arriving after only none rows must widen the column like a record does, never hit an
928		// unreachable arm.
929		let mut col = ColumnBuffer::none_typed(ValueType::Boolean, 1);
930		col.push_value(Value::Type(ValueType::Int4));
931		assert_eq!(col.len(), 2);
932		assert!(!col.is_defined(0));
933		assert!(col.is_defined(1));
934		assert_eq!(col.get_value(1), Value::Any(Box::new(Value::Type(ValueType::Int4))));
935	}
936}