Trait spacetimedb_table::read_column::ReadColumn

source ·
pub unsafe trait ReadColumn: Sized {
    // Required methods
    fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool;
    unsafe fn unchecked_read_column(
        row_ref: RowRef<'_>,
        layout: &ProductTypeElementLayout
    ) -> Self;

    // Provided method
    fn read_column(row_ref: RowRef<'_>, idx: usize) -> Result<Self, TypeError> { ... }
}
Expand description

Types which can be stored in a column of a row, and can be extracted directly from a row.

§Safety

The implementor must define is_compatible_type to return true only for AlgebraicTypeLayouts for which unchecked_read_column is safe. The provided read_column method uses is_compatible_type to detect type errors, and calls unchecked_read_column if is_compatible_type returns true.

Required Methods§

source

fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool

Is ty compatible with Self?

The definition of “compatible” here is left to the implementor, to be defined by Self::is_compatible_type.

For most types,“compatibility” will mean that each Rust type which implements ReadColumn has exactly one corresponding AlgebraicTypeLayout which represents it, and the column in table.row_layout must be of that type.

Notable exceptions are AlgebraicValue, ProductValue and SumValue. Any ProductTypeLayout is compatible with ProductValue, any SumTypeLayout is compatible with SumValue, and any AlgebraicTypeLayout at all is compatible with AlgebraicValue.

source

unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout ) -> Self

Extract a value of type Self from the row pointed to by row_ref which is stored in the column defined by layout.

§Safety

layout must appear as a column in the table.row_layout.product().elements, not to a nested field of a column which is a product or sum value. That column must have the same layout as layout. This restriction may be loosened in the future.

Assuming that the row_ref refers to a properly-aligned row, adding the layout.offset must result in a properly-aligned value of that compatible type.

layout.ty must be compatible with Self. The definition of “compatible” here is left to the implementor, to be defined by Self::is_compatible_type.

For most types,“compatibility” will mean that each Rust type which implements ReadColumn has exactly one corresponding AlgebraicTypeLayout which represents it, and the column in table.row_layout must be of that type.

Notable exceptions are AlgebraicValue, ProductValue and SumValue. Any ProductTypeLayout is compatible with ProductValue, any SumTypeLayout is compatible with SumValue, and any AlgebraicTypeLayout at all is compatible with AlgebraicValue.

§Notes for implementors

Implementors may depend on all of the above safety requirements, and on the validity of the row_ref. Assuming all of the above safety requirements are met and the row_ref refers to a valid row, this method must never invoke Undefined Behavior.

Implementors should carefully study the BFLATN format. Currently BFLATN lacks a normative specification, so implementors should read the definitions in [layout.rs], [bflatn_to.rs] and [bflatn_from.rs]. A few highlights are included here:

  • Variable-length columns, i.e. AlgebraicType::String, AlgebraicType::Array and AlgebraicType::Map are stored within the row as [crate::var_len::VarLenRefs], which refer to an intrusive linked list of 62-byte “granules”, allocated separately in a space starting from the end of the page. Strings are stored as UTF-8 bytes; all other var-len types are stored as BSATN-encoded bytes.

  • Fixed-length columns, i.e. all types not listed above as variable-length, are stored inline at a known offset. Their layout generally matches the C ABI on an x86_64 Linux machine, with the notable exception of sum types, since the C ABI doesn’t define a layout for sums.

  • Fixed-length columns are stored in order, with padding between to ensure proper alignment.

  • Primitive (non-compound) fixed-length types, i.e. integers, floats and booleans, have alignment equal to their size.

  • Integers are stored little-endian.

  • Floats are stored by bitwise converting to integers as per IEEE-754, then storing those integers little-endian.

  • Booleans are stored as u8, i.e. bytes, restricted to the values 0 and 1.

  • Products store their elements in order, with padding between to ensure proper alignment.

  • The first element of a product has offset 0.

  • The alignment of a product is the maximum alignment of its elements, or 1 for the empty product.

  • The size of a product is the number of bytes required to store its elements, including padding, plus trailing padding bytes so that the size is a multiple of the alignment.

  • Sums store their payload at offset 0, followed by a 1-byte tag.

  • The alignment of a sum is the maximum alignment of its variants’ payloads.

  • The size of a sum is the maximum size of its variants’ payloads, plus 1 (the tag), plus trailing padding bytes so that the size is a multiple of the alignment.

  • The offset of a sum’s tag bit is the maximum size of its variants’ payloads.

Provided Methods§

source

fn read_column(row_ref: RowRef<'_>, idx: usize) -> Result<Self, TypeError>

Check that the idxth column of the row type stored by row_ref is compatible with Self, and read the value of that column from row_ref.

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl ReadColumn for AlgebraicValue

source§

impl ReadColumn for ArrayValue

source§

impl ReadColumn for bool

source§

impl ReadColumn for f32

source§

impl ReadColumn for f64

source§

impl ReadColumn for i8

source§

impl ReadColumn for i16

source§

impl ReadColumn for i32

source§

impl ReadColumn for i64

source§

impl ReadColumn for i128

source§

impl ReadColumn for u8

source§

impl ReadColumn for u16

source§

impl ReadColumn for u32

source§

impl ReadColumn for u64

source§

impl ReadColumn for u128

source§

impl ReadColumn for String

source§

impl ReadColumn for ColId

source§

impl ReadColumn for ConstraintId

source§

impl ReadColumn for IndexId

source§

impl ReadColumn for SequenceId

source§

impl ReadColumn for TableId

source§

impl ReadColumn for ProductValue

source§

impl ReadColumn for SumValue

source§

impl ReadColumn for MapValue

Implementors§