use reifydb_core::encoded::shape::RowShape;
use reifydb_type::value::{blob::Blob, int::Int, r#type::Type};
#[test]
fn test_unaligned_access_all_types() {
let types_to_test = vec![
Type::Boolean,
Type::Int1,
Type::Int2,
Type::Int4,
Type::Int8,
Type::Int16,
Type::Uint1,
Type::Uint2,
Type::Uint4,
Type::Uint8,
Type::Uint16,
Type::Float4,
Type::Float8,
Type::Date,
Type::DateTime,
Type::Time,
Type::Duration,
Type::Uuid4,
Type::Uuid7,
Type::IdentityId,
Type::Utf8,
Type::Blob,
Type::Int,
Type::Uint,
Type::Decimal,
];
for target_type in types_to_test {
let shape = RowShape::testing(&[
Type::Int1, target_type.clone(), Type::Int1, target_type.clone(), ]);
let mut row = shape.allocate();
match target_type {
Type::Boolean => {
shape.set_bool(&mut row, 1, true);
assert_eq!(shape.get_bool(&row, 1), true);
shape.set_bool(&mut row, 3, false);
assert_eq!(shape.get_bool(&row, 3), false);
}
Type::Int1 => {
shape.set_i8(&mut row, 1, 42);
assert_eq!(shape.get_i8(&row, 1), 42);
}
Type::Int2 => {
shape.set_i16(&mut row, 1, 1234i16);
assert_eq!(shape.get_i16(&row, 1), 1234);
}
Type::Int4 => {
shape.set_i32(&mut row, 1, 123456);
assert_eq!(shape.get_i32(&row, 1), 123456);
}
Type::Int8 => {
shape.set_i64(&mut row, 1, 1234567890);
assert_eq!(shape.get_i64(&row, 1), 1234567890);
}
Type::Float4 => {
shape.set_f32(&mut row, 1, 3.14);
assert!((shape.get_f32(&row, 1) - 3.14).abs() < f32::EPSILON);
}
Type::Float8 => {
shape.set_f64(&mut row, 1, 3.14159);
assert!((shape.get_f64(&row, 1) - 3.14159).abs() < f64::EPSILON);
}
Type::Utf8 => {
shape.set_utf8(&mut row, 1, "test");
assert_eq!(shape.get_utf8(&row, 1), "test");
}
_ => {
shape.set_none(&mut row, 1);
assert!(!row.is_defined(1));
}
}
}
}
#[test]
fn test_repeated_overwrites_no_memory_leak() {
let shape = RowShape::testing(&[
Type::Int4, Type::Float8, Type::Utf8, Type::Blob, Type::Int, ]);
let mut row = shape.allocate();
let initial_size = row.len();
for i in 0..10000 {
shape.set_i32(&mut row, 0, i);
shape.set_f64(&mut row, 1, i as f64);
}
assert_eq!(row.len(), initial_size, "Static fields caused memory growth");
shape.set_utf8(&mut row, 2, "constant");
shape.set_blob(&mut row, 3, &Blob::from(&b"fixed"[..]));
shape.set_int(&mut row, 4, &Int::from(123i64));
let size_after_dynamic = row.len();
assert!(size_after_dynamic > initial_size, "Dynamic fields should increase size");
assert!(size_after_dynamic < initial_size * 3, "Dynamic fields shouldn't triple size");
let rows: Vec<_> = (0..100)
.map(|_| {
let mut r = shape.allocate();
shape.set_i32(&mut r, 0, 42);
shape.set_f64(&mut r, 1, 3.14);
shape.set_utf8(&mut r, 2, "constant");
shape.set_blob(&mut r, 3, &Blob::from(&b"fixed"[..]));
shape.set_int(&mut r, 4, &Int::from(123i64));
r
})
.collect();
for r in &rows {
assert_eq!(r.len(), size_after_dynamic, "Row sizes should be consistent");
}
}
#[test]
fn test_minimal_row_handling() {
let shape = RowShape::testing(&[Type::Boolean]);
let row = shape.allocate();
assert!(row.len() > 0, "Row should have validity bits and data");
}
#[test]
fn test_maximum_field_count() {
let types: Vec<Type> = (0..256)
.map(|i| match i % 5 {
0 => Type::Boolean,
1 => Type::Int4,
2 => Type::Float8,
3 => Type::Utf8,
_ => Type::Date,
})
.collect();
let shape = RowShape::testing(&types);
let mut row = shape.allocate();
shape.set_bool(&mut row, 0, true);
assert_eq!(shape.get_bool(&row, 0), true);
shape.set_i32(&mut row, 1, 42);
assert_eq!(shape.get_i32(&row, 1), 42);
shape.set_utf8(&mut row, 253, "field 253");
assert_eq!(shape.get_utf8(&row, 253), "field 253");
}