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