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_codec::encoded::{row::EncodedRow, shape::RowShape};
5use reifydb_value::{
6	Result, reifydb_assertions,
7	storage::DataBitVec,
8	util::bitvec::BitVec,
9	value::{
10		Value,
11		blob::Blob,
12		constraint::Constraint,
13		date::Date,
14		datetime::DateTime,
15		decimal::Decimal,
16		duration::Duration,
17		int::Int,
18		row_number::RowNumber,
19		time::Time,
20		uint::Uint,
21		uuid::{Uuid4, Uuid7},
22		value_type::ValueType,
23	},
24};
25use uuid::Uuid;
26
27use crate::{
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_codec::encoded::shape::{RowShape, RowShapeField};
951		use reifydb_value::{
952			fragment::Fragment,
953			util::bitvec::BitVec,
954			value::{
955				Value,
956				blob::Blob,
957				constraint::TypeConstraint,
958				dictionary::{DictionaryEntryId, DictionaryId},
959				identity::IdentityId,
960				ordered_f32::OrderedF32,
961				ordered_f64::OrderedF64,
962				value_type::ValueType,
963			},
964		};
965
966		use crate::value::column::{ColumnBuffer, ColumnWithName, columns::Columns};
967
968		#[test]
969		fn test_before_undefined_bool() {
970			let mut test_instance =
971				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
972
973			let shape = RowShape::testing(&[ValueType::Boolean]);
974			let mut row = shape.allocate();
975			shape.set_values(&mut row, &[Value::Boolean(true)]);
976
977			test_instance.append_rows(&shape, [row], vec![]).unwrap();
978
979			assert_eq!(
980				test_instance[0],
981				ColumnBuffer::bool_with_bitvec(
982					[false, false, true],
983					BitVec::from_slice(&[false, false, true])
984				)
985			);
986		}
987
988		#[test]
989		fn test_before_undefined_float4() {
990			let mut test_instance =
991				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
992			let shape = RowShape::testing(&[ValueType::Float4]);
993			let mut row = shape.allocate();
994			shape.set_values(&mut row, &[Value::Float4(OrderedF32::try_from(1.5).unwrap())]);
995			test_instance.append_rows(&shape, [row], vec![]).unwrap();
996
997			assert_eq!(
998				test_instance[0],
999				ColumnBuffer::float4_with_bitvec(
1000					[0.0, 0.0, 1.5],
1001					BitVec::from_slice(&[false, false, true])
1002				)
1003			);
1004		}
1005
1006		#[test]
1007		fn test_before_undefined_float8() {
1008			let mut test_instance =
1009				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1010			let shape = RowShape::testing(&[ValueType::Float8]);
1011			let mut row = shape.allocate();
1012			shape.set_values(&mut row, &[Value::Float8(OrderedF64::try_from(2.25).unwrap())]);
1013			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1014
1015			assert_eq!(
1016				test_instance[0],
1017				ColumnBuffer::float8_with_bitvec(
1018					[0.0, 0.0, 2.25],
1019					BitVec::from_slice(&[false, false, true])
1020				)
1021			);
1022		}
1023
1024		#[test]
1025		fn test_before_undefined_int1() {
1026			let mut test_instance =
1027				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1028			let shape = RowShape::testing(&[ValueType::Int1]);
1029			let mut row = shape.allocate();
1030			shape.set_values(&mut row, &[Value::Int1(42)]);
1031			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1032
1033			assert_eq!(
1034				test_instance[0],
1035				ColumnBuffer::int1_with_bitvec([0, 0, 42], BitVec::from_slice(&[false, false, true]))
1036			);
1037		}
1038
1039		#[test]
1040		fn test_before_undefined_int2() {
1041			let mut test_instance =
1042				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1043			let shape = RowShape::testing(&[ValueType::Int2]);
1044			let mut row = shape.allocate();
1045			shape.set_values(&mut row, &[Value::Int2(-1234)]);
1046			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1047
1048			assert_eq!(
1049				test_instance[0],
1050				ColumnBuffer::int2_with_bitvec(
1051					[0, 0, -1234],
1052					BitVec::from_slice(&[false, false, true])
1053				)
1054			);
1055		}
1056
1057		#[test]
1058		fn test_before_undefined_int4() {
1059			let mut test_instance =
1060				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1061			let shape = RowShape::testing(&[ValueType::Int4]);
1062			let mut row = shape.allocate();
1063			shape.set_values(&mut row, &[Value::Int4(56789)]);
1064			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1065
1066			assert_eq!(
1067				test_instance[0],
1068				ColumnBuffer::int4_with_bitvec(
1069					[0, 0, 56789],
1070					BitVec::from_slice(&[false, false, true])
1071				)
1072			);
1073		}
1074
1075		#[test]
1076		fn test_before_undefined_int8() {
1077			let mut test_instance =
1078				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1079			let shape = RowShape::testing(&[ValueType::Int8]);
1080			let mut row = shape.allocate();
1081			shape.set_values(&mut row, &[Value::Int8(-987654321)]);
1082			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1083
1084			assert_eq!(
1085				test_instance[0],
1086				ColumnBuffer::int8_with_bitvec(
1087					[0, 0, -987654321],
1088					BitVec::from_slice(&[false, false, true])
1089				)
1090			);
1091		}
1092
1093		#[test]
1094		fn test_before_undefined_int16() {
1095			let mut test_instance =
1096				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1097			let shape = RowShape::testing(&[ValueType::Int16]);
1098			let mut row = shape.allocate();
1099			shape.set_values(&mut row, &[Value::Int16(123456789012345678901234567890i128)]);
1100			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1101
1102			assert_eq!(
1103				test_instance[0],
1104				ColumnBuffer::int16_with_bitvec(
1105					[0, 0, 123456789012345678901234567890i128],
1106					BitVec::from_slice(&[false, false, true])
1107				)
1108			);
1109		}
1110
1111		#[test]
1112		fn test_before_undefined_string() {
1113			let mut test_instance =
1114				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1115			let shape = RowShape::testing(&[ValueType::Utf8]);
1116			let mut row = shape.allocate();
1117			shape.set_values(&mut row, &[Value::Utf8("reifydb".into())]);
1118			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1119
1120			assert_eq!(
1121				test_instance[0],
1122				ColumnBuffer::utf8_with_bitvec(
1123					["".to_string(), "".to_string(), "reifydb".to_string()],
1124					BitVec::from_slice(&[false, false, true])
1125				)
1126			);
1127		}
1128
1129		#[test]
1130		fn test_before_undefined_uint1() {
1131			let mut test_instance =
1132				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1133			let shape = RowShape::testing(&[ValueType::Uint1]);
1134			let mut row = shape.allocate();
1135			shape.set_values(&mut row, &[Value::Uint1(255)]);
1136			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1137
1138			assert_eq!(
1139				test_instance[0],
1140				ColumnBuffer::uint1_with_bitvec([0, 0, 255], BitVec::from_slice(&[false, false, true]))
1141			);
1142		}
1143
1144		#[test]
1145		fn test_before_undefined_uint2() {
1146			let mut test_instance =
1147				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1148			let shape = RowShape::testing(&[ValueType::Uint2]);
1149			let mut row = shape.allocate();
1150			shape.set_values(&mut row, &[Value::Uint2(65535)]);
1151			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1152
1153			assert_eq!(
1154				test_instance[0],
1155				ColumnBuffer::uint2_with_bitvec(
1156					[0, 0, 65535],
1157					BitVec::from_slice(&[false, false, true])
1158				)
1159			);
1160		}
1161
1162		#[test]
1163		fn test_before_undefined_uint4() {
1164			let mut test_instance =
1165				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1166			let shape = RowShape::testing(&[ValueType::Uint4]);
1167			let mut row = shape.allocate();
1168			shape.set_values(&mut row, &[Value::Uint4(4294967295)]);
1169			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1170
1171			assert_eq!(
1172				test_instance[0],
1173				ColumnBuffer::uint4_with_bitvec(
1174					[0, 0, 4294967295],
1175					BitVec::from_slice(&[false, false, true])
1176				)
1177			);
1178		}
1179
1180		#[test]
1181		fn test_before_undefined_uint8() {
1182			let mut test_instance =
1183				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1184			let shape = RowShape::testing(&[ValueType::Uint8]);
1185			let mut row = shape.allocate();
1186			shape.set_values(&mut row, &[Value::Uint8(18446744073709551615)]);
1187			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1188
1189			assert_eq!(
1190				test_instance[0],
1191				ColumnBuffer::uint8_with_bitvec(
1192					[0, 0, 18446744073709551615],
1193					BitVec::from_slice(&[false, false, true])
1194				)
1195			);
1196		}
1197
1198		#[test]
1199		fn test_before_undefined_uint16() {
1200			let mut test_instance =
1201				Columns::new(vec![ColumnWithName::undefined_typed("test_col", ValueType::Boolean, 2)]);
1202			let shape = RowShape::testing(&[ValueType::Uint16]);
1203			let mut row = shape.allocate();
1204			shape.set_values(&mut row, &[Value::Uint16(340282366920938463463374607431768211455u128)]);
1205			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1206
1207			assert_eq!(
1208				test_instance[0],
1209				ColumnBuffer::uint16_with_bitvec(
1210					[0, 0, 340282366920938463463374607431768211455u128],
1211					BitVec::from_slice(&[false, false, true])
1212				)
1213			);
1214		}
1215
1216		#[test]
1217		fn test_mismatched_columns() {
1218			let mut test_instance = Columns::new(vec![]);
1219
1220			let shape = RowShape::testing(&[ValueType::Int2]);
1221			let mut row = shape.allocate();
1222			shape.set_values(&mut row, &[Value::Int2(2)]);
1223
1224			let err = test_instance.append_rows(&shape, [row], vec![]).err().unwrap();
1225			assert!(err.to_string().contains("mismatched column count: expected 0, got 1"));
1226		}
1227
1228		#[test]
1229		fn test_ok() {
1230			let mut test_instance = test_instance_with_columns();
1231
1232			let shape = RowShape::testing(&[ValueType::Int2, ValueType::Boolean]);
1233			let mut row_one = shape.allocate();
1234			shape.set_values(&mut row_one, &[Value::Int2(2), Value::Boolean(true)]);
1235			let mut row_two = shape.allocate();
1236			shape.set_values(&mut row_two, &[Value::Int2(3), Value::Boolean(false)]);
1237
1238			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1239
1240			assert_eq!(test_instance[0], ColumnBuffer::int2([1, 2, 3]));
1241			assert_eq!(test_instance[1], ColumnBuffer::bool([true, true, false]));
1242		}
1243
1244		#[test]
1245		fn test_all_defined_bool() {
1246			let mut test_instance =
1247				Columns::new(vec![ColumnWithName::bool("test_col", Vec::<bool>::new())]);
1248
1249			let shape = RowShape::testing(&[ValueType::Boolean]);
1250			let mut row_one = shape.allocate();
1251			shape.set_bool(&mut row_one, 0, true);
1252			let mut row_two = shape.allocate();
1253			shape.set_bool(&mut row_two, 0, false);
1254
1255			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1256
1257			assert_eq!(test_instance[0], ColumnBuffer::bool([true, false]));
1258		}
1259
1260		#[test]
1261		fn test_all_defined_float4() {
1262			let mut test_instance =
1263				Columns::new(vec![ColumnWithName::float4("test_col", Vec::<f32>::new())]);
1264
1265			let shape = RowShape::testing(&[ValueType::Float4]);
1266			let mut row_one = shape.allocate();
1267			shape.set_values(&mut row_one, &[Value::Float4(OrderedF32::try_from(1.0).unwrap())]);
1268			let mut row_two = shape.allocate();
1269			shape.set_values(&mut row_two, &[Value::Float4(OrderedF32::try_from(2.0).unwrap())]);
1270
1271			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1272
1273			assert_eq!(test_instance[0], ColumnBuffer::float4([1.0, 2.0]));
1274		}
1275
1276		#[test]
1277		fn test_all_defined_float8() {
1278			let mut test_instance =
1279				Columns::new(vec![ColumnWithName::float8("test_col", Vec::<f64>::new())]);
1280
1281			let shape = RowShape::testing(&[ValueType::Float8]);
1282			let mut row_one = shape.allocate();
1283			shape.set_values(&mut row_one, &[Value::Float8(OrderedF64::try_from(1.0).unwrap())]);
1284			let mut row_two = shape.allocate();
1285			shape.set_values(&mut row_two, &[Value::Float8(OrderedF64::try_from(2.0).unwrap())]);
1286
1287			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1288
1289			assert_eq!(test_instance[0], ColumnBuffer::float8([1.0, 2.0]));
1290		}
1291
1292		#[test]
1293		fn test_all_defined_int1() {
1294			let mut test_instance = Columns::new(vec![ColumnWithName::int1("test_col", Vec::<i8>::new())]);
1295
1296			let shape = RowShape::testing(&[ValueType::Int1]);
1297			let mut row_one = shape.allocate();
1298			shape.set_values(&mut row_one, &[Value::Int1(1)]);
1299			let mut row_two = shape.allocate();
1300			shape.set_values(&mut row_two, &[Value::Int1(2)]);
1301
1302			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1303
1304			assert_eq!(test_instance[0], ColumnBuffer::int1([1, 2]));
1305		}
1306
1307		#[test]
1308		fn test_all_defined_int2() {
1309			let mut test_instance = Columns::new(vec![ColumnWithName::int2("test_col", Vec::<i16>::new())]);
1310
1311			let shape = RowShape::testing(&[ValueType::Int2]);
1312			let mut row_one = shape.allocate();
1313			shape.set_values(&mut row_one, &[Value::Int2(100)]);
1314			let mut row_two = shape.allocate();
1315			shape.set_values(&mut row_two, &[Value::Int2(200)]);
1316
1317			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1318
1319			assert_eq!(test_instance[0], ColumnBuffer::int2([100, 200]));
1320		}
1321
1322		#[test]
1323		fn test_all_defined_int4() {
1324			let mut test_instance = Columns::new(vec![ColumnWithName::int4("test_col", Vec::<i32>::new())]);
1325
1326			let shape = RowShape::testing(&[ValueType::Int4]);
1327			let mut row_one = shape.allocate();
1328			shape.set_values(&mut row_one, &[Value::Int4(1000)]);
1329			let mut row_two = shape.allocate();
1330			shape.set_values(&mut row_two, &[Value::Int4(2000)]);
1331
1332			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1333
1334			assert_eq!(test_instance[0], ColumnBuffer::int4([1000, 2000]));
1335		}
1336
1337		#[test]
1338		fn test_all_defined_int8() {
1339			let mut test_instance = Columns::new(vec![ColumnWithName::int8("test_col", Vec::<i64>::new())]);
1340
1341			let shape = RowShape::testing(&[ValueType::Int8]);
1342			let mut row_one = shape.allocate();
1343			shape.set_values(&mut row_one, &[Value::Int8(10000)]);
1344			let mut row_two = shape.allocate();
1345			shape.set_values(&mut row_two, &[Value::Int8(20000)]);
1346
1347			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1348
1349			assert_eq!(test_instance[0], ColumnBuffer::int8([10000, 20000]));
1350		}
1351
1352		#[test]
1353		fn test_all_defined_int16() {
1354			let mut test_instance =
1355				Columns::new(vec![ColumnWithName::int16("test_col", Vec::<i128>::new())]);
1356
1357			let shape = RowShape::testing(&[ValueType::Int16]);
1358			let mut row_one = shape.allocate();
1359			shape.set_values(&mut row_one, &[Value::Int16(1000)]);
1360			let mut row_two = shape.allocate();
1361			shape.set_values(&mut row_two, &[Value::Int16(2000)]);
1362
1363			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1364
1365			assert_eq!(test_instance[0], ColumnBuffer::int16([1000, 2000]));
1366		}
1367
1368		#[test]
1369		fn test_all_defined_string() {
1370			let mut test_instance =
1371				Columns::new(vec![ColumnWithName::utf8("test_col", Vec::<String>::new())]);
1372
1373			let shape = RowShape::testing(&[ValueType::Utf8]);
1374			let mut row_one = shape.allocate();
1375			shape.set_values(&mut row_one, &[Value::Utf8("a".into())]);
1376			let mut row_two = shape.allocate();
1377			shape.set_values(&mut row_two, &[Value::Utf8("b".into())]);
1378
1379			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1380
1381			assert_eq!(test_instance[0], ColumnBuffer::utf8(["a".to_string(), "b".to_string()]));
1382		}
1383
1384		#[test]
1385		fn test_all_defined_uint1() {
1386			let mut test_instance = Columns::new(vec![ColumnWithName::uint1("test_col", Vec::<u8>::new())]);
1387
1388			let shape = RowShape::testing(&[ValueType::Uint1]);
1389			let mut row_one = shape.allocate();
1390			shape.set_values(&mut row_one, &[Value::Uint1(1)]);
1391			let mut row_two = shape.allocate();
1392			shape.set_values(&mut row_two, &[Value::Uint1(2)]);
1393
1394			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1395
1396			assert_eq!(test_instance[0], ColumnBuffer::uint1([1, 2]));
1397		}
1398
1399		#[test]
1400		fn test_all_defined_uint2() {
1401			let mut test_instance =
1402				Columns::new(vec![ColumnWithName::uint2("test_col", Vec::<u16>::new())]);
1403
1404			let shape = RowShape::testing(&[ValueType::Uint2]);
1405			let mut row_one = shape.allocate();
1406			shape.set_values(&mut row_one, &[Value::Uint2(100)]);
1407			let mut row_two = shape.allocate();
1408			shape.set_values(&mut row_two, &[Value::Uint2(200)]);
1409
1410			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1411
1412			assert_eq!(test_instance[0], ColumnBuffer::uint2([100, 200]));
1413		}
1414
1415		#[test]
1416		fn test_all_defined_uint4() {
1417			let mut test_instance =
1418				Columns::new(vec![ColumnWithName::uint4("test_col", Vec::<u32>::new())]);
1419
1420			let shape = RowShape::testing(&[ValueType::Uint4]);
1421			let mut row_one = shape.allocate();
1422			shape.set_values(&mut row_one, &[Value::Uint4(1000)]);
1423			let mut row_two = shape.allocate();
1424			shape.set_values(&mut row_two, &[Value::Uint4(2000)]);
1425
1426			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1427
1428			assert_eq!(test_instance[0], ColumnBuffer::uint4([1000, 2000]));
1429		}
1430
1431		#[test]
1432		fn test_all_defined_uint8() {
1433			let mut test_instance =
1434				Columns::new(vec![ColumnWithName::uint8("test_col", Vec::<u64>::new())]);
1435
1436			let shape = RowShape::testing(&[ValueType::Uint8]);
1437			let mut row_one = shape.allocate();
1438			shape.set_values(&mut row_one, &[Value::Uint8(10000)]);
1439			let mut row_two = shape.allocate();
1440			shape.set_values(&mut row_two, &[Value::Uint8(20000)]);
1441
1442			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1443
1444			assert_eq!(test_instance[0], ColumnBuffer::uint8([10000, 20000]));
1445		}
1446
1447		#[test]
1448		fn test_all_defined_uint16() {
1449			let mut test_instance =
1450				Columns::new(vec![ColumnWithName::uint16("test_col", Vec::<u128>::new())]);
1451
1452			let shape = RowShape::testing(&[ValueType::Uint16]);
1453			let mut row_one = shape.allocate();
1454			shape.set_values(&mut row_one, &[Value::Uint16(1000)]);
1455			let mut row_two = shape.allocate();
1456			shape.set_values(&mut row_two, &[Value::Uint16(2000)]);
1457
1458			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1459
1460			assert_eq!(test_instance[0], ColumnBuffer::uint16([1000, 2000]));
1461		}
1462
1463		#[test]
1464		fn test_row_with_undefined() {
1465			let mut test_instance = test_instance_with_columns();
1466
1467			let shape = RowShape::testing(&[ValueType::Int2, ValueType::Boolean]);
1468			let mut row = shape.allocate();
1469			shape.set_values(&mut row, &[Value::none(), Value::Boolean(false)]);
1470
1471			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1472
1473			assert_eq!(test_instance[0], ColumnBuffer::int2_with_bitvec(vec![1, 0], vec![true, false]));
1474			assert_eq!(test_instance[1], ColumnBuffer::bool_with_bitvec([true, false], [true, true]));
1475		}
1476
1477		#[test]
1478		fn test_row_with_type_mismatch_fails() {
1479			let mut test_instance = test_instance_with_columns();
1480
1481			let shape = RowShape::testing(&[ValueType::Boolean, ValueType::Boolean]);
1482			let mut row = shape.allocate();
1483			shape.set_values(&mut row, &[Value::Boolean(true), Value::Boolean(true)]);
1484
1485			let result = test_instance.append_rows(&shape, [row], vec![]);
1486			assert!(result.is_err());
1487			assert!(result.unwrap_err().to_string().contains("type mismatch"));
1488		}
1489
1490		#[test]
1491		fn test_row_wrong_length_fails() {
1492			let mut test_instance = test_instance_with_columns();
1493
1494			let shape = RowShape::testing(&[ValueType::Int2]);
1495			let mut row = shape.allocate();
1496			shape.set_values(&mut row, &[Value::Int2(2)]);
1497
1498			let result = test_instance.append_rows(&shape, [row], vec![]);
1499			assert!(result.is_err());
1500			assert!(result.unwrap_err().to_string().contains("mismatched column count"));
1501		}
1502
1503		#[test]
1504		fn test_fallback_bool() {
1505			let mut test_instance = Columns::new(vec![
1506				ColumnWithName::bool("test_col", Vec::<bool>::new()),
1507				ColumnWithName::bool("none", Vec::<bool>::new()),
1508			]);
1509
1510			let shape = RowShape::testing(&[ValueType::Boolean, ValueType::Boolean]);
1511			let mut row_one = shape.allocate();
1512			shape.set_bool(&mut row_one, 0, true);
1513			shape.set_none(&mut row_one, 1);
1514
1515			test_instance.append_rows(&shape, [row_one], vec![]).unwrap();
1516
1517			assert_eq!(test_instance[0], ColumnBuffer::bool_with_bitvec([true], [true]));
1518
1519			assert_eq!(test_instance[1], ColumnBuffer::bool_with_bitvec([false], [false]));
1520		}
1521
1522		#[test]
1523		fn test_fallback_float4() {
1524			let mut test_instance = Columns::new(vec![
1525				ColumnWithName::float4("test_col", Vec::<f32>::new()),
1526				ColumnWithName::float4("none", Vec::<f32>::new()),
1527			]);
1528
1529			let shape = RowShape::testing(&[ValueType::Float4, ValueType::Float4]);
1530			let mut row = shape.allocate();
1531			shape.set_f32(&mut row, 0, 1.5);
1532			shape.set_none(&mut row, 1);
1533
1534			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1535
1536			assert_eq!(test_instance[0], ColumnBuffer::float4_with_bitvec([1.5], [true]));
1537			assert_eq!(test_instance[1], ColumnBuffer::float4_with_bitvec([0.0], [false]));
1538		}
1539
1540		#[test]
1541		fn test_fallback_float8() {
1542			let mut test_instance = Columns::new(vec![
1543				ColumnWithName::float8("test_col", Vec::<f64>::new()),
1544				ColumnWithName::float8("none", Vec::<f64>::new()),
1545			]);
1546
1547			let shape = RowShape::testing(&[ValueType::Float8, ValueType::Float8]);
1548			let mut row = shape.allocate();
1549			shape.set_f64(&mut row, 0, 2.5);
1550			shape.set_none(&mut row, 1);
1551
1552			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1553
1554			assert_eq!(test_instance[0], ColumnBuffer::float8_with_bitvec([2.5], [true]));
1555			assert_eq!(test_instance[1], ColumnBuffer::float8_with_bitvec([0.0], [false]));
1556		}
1557
1558		#[test]
1559		fn test_fallback_int1() {
1560			let mut test_instance = Columns::new(vec![
1561				ColumnWithName::int1("test_col", Vec::<i8>::new()),
1562				ColumnWithName::int1("none", Vec::<i8>::new()),
1563			]);
1564
1565			let shape = RowShape::testing(&[ValueType::Int1, ValueType::Int1]);
1566			let mut row = shape.allocate();
1567			shape.set_i8(&mut row, 0, 42);
1568			shape.set_none(&mut row, 1);
1569
1570			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1571
1572			assert_eq!(test_instance[0], ColumnBuffer::int1_with_bitvec([42], [true]));
1573			assert_eq!(test_instance[1], ColumnBuffer::int1_with_bitvec([0], [false]));
1574		}
1575
1576		#[test]
1577		fn test_fallback_int2() {
1578			let mut test_instance = Columns::new(vec![
1579				ColumnWithName::int2("test_col", Vec::<i16>::new()),
1580				ColumnWithName::int2("none", Vec::<i16>::new()),
1581			]);
1582
1583			let shape = RowShape::testing(&[ValueType::Int2, ValueType::Int2]);
1584			let mut row = shape.allocate();
1585			shape.set_i16(&mut row, 0, -1234i16);
1586			shape.set_none(&mut row, 1);
1587
1588			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1589
1590			assert_eq!(test_instance[0], ColumnBuffer::int2_with_bitvec([-1234], [true]));
1591			assert_eq!(test_instance[1], ColumnBuffer::int2_with_bitvec([0], [false]));
1592		}
1593
1594		#[test]
1595		fn test_fallback_int4() {
1596			let mut test_instance = Columns::new(vec![
1597				ColumnWithName::int4("test_col", Vec::<i32>::new()),
1598				ColumnWithName::int4("none", Vec::<i32>::new()),
1599			]);
1600
1601			let shape = RowShape::testing(&[ValueType::Int4, ValueType::Int4]);
1602			let mut row = shape.allocate();
1603			shape.set_i32(&mut row, 0, 56789);
1604			shape.set_none(&mut row, 1);
1605
1606			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1607
1608			assert_eq!(test_instance[0], ColumnBuffer::int4_with_bitvec([56789], [true]));
1609			assert_eq!(test_instance[1], ColumnBuffer::int4_with_bitvec([0], [false]));
1610		}
1611
1612		#[test]
1613		fn test_fallback_int8() {
1614			let mut test_instance = Columns::new(vec![
1615				ColumnWithName::int8("test_col", Vec::<i64>::new()),
1616				ColumnWithName::int8("none", Vec::<i64>::new()),
1617			]);
1618
1619			let shape = RowShape::testing(&[ValueType::Int8, ValueType::Int8]);
1620			let mut row = shape.allocate();
1621			shape.set_i64(&mut row, 0, -987654321);
1622			shape.set_none(&mut row, 1);
1623
1624			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1625
1626			assert_eq!(test_instance[0], ColumnBuffer::int8_with_bitvec([-987654321], [true]));
1627			assert_eq!(test_instance[1], ColumnBuffer::int8_with_bitvec([0], [false]));
1628		}
1629
1630		#[test]
1631		fn test_fallback_int16() {
1632			let mut test_instance = Columns::new(vec![
1633				ColumnWithName::int16("test_col", Vec::<i128>::new()),
1634				ColumnWithName::int16("none", Vec::<i128>::new()),
1635			]);
1636
1637			let shape = RowShape::testing(&[ValueType::Int16, ValueType::Int16]);
1638			let mut row = shape.allocate();
1639			shape.set_i128(&mut row, 0, 123456789012345678901234567890i128);
1640			shape.set_none(&mut row, 1);
1641
1642			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1643
1644			assert_eq!(
1645				test_instance[0],
1646				ColumnBuffer::int16_with_bitvec([123456789012345678901234567890i128], [true])
1647			);
1648			assert_eq!(test_instance[1], ColumnBuffer::int16_with_bitvec([0], [false]));
1649		}
1650
1651		#[test]
1652		fn test_fallback_string() {
1653			let mut test_instance = Columns::new(vec![
1654				ColumnWithName::utf8("test_col", Vec::<String>::new()),
1655				ColumnWithName::utf8("none", Vec::<String>::new()),
1656			]);
1657
1658			let shape = RowShape::testing(&[ValueType::Utf8, ValueType::Utf8]);
1659			let mut row = shape.allocate();
1660			shape.set_utf8(&mut row, 0, "reifydb");
1661			shape.set_none(&mut row, 1);
1662
1663			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1664
1665			assert_eq!(test_instance[0], ColumnBuffer::utf8_with_bitvec(["reifydb".to_string()], [true]));
1666			assert_eq!(test_instance[1], ColumnBuffer::utf8_with_bitvec(["".to_string()], [false]));
1667		}
1668
1669		#[test]
1670		fn test_fallback_uint1() {
1671			let mut test_instance = Columns::new(vec![
1672				ColumnWithName::uint1("test_col", Vec::<u8>::new()),
1673				ColumnWithName::uint1("none", Vec::<u8>::new()),
1674			]);
1675
1676			let shape = RowShape::testing(&[ValueType::Uint1, ValueType::Uint1]);
1677			let mut row = shape.allocate();
1678			shape.set_u8(&mut row, 0, 255);
1679			shape.set_none(&mut row, 1);
1680
1681			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1682
1683			assert_eq!(test_instance[0], ColumnBuffer::uint1_with_bitvec([255], [true]));
1684			assert_eq!(test_instance[1], ColumnBuffer::uint1_with_bitvec([0], [false]));
1685		}
1686
1687		#[test]
1688		fn test_fallback_uint2() {
1689			let mut test_instance = Columns::new(vec![
1690				ColumnWithName::uint2("test_col", Vec::<u16>::new()),
1691				ColumnWithName::uint2("none", Vec::<u16>::new()),
1692			]);
1693
1694			let shape = RowShape::testing(&[ValueType::Uint2, ValueType::Uint2]);
1695			let mut row = shape.allocate();
1696			shape.set_u16(&mut row, 0, 65535u16);
1697			shape.set_none(&mut row, 1);
1698
1699			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1700
1701			assert_eq!(test_instance[0], ColumnBuffer::uint2_with_bitvec([65535], [true]));
1702			assert_eq!(test_instance[1], ColumnBuffer::uint2_with_bitvec([0], [false]));
1703		}
1704
1705		#[test]
1706		fn test_fallback_uint4() {
1707			let mut test_instance = Columns::new(vec![
1708				ColumnWithName::uint4("test_col", Vec::<u32>::new()),
1709				ColumnWithName::uint4("none", Vec::<u32>::new()),
1710			]);
1711
1712			let shape = RowShape::testing(&[ValueType::Uint4, ValueType::Uint4]);
1713			let mut row = shape.allocate();
1714			shape.set_u32(&mut row, 0, 4294967295u32);
1715			shape.set_none(&mut row, 1);
1716
1717			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1718
1719			assert_eq!(test_instance[0], ColumnBuffer::uint4_with_bitvec([4294967295], [true]));
1720			assert_eq!(test_instance[1], ColumnBuffer::uint4_with_bitvec([0], [false]));
1721		}
1722
1723		#[test]
1724		fn test_fallback_uint8() {
1725			let mut test_instance = Columns::new(vec![
1726				ColumnWithName::uint8("test_col", Vec::<u64>::new()),
1727				ColumnWithName::uint8("none", Vec::<u64>::new()),
1728			]);
1729
1730			let shape = RowShape::testing(&[ValueType::Uint8, ValueType::Uint8]);
1731			let mut row = shape.allocate();
1732			shape.set_u64(&mut row, 0, 18446744073709551615u64);
1733			shape.set_none(&mut row, 1);
1734
1735			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1736
1737			assert_eq!(test_instance[0], ColumnBuffer::uint8_with_bitvec([18446744073709551615], [true]));
1738			assert_eq!(test_instance[1], ColumnBuffer::uint8_with_bitvec([0], [false]));
1739		}
1740
1741		#[test]
1742		fn test_fallback_uint16() {
1743			let mut test_instance = Columns::new(vec![
1744				ColumnWithName::uint16("test_col", Vec::<u128>::new()),
1745				ColumnWithName::uint16("none", Vec::<u128>::new()),
1746			]);
1747
1748			let shape = RowShape::testing(&[ValueType::Uint16, ValueType::Uint16]);
1749			let mut row = shape.allocate();
1750			shape.set_u128(&mut row, 0, 340282366920938463463374607431768211455u128);
1751			shape.set_none(&mut row, 1);
1752
1753			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1754
1755			assert_eq!(
1756				test_instance[0],
1757				ColumnBuffer::uint16_with_bitvec([340282366920938463463374607431768211455u128], [true])
1758			);
1759			assert_eq!(test_instance[1], ColumnBuffer::uint16_with_bitvec([0], [false]));
1760		}
1761
1762		#[test]
1763		fn test_all_defined_dictionary_id() {
1764			let constraint = TypeConstraint::dictionary(DictionaryId::from(1u64), ValueType::Uint4);
1765			let shape = RowShape::new(vec![RowShapeField::new("status", constraint)]);
1766
1767			let mut test_instance = Columns::new(vec![ColumnWithName::dictionary_id(
1768				"status",
1769				Vec::<DictionaryEntryId>::new(),
1770			)]);
1771
1772			let mut row_one = shape.allocate();
1773			shape.set_values(&mut row_one, &[Value::DictionaryId(DictionaryEntryId::U4(10))]);
1774			let mut row_two = shape.allocate();
1775			shape.set_values(&mut row_two, &[Value::DictionaryId(DictionaryEntryId::U4(20))]);
1776
1777			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1778
1779			assert_eq!(test_instance[0].get_value(0), Value::DictionaryId(DictionaryEntryId::U4(10)));
1780			assert_eq!(test_instance[0].get_value(1), Value::DictionaryId(DictionaryEntryId::U4(20)));
1781		}
1782
1783		#[test]
1784		fn test_fallback_dictionary_id() {
1785			let dict_constraint = TypeConstraint::dictionary(DictionaryId::from(1u64), ValueType::Uint4);
1786			let shape = RowShape::new(vec![
1787				RowShapeField::new("dict_col", dict_constraint),
1788				RowShapeField::unconstrained("bool_col", ValueType::Boolean),
1789			]);
1790
1791			let mut test_instance = Columns::new(vec![
1792				ColumnWithName::dictionary_id("dict_col", Vec::<DictionaryEntryId>::new()),
1793				ColumnWithName::bool("bool_col", Vec::<bool>::new()),
1794			]);
1795
1796			let mut row = shape.allocate();
1797			shape.set_values(&mut row, &[Value::none(), Value::Boolean(true)]);
1798
1799			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1800
1801			// Dictionary column should be undefined
1802			assert!(!test_instance[0].is_defined(0));
1803			// Bool column should be defined
1804			assert_eq!(test_instance[1].get_value(0), Value::Boolean(true));
1805		}
1806
1807		#[test]
1808		fn test_before_undefined_dictionary_id() {
1809			let constraint = TypeConstraint::dictionary(DictionaryId::from(2u64), ValueType::Uint4);
1810			let shape = RowShape::new(vec![RowShapeField::new("tag", constraint)]);
1811
1812			let mut test_instance =
1813				Columns::new(vec![ColumnWithName::undefined_typed("tag", ValueType::Boolean, 2)]);
1814
1815			let mut row = shape.allocate();
1816			shape.set_values(&mut row, &[Value::DictionaryId(DictionaryEntryId::U4(5))]);
1817
1818			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1819
1820			// First two are undefined (promoted from Undefined column), third is defined
1821			assert!(!test_instance[0].is_defined(0));
1822			assert!(!test_instance[0].is_defined(1));
1823			assert!(test_instance[0].is_defined(2));
1824			assert_eq!(test_instance[0].get_value(2), Value::DictionaryId(DictionaryEntryId::U4(5)));
1825		}
1826
1827		#[test]
1828		fn test_all_defined_identity_id() {
1829			let id1 = IdentityId::anonymous();
1830			let id2 = IdentityId::root();
1831
1832			let shape = RowShape::testing(&[ValueType::IdentityId]);
1833			let mut test_instance = Columns::new(vec![ColumnWithName::new(
1834				Fragment::internal("id_col"),
1835				ColumnBuffer::identity_id(Vec::<IdentityId>::new()),
1836			)]);
1837
1838			let mut row_one = shape.allocate();
1839			shape.set_identity_id(&mut row_one, 0, id1);
1840			let mut row_two = shape.allocate();
1841			shape.set_identity_id(&mut row_two, 0, id2);
1842
1843			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1844
1845			assert_eq!(test_instance[0].get_value(0), Value::IdentityId(id1));
1846			assert_eq!(test_instance[0].get_value(1), Value::IdentityId(id2));
1847		}
1848
1849		#[test]
1850		fn test_fallback_identity_id() {
1851			let id = IdentityId::anonymous();
1852
1853			let shape = RowShape::testing(&[ValueType::IdentityId, ValueType::Boolean]);
1854			let mut test_instance = Columns::new(vec![
1855				ColumnWithName::new(
1856					Fragment::internal("id_col"),
1857					ColumnBuffer::identity_id(Vec::<IdentityId>::new()),
1858				),
1859				ColumnWithName::bool("bool_col", Vec::<bool>::new()),
1860			]);
1861
1862			let mut row = shape.allocate();
1863			shape.set_identity_id(&mut row, 0, id);
1864			shape.set_none(&mut row, 1);
1865
1866			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1867
1868			assert_eq!(test_instance[0].get_value(0), Value::IdentityId(id));
1869			assert!(test_instance[0].is_defined(0));
1870			assert!(!test_instance[1].is_defined(0));
1871		}
1872
1873		#[test]
1874		fn test_all_defined_blob() {
1875			let blob1 = Blob::new(vec![1, 2, 3]);
1876			let blob2 = Blob::new(vec![4, 5]);
1877
1878			let shape = RowShape::testing(&[ValueType::Blob]);
1879			let mut test_instance = Columns::new(vec![ColumnWithName::new(
1880				Fragment::internal("blob_col"),
1881				ColumnBuffer::blob(Vec::<Blob>::new()),
1882			)]);
1883
1884			let mut row_one = shape.allocate();
1885			shape.set_blob(&mut row_one, 0, &blob1);
1886			let mut row_two = shape.allocate();
1887			shape.set_blob(&mut row_two, 0, &blob2);
1888
1889			test_instance.append_rows(&shape, [row_one, row_two], vec![]).unwrap();
1890
1891			assert_eq!(test_instance[0].get_value(0), Value::Blob(blob1));
1892			assert_eq!(test_instance[0].get_value(1), Value::Blob(blob2));
1893		}
1894
1895		#[test]
1896		fn test_fallback_blob() {
1897			let blob = Blob::new(vec![10, 20, 30]);
1898
1899			let shape = RowShape::testing(&[ValueType::Blob, ValueType::Boolean]);
1900			let mut test_instance = Columns::new(vec![
1901				ColumnWithName::new(
1902					Fragment::internal("blob_col"),
1903					ColumnBuffer::blob(Vec::<Blob>::new()),
1904				),
1905				ColumnWithName::bool("bool_col", Vec::<bool>::new()),
1906			]);
1907
1908			let mut row = shape.allocate();
1909			shape.set_blob(&mut row, 0, &blob);
1910			shape.set_none(&mut row, 1);
1911
1912			test_instance.append_rows(&shape, [row], vec![]).unwrap();
1913
1914			assert_eq!(test_instance[0].get_value(0), Value::Blob(blob));
1915			assert!(test_instance[0].is_defined(0));
1916			assert!(!test_instance[1].is_defined(0));
1917		}
1918
1919		fn test_instance_with_columns() -> Columns {
1920			Columns::new(vec![
1921				ColumnWithName::new(Fragment::internal("int2"), ColumnBuffer::int2(vec![1])),
1922				ColumnWithName::new(Fragment::internal("bool"), ColumnBuffer::bool(vec![true])),
1923			])
1924		}
1925	}
1926}