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