1use crate::{LogicalType, LogicalTypeKind, Result, TableError, TimestampKind};
2use bytes::Bytes;
3use std::ops::Range;
4
5const NANOS_PER_DAY: i64 = 86_400_000_000_000;
6
7#[derive(Clone, Debug, PartialEq)]
9pub enum Value {
10 Null,
11 Boolean(bool),
12 Int8(i8),
13 Int16(i16),
14 Int32(i32),
15 Int64(i64),
16 Float32(f32),
17 Float64(f64),
18 Decimal {
19 precision: u8,
20 scale: u8,
21 unscaled: i128,
22 },
23 Date(i32),
24 Time(i64),
25 Timestamp {
26 precision: u8,
27 timestamp_kind: TimestampKind,
28 seconds: i64,
29 nanos: u32,
30 },
31 String(String),
32 Binary(Bytes),
33 List(Vec<Value>),
34 Map(Vec<(Value, Value)>),
35 Struct(Vec<Value>),
36 Extension {
37 type_id: String,
38 value: Box<Value>,
39 },
40}
41
42impl From<Vec<u8>> for Value {
43 fn from(value: Vec<u8>) -> Self {
44 Self::Binary(Bytes::from(value))
45 }
46}
47
48impl From<Bytes> for Value {
49 fn from(value: Bytes) -> Self {
50 Self::Binary(value)
51 }
52}
53
54pub struct KeyCodec;
56
57impl KeyCodec {
58 pub fn encode_row(types: &[LogicalType], values: &[Value]) -> Result<Vec<u8>> {
59 let mut out = Vec::new();
60 Self::encode_row_into(types, values, &mut out)?;
61 Ok(out)
62 }
63
64 pub fn encode_row_into(
65 types: &[LogicalType],
66 values: &[Value],
67 out: &mut Vec<u8>,
68 ) -> Result<()> {
69 let start = out.len();
70 let result = Self::append_row(types, values, out);
71 if result.is_err() {
72 out.truncate(start);
73 }
74 result
75 }
76
77 pub(crate) fn encode_row_with_prefix_validated(
79 types: &[LogicalType],
80 values: &[Value],
81 prefix_fields: usize,
82 out: &mut Vec<u8>,
83 ) -> Result<usize> {
84 let start = out.len();
85 let result = (|| {
86 if types.len() != values.len() {
87 return Err(TableError::codec(
88 "key field count does not match value count",
89 ));
90 }
91 debug_assert!(prefix_fields <= types.len());
92 let mut prefix_end = start;
93 for (index, (logical_type, value)) in types.iter().zip(values).enumerate() {
94 encode_key(logical_type, value, out)?;
95 if index + 1 == prefix_fields {
96 prefix_end = out.len();
97 }
98 }
99 Ok(prefix_end - start)
100 })();
101 if result.is_err() {
102 out.truncate(start);
103 }
104 result
105 }
106
107 pub(crate) fn encode_row_from_positions_validated(
109 types: &[LogicalType],
110 row: &[Value],
111 positions: &[usize],
112 prefix_fields: usize,
113 ) -> Result<(Vec<u8>, usize)> {
114 debug_assert_eq!(types.len(), positions.len());
115 debug_assert!(prefix_fields <= types.len());
116 let mut encoded = Vec::new();
117 let mut prefix_end = 0;
118 for (index, (logical_type, position)) in types.iter().zip(positions).enumerate() {
119 encode_key(logical_type, &row[*position], &mut encoded)?;
120 if index + 1 == prefix_fields {
121 prefix_end = encoded.len();
122 }
123 }
124 Ok((encoded, prefix_end))
125 }
126
127 fn append_row(types: &[LogicalType], values: &[Value], out: &mut Vec<u8>) -> Result<()> {
128 if types.len() != values.len() {
129 return Err(TableError::codec(
130 "key field count does not match value count",
131 ));
132 }
133 for (logical_type, value) in types.iter().zip(values) {
134 logical_type.validate()?;
135 encode_key(logical_type, value, out)?;
136 }
137 Ok(())
138 }
139
140 pub fn encode_scalar(logical_type: &LogicalType, value: &Value) -> Result<Vec<u8>> {
141 let mut out = Vec::new();
142 logical_type.validate()?;
143 encode_key(logical_type, value, &mut out)?;
144 Ok(out)
145 }
146
147 pub fn decode_row(types: &[LogicalType], encoded: &[u8]) -> Result<Vec<Value>> {
148 for logical_type in types {
149 logical_type.validate()?;
150 }
151 Self::decode_row_validated(types, encoded)
152 }
153
154 pub(crate) fn decode_row_validated(
156 types: &[LogicalType],
157 encoded: &[u8],
158 ) -> Result<Vec<Value>> {
159 let mut offset = 0;
160 let mut values = Vec::with_capacity(types.len());
161 for logical_type in types {
162 let (value, consumed) = decode_key(logical_type, &encoded[offset..])?;
163 offset += consumed;
164 values.push(value);
165 }
166 ensure_consumed(encoded.len(), offset)?;
167 Ok(values)
168 }
169
170 pub(crate) fn decode_row_into_positions_validated(
172 types: &[LogicalType],
173 encoded: &[u8],
174 positions: &[usize],
175 row: &mut [Value],
176 ) -> Result<()> {
177 debug_assert_eq!(types.len(), positions.len());
178 debug_assert!(positions.iter().all(|position| *position < row.len()));
179 let mut offset = 0;
180 for (logical_type, position) in types.iter().zip(positions) {
181 let (value, consumed) = decode_key(logical_type, &encoded[offset..])?;
182 row[*position] = value;
183 offset += consumed;
184 }
185 ensure_consumed(encoded.len(), offset)
186 }
187
188 pub fn decode_scalar(logical_type: &LogicalType, encoded: &[u8]) -> Result<Value> {
189 logical_type.validate()?;
190 let (value, consumed) = decode_key(logical_type, encoded)?;
191 ensure_consumed(encoded.len(), consumed)?;
192 Ok(value)
193 }
194}
195
196pub struct ValueCodec;
198
199impl ValueCodec {
200 pub fn encode(logical_type: &LogicalType, value: &Value) -> Result<Vec<u8>> {
201 let mut out = Vec::new();
202 Self::encode_into(logical_type, value, &mut out)?;
203 Ok(out)
204 }
205
206 pub fn encode_into(logical_type: &LogicalType, value: &Value, out: &mut Vec<u8>) -> Result<()> {
207 let start = out.len();
208 let result = logical_type
209 .validate()
210 .and_then(|_| encode_value(logical_type, value, out));
211 if result.is_err() {
212 out.truncate(start);
213 }
214 result
215 }
216
217 pub(crate) fn encode_validated(logical_type: &LogicalType, value: &Value) -> Result<Vec<u8>> {
219 let mut out = Vec::new();
220 encode_value(logical_type, value, &mut out)?;
221 Ok(out)
222 }
223
224 pub fn encoded_size(logical_type: &LogicalType, value: &Value) -> Result<usize> {
225 logical_type.validate()?;
226 value_size(logical_type, value)
227 }
228
229 pub fn decode(logical_type: &LogicalType, encoded: &[u8]) -> Result<Value> {
230 logical_type.validate()?;
231 decode_value(logical_type, Input::Borrowed(encoded))
232 }
233
234 pub fn decode_bytes(logical_type: &LogicalType, encoded: Bytes) -> Result<Value> {
237 logical_type.validate()?;
238 decode_value(logical_type, Input::Owned(encoded))
239 }
240
241 pub(crate) fn decode_bytes_validated(
243 logical_type: &LogicalType,
244 encoded: Bytes,
245 ) -> Result<Value> {
246 decode_value(logical_type, Input::Owned(encoded))
247 }
248}
249
250enum Input<'a> {
251 Borrowed(&'a [u8]),
252 Owned(Bytes),
253}
254
255impl Input<'_> {
256 fn bytes(&self) -> &[u8] {
257 match self {
258 Self::Borrowed(bytes) => bytes,
259 Self::Owned(bytes) => bytes,
260 }
261 }
262
263 fn slice(&self, range: Range<usize>) -> Self {
264 match self {
265 Self::Borrowed(bytes) => Self::Borrowed(&bytes[range]),
266 Self::Owned(bytes) => Self::Owned(bytes.slice(range)),
267 }
268 }
269
270 fn into_bytes(self) -> Bytes {
271 match self {
272 Self::Borrowed(bytes) => Bytes::copy_from_slice(bytes),
273 Self::Owned(bytes) => bytes,
274 }
275 }
276}
277
278fn encode_key(logical_type: &LogicalType, value: &Value, out: &mut Vec<u8>) -> Result<()> {
279 if !logical_type.is_key_compatible() {
280 return Err(TableError::codec("type cannot be used as a key"));
281 }
282 match (&logical_type.kind, value) {
283 (LogicalTypeKind::Boolean, Value::Boolean(value)) => out.push(u8::from(*value)),
284 (LogicalTypeKind::Int8, Value::Int8(value)) => ordered_i128(*value as i128, 1, out),
285 (LogicalTypeKind::Int16, Value::Int16(value)) => ordered_i128(*value as i128, 2, out),
286 (LogicalTypeKind::Int32, Value::Int32(value)) => ordered_i128(*value as i128, 4, out),
287 (LogicalTypeKind::Int64, Value::Int64(value)) => ordered_i128(*value as i128, 8, out),
288 (
289 LogicalTypeKind::Decimal { precision, scale },
290 Value::Decimal {
291 precision: actual_precision,
292 scale: actual_scale,
293 unscaled,
294 },
295 ) => {
296 validate_decimal(
297 *precision,
298 *scale,
299 *actual_precision,
300 *actual_scale,
301 *unscaled,
302 )?;
303 ordered_i128(*unscaled, decimal_width(*precision), out);
304 }
305 (LogicalTypeKind::Date, Value::Date(value)) => ordered_i128(*value as i128, 4, out),
306 (LogicalTypeKind::Time { precision }, Value::Time(value)) => {
307 validate_time(*value, *precision)?;
308 ordered_i128(*value as i128, 8, out);
309 }
310 (
311 LogicalTypeKind::Timestamp {
312 precision,
313 timestamp_kind,
314 },
315 Value::Timestamp {
316 precision: actual_precision,
317 timestamp_kind: actual_kind,
318 seconds,
319 nanos,
320 },
321 ) => {
322 validate_timestamp(
323 *precision,
324 *timestamp_kind,
325 *actual_precision,
326 *actual_kind,
327 *seconds,
328 *nanos,
329 )?;
330 ordered_i128(*seconds as i128, 8, out);
331 out.extend_from_slice(&nanos.to_be_bytes());
332 }
333 (LogicalTypeKind::String, Value::String(value)) => append_escaped(value.as_bytes(), out),
334 (LogicalTypeKind::Binary, Value::Binary(value)) => append_escaped(value, out),
335 _ => return Err(type_mismatch(logical_type, value)),
336 }
337 Ok(())
338}
339
340fn decode_key(logical_type: &LogicalType, encoded: &[u8]) -> Result<(Value, usize)> {
341 if !logical_type.is_key_compatible() {
342 return Err(TableError::codec("type cannot be used as a key"));
343 }
344 match &logical_type.kind {
345 LogicalTypeKind::Boolean => Ok((Value::Boolean(read_bool(encoded)?), 1)),
346 LogicalTypeKind::Int8 => Ok((Value::Int8(read_ordered(encoded, 1)? as i8), 1)),
347 LogicalTypeKind::Int16 => Ok((Value::Int16(read_ordered(encoded, 2)? as i16), 2)),
348 LogicalTypeKind::Int32 => Ok((Value::Int32(read_ordered(encoded, 4)? as i32), 4)),
349 LogicalTypeKind::Int64 => Ok((Value::Int64(read_ordered(encoded, 8)? as i64), 8)),
350 LogicalTypeKind::Decimal { precision, scale } => {
351 let width = decimal_width(*precision);
352 let unscaled = read_ordered(encoded, width)?;
353 validate_decimal(*precision, *scale, *precision, *scale, unscaled)?;
354 Ok((
355 Value::Decimal {
356 precision: *precision,
357 scale: *scale,
358 unscaled,
359 },
360 width,
361 ))
362 }
363 LogicalTypeKind::Date => Ok((Value::Date(read_ordered(encoded, 4)? as i32), 4)),
364 LogicalTypeKind::Time { precision } => {
365 let value = read_ordered(encoded, 8)? as i64;
366 validate_time(value, *precision)?;
367 Ok((Value::Time(value), 8))
368 }
369 LogicalTypeKind::Timestamp {
370 precision,
371 timestamp_kind,
372 } => {
373 require_len(encoded, 12)?;
374 let seconds = read_ordered(encoded, 8)? as i64;
375 let nanos = u32::from_be_bytes(encoded[8..12].try_into().unwrap());
376 validate_timestamp(
377 *precision,
378 *timestamp_kind,
379 *precision,
380 *timestamp_kind,
381 seconds,
382 nanos,
383 )?;
384 Ok((
385 Value::Timestamp {
386 precision: *precision,
387 timestamp_kind: *timestamp_kind,
388 seconds,
389 nanos,
390 },
391 12,
392 ))
393 }
394 LogicalTypeKind::String => {
395 let (bytes, consumed) = read_escaped(encoded)?;
396 let value =
397 String::from_utf8(bytes).map_err(|_| TableError::codec("invalid UTF-8 key"))?;
398 Ok((Value::String(value), consumed))
399 }
400 LogicalTypeKind::Binary => {
401 let (bytes, consumed) = read_escaped(encoded)?;
402 Ok((Value::Binary(Bytes::from(bytes)), consumed))
403 }
404 _ => Err(TableError::codec("type cannot be used as a key")),
405 }
406}
407
408fn encode_value(logical_type: &LogicalType, value: &Value, out: &mut Vec<u8>) -> Result<()> {
409 if logical_type.nullable {
410 match value {
411 Value::Null => {
412 out.push(0);
413 return Ok(());
414 }
415 _ => out.push(1),
416 }
417 } else if matches!(value, Value::Null) {
418 return Err(type_mismatch(logical_type, value));
419 }
420 encode_non_null(logical_type, value, out)
421}
422
423fn encode_non_null(logical_type: &LogicalType, value: &Value, out: &mut Vec<u8>) -> Result<()> {
424 match (&logical_type.kind, value) {
425 (LogicalTypeKind::Boolean, Value::Boolean(value)) => out.push(u8::from(*value)),
426 (LogicalTypeKind::Int8, Value::Int8(value)) => ordered_i128(*value as i128, 1, out),
427 (LogicalTypeKind::Int16, Value::Int16(value)) => ordered_i128(*value as i128, 2, out),
428 (LogicalTypeKind::Int32, Value::Int32(value)) => ordered_i128(*value as i128, 4, out),
429 (LogicalTypeKind::Int64, Value::Int64(value)) => ordered_i128(*value as i128, 8, out),
430 (LogicalTypeKind::Float32, Value::Float32(value)) => {
431 out.extend_from_slice(&value.to_le_bytes())
432 }
433 (LogicalTypeKind::Float64, Value::Float64(value)) => {
434 out.extend_from_slice(&value.to_le_bytes())
435 }
436 (
437 LogicalTypeKind::Decimal { precision, scale },
438 Value::Decimal {
439 precision: actual_precision,
440 scale: actual_scale,
441 unscaled,
442 },
443 ) => {
444 validate_decimal(
445 *precision,
446 *scale,
447 *actual_precision,
448 *actual_scale,
449 *unscaled,
450 )?;
451 ordered_i128(*unscaled, decimal_width(*precision), out);
452 }
453 (LogicalTypeKind::Date, Value::Date(value)) => ordered_i128(*value as i128, 4, out),
454 (LogicalTypeKind::Time { precision }, Value::Time(value)) => {
455 validate_time(*value, *precision)?;
456 ordered_i128(*value as i128, 8, out);
457 }
458 (
459 LogicalTypeKind::Timestamp {
460 precision,
461 timestamp_kind,
462 },
463 Value::Timestamp {
464 precision: actual_precision,
465 timestamp_kind: actual_kind,
466 seconds,
467 nanos,
468 },
469 ) => {
470 validate_timestamp(
471 *precision,
472 *timestamp_kind,
473 *actual_precision,
474 *actual_kind,
475 *seconds,
476 *nanos,
477 )?;
478 ordered_i128(*seconds as i128, 8, out);
479 out.extend_from_slice(&nanos.to_be_bytes());
480 }
481 (LogicalTypeKind::String, Value::String(value)) => out.extend_from_slice(value.as_bytes()),
482 (LogicalTypeKind::Binary, Value::Binary(value)) => out.extend_from_slice(value),
483 (LogicalTypeKind::List { element_type }, Value::List(values)) => {
484 append_count(values.len(), out)?;
485 for value in values {
486 append_framed(element_type, value, out)?;
487 }
488 }
489 (
490 LogicalTypeKind::Map {
491 key_type,
492 value_type,
493 },
494 Value::Map(entries),
495 ) => {
496 append_count(entries.len(), out)?;
497 for (key, value) in entries {
498 append_framed(key_type, key, out)?;
499 append_framed(value_type, value, out)?;
500 }
501 }
502 (LogicalTypeKind::Struct { fields }, Value::Struct(values)) => {
503 if fields.len() != values.len() {
504 return Err(TableError::codec(
505 "struct field count does not match schema",
506 ));
507 }
508 for (field, value) in fields.iter().zip(values) {
509 append_framed(&field.logical_type, value, out)?;
510 }
511 }
512 (LogicalTypeKind::Extension { extension }, Value::Extension { type_id, value })
513 if type_id == &extension.type_id =>
514 {
515 encode_value(&extension.physical_type, value, out)?;
516 }
517 _ => return Err(type_mismatch(logical_type, value)),
518 }
519 Ok(())
520}
521
522fn decode_value(logical_type: &LogicalType, input: Input<'_>) -> Result<Value> {
523 if !logical_type.nullable {
524 return decode_non_null(logical_type, input);
525 }
526 let bytes = input.bytes();
527 let Some((&marker, payload)) = bytes.split_first() else {
528 return Err(TableError::codec("nullable value is missing marker"));
529 };
530 match marker {
531 0 if payload.is_empty() => Ok(Value::Null),
532 0 => Err(TableError::codec("null value has trailing bytes")),
533 1 => decode_non_null(logical_type, input.slice(1..bytes.len())),
534 _ => Err(TableError::codec("invalid nullable marker")),
535 }
536}
537
538fn decode_non_null(logical_type: &LogicalType, input: Input<'_>) -> Result<Value> {
539 let bytes = input.bytes();
540 match &logical_type.kind {
541 LogicalTypeKind::Boolean => Ok(Value::Boolean(read_bool_exact(bytes)?)),
542 LogicalTypeKind::Int8 => Ok(Value::Int8(read_ordered_exact(bytes, 1)? as i8)),
543 LogicalTypeKind::Int16 => Ok(Value::Int16(read_ordered_exact(bytes, 2)? as i16)),
544 LogicalTypeKind::Int32 => Ok(Value::Int32(read_ordered_exact(bytes, 4)? as i32)),
545 LogicalTypeKind::Int64 => Ok(Value::Int64(read_ordered_exact(bytes, 8)? as i64)),
546 LogicalTypeKind::Float32 => Ok(Value::Float32(f32::from_le_bytes(read_exact(bytes)?))),
547 LogicalTypeKind::Float64 => Ok(Value::Float64(f64::from_le_bytes(read_exact(bytes)?))),
548 LogicalTypeKind::Decimal { precision, scale } => {
549 let width = decimal_width(*precision);
550 require_exact_len(bytes, width)?;
551 let unscaled = read_ordered(bytes, width)?;
552 validate_decimal(*precision, *scale, *precision, *scale, unscaled)?;
553 Ok(Value::Decimal {
554 precision: *precision,
555 scale: *scale,
556 unscaled,
557 })
558 }
559 LogicalTypeKind::Date => Ok(Value::Date(read_ordered_exact(bytes, 4)? as i32)),
560 LogicalTypeKind::Time { precision } => {
561 let value = read_ordered_exact(bytes, 8)? as i64;
562 validate_time(value, *precision)?;
563 Ok(Value::Time(value))
564 }
565 LogicalTypeKind::Timestamp {
566 precision,
567 timestamp_kind,
568 } => {
569 require_exact_len(bytes, 12)?;
570 let seconds = read_ordered(bytes, 8)? as i64;
571 let nanos = u32::from_be_bytes(bytes[8..12].try_into().unwrap());
572 validate_timestamp(
573 *precision,
574 *timestamp_kind,
575 *precision,
576 *timestamp_kind,
577 seconds,
578 nanos,
579 )?;
580 Ok(Value::Timestamp {
581 precision: *precision,
582 timestamp_kind: *timestamp_kind,
583 seconds,
584 nanos,
585 })
586 }
587 LogicalTypeKind::String => String::from_utf8(bytes.to_vec())
588 .map(Value::String)
589 .map_err(|_| TableError::codec("invalid UTF-8 value")),
590 LogicalTypeKind::Binary => Ok(Value::Binary(input.into_bytes())),
591 LogicalTypeKind::List { element_type } => {
592 let mut cursor = 0;
593 let count = read_count(bytes, &mut cursor)?;
594 if count > (bytes.len() - cursor) / 4 {
595 return Err(TableError::codec("list count exceeds encoded frames"));
596 }
597 let mut values = Vec::with_capacity(count);
598 for _ in 0..count {
599 values.push(decode_framed(element_type, &input, &mut cursor)?);
600 }
601 ensure_consumed(bytes.len(), cursor)?;
602 Ok(Value::List(values))
603 }
604 LogicalTypeKind::Map {
605 key_type,
606 value_type,
607 } => {
608 let mut cursor = 0;
609 let count = read_count(bytes, &mut cursor)?;
610 if count > (bytes.len() - cursor) / 8 {
611 return Err(TableError::codec("map count exceeds encoded frames"));
612 }
613 let mut entries = Vec::with_capacity(count);
614 for _ in 0..count {
615 let key = decode_framed(key_type, &input, &mut cursor)?;
616 let value = decode_framed(value_type, &input, &mut cursor)?;
617 entries.push((key, value));
618 }
619 ensure_consumed(bytes.len(), cursor)?;
620 Ok(Value::Map(entries))
621 }
622 LogicalTypeKind::Struct { fields } => {
623 let mut cursor = 0;
624 let mut values = Vec::with_capacity(fields.len());
625 for field in fields {
626 values.push(decode_framed(&field.logical_type, &input, &mut cursor)?);
627 }
628 ensure_consumed(bytes.len(), cursor)?;
629 Ok(Value::Struct(values))
630 }
631 LogicalTypeKind::Extension { extension } => Ok(Value::Extension {
632 type_id: extension.type_id.clone(),
633 value: Box::new(decode_value(&extension.physical_type, input)?),
634 }),
635 }
636}
637
638fn value_size(logical_type: &LogicalType, value: &Value) -> Result<usize> {
639 if logical_type.nullable && matches!(value, Value::Null) {
640 return Ok(1);
641 }
642 if !logical_type.nullable && matches!(value, Value::Null) {
643 return Err(type_mismatch(logical_type, value));
644 }
645 let marker = usize::from(logical_type.nullable);
646 let payload = match (&logical_type.kind, value) {
647 (LogicalTypeKind::Boolean, Value::Boolean(_)) | (LogicalTypeKind::Int8, Value::Int8(_)) => {
648 1
649 }
650 (LogicalTypeKind::Int16, Value::Int16(_)) => 2,
651 (LogicalTypeKind::Int32, Value::Int32(_))
652 | (LogicalTypeKind::Float32, Value::Float32(_))
653 | (LogicalTypeKind::Date, Value::Date(_)) => 4,
654 (LogicalTypeKind::Int64, Value::Int64(_))
655 | (LogicalTypeKind::Float64, Value::Float64(_)) => 8,
656 (LogicalTypeKind::Time { precision }, Value::Time(value)) => {
657 validate_time(*value, *precision)?;
658 8
659 }
660 (
661 LogicalTypeKind::Timestamp {
662 precision,
663 timestamp_kind,
664 },
665 Value::Timestamp {
666 precision: actual_precision,
667 timestamp_kind: actual_kind,
668 seconds,
669 nanos,
670 },
671 ) => {
672 validate_timestamp(
673 *precision,
674 *timestamp_kind,
675 *actual_precision,
676 *actual_kind,
677 *seconds,
678 *nanos,
679 )?;
680 12
681 }
682 (
683 LogicalTypeKind::Decimal { precision, scale },
684 Value::Decimal {
685 precision: actual_precision,
686 scale: actual_scale,
687 unscaled,
688 },
689 ) => {
690 validate_decimal(
691 *precision,
692 *scale,
693 *actual_precision,
694 *actual_scale,
695 *unscaled,
696 )?;
697 decimal_width(*precision)
698 }
699 (LogicalTypeKind::String, Value::String(value)) => value.len(),
700 (LogicalTypeKind::Binary, Value::Binary(value)) => value.len(),
701 (LogicalTypeKind::List { element_type }, Value::List(values)) => {
702 ensure_count(values.len())?;
703 values.iter().try_fold(4, |size, value| {
704 checked_size_add(size, framed_size(element_type, value)?)
705 })?
706 }
707 (
708 LogicalTypeKind::Map {
709 key_type,
710 value_type,
711 },
712 Value::Map(entries),
713 ) => {
714 ensure_count(entries.len())?;
715 entries.iter().try_fold(4, |size, (key, value)| {
716 checked_size_add(
717 size,
718 checked_size_add(framed_size(key_type, key)?, framed_size(value_type, value)?)?,
719 )
720 })?
721 }
722 (LogicalTypeKind::Struct { fields }, Value::Struct(values))
723 if fields.len() == values.len() =>
724 {
725 fields
726 .iter()
727 .zip(values)
728 .try_fold(0, |size, (field, value)| {
729 checked_size_add(size, framed_size(&field.logical_type, value)?)
730 })?
731 }
732 (LogicalTypeKind::Extension { extension }, Value::Extension { type_id, value })
733 if type_id == &extension.type_id =>
734 {
735 value_size(&extension.physical_type, value)?
736 }
737 _ => return Err(type_mismatch(logical_type, value)),
738 };
739 checked_size_add(marker, payload)
740}
741
742fn append_framed(logical_type: &LogicalType, value: &Value, out: &mut Vec<u8>) -> Result<()> {
743 let start = out.len();
744 out.extend_from_slice(&[0; 4]);
745 if let Err(error) = encode_value(logical_type, value, out) {
746 out.truncate(start);
747 return Err(error);
748 }
749 let length = match u32::try_from(out.len() - start - 4) {
750 Ok(length) => length,
751 Err(_) => {
752 out.truncate(start);
753 return Err(TableError::codec("nested value exceeds u32 length"));
754 }
755 };
756 out[start..start + 4].copy_from_slice(&length.to_le_bytes());
757 Ok(())
758}
759
760fn decode_framed(
761 logical_type: &LogicalType,
762 input: &Input<'_>,
763 cursor: &mut usize,
764) -> Result<Value> {
765 let bytes = input.bytes();
766 let length = read_u32(bytes, cursor)? as usize;
767 let end = cursor
768 .checked_add(length)
769 .filter(|end| *end <= bytes.len())
770 .ok_or_else(|| TableError::codec("nested value length exceeds container"))?;
771 let value = decode_value(logical_type, input.slice(*cursor..end))?;
772 *cursor = end;
773 Ok(value)
774}
775
776fn append_count(count: usize, out: &mut Vec<u8>) -> Result<()> {
777 out.extend_from_slice(
778 &u32::try_from(count)
779 .map_err(|_| TableError::codec("container has more than u32 values"))?
780 .to_le_bytes(),
781 );
782 Ok(())
783}
784
785fn read_count(bytes: &[u8], cursor: &mut usize) -> Result<usize> {
786 Ok(read_u32(bytes, cursor)? as usize)
787}
788
789fn read_u32(bytes: &[u8], cursor: &mut usize) -> Result<u32> {
790 let end = cursor
791 .checked_add(4)
792 .filter(|end| *end <= bytes.len())
793 .ok_or_else(|| TableError::codec("container is truncated"))?;
794 let value = u32::from_le_bytes(bytes[*cursor..end].try_into().unwrap());
795 *cursor = end;
796 Ok(value)
797}
798
799fn ordered_i128(value: i128, width: usize, out: &mut Vec<u8>) {
800 let start = out.len();
801 out.extend_from_slice(&value.to_be_bytes()[16 - width..]);
802 out[start] ^= 0x80;
803}
804
805fn read_ordered(bytes: &[u8], width: usize) -> Result<i128> {
806 require_len(bytes, width)?;
807 let mut fixed = [0u8; 16];
808 fixed[16 - width..].copy_from_slice(&bytes[..width]);
809 fixed[16 - width] ^= 0x80;
810 if fixed[16 - width] & 0x80 != 0 {
811 fixed[..16 - width].fill(0xff);
812 }
813 Ok(i128::from_be_bytes(fixed))
814}
815
816fn read_ordered_exact(bytes: &[u8], width: usize) -> Result<i128> {
817 require_exact_len(bytes, width)?;
818 read_ordered(bytes, width)
819}
820
821fn append_escaped(bytes: &[u8], out: &mut Vec<u8>) {
822 for byte in bytes {
823 if *byte == 0 {
824 out.extend_from_slice(&[0, 0xff]);
825 } else {
826 out.push(*byte);
827 }
828 }
829 out.extend_from_slice(&[0, 0]);
830}
831
832fn read_escaped(bytes: &[u8]) -> Result<(Vec<u8>, usize)> {
833 let mut out = Vec::new();
834 let mut cursor = 0;
835 while cursor < bytes.len() {
836 if bytes[cursor] != 0 {
837 out.push(bytes[cursor]);
838 cursor += 1;
839 continue;
840 }
841 let next = *bytes
842 .get(cursor + 1)
843 .ok_or_else(|| TableError::codec("unterminated escaped key"))?;
844 match next {
845 0 => return Ok((out, cursor + 2)),
846 0xff => out.push(0),
847 _ => return Err(TableError::codec("invalid key escape")),
848 }
849 cursor += 2;
850 }
851 Err(TableError::codec("unterminated escaped key"))
852}
853
854fn validate_decimal(
855 precision: u8,
856 scale: u8,
857 actual_precision: u8,
858 actual_scale: u8,
859 unscaled: i128,
860) -> Result<()> {
861 if !(1..=38).contains(&precision) || scale > precision {
862 return Err(TableError::codec("invalid decimal value or precision"));
863 }
864 let limit = 10_i128.pow(precision as u32);
865 if precision != actual_precision
866 || scale != actual_scale
867 || unscaled <= -limit
868 || unscaled >= limit
869 {
870 return Err(TableError::codec("invalid decimal value or precision"));
871 }
872 Ok(())
873}
874
875fn decimal_width(precision: u8) -> usize {
876 if precision <= 9 {
877 4
878 } else if precision <= 18 {
879 8
880 } else {
881 16
882 }
883}
884
885fn validate_time(value: i64, precision: u8) -> Result<()> {
886 if precision > 9
887 || !(0..NANOS_PER_DAY).contains(&value)
888 || !(value as u64).is_multiple_of(10_u64.pow((9 - precision) as u32))
889 {
890 return Err(TableError::codec("invalid time value"));
891 }
892 Ok(())
893}
894
895fn validate_timestamp(
896 precision: u8,
897 expected_kind: TimestampKind,
898 actual_precision: u8,
899 actual_kind: TimestampKind,
900 seconds: i64,
901 nanos: u32,
902) -> Result<()> {
903 if precision > 9
904 || precision != actual_precision
905 || expected_kind != actual_kind
906 || nanos >= 1_000_000_000
907 || !nanos.is_multiple_of(10_u32.pow((9 - precision) as u32))
908 {
909 return Err(TableError::codec(format!(
910 "invalid timestamp seconds={seconds} nanos={nanos}"
911 )));
912 }
913 Ok(())
914}
915
916fn read_bool(bytes: &[u8]) -> Result<bool> {
917 match *bytes
918 .first()
919 .ok_or_else(|| TableError::codec("value is truncated"))?
920 {
921 0 => Ok(false),
922 1 => Ok(true),
923 _ => Err(TableError::codec("invalid boolean byte")),
924 }
925}
926fn read_bool_exact(bytes: &[u8]) -> Result<bool> {
927 require_exact_len(bytes, 1)?;
928 read_bool(bytes)
929}
930fn require_len(bytes: &[u8], length: usize) -> Result<()> {
931 if bytes.len() < length {
932 Err(TableError::codec("value is truncated"))
933 } else {
934 Ok(())
935 }
936}
937fn require_exact_len(bytes: &[u8], length: usize) -> Result<()> {
938 if bytes.len() != length {
939 Err(TableError::codec("invalid value length"))
940 } else {
941 Ok(())
942 }
943}
944fn ensure_consumed(length: usize, consumed: usize) -> Result<()> {
945 if length == consumed {
946 Ok(())
947 } else {
948 Err(TableError::codec("trailing bytes"))
949 }
950}
951fn read_exact<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {
952 require_exact_len(bytes, N)?;
953 Ok(bytes.try_into().unwrap())
954}
955fn type_mismatch(logical_type: &LogicalType, _: &Value) -> TableError {
956 TableError::codec(format!("value does not match {:?}", logical_type.kind))
957}
958
959fn checked_size_add(left: usize, right: usize) -> Result<usize> {
960 left.checked_add(right)
961 .ok_or_else(|| TableError::codec("encoded value exceeds addressable memory"))
962}
963
964fn ensure_count(count: usize) -> Result<()> {
965 u32::try_from(count)
966 .map(|_| ())
967 .map_err(|_| TableError::codec("container has more than u32 values"))
968}
969
970fn framed_size(logical_type: &LogicalType, value: &Value) -> Result<usize> {
971 let payload = value_size(logical_type, value)?;
972 u32::try_from(payload).map_err(|_| TableError::codec("nested value exceeds u32 length"))?;
973 checked_size_add(4, payload)
974}