Skip to main content

reifydb_core/value/column/transform/
append.rs

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