mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-08-03 17:48:17 +00:00
Fix unreachable panic when calling serialize
on Value::Integer(0)
by handling `SerialTypeKind` `ConstInt0` and `ConstInt1` in `Record::serialize()` - Changed `test_serialize_integers` to accomodate this change.
This commit is contained in:
parent
35948c6dbb
commit
e3bc78f7e4
1 changed files with 48 additions and 24 deletions
|
@ -1354,6 +1354,7 @@ impl Record {
|
|||
Value::Integer(i) => {
|
||||
let serial_type = SerialType::from(value);
|
||||
match serial_type.kind() {
|
||||
SerialTypeKind::ConstInt0 | SerialTypeKind::ConstInt1 => {}
|
||||
SerialTypeKind::I8 => buf.extend_from_slice(&(*i as i8).to_be_bytes()),
|
||||
SerialTypeKind::I16 => buf.extend_from_slice(&(*i as i16).to_be_bytes()),
|
||||
SerialTypeKind::I24 => {
|
||||
|
@ -1525,6 +1526,8 @@ mod tests {
|
|||
#[test]
|
||||
fn test_serialize_integers() {
|
||||
let record = Record::new(vec![
|
||||
Value::Integer(0), // Should use ConstInt0
|
||||
Value::Integer(1), // Should use ConstInt1
|
||||
Value::Integer(42), // Should use SERIAL_TYPE_I8
|
||||
Value::Integer(1000), // Should use SERIAL_TYPE_I16
|
||||
Value::Integer(1_000_000), // Should use SERIAL_TYPE_I24
|
||||
|
@ -1541,39 +1544,57 @@ mod tests {
|
|||
assert_eq!(header[0], header_length as u8); // Header should be larger than number of values
|
||||
|
||||
// Check that correct serial types were chosen
|
||||
assert_eq!(header[1] as u64, u64::from(SerialType::i8()));
|
||||
assert_eq!(header[2] as u64, u64::from(SerialType::i16()));
|
||||
assert_eq!(header[3] as u64, u64::from(SerialType::i24()));
|
||||
assert_eq!(header[4] as u64, u64::from(SerialType::i32()));
|
||||
assert_eq!(header[5] as u64, u64::from(SerialType::i48()));
|
||||
assert_eq!(header[6] as u64, u64::from(SerialType::i64()));
|
||||
assert_eq!(header[1] as u64, u64::from(SerialType::const_int0())); // 8
|
||||
assert_eq!(header[2] as u64, u64::from(SerialType::const_int1())); // 9
|
||||
assert_eq!(header[3] as u64, u64::from(SerialType::i8())); // 1
|
||||
assert_eq!(header[4] as u64, u64::from(SerialType::i16())); // 2
|
||||
assert_eq!(header[5] as u64, u64::from(SerialType::i24())); // 3
|
||||
assert_eq!(header[6] as u64, u64::from(SerialType::i32())); // 4
|
||||
assert_eq!(header[7] as u64, u64::from(SerialType::i48())); // 5
|
||||
assert_eq!(header[8] as u64, u64::from(SerialType::i64())); // 6
|
||||
|
||||
// test that the bytes after the header can be interpreted as the correct values
|
||||
let mut cur_offset = header_length;
|
||||
|
||||
// Value::Integer(0) - ConstInt0: NO PAYLOAD BYTES
|
||||
// Value::Integer(1) - ConstInt1: NO PAYLOAD BYTES
|
||||
|
||||
// Value::Integer(42) - I8: 1 byte
|
||||
let i8_bytes = &buf[cur_offset..cur_offset + size_of::<i8>()];
|
||||
cur_offset += size_of::<i8>();
|
||||
|
||||
// Value::Integer(1000) - I16: 2 bytes
|
||||
let i16_bytes = &buf[cur_offset..cur_offset + size_of::<i16>()];
|
||||
cur_offset += size_of::<i16>();
|
||||
let i24_bytes = &buf[cur_offset..cur_offset + size_of::<i32>() - 1];
|
||||
cur_offset += size_of::<i32>() - 1; // i24
|
||||
|
||||
// Value::Integer(1_000_000) - I24: 3 bytes
|
||||
let i24_bytes = &buf[cur_offset..cur_offset + 3];
|
||||
cur_offset += 3;
|
||||
|
||||
// Value::Integer(1_000_000_000) - I32: 4 bytes
|
||||
let i32_bytes = &buf[cur_offset..cur_offset + size_of::<i32>()];
|
||||
cur_offset += size_of::<i32>();
|
||||
let i48_bytes = &buf[cur_offset..cur_offset + size_of::<i64>() - 2];
|
||||
cur_offset += size_of::<i64>() - 2; // i48
|
||||
|
||||
// Value::Integer(1_000_000_000_000) - I48: 6 bytes
|
||||
let i48_bytes = &buf[cur_offset..cur_offset + 6];
|
||||
cur_offset += 6;
|
||||
|
||||
// Value::Integer(i64::MAX) - I64: 8 bytes
|
||||
let i64_bytes = &buf[cur_offset..cur_offset + size_of::<i64>()];
|
||||
|
||||
// Verify the payload values
|
||||
let val_int8 = i8::from_be_bytes(i8_bytes.try_into().unwrap());
|
||||
let val_int16 = i16::from_be_bytes(i16_bytes.try_into().unwrap());
|
||||
|
||||
let mut leading_0 = vec![0];
|
||||
leading_0.extend(i24_bytes);
|
||||
let val_int24 = i32::from_be_bytes(leading_0.try_into().unwrap());
|
||||
let mut i24_with_padding = vec![0];
|
||||
i24_with_padding.extend(i24_bytes);
|
||||
let val_int24 = i32::from_be_bytes(i24_with_padding.try_into().unwrap());
|
||||
|
||||
let val_int32 = i32::from_be_bytes(i32_bytes.try_into().unwrap());
|
||||
|
||||
let mut leading_00 = vec![0, 0];
|
||||
leading_00.extend(i48_bytes);
|
||||
let val_int48 = i64::from_be_bytes(leading_00.try_into().unwrap());
|
||||
let mut i48_with_padding = vec![0, 0];
|
||||
i48_with_padding.extend(i48_bytes);
|
||||
let val_int48 = i64::from_be_bytes(i48_with_padding.try_into().unwrap());
|
||||
|
||||
let val_int64 = i64::from_be_bytes(i64_bytes.try_into().unwrap());
|
||||
|
||||
|
@ -1584,16 +1605,19 @@ mod tests {
|
|||
assert_eq!(val_int48, 1_000_000_000_000);
|
||||
assert_eq!(val_int64, i64::MAX);
|
||||
|
||||
// assert correct size of buffer: header + values (bytes per value depends on serial type)
|
||||
//Size of buffer = header + payload bytes
|
||||
// ConstInt0 and ConstInt1 contribute 0 bytes to payload
|
||||
assert_eq!(
|
||||
buf.len(),
|
||||
header_length
|
||||
+ size_of::<i8>()
|
||||
+ size_of::<i16>()
|
||||
+ (size_of::<i32>() - 1) // i24
|
||||
+ size_of::<i32>()
|
||||
+ (size_of::<i64>() - 2) // i48
|
||||
+ size_of::<f64>()
|
||||
header_length // 9 bytes (header size + 8 serial types)
|
||||
+ 0 // ConstInt0: 0 bytes
|
||||
+ 0 // ConstInt1: 0 bytes
|
||||
+ size_of::<i8>() // I8: 1 byte
|
||||
+ size_of::<i16>() // I16: 2 bytes
|
||||
+ (size_of::<i32>() - 1) // I24: 3 bytes
|
||||
+ size_of::<i32>() // I32: 4 bytes
|
||||
+ (size_of::<i64>() - 1) // I48: 6 bytes
|
||||
+ size_of::<i64>() // I64: 8 bytes
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue