Skip to main content

reifydb_core/value/column/transform/
append.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_type::{
5	Result,
6	storage::DataBitVec,
7	util::bitvec::BitVec,
8	value::{
9		Value,
10		blob::Blob,
11		constraint::Constraint,
12		date::Date,
13		datetime::DateTime,
14		decimal::Decimal,
15		duration::Duration,
16		int::Int,
17		row_number::RowNumber,
18		time::Time,
19		r#type::Type,
20		uint::Uint,
21		uuid::{Uuid4, Uuid7},
22	},
23};
24use uuid::Uuid;
25
26use crate::{
27	encoded::{row::EncodedRow, shape::RowShape},
28	error::CoreError,
29	value::column::{ColumnBuffer, columns::Columns},
30};
31
32impl Columns {
33	pub fn append_columns(&mut self, other: Columns) -> Result<()> {
34		if self.len() != other.len() {
35			return Err(CoreError::FrameError {
36				message: "mismatched column count".to_string(),
37			}
38			.into());
39		}
40
41		// Append system columns from the other columns
42		if !other.row_numbers.is_empty() {
43			self.row_numbers.make_mut().extend(other.row_numbers.iter().copied());
44		}
45		if !other.created_at.is_empty() {
46			self.created_at.make_mut().extend(other.created_at.iter().copied());
47		}
48		if !other.updated_at.is_empty() {
49			self.updated_at.make_mut().extend(other.updated_at.iter().copied());
50		}
51
52		for i in 0..self.columns.len() {
53			let self_name = self.names[i].text().to_string();
54			let other_name = other.names[i].text().to_string();
55			if self_name != other_name {
56				return Err(CoreError::FrameError {
57					message: format!(
58						"column name mismatch at index {}: '{}' vs '{}'",
59						i, self_name, other_name,
60					),
61				}
62				.into());
63			}
64			let other_data = other.columns[i].clone();
65			self.columns.make_mut()[i].extend(other_data)?;
66		}
67		Ok(())
68	}
69}
70
71impl Columns {
72	pub fn append_rows(
73		&mut self,
74		shape: &RowShape,
75		rows: impl IntoIterator<Item = EncodedRow>,
76		row_numbers: Vec<RowNumber>,
77	) -> Result<()> {
78		if self.len() != shape.field_count() {
79			return Err(CoreError::FrameError {
80				message: format!(
81					"mismatched column count: expected {}, got {}",
82					self.len(),
83					shape.field_count()
84				),
85			}
86			.into());
87		}
88
89		let rows: Vec<EncodedRow> = rows.into_iter().collect();
90
91		// Verify row_numbers length if provided
92		if !row_numbers.is_empty() && row_numbers.len() != rows.len() {
93			return Err(CoreError::FrameError {
94				message: format!(
95					"row_numbers length {} does not match rows length {}",
96					row_numbers.len(),
97					rows.len()
98				),
99			}
100			.into());
101		}
102
103		// Append row numbers if provided
104		if !row_numbers.is_empty() {
105			self.row_numbers.make_mut().extend(row_numbers);
106		}
107
108		// Extract and append timestamps from encoded rows
109		for row in &rows {
110			self.created_at.make_mut().push(DateTime::from_nanos(row.created_at_nanos()));
111			self.updated_at.make_mut().push(DateTime::from_nanos(row.updated_at_nanos()));
112		}
113
114		// Handle all-none Option column conversion to properly-typed Option column
115		let columns = self.columns.make_mut();
116		for (index, column) in columns.iter_mut().enumerate() {
117			let field = shape.get_field(index).unwrap();
118			let is_all_none = if let ColumnBuffer::Option {
119				bitvec,
120				..
121			} = &*column
122			{
123				DataBitVec::count_ones(bitvec) == 0
124			} else {
125				false
126			};
127			if is_all_none {
128				let size = column.len();
129				let new_data = match field.constraint.get_type() {
130					Type::Boolean => ColumnBuffer::bool_with_bitvec(
131						vec![false; size],
132						BitVec::repeat(size, false),
133					),
134					Type::Float4 => ColumnBuffer::float4_with_bitvec(
135						vec![0.0f32; size],
136						BitVec::repeat(size, false),
137					),
138					Type::Float8 => ColumnBuffer::float8_with_bitvec(
139						vec![0.0f64; size],
140						BitVec::repeat(size, false),
141					),
142					Type::Int1 => ColumnBuffer::int1_with_bitvec(
143						vec![0i8; size],
144						BitVec::repeat(size, false),
145					),
146					Type::Int2 => ColumnBuffer::int2_with_bitvec(
147						vec![0i16; size],
148						BitVec::repeat(size, false),
149					),
150					Type::Int4 => ColumnBuffer::int4_with_bitvec(
151						vec![0i32; size],
152						BitVec::repeat(size, false),
153					),
154					Type::Int8 => ColumnBuffer::int8_with_bitvec(
155						vec![0i64; size],
156						BitVec::repeat(size, false),
157					),
158					Type::Int16 => ColumnBuffer::int16_with_bitvec(
159						vec![0i128; size],
160						BitVec::repeat(size, false),
161					),
162					Type::Utf8 => ColumnBuffer::utf8_with_bitvec(
163						vec![String::new(); size],
164						BitVec::repeat(size, false),
165					),
166					Type::Uint1 => ColumnBuffer::uint1_with_bitvec(
167						vec![0u8; size],
168						BitVec::repeat(size, false),
169					),
170					Type::Uint2 => ColumnBuffer::uint2_with_bitvec(
171						vec![0u16; size],
172						BitVec::repeat(size, false),
173					),
174					Type::Uint4 => ColumnBuffer::uint4_with_bitvec(
175						vec![0u32; size],
176						BitVec::repeat(size, false),
177					),
178					Type::Uint8 => ColumnBuffer::uint8_with_bitvec(
179						vec![0u64; size],
180						BitVec::repeat(size, false),
181					),
182					Type::Uint16 => ColumnBuffer::uint16_with_bitvec(
183						vec![0u128; size],
184						BitVec::repeat(size, false),
185					),
186					Type::Date => ColumnBuffer::date_with_bitvec(
187						vec![Date::default(); size],
188						BitVec::repeat(size, false),
189					),
190					Type::DateTime => ColumnBuffer::datetime_with_bitvec(
191						vec![DateTime::default(); size],
192						BitVec::repeat(size, false),
193					),
194					Type::Time => ColumnBuffer::time_with_bitvec(
195						vec![Time::default(); size],
196						BitVec::repeat(size, false),
197					),
198					Type::Duration => ColumnBuffer::duration_with_bitvec(
199						vec![Duration::default(); size],
200						BitVec::repeat(size, false),
201					),
202					Type::Option(_) => column.clone(),
203					Type::IdentityId => ColumnBuffer::identity_id_with_bitvec(
204						vec![Default::default(); size],
205						BitVec::repeat(size, false),
206					),
207					Type::Uuid4 => ColumnBuffer::uuid4_with_bitvec(
208						vec![Uuid4::from(Uuid::nil()); size],
209						BitVec::repeat(size, false),
210					),
211					Type::Uuid7 => ColumnBuffer::uuid7_with_bitvec(
212						vec![Uuid7::from(Uuid::nil()); size],
213						BitVec::repeat(size, false),
214					),
215					Type::Blob => ColumnBuffer::blob_with_bitvec(
216						vec![Blob::new(vec![]); size],
217						BitVec::repeat(size, false),
218					),
219					Type::Int => ColumnBuffer::int_with_bitvec(
220						vec![Int::default(); size],
221						BitVec::repeat(size, false),
222					),
223					Type::Uint => ColumnBuffer::uint_with_bitvec(
224						vec![Uint::default(); size],
225						BitVec::repeat(size, false),
226					),
227					Type::Decimal => ColumnBuffer::decimal_with_bitvec(
228						vec![Decimal::from(0); size],
229						BitVec::repeat(size, false),
230					),
231					Type::DictionaryId => {
232						let mut col_data = ColumnBuffer::dictionary_id_with_bitvec(
233							vec![Default::default(); size],
234							BitVec::repeat(size, false),
235						);
236						if let ColumnBuffer::DictionaryId(container) = &mut col_data
237							&& let Some(Constraint::Dictionary(dict_id, _)) =
238								field.constraint.constraint()
239						{
240							container.set_dictionary_id(*dict_id);
241						}
242						col_data
243					}
244					Type::Any | Type::List(_) | Type::Record(_) | Type::Tuple(_) => {
245						ColumnBuffer::any_with_bitvec(
246							vec![Box::new(Value::none()); size],
247							BitVec::repeat(size, false),
248						)
249					}
250				};
251
252				*column = new_data;
253			}
254
255			// Set dictionary_id on DictionaryId containers from shape constraint
256			if let ColumnBuffer::DictionaryId(container) = &mut *column
257				&& container.dictionary_id().is_none()
258				&& let Some(Constraint::Dictionary(dict_id, _)) = field.constraint.constraint()
259			{
260				container.set_dictionary_id(*dict_id);
261			}
262		}
263
264		// Append rows using RowShape methods
265		for row in &rows {
266			// Check if all fields are defined
267			let all_defined = (0..shape.field_count()).all(|i| row.is_defined(i));
268
269			if all_defined {
270				self.append_all_defined_from_shape(shape, row)?;
271			} else {
272				self.append_fallback_from_shape(shape, row)?;
273			}
274		}
275
276		Ok(())
277	}
278
279	fn append_all_defined_from_shape(&mut self, shape: &RowShape, row: &EncodedRow) -> Result<()> {
280		let names_snapshot: Vec<String> = self.names.iter().map(|n| n.text().to_string()).collect();
281		let columns = self.columns.make_mut();
282		for (index, column) in columns.iter_mut().enumerate() {
283			let field = shape.get_field(index).unwrap();
284			match (&mut *column, field.constraint.get_type()) {
285				// Handle Option-wrapped columns by unwrapping and pushing to inner + bitvec
286				(
287					ColumnBuffer::Option {
288						inner,
289						bitvec,
290					},
291					_ty,
292				) => {
293					let value = shape.get_value(row, index);
294					if matches!(value, Value::None { .. }) {
295						inner.push_none();
296						DataBitVec::push(bitvec, false);
297					} else {
298						inner.push_value(value);
299						DataBitVec::push(bitvec, true);
300					}
301				}
302				(ColumnBuffer::Bool(container), Type::Boolean) => {
303					container.push(shape.get_bool(row, index));
304				}
305				(ColumnBuffer::Float4(container), Type::Float4) => {
306					container.push(shape.get_f32(row, index));
307				}
308				(ColumnBuffer::Float8(container), Type::Float8) => {
309					container.push(shape.get_f64(row, index));
310				}
311				(ColumnBuffer::Int1(container), Type::Int1) => {
312					container.push(shape.get_i8(row, index));
313				}
314				(ColumnBuffer::Int2(container), Type::Int2) => {
315					container.push(shape.get_i16(row, index));
316				}
317				(ColumnBuffer::Int4(container), Type::Int4) => {
318					container.push(shape.get_i32(row, index));
319				}
320				(ColumnBuffer::Int8(container), Type::Int8) => {
321					container.push(shape.get_i64(row, index));
322				}
323				(ColumnBuffer::Int16(container), Type::Int16) => {
324					container.push(shape.get_i128(row, index));
325				}
326				(
327					ColumnBuffer::Utf8 {
328						container,
329						..
330					},
331					Type::Utf8,
332				) => {
333					container.push(shape.get_utf8(row, index).to_string());
334				}
335				(ColumnBuffer::Uint1(container), Type::Uint1) => {
336					container.push(shape.get_u8(row, index));
337				}
338				(ColumnBuffer::Uint2(container), Type::Uint2) => {
339					container.push(shape.get_u16(row, index));
340				}
341				(ColumnBuffer::Uint4(container), Type::Uint4) => {
342					container.push(shape.get_u32(row, index));
343				}
344				(ColumnBuffer::Uint8(container), Type::Uint8) => {
345					container.push(shape.get_u64(row, index));
346				}
347				(ColumnBuffer::Uint16(container), Type::Uint16) => {
348					container.push(shape.get_u128(row, index));
349				}
350				(ColumnBuffer::Date(container), Type::Date) => {
351					container.push(shape.get_date(row, index));
352				}
353				(ColumnBuffer::DateTime(container), Type::DateTime) => {
354					container.push(shape.get_datetime(row, index));
355				}
356				(ColumnBuffer::Time(container), Type::Time) => {
357					container.push(shape.get_time(row, index));
358				}
359				(ColumnBuffer::Duration(container), Type::Duration) => {
360					container.push(shape.get_duration(row, index));
361				}
362				(ColumnBuffer::Uuid4(container), Type::Uuid4) => {
363					container.push(shape.get_uuid4(row, index));
364				}
365				(ColumnBuffer::Uuid7(container), Type::Uuid7) => {
366					container.push(shape.get_uuid7(row, index));
367				}
368				(ColumnBuffer::IdentityId(container), Type::IdentityId) => {
369					container.push(shape.get_identity_id(row, index));
370				}
371				(
372					ColumnBuffer::Blob {
373						container,
374						..
375					},
376					Type::Blob,
377				) => {
378					container.push(shape.get_blob(row, index));
379				}
380				(
381					ColumnBuffer::Int {
382						container,
383						..
384					},
385					Type::Int,
386				) => {
387					container.push(shape.get_int(row, index));
388				}
389				(
390					ColumnBuffer::Uint {
391						container,
392						..
393					},
394					Type::Uint,
395				) => {
396					container.push(shape.get_uint(row, index));
397				}
398				(
399					ColumnBuffer::Decimal {
400						container,
401						..
402					},
403					Type::Decimal,
404				) => {
405					container.push(shape.get_decimal(row, index));
406				}
407				(ColumnBuffer::DictionaryId(container), Type::DictionaryId) => {
408					match shape.get_value(row, index) {
409						Value::DictionaryId(id) => container.push(id),
410						_ => container.push_default(),
411					}
412				}
413				(_, v) => {
414					return Err(CoreError::FrameError {
415						message: format!(
416							"type mismatch for column '{}'({}): incompatible with value {}",
417							names_snapshot[index],
418							column.get_type(),
419							v
420						),
421					}
422					.into());
423				}
424			}
425		}
426		Ok(())
427	}
428
429	fn append_fallback_from_shape(&mut self, shape: &RowShape, row: &EncodedRow) -> Result<()> {
430		let columns = self.columns.make_mut();
431		for (index, column) in columns.iter_mut().enumerate() {
432			let field = shape.get_field(index).unwrap();
433
434			// If the value is undefined, use ColumnBuffer-level push_none
435			// which correctly promotes bare containers to Option-wrapped
436			if !row.is_defined(index) {
437				column.push_none();
438				continue;
439			}
440
441			match (&mut *column, field.constraint.get_type()) {
442				// Handle Option-wrapped columns
443				(
444					ColumnBuffer::Option {
445						inner,
446						bitvec,
447					},
448					_ty,
449				) => {
450					let value = shape.get_value(row, index);
451					inner.push_value(value);
452					DataBitVec::push(bitvec, true);
453				}
454				(ColumnBuffer::Bool(container), Type::Boolean) => {
455					container.push(shape.get_bool(row, index));
456				}
457				(ColumnBuffer::Float4(container), Type::Float4) => {
458					container.push(shape.get_f32(row, index));
459				}
460				(ColumnBuffer::Float8(container), Type::Float8) => {
461					container.push(shape.get_f64(row, index));
462				}
463				(ColumnBuffer::Int1(container), Type::Int1) => {
464					container.push(shape.get_i8(row, index));
465				}
466				(ColumnBuffer::Int2(container), Type::Int2) => {
467					container.push(shape.get_i16(row, index));
468				}
469				(ColumnBuffer::Int4(container), Type::Int4) => {
470					container.push(shape.get_i32(row, index));
471				}
472				(ColumnBuffer::Int8(container), Type::Int8) => {
473					container.push(shape.get_i64(row, index));
474				}
475				(ColumnBuffer::Int16(container), Type::Int16) => {
476					container.push(shape.get_i128(row, index));
477				}
478				(
479					ColumnBuffer::Utf8 {
480						container,
481						..
482					},
483					Type::Utf8,
484				) => {
485					container.push(shape.get_utf8(row, index).to_string());
486				}
487				(ColumnBuffer::Uint1(container), Type::Uint1) => {
488					container.push(shape.get_u8(row, index));
489				}
490				(ColumnBuffer::Uint2(container), Type::Uint2) => {
491					container.push(shape.get_u16(row, index));
492				}
493				(ColumnBuffer::Uint4(container), Type::Uint4) => {
494					container.push(shape.get_u32(row, index));
495				}
496				(ColumnBuffer::Uint8(container), Type::Uint8) => {
497					container.push(shape.get_u64(row, index));
498				}
499				(ColumnBuffer::Uint16(container), Type::Uint16) => {
500					container.push(shape.get_u128(row, index));
501				}
502				(ColumnBuffer::Date(container), Type::Date) => {
503					container.push(shape.get_date(row, index));
504				}
505				(ColumnBuffer::DateTime(container), Type::DateTime) => {
506					container.push(shape.get_datetime(row, index));
507				}
508				(ColumnBuffer::Time(container), Type::Time) => {
509					container.push(shape.get_time(row, index));
510				}
511				(ColumnBuffer::Duration(container), Type::Duration) => {
512					container.push(shape.get_duration(row, index));
513				}
514				(ColumnBuffer::Uuid4(container), Type::Uuid4) => {
515					container.push(shape.get_uuid4(row, index));
516				}
517				(ColumnBuffer::Uuid7(container), Type::Uuid7) => {
518					container.push(shape.get_uuid7(row, index));
519				}
520				(
521					ColumnBuffer::Int {
522						container,
523						..
524					},
525					Type::Int,
526				) => {
527					container.push(shape.get_int(row, index));
528				}
529				(
530					ColumnBuffer::Uint {
531						container,
532						..
533					},
534					Type::Uint,
535				) => {
536					container.push(shape.get_uint(row, index));
537				}
538				(
539					ColumnBuffer::Decimal {
540						container,
541						..
542					},
543					Type::Decimal,
544				) => {
545					container.push(shape.get_decimal(row, index));
546				}
547				(ColumnBuffer::DictionaryId(container), Type::DictionaryId) => {
548					match shape.get_value(row, index) {
549						Value::DictionaryId(id) => container.push(id),
550						_ => container.push_default(),
551					}
552				}
553				(l, r) => unreachable!("{:#?} {:#?}", l, r),
554			}
555		}
556		Ok(())
557	}
558}
559
560#[cfg(test)]
561pub mod tests {
562	mod columns {
563		use reifydb_type::value::{
564			r#type::Type,
565			uuid::{Uuid4, Uuid7},
566		};
567		use uuid::{Timestamp, Uuid};
568
569		use crate::value::column::{ColumnBuffer, ColumnWithName, columns::Columns};
570
571		#[test]
572		fn test_boolean() {
573			let mut test_instance1 =
574				Columns::new(vec![ColumnWithName::bool_with_bitvec("id", [true], [false])]);
575
576			let test_instance2 =
577				Columns::new(vec![ColumnWithName::bool_with_bitvec("id", [false], [true])]);
578
579			test_instance1.append_columns(test_instance2).unwrap();
580
581			assert_eq!(test_instance1[0], ColumnBuffer::bool_with_bitvec([true, false], [false, true]));
582		}
583
584		#[test]
585		fn test_float4() {
586			let mut test_instance1 = Columns::new(vec![ColumnWithName::float4("id", [1.0f32, 2.0])]);
587
588			let test_instance2 = Columns::new(vec![ColumnWithName::float4_with_bitvec(
589				"id",
590				[3.0f32, 4.0],
591				[true, false],
592			)]);
593
594			test_instance1.append_columns(test_instance2).unwrap();
595
596			assert_eq!(
597				test_instance1[0],
598				ColumnBuffer::float4_with_bitvec([1.0f32, 2.0, 3.0, 4.0], [true, true, true, false])
599			);
600		}
601
602		#[test]
603		fn test_float8() {
604			let mut test_instance1 = Columns::new(vec![ColumnWithName::float8("id", [1.0f64, 2.0])]);
605
606			let test_instance2 = Columns::new(vec![ColumnWithName::float8_with_bitvec(
607				"id",
608				[3.0f64, 4.0],
609				[true, false],
610			)]);
611
612			test_instance1.append_columns(test_instance2).unwrap();
613
614			assert_eq!(
615				test_instance1[0],
616				ColumnBuffer::float8_with_bitvec([1.0f64, 2.0, 3.0, 4.0], [true, true, true, false])
617			);
618		}
619
620		#[test]
621		fn test_int1() {
622			let mut test_instance1 = Columns::new(vec![ColumnWithName::int1("id", [1, 2])]);
623
624			let test_instance2 =
625				Columns::new(vec![ColumnWithName::int1_with_bitvec("id", [3, 4], [true, false])]);
626
627			test_instance1.append_columns(test_instance2).unwrap();
628
629			assert_eq!(
630				test_instance1[0],
631				ColumnBuffer::int1_with_bitvec([1, 2, 3, 4], [true, true, true, false])
632			);
633		}
634
635		#[test]
636		fn test_int2() {
637			let mut test_instance1 = Columns::new(vec![ColumnWithName::int2("id", [1, 2])]);
638
639			let test_instance2 =
640				Columns::new(vec![ColumnWithName::int2_with_bitvec("id", [3, 4], [true, false])]);
641
642			test_instance1.append_columns(test_instance2).unwrap();
643
644			assert_eq!(
645				test_instance1[0],
646				ColumnBuffer::int2_with_bitvec([1, 2, 3, 4], [true, true, true, false])
647			);
648		}
649
650		#[test]
651		fn test_int4() {
652			let mut test_instance1 = Columns::new(vec![ColumnWithName::int4("id", [1, 2])]);
653
654			let test_instance2 =
655				Columns::new(vec![ColumnWithName::int4_with_bitvec("id", [3, 4], [true, false])]);
656
657			test_instance1.append_columns(test_instance2).unwrap();
658
659			assert_eq!(
660				test_instance1[0],
661				ColumnBuffer::int4_with_bitvec([1, 2, 3, 4], [true, true, true, false])
662			);
663		}
664
665		#[test]
666		fn test_int8() {
667			let mut test_instance1 = Columns::new(vec![ColumnWithName::int8("id", [1, 2])]);
668
669			let test_instance2 =
670				Columns::new(vec![ColumnWithName::int8_with_bitvec("id", [3, 4], [true, false])]);
671
672			test_instance1.append_columns(test_instance2).unwrap();
673
674			assert_eq!(
675				test_instance1[0],
676				ColumnBuffer::int8_with_bitvec([1, 2, 3, 4], [true, true, true, false])
677			);
678		}
679
680		#[test]
681		fn test_int16() {
682			let mut test_instance1 = Columns::new(vec![ColumnWithName::int16("id", [1, 2])]);
683
684			let test_instance2 =
685				Columns::new(vec![ColumnWithName::int16_with_bitvec("id", [3, 4], [true, false])]);
686
687			test_instance1.append_columns(test_instance2).unwrap();
688
689			assert_eq!(
690				test_instance1[0],
691				ColumnBuffer::int16_with_bitvec([1, 2, 3, 4], [true, true, true, false])
692			);
693		}
694
695		#[test]
696		fn test_string() {
697			let mut test_instance1 = Columns::new(vec![ColumnWithName::utf8_with_bitvec(
698				"id",
699				vec!["a".to_string(), "b".to_string()],
700				[true, true],
701			)]);
702
703			let test_instance2 = Columns::new(vec![ColumnWithName::utf8_with_bitvec(
704				"id",
705				vec!["c".to_string(), "d".to_string()],
706				[true, false],
707			)]);
708
709			test_instance1.append_columns(test_instance2).unwrap();
710
711			assert_eq!(
712				test_instance1[0],
713				ColumnBuffer::utf8_with_bitvec(
714					vec!["a".to_string(), "b".to_string(), "c".to_string(), "d".to_string()],
715					vec![true, true, true, false]
716				)
717			);
718		}
719
720		#[test]
721		fn test_uint1() {
722			let mut test_instance1 = Columns::new(vec![ColumnWithName::uint1("id", [1, 2])]);
723
724			let test_instance2 =
725				Columns::new(vec![ColumnWithName::uint1_with_bitvec("id", [3, 4], [true, false])]);
726
727			test_instance1.append_columns(test_instance2).unwrap();
728
729			assert_eq!(
730				test_instance1[0],
731				ColumnBuffer::uint1_with_bitvec([1, 2, 3, 4], [true, true, true, false])
732			);
733		}
734
735		#[test]
736		fn test_uint2() {
737			let mut test_instance1 = Columns::new(vec![ColumnWithName::uint2("id", [1, 2])]);
738
739			let test_instance2 =
740				Columns::new(vec![ColumnWithName::uint2_with_bitvec("id", [3, 4], [true, false])]);
741
742			test_instance1.append_columns(test_instance2).unwrap();
743
744			assert_eq!(
745				test_instance1[0],
746				ColumnBuffer::uint2_with_bitvec([1, 2, 3, 4], [true, true, true, false])
747			);
748		}
749
750		#[test]
751		fn test_uint4() {
752			let mut test_instance1 = Columns::new(vec![ColumnWithName::uint4("id", [1, 2])]);
753
754			let test_instance2 =
755				Columns::new(vec![ColumnWithName::uint4_with_bitvec("id", [3, 4], [true, false])]);
756
757			test_instance1.append_columns(test_instance2).unwrap();
758
759			assert_eq!(
760				test_instance1[0],
761				ColumnBuffer::uint4_with_bitvec([1, 2, 3, 4], [true, true, true, false])
762			);
763		}
764
765		#[test]
766		fn test_uint8() {
767			let mut test_instance1 = Columns::new(vec![ColumnWithName::uint8("id", [1, 2])]);
768
769			let test_instance2 =
770				Columns::new(vec![ColumnWithName::uint8_with_bitvec("id", [3, 4], [true, false])]);
771
772			test_instance1.append_columns(test_instance2).unwrap();
773
774			assert_eq!(
775				test_instance1[0],
776				ColumnBuffer::uint8_with_bitvec([1, 2, 3, 4], [true, true, true, false])
777			);
778		}
779
780		#[test]
781		fn test_uint16() {
782			let mut test_instance1 = Columns::new(vec![ColumnWithName::uint16("id", [1, 2])]);
783
784			let test_instance2 =
785				Columns::new(vec![ColumnWithName::uint16_with_bitvec("id", [3, 4], [true, false])]);
786
787			test_instance1.append_columns(test_instance2).unwrap();
788
789			assert_eq!(
790				test_instance1[0],
791				ColumnBuffer::uint16_with_bitvec([1, 2, 3, 4], [true, true, true, false])
792			);
793		}
794
795		#[test]
796		fn test_uuid4() {
797			let uuid1 = Uuid4::from(Uuid::new_v4());
798			let uuid2 = Uuid4::from(Uuid::new_v4());
799			let uuid3 = Uuid4::from(Uuid::new_v4());
800			let uuid4 = Uuid4::from(Uuid::new_v4());
801
802			let mut test_instance1 = Columns::new(vec![ColumnWithName::uuid4("id", [uuid1, uuid2])]);
803
804			let test_instance2 = Columns::new(vec![ColumnWithName::uuid4_with_bitvec(
805				"id",
806				[uuid3, uuid4],
807				[true, false],
808			)]);
809
810			test_instance1.append_columns(test_instance2).unwrap();
811
812			assert_eq!(
813				test_instance1[0],
814				ColumnBuffer::uuid4_with_bitvec(
815					[uuid1, uuid2, uuid3, uuid4],
816					[true, true, true, false]
817				)
818			);
819		}
820
821		#[test]
822		fn test_uuid7() {
823			let uuid1 = Uuid7::from(Uuid::new_v7(Timestamp::from_gregorian_time(1, 1)));
824			let uuid2 = Uuid7::from(Uuid::new_v7(Timestamp::from_gregorian_time(1, 2)));
825			let uuid3 = Uuid7::from(Uuid::new_v7(Timestamp::from_gregorian_time(2, 1)));
826			let uuid4 = Uuid7::from(Uuid::new_v7(Timestamp::from_gregorian_time(2, 2)));
827
828			let mut test_instance1 = Columns::new(vec![ColumnWithName::uuid7("id", [uuid1, uuid2])]);
829
830			let test_instance2 = Columns::new(vec![ColumnWithName::uuid7_with_bitvec(
831				"id",
832				[uuid3, uuid4],
833				[true, false],
834			)]);
835
836			test_instance1.append_columns(test_instance2).unwrap();
837
838			assert_eq!(
839				test_instance1[0],
840				ColumnBuffer::uuid7_with_bitvec(
841					[uuid1, uuid2, uuid3, uuid4],
842					[true, true, true, false]
843				)
844			);
845		}
846
847		#[test]
848		fn test_with_undefined_lr_promotes_correctly() {
849			let mut test_instance1 =
850				Columns::new(vec![ColumnWithName::int2_with_bitvec("id", [1, 2], [true, false])]);
851
852			let test_instance2 =
853				Columns::new(vec![ColumnWithName::undefined_typed("id", Type::Boolean, 2)]);
854
855			test_instance1.append_columns(test_instance2).unwrap();
856
857			assert_eq!(
858				test_instance1[0],
859				ColumnBuffer::int2_with_bitvec([1, 2, 0, 0], [true, false, false, false])
860			);
861		}
862
863		#[test]
864		fn test_with_undefined_l_promotes_correctly() {
865			let mut test_instance1 =
866				Columns::new(vec![ColumnWithName::undefined_typed("score", Type::Boolean, 2)]);
867
868			let test_instance2 =
869				Columns::new(vec![ColumnWithName::int2_with_bitvec("score", [10, 20], [true, false])]);
870
871			test_instance1.append_columns(test_instance2).unwrap();
872
873			assert_eq!(
874				test_instance1[0],
875				ColumnBuffer::int2_with_bitvec([0, 0, 10, 20], [false, false, true, false])
876			);
877		}
878
879		#[test]
880		fn test_fails_on_column_count_mismatch() {
881			let mut test_instance1 = Columns::new(vec![ColumnWithName::int2("id", [1])]);
882
883			let test_instance2 = Columns::new(vec![
884				ColumnWithName::int2("id", [2]),
885				ColumnWithName::utf8("name", vec!["Bob".to_string()]),
886			]);
887
888			let result = test_instance1.append_columns(test_instance2);
889			assert!(result.is_err());
890		}
891
892		#[test]
893		fn test_fails_on_column_name_mismatch() {
894			let mut test_instance1 = Columns::new(vec![ColumnWithName::int2("id", [1])]);
895
896			let test_instance2 = Columns::new(vec![ColumnWithName::int2("wrong", [2])]);
897
898			let result = test_instance1.append_columns(test_instance2);
899			assert!(result.is_err());
900		}
901
902		#[test]
903		fn test_fails_on_type_mismatch() {
904			let mut test_instance1 = Columns::new(vec![ColumnWithName::int2("id", [1])]);
905
906			let test_instance2 = Columns::new(vec![ColumnWithName::utf8("id", vec!["A".to_string()])]);
907
908			let result = test_instance1.append_columns(test_instance2);
909			assert!(result.is_err());
910		}
911	}
912
913	mod row {
914		use reifydb_type::{
915			fragment::Fragment,
916			util::bitvec::BitVec,
917			value::{
918				Value,
919				constraint::TypeConstraint,
920				dictionary::{DictionaryEntryId, DictionaryId},
921				ordered_f32::OrderedF32,
922				ordered_f64::OrderedF64,
923				r#type::Type,
924			},
925		};
926
927		use crate::{
928			encoded::shape::{RowShape, RowShapeField},
929			value::column::{ColumnBuffer, ColumnWithName, columns::Columns},
930		};
931
932		#[test]
933		fn test_before_undefined_bool() {
934			let mut test_instance =
935				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
936
937			let shape = RowShape::testing(&[Type::Boolean]);
938			let mut row = shape.allocate();
939			shape.set_values(&mut row, &[Value::Boolean(true)]);
940
941			test_instance.append_rows(&shape, [row], vec![]).unwrap();
942
943			assert_eq!(
944				test_instance[0],
945				ColumnBuffer::bool_with_bitvec(
946					[false, false, true],
947					BitVec::from_slice(&[false, false, true])
948				)
949			);
950		}
951
952		#[test]
953		fn test_before_undefined_float4() {
954			let mut test_instance =
955				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
956			let shape = RowShape::testing(&[Type::Float4]);
957			let mut row = shape.allocate();
958			shape.set_values(&mut row, &[Value::Float4(OrderedF32::try_from(1.5).unwrap())]);
959			test_instance.append_rows(&shape, [row], vec![]).unwrap();
960
961			assert_eq!(
962				test_instance[0],
963				ColumnBuffer::float4_with_bitvec(
964					[0.0, 0.0, 1.5],
965					BitVec::from_slice(&[false, false, true])
966				)
967			);
968		}
969
970		#[test]
971		fn test_before_undefined_float8() {
972			let mut test_instance =
973				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
974			let shape = RowShape::testing(&[Type::Float8]);
975			let mut row = shape.allocate();
976			shape.set_values(&mut row, &[Value::Float8(OrderedF64::try_from(2.25).unwrap())]);
977			test_instance.append_rows(&shape, [row], vec![]).unwrap();
978
979			assert_eq!(
980				test_instance[0],
981				ColumnBuffer::float8_with_bitvec(
982					[0.0, 0.0, 2.25],
983					BitVec::from_slice(&[false, false, true])
984				)
985			);
986		}
987
988		#[test]
989		fn test_before_undefined_int1() {
990			let mut test_instance =
991				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
992			let shape = RowShape::testing(&[Type::Int1]);
993			let mut row = shape.allocate();
994			shape.set_values(&mut row, &[Value::Int1(42)]);
995			test_instance.append_rows(&shape, [row], vec![]).unwrap();
996
997			assert_eq!(
998				test_instance[0],
999				ColumnBuffer::int1_with_bitvec([0, 0, 42], BitVec::from_slice(&[false, false, true]))
1000			);
1001		}
1002
1003		#[test]
1004		fn test_before_undefined_int2() {
1005			let mut test_instance =
1006				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
1007			let shape = RowShape::testing(&[Type::Int2]);
1008			let mut row = shape.allocate();
1009			shape.set_values(&mut row, &[Value::Int2(-1234)]);
1010			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1011
1012			assert_eq!(
1013				test_instance[0],
1014				ColumnBuffer::int2_with_bitvec(
1015					[0, 0, -1234],
1016					BitVec::from_slice(&[false, false, true])
1017				)
1018			);
1019		}
1020
1021		#[test]
1022		fn test_before_undefined_int4() {
1023			let mut test_instance =
1024				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
1025			let shape = RowShape::testing(&[Type::Int4]);
1026			let mut row = shape.allocate();
1027			shape.set_values(&mut row, &[Value::Int4(56789)]);
1028			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1029
1030			assert_eq!(
1031				test_instance[0],
1032				ColumnBuffer::int4_with_bitvec(
1033					[0, 0, 56789],
1034					BitVec::from_slice(&[false, false, true])
1035				)
1036			);
1037		}
1038
1039		#[test]
1040		fn test_before_undefined_int8() {
1041			let mut test_instance =
1042				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
1043			let shape = RowShape::testing(&[Type::Int8]);
1044			let mut row = shape.allocate();
1045			shape.set_values(&mut row, &[Value::Int8(-987654321)]);
1046			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1047
1048			assert_eq!(
1049				test_instance[0],
1050				ColumnBuffer::int8_with_bitvec(
1051					[0, 0, -987654321],
1052					BitVec::from_slice(&[false, false, true])
1053				)
1054			);
1055		}
1056
1057		#[test]
1058		fn test_before_undefined_int16() {
1059			let mut test_instance =
1060				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
1061			let shape = RowShape::testing(&[Type::Int16]);
1062			let mut row = shape.allocate();
1063			shape.set_values(&mut row, &[Value::Int16(123456789012345678901234567890i128)]);
1064			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1065
1066			assert_eq!(
1067				test_instance[0],
1068				ColumnBuffer::int16_with_bitvec(
1069					[0, 0, 123456789012345678901234567890i128],
1070					BitVec::from_slice(&[false, false, true])
1071				)
1072			);
1073		}
1074
1075		#[test]
1076		fn test_before_undefined_string() {
1077			let mut test_instance =
1078				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
1079			let shape = RowShape::testing(&[Type::Utf8]);
1080			let mut row = shape.allocate();
1081			shape.set_values(&mut row, &[Value::Utf8("reifydb".into())]);
1082			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1083
1084			assert_eq!(
1085				test_instance[0],
1086				ColumnBuffer::utf8_with_bitvec(
1087					["".to_string(), "".to_string(), "reifydb".to_string()],
1088					BitVec::from_slice(&[false, false, true])
1089				)
1090			);
1091		}
1092
1093		#[test]
1094		fn test_before_undefined_uint1() {
1095			let mut test_instance =
1096				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
1097			let shape = RowShape::testing(&[Type::Uint1]);
1098			let mut row = shape.allocate();
1099			shape.set_values(&mut row, &[Value::Uint1(255)]);
1100			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1101
1102			assert_eq!(
1103				test_instance[0],
1104				ColumnBuffer::uint1_with_bitvec([0, 0, 255], BitVec::from_slice(&[false, false, true]))
1105			);
1106		}
1107
1108		#[test]
1109		fn test_before_undefined_uint2() {
1110			let mut test_instance =
1111				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
1112			let shape = RowShape::testing(&[Type::Uint2]);
1113			let mut row = shape.allocate();
1114			shape.set_values(&mut row, &[Value::Uint2(65535)]);
1115			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1116
1117			assert_eq!(
1118				test_instance[0],
1119				ColumnBuffer::uint2_with_bitvec(
1120					[0, 0, 65535],
1121					BitVec::from_slice(&[false, false, true])
1122				)
1123			);
1124		}
1125
1126		#[test]
1127		fn test_before_undefined_uint4() {
1128			let mut test_instance =
1129				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
1130			let shape = RowShape::testing(&[Type::Uint4]);
1131			let mut row = shape.allocate();
1132			shape.set_values(&mut row, &[Value::Uint4(4294967295)]);
1133			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1134
1135			assert_eq!(
1136				test_instance[0],
1137				ColumnBuffer::uint4_with_bitvec(
1138					[0, 0, 4294967295],
1139					BitVec::from_slice(&[false, false, true])
1140				)
1141			);
1142		}
1143
1144		#[test]
1145		fn test_before_undefined_uint8() {
1146			let mut test_instance =
1147				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
1148			let shape = RowShape::testing(&[Type::Uint8]);
1149			let mut row = shape.allocate();
1150			shape.set_values(&mut row, &[Value::Uint8(18446744073709551615)]);
1151			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1152
1153			assert_eq!(
1154				test_instance[0],
1155				ColumnBuffer::uint8_with_bitvec(
1156					[0, 0, 18446744073709551615],
1157					BitVec::from_slice(&[false, false, true])
1158				)
1159			);
1160		}
1161
1162		#[test]
1163		fn test_before_undefined_uint16() {
1164			let mut test_instance =
1165				Columns::new(vec![ColumnWithName::undefined_typed("test_col", Type::Boolean, 2)]);
1166			let shape = RowShape::testing(&[Type::Uint16]);
1167			let mut row = shape.allocate();
1168			shape.set_values(&mut row, &[Value::Uint16(340282366920938463463374607431768211455u128)]);
1169			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1170
1171			assert_eq!(
1172				test_instance[0],
1173				ColumnBuffer::uint16_with_bitvec(
1174					[0, 0, 340282366920938463463374607431768211455u128],
1175					BitVec::from_slice(&[false, false, true])
1176				)
1177			);
1178		}
1179
1180		#[test]
1181		fn test_mismatched_columns() {
1182			let mut test_instance = Columns::new(vec![]);
1183
1184			let shape = RowShape::testing(&[Type::Int2]);
1185			let mut row = shape.allocate();
1186			shape.set_values(&mut row, &[Value::Int2(2)]);
1187
1188			let err = test_instance.append_rows(&shape, [row], vec![]).err().unwrap();
1189			assert!(err.to_string().contains("mismatched column count: expected 0, got 1"));
1190		}
1191
1192		#[test]
1193		fn test_ok() {
1194			let mut test_instance = test_instance_with_columns();
1195
1196			let shape = RowShape::testing(&[Type::Int2, Type::Boolean]);
1197			let mut row_one = shape.allocate();
1198			shape.set_values(&mut row_one, &[Value::Int2(2), Value::Boolean(true)]);
1199			let mut row_two = shape.allocate();
1200			shape.set_values(&mut row_two, &[Value::Int2(3), Value::Boolean(false)]);
1201
1202			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1203
1204			assert_eq!(test_instance[0], ColumnBuffer::int2([1, 2, 3]));
1205			assert_eq!(test_instance[1], ColumnBuffer::bool([true, true, false]));
1206		}
1207
1208		#[test]
1209		fn test_all_defined_bool() {
1210			let mut test_instance =
1211				Columns::new(vec![ColumnWithName::bool("test_col", Vec::<bool>::new())]);
1212
1213			let shape = RowShape::testing(&[Type::Boolean]);
1214			let mut row_one = shape.allocate();
1215			shape.set_bool(&mut row_one, 0, true);
1216			let mut row_two = shape.allocate();
1217			shape.set_bool(&mut row_two, 0, false);
1218
1219			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1220
1221			assert_eq!(test_instance[0], ColumnBuffer::bool([true, false]));
1222		}
1223
1224		#[test]
1225		fn test_all_defined_float4() {
1226			let mut test_instance =
1227				Columns::new(vec![ColumnWithName::float4("test_col", Vec::<f32>::new())]);
1228
1229			let shape = RowShape::testing(&[Type::Float4]);
1230			let mut row_one = shape.allocate();
1231			shape.set_values(&mut row_one, &[Value::Float4(OrderedF32::try_from(1.0).unwrap())]);
1232			let mut row_two = shape.allocate();
1233			shape.set_values(&mut row_two, &[Value::Float4(OrderedF32::try_from(2.0).unwrap())]);
1234
1235			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1236
1237			assert_eq!(test_instance[0], ColumnBuffer::float4([1.0, 2.0]));
1238		}
1239
1240		#[test]
1241		fn test_all_defined_float8() {
1242			let mut test_instance =
1243				Columns::new(vec![ColumnWithName::float8("test_col", Vec::<f64>::new())]);
1244
1245			let shape = RowShape::testing(&[Type::Float8]);
1246			let mut row_one = shape.allocate();
1247			shape.set_values(&mut row_one, &[Value::Float8(OrderedF64::try_from(1.0).unwrap())]);
1248			let mut row_two = shape.allocate();
1249			shape.set_values(&mut row_two, &[Value::Float8(OrderedF64::try_from(2.0).unwrap())]);
1250
1251			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1252
1253			assert_eq!(test_instance[0], ColumnBuffer::float8([1.0, 2.0]));
1254		}
1255
1256		#[test]
1257		fn test_all_defined_int1() {
1258			let mut test_instance = Columns::new(vec![ColumnWithName::int1("test_col", Vec::<i8>::new())]);
1259
1260			let shape = RowShape::testing(&[Type::Int1]);
1261			let mut row_one = shape.allocate();
1262			shape.set_values(&mut row_one, &[Value::Int1(1)]);
1263			let mut row_two = shape.allocate();
1264			shape.set_values(&mut row_two, &[Value::Int1(2)]);
1265
1266			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1267
1268			assert_eq!(test_instance[0], ColumnBuffer::int1([1, 2]));
1269		}
1270
1271		#[test]
1272		fn test_all_defined_int2() {
1273			let mut test_instance = Columns::new(vec![ColumnWithName::int2("test_col", Vec::<i16>::new())]);
1274
1275			let shape = RowShape::testing(&[Type::Int2]);
1276			let mut row_one = shape.allocate();
1277			shape.set_values(&mut row_one, &[Value::Int2(100)]);
1278			let mut row_two = shape.allocate();
1279			shape.set_values(&mut row_two, &[Value::Int2(200)]);
1280
1281			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1282
1283			assert_eq!(test_instance[0], ColumnBuffer::int2([100, 200]));
1284		}
1285
1286		#[test]
1287		fn test_all_defined_int4() {
1288			let mut test_instance = Columns::new(vec![ColumnWithName::int4("test_col", Vec::<i32>::new())]);
1289
1290			let shape = RowShape::testing(&[Type::Int4]);
1291			let mut row_one = shape.allocate();
1292			shape.set_values(&mut row_one, &[Value::Int4(1000)]);
1293			let mut row_two = shape.allocate();
1294			shape.set_values(&mut row_two, &[Value::Int4(2000)]);
1295
1296			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1297
1298			assert_eq!(test_instance[0], ColumnBuffer::int4([1000, 2000]));
1299		}
1300
1301		#[test]
1302		fn test_all_defined_int8() {
1303			let mut test_instance = Columns::new(vec![ColumnWithName::int8("test_col", Vec::<i64>::new())]);
1304
1305			let shape = RowShape::testing(&[Type::Int8]);
1306			let mut row_one = shape.allocate();
1307			shape.set_values(&mut row_one, &[Value::Int8(10000)]);
1308			let mut row_two = shape.allocate();
1309			shape.set_values(&mut row_two, &[Value::Int8(20000)]);
1310
1311			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1312
1313			assert_eq!(test_instance[0], ColumnBuffer::int8([10000, 20000]));
1314		}
1315
1316		#[test]
1317		fn test_all_defined_int16() {
1318			let mut test_instance =
1319				Columns::new(vec![ColumnWithName::int16("test_col", Vec::<i128>::new())]);
1320
1321			let shape = RowShape::testing(&[Type::Int16]);
1322			let mut row_one = shape.allocate();
1323			shape.set_values(&mut row_one, &[Value::Int16(1000)]);
1324			let mut row_two = shape.allocate();
1325			shape.set_values(&mut row_two, &[Value::Int16(2000)]);
1326
1327			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1328
1329			assert_eq!(test_instance[0], ColumnBuffer::int16([1000, 2000]));
1330		}
1331
1332		#[test]
1333		fn test_all_defined_string() {
1334			let mut test_instance =
1335				Columns::new(vec![ColumnWithName::utf8("test_col", Vec::<String>::new())]);
1336
1337			let shape = RowShape::testing(&[Type::Utf8]);
1338			let mut row_one = shape.allocate();
1339			shape.set_values(&mut row_one, &[Value::Utf8("a".into())]);
1340			let mut row_two = shape.allocate();
1341			shape.set_values(&mut row_two, &[Value::Utf8("b".into())]);
1342
1343			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1344
1345			assert_eq!(test_instance[0], ColumnBuffer::utf8(["a".to_string(), "b".to_string()]));
1346		}
1347
1348		#[test]
1349		fn test_all_defined_uint1() {
1350			let mut test_instance = Columns::new(vec![ColumnWithName::uint1("test_col", Vec::<u8>::new())]);
1351
1352			let shape = RowShape::testing(&[Type::Uint1]);
1353			let mut row_one = shape.allocate();
1354			shape.set_values(&mut row_one, &[Value::Uint1(1)]);
1355			let mut row_two = shape.allocate();
1356			shape.set_values(&mut row_two, &[Value::Uint1(2)]);
1357
1358			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1359
1360			assert_eq!(test_instance[0], ColumnBuffer::uint1([1, 2]));
1361		}
1362
1363		#[test]
1364		fn test_all_defined_uint2() {
1365			let mut test_instance =
1366				Columns::new(vec![ColumnWithName::uint2("test_col", Vec::<u16>::new())]);
1367
1368			let shape = RowShape::testing(&[Type::Uint2]);
1369			let mut row_one = shape.allocate();
1370			shape.set_values(&mut row_one, &[Value::Uint2(100)]);
1371			let mut row_two = shape.allocate();
1372			shape.set_values(&mut row_two, &[Value::Uint2(200)]);
1373
1374			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1375
1376			assert_eq!(test_instance[0], ColumnBuffer::uint2([100, 200]));
1377		}
1378
1379		#[test]
1380		fn test_all_defined_uint4() {
1381			let mut test_instance =
1382				Columns::new(vec![ColumnWithName::uint4("test_col", Vec::<u32>::new())]);
1383
1384			let shape = RowShape::testing(&[Type::Uint4]);
1385			let mut row_one = shape.allocate();
1386			shape.set_values(&mut row_one, &[Value::Uint4(1000)]);
1387			let mut row_two = shape.allocate();
1388			shape.set_values(&mut row_two, &[Value::Uint4(2000)]);
1389
1390			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1391
1392			assert_eq!(test_instance[0], ColumnBuffer::uint4([1000, 2000]));
1393		}
1394
1395		#[test]
1396		fn test_all_defined_uint8() {
1397			let mut test_instance =
1398				Columns::new(vec![ColumnWithName::uint8("test_col", Vec::<u64>::new())]);
1399
1400			let shape = RowShape::testing(&[Type::Uint8]);
1401			let mut row_one = shape.allocate();
1402			shape.set_values(&mut row_one, &[Value::Uint8(10000)]);
1403			let mut row_two = shape.allocate();
1404			shape.set_values(&mut row_two, &[Value::Uint8(20000)]);
1405
1406			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1407
1408			assert_eq!(test_instance[0], ColumnBuffer::uint8([10000, 20000]));
1409		}
1410
1411		#[test]
1412		fn test_all_defined_uint16() {
1413			let mut test_instance =
1414				Columns::new(vec![ColumnWithName::uint16("test_col", Vec::<u128>::new())]);
1415
1416			let shape = RowShape::testing(&[Type::Uint16]);
1417			let mut row_one = shape.allocate();
1418			shape.set_values(&mut row_one, &[Value::Uint16(1000)]);
1419			let mut row_two = shape.allocate();
1420			shape.set_values(&mut row_two, &[Value::Uint16(2000)]);
1421
1422			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1423
1424			assert_eq!(test_instance[0], ColumnBuffer::uint16([1000, 2000]));
1425		}
1426
1427		#[test]
1428		fn test_row_with_undefined() {
1429			let mut test_instance = test_instance_with_columns();
1430
1431			let shape = RowShape::testing(&[Type::Int2, Type::Boolean]);
1432			let mut row = shape.allocate();
1433			shape.set_values(&mut row, &[Value::none(), Value::Boolean(false)]);
1434
1435			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1436
1437			assert_eq!(test_instance[0], ColumnBuffer::int2_with_bitvec(vec![1, 0], vec![true, false]));
1438			assert_eq!(test_instance[1], ColumnBuffer::bool_with_bitvec([true, false], [true, true]));
1439		}
1440
1441		#[test]
1442		fn test_row_with_type_mismatch_fails() {
1443			let mut test_instance = test_instance_with_columns();
1444
1445			let shape = RowShape::testing(&[Type::Boolean, Type::Boolean]);
1446			let mut row = shape.allocate();
1447			shape.set_values(&mut row, &[Value::Boolean(true), Value::Boolean(true)]);
1448
1449			let result = test_instance.append_rows(&shape, [row], vec![]);
1450			assert!(result.is_err());
1451			assert!(result.unwrap_err().to_string().contains("type mismatch"));
1452		}
1453
1454		#[test]
1455		fn test_row_wrong_length_fails() {
1456			let mut test_instance = test_instance_with_columns();
1457
1458			let shape = RowShape::testing(&[Type::Int2]);
1459			let mut row = shape.allocate();
1460			shape.set_values(&mut row, &[Value::Int2(2)]);
1461
1462			let result = test_instance.append_rows(&shape, [row], vec![]);
1463			assert!(result.is_err());
1464			assert!(result.unwrap_err().to_string().contains("mismatched column count"));
1465		}
1466
1467		#[test]
1468		fn test_fallback_bool() {
1469			let mut test_instance = Columns::new(vec![
1470				ColumnWithName::bool("test_col", Vec::<bool>::new()),
1471				ColumnWithName::bool("none", Vec::<bool>::new()),
1472			]);
1473
1474			let shape = RowShape::testing(&[Type::Boolean, Type::Boolean]);
1475			let mut row_one = shape.allocate();
1476			shape.set_bool(&mut row_one, 0, true);
1477			shape.set_none(&mut row_one, 1);
1478
1479			test_instance.append_rows(&shape, [row_one], vec![]).unwrap();
1480
1481			assert_eq!(test_instance[0], ColumnBuffer::bool_with_bitvec([true], [true]));
1482
1483			assert_eq!(test_instance[1], ColumnBuffer::bool_with_bitvec([false], [false]));
1484		}
1485
1486		#[test]
1487		fn test_fallback_float4() {
1488			let mut test_instance = Columns::new(vec![
1489				ColumnWithName::float4("test_col", Vec::<f32>::new()),
1490				ColumnWithName::float4("none", Vec::<f32>::new()),
1491			]);
1492
1493			let shape = RowShape::testing(&[Type::Float4, Type::Float4]);
1494			let mut row = shape.allocate();
1495			shape.set_f32(&mut row, 0, 1.5);
1496			shape.set_none(&mut row, 1);
1497
1498			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1499
1500			assert_eq!(test_instance[0], ColumnBuffer::float4_with_bitvec([1.5], [true]));
1501			assert_eq!(test_instance[1], ColumnBuffer::float4_with_bitvec([0.0], [false]));
1502		}
1503
1504		#[test]
1505		fn test_fallback_float8() {
1506			let mut test_instance = Columns::new(vec![
1507				ColumnWithName::float8("test_col", Vec::<f64>::new()),
1508				ColumnWithName::float8("none", Vec::<f64>::new()),
1509			]);
1510
1511			let shape = RowShape::testing(&[Type::Float8, Type::Float8]);
1512			let mut row = shape.allocate();
1513			shape.set_f64(&mut row, 0, 2.5);
1514			shape.set_none(&mut row, 1);
1515
1516			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1517
1518			assert_eq!(test_instance[0], ColumnBuffer::float8_with_bitvec([2.5], [true]));
1519			assert_eq!(test_instance[1], ColumnBuffer::float8_with_bitvec([0.0], [false]));
1520		}
1521
1522		#[test]
1523		fn test_fallback_int1() {
1524			let mut test_instance = Columns::new(vec![
1525				ColumnWithName::int1("test_col", Vec::<i8>::new()),
1526				ColumnWithName::int1("none", Vec::<i8>::new()),
1527			]);
1528
1529			let shape = RowShape::testing(&[Type::Int1, Type::Int1]);
1530			let mut row = shape.allocate();
1531			shape.set_i8(&mut row, 0, 42);
1532			shape.set_none(&mut row, 1);
1533
1534			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1535
1536			assert_eq!(test_instance[0], ColumnBuffer::int1_with_bitvec([42], [true]));
1537			assert_eq!(test_instance[1], ColumnBuffer::int1_with_bitvec([0], [false]));
1538		}
1539
1540		#[test]
1541		fn test_fallback_int2() {
1542			let mut test_instance = Columns::new(vec![
1543				ColumnWithName::int2("test_col", Vec::<i16>::new()),
1544				ColumnWithName::int2("none", Vec::<i16>::new()),
1545			]);
1546
1547			let shape = RowShape::testing(&[Type::Int2, Type::Int2]);
1548			let mut row = shape.allocate();
1549			shape.set_i16(&mut row, 0, -1234i16);
1550			shape.set_none(&mut row, 1);
1551
1552			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1553
1554			assert_eq!(test_instance[0], ColumnBuffer::int2_with_bitvec([-1234], [true]));
1555			assert_eq!(test_instance[1], ColumnBuffer::int2_with_bitvec([0], [false]));
1556		}
1557
1558		#[test]
1559		fn test_fallback_int4() {
1560			let mut test_instance = Columns::new(vec![
1561				ColumnWithName::int4("test_col", Vec::<i32>::new()),
1562				ColumnWithName::int4("none", Vec::<i32>::new()),
1563			]);
1564
1565			let shape = RowShape::testing(&[Type::Int4, Type::Int4]);
1566			let mut row = shape.allocate();
1567			shape.set_i32(&mut row, 0, 56789);
1568			shape.set_none(&mut row, 1);
1569
1570			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1571
1572			assert_eq!(test_instance[0], ColumnBuffer::int4_with_bitvec([56789], [true]));
1573			assert_eq!(test_instance[1], ColumnBuffer::int4_with_bitvec([0], [false]));
1574		}
1575
1576		#[test]
1577		fn test_fallback_int8() {
1578			let mut test_instance = Columns::new(vec![
1579				ColumnWithName::int8("test_col", Vec::<i64>::new()),
1580				ColumnWithName::int8("none", Vec::<i64>::new()),
1581			]);
1582
1583			let shape = RowShape::testing(&[Type::Int8, Type::Int8]);
1584			let mut row = shape.allocate();
1585			shape.set_i64(&mut row, 0, -987654321);
1586			shape.set_none(&mut row, 1);
1587
1588			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1589
1590			assert_eq!(test_instance[0], ColumnBuffer::int8_with_bitvec([-987654321], [true]));
1591			assert_eq!(test_instance[1], ColumnBuffer::int8_with_bitvec([0], [false]));
1592		}
1593
1594		#[test]
1595		fn test_fallback_int16() {
1596			let mut test_instance = Columns::new(vec![
1597				ColumnWithName::int16("test_col", Vec::<i128>::new()),
1598				ColumnWithName::int16("none", Vec::<i128>::new()),
1599			]);
1600
1601			let shape = RowShape::testing(&[Type::Int16, Type::Int16]);
1602			let mut row = shape.allocate();
1603			shape.set_i128(&mut row, 0, 123456789012345678901234567890i128);
1604			shape.set_none(&mut row, 1);
1605
1606			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1607
1608			assert_eq!(
1609				test_instance[0],
1610				ColumnBuffer::int16_with_bitvec([123456789012345678901234567890i128], [true])
1611			);
1612			assert_eq!(test_instance[1], ColumnBuffer::int16_with_bitvec([0], [false]));
1613		}
1614
1615		#[test]
1616		fn test_fallback_string() {
1617			let mut test_instance = Columns::new(vec![
1618				ColumnWithName::utf8("test_col", Vec::<String>::new()),
1619				ColumnWithName::utf8("none", Vec::<String>::new()),
1620			]);
1621
1622			let shape = RowShape::testing(&[Type::Utf8, Type::Utf8]);
1623			let mut row = shape.allocate();
1624			shape.set_utf8(&mut row, 0, "reifydb");
1625			shape.set_none(&mut row, 1);
1626
1627			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1628
1629			assert_eq!(test_instance[0], ColumnBuffer::utf8_with_bitvec(["reifydb".to_string()], [true]));
1630			assert_eq!(test_instance[1], ColumnBuffer::utf8_with_bitvec(["".to_string()], [false]));
1631		}
1632
1633		#[test]
1634		fn test_fallback_uint1() {
1635			let mut test_instance = Columns::new(vec![
1636				ColumnWithName::uint1("test_col", Vec::<u8>::new()),
1637				ColumnWithName::uint1("none", Vec::<u8>::new()),
1638			]);
1639
1640			let shape = RowShape::testing(&[Type::Uint1, Type::Uint1]);
1641			let mut row = shape.allocate();
1642			shape.set_u8(&mut row, 0, 255);
1643			shape.set_none(&mut row, 1);
1644
1645			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1646
1647			assert_eq!(test_instance[0], ColumnBuffer::uint1_with_bitvec([255], [true]));
1648			assert_eq!(test_instance[1], ColumnBuffer::uint1_with_bitvec([0], [false]));
1649		}
1650
1651		#[test]
1652		fn test_fallback_uint2() {
1653			let mut test_instance = Columns::new(vec![
1654				ColumnWithName::uint2("test_col", Vec::<u16>::new()),
1655				ColumnWithName::uint2("none", Vec::<u16>::new()),
1656			]);
1657
1658			let shape = RowShape::testing(&[Type::Uint2, Type::Uint2]);
1659			let mut row = shape.allocate();
1660			shape.set_u16(&mut row, 0, 65535u16);
1661			shape.set_none(&mut row, 1);
1662
1663			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1664
1665			assert_eq!(test_instance[0], ColumnBuffer::uint2_with_bitvec([65535], [true]));
1666			assert_eq!(test_instance[1], ColumnBuffer::uint2_with_bitvec([0], [false]));
1667		}
1668
1669		#[test]
1670		fn test_fallback_uint4() {
1671			let mut test_instance = Columns::new(vec![
1672				ColumnWithName::uint4("test_col", Vec::<u32>::new()),
1673				ColumnWithName::uint4("none", Vec::<u32>::new()),
1674			]);
1675
1676			let shape = RowShape::testing(&[Type::Uint4, Type::Uint4]);
1677			let mut row = shape.allocate();
1678			shape.set_u32(&mut row, 0, 4294967295u32);
1679			shape.set_none(&mut row, 1);
1680
1681			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1682
1683			assert_eq!(test_instance[0], ColumnBuffer::uint4_with_bitvec([4294967295], [true]));
1684			assert_eq!(test_instance[1], ColumnBuffer::uint4_with_bitvec([0], [false]));
1685		}
1686
1687		#[test]
1688		fn test_fallback_uint8() {
1689			let mut test_instance = Columns::new(vec![
1690				ColumnWithName::uint8("test_col", Vec::<u64>::new()),
1691				ColumnWithName::uint8("none", Vec::<u64>::new()),
1692			]);
1693
1694			let shape = RowShape::testing(&[Type::Uint8, Type::Uint8]);
1695			let mut row = shape.allocate();
1696			shape.set_u64(&mut row, 0, 18446744073709551615u64);
1697			shape.set_none(&mut row, 1);
1698
1699			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1700
1701			assert_eq!(test_instance[0], ColumnBuffer::uint8_with_bitvec([18446744073709551615], [true]));
1702			assert_eq!(test_instance[1], ColumnBuffer::uint8_with_bitvec([0], [false]));
1703		}
1704
1705		#[test]
1706		fn test_fallback_uint16() {
1707			let mut test_instance = Columns::new(vec![
1708				ColumnWithName::uint16("test_col", Vec::<u128>::new()),
1709				ColumnWithName::uint16("none", Vec::<u128>::new()),
1710			]);
1711
1712			let shape = RowShape::testing(&[Type::Uint16, Type::Uint16]);
1713			let mut row = shape.allocate();
1714			shape.set_u128(&mut row, 0, 340282366920938463463374607431768211455u128);
1715			shape.set_none(&mut row, 1);
1716
1717			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1718
1719			assert_eq!(
1720				test_instance[0],
1721				ColumnBuffer::uint16_with_bitvec([340282366920938463463374607431768211455u128], [true])
1722			);
1723			assert_eq!(test_instance[1], ColumnBuffer::uint16_with_bitvec([0], [false]));
1724		}
1725
1726		#[test]
1727		fn test_all_defined_dictionary_id() {
1728			let constraint = TypeConstraint::dictionary(DictionaryId::from(1u64), Type::Uint4);
1729			let shape = RowShape::new(vec![RowShapeField::new("status", constraint)]);
1730
1731			let mut test_instance = Columns::new(vec![ColumnWithName::dictionary_id(
1732				"status",
1733				Vec::<DictionaryEntryId>::new(),
1734			)]);
1735
1736			let mut row_one = shape.allocate();
1737			shape.set_values(&mut row_one, &[Value::DictionaryId(DictionaryEntryId::U4(10))]);
1738			let mut row_two = shape.allocate();
1739			shape.set_values(&mut row_two, &[Value::DictionaryId(DictionaryEntryId::U4(20))]);
1740
1741			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1742
1743			assert_eq!(test_instance[0].get_value(0), Value::DictionaryId(DictionaryEntryId::U4(10)));
1744			assert_eq!(test_instance[0].get_value(1), Value::DictionaryId(DictionaryEntryId::U4(20)));
1745		}
1746
1747		#[test]
1748		fn test_fallback_dictionary_id() {
1749			let dict_constraint = TypeConstraint::dictionary(DictionaryId::from(1u64), Type::Uint4);
1750			let shape = RowShape::new(vec![
1751				RowShapeField::new("dict_col", dict_constraint),
1752				RowShapeField::unconstrained("bool_col", Type::Boolean),
1753			]);
1754
1755			let mut test_instance = Columns::new(vec![
1756				ColumnWithName::dictionary_id("dict_col", Vec::<DictionaryEntryId>::new()),
1757				ColumnWithName::bool("bool_col", Vec::<bool>::new()),
1758			]);
1759
1760			let mut row = shape.allocate();
1761			shape.set_values(&mut row, &[Value::none(), Value::Boolean(true)]);
1762
1763			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1764
1765			// Dictionary column should be undefined
1766			assert!(!test_instance[0].is_defined(0));
1767			// Bool column should be defined
1768			assert_eq!(test_instance[1].get_value(0), Value::Boolean(true));
1769		}
1770
1771		#[test]
1772		fn test_before_undefined_dictionary_id() {
1773			let constraint = TypeConstraint::dictionary(DictionaryId::from(2u64), Type::Uint4);
1774			let shape = RowShape::new(vec![RowShapeField::new("tag", constraint)]);
1775
1776			let mut test_instance =
1777				Columns::new(vec![ColumnWithName::undefined_typed("tag", Type::Boolean, 2)]);
1778
1779			let mut row = shape.allocate();
1780			shape.set_values(&mut row, &[Value::DictionaryId(DictionaryEntryId::U4(5))]);
1781
1782			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1783
1784			// First two are undefined (promoted from Undefined column), third is defined
1785			assert!(!test_instance[0].is_defined(0));
1786			assert!(!test_instance[0].is_defined(1));
1787			assert!(test_instance[0].is_defined(2));
1788			assert_eq!(test_instance[0].get_value(2), Value::DictionaryId(DictionaryEntryId::U4(5)));
1789		}
1790
1791		fn test_instance_with_columns() -> Columns {
1792			Columns::new(vec![
1793				ColumnWithName::new(Fragment::internal("int2"), ColumnBuffer::int2(vec![1])),
1794				ColumnWithName::new(Fragment::internal("bool"), ColumnBuffer::bool(vec![true])),
1795			])
1796		}
1797	}
1798}