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§
Sourcefn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
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.
Sourceunsafe fn unchecked_read_column(
row_ref: RowRef<'_>,
layout: &ProductTypeElementLayout,
) -> Self
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::ArrayandAlgebraicType::Mapare 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 values0and1. -
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§
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementations on Foreign Types§
Source§impl ReadColumn for AlgebraicValue
impl ReadColumn for AlgebraicValue
fn is_compatible_type(_ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for ArrayValue
impl ReadColumn for ArrayValue
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for bool
impl ReadColumn for bool
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for f32
impl ReadColumn for f32
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for f64
impl ReadColumn for f64
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for i8
impl ReadColumn for i8
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for i16
impl ReadColumn for i16
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for i32
impl ReadColumn for i32
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for i64
impl ReadColumn for i64
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for i128
impl ReadColumn for i128
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for u8
impl ReadColumn for u8
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for u16
impl ReadColumn for u16
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for u32
impl ReadColumn for u32
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for u64
impl ReadColumn for u64
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for u128
impl ReadColumn for u128
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for Box<str>
impl ReadColumn for Box<str>
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for Box<i256>
impl ReadColumn for Box<i256>
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for Box<u256>
impl ReadColumn for Box<u256>
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for ColId
impl ReadColumn for ColId
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for ConstraintId
impl ReadColumn for ConstraintId
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for IndexId
impl ReadColumn for IndexId
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for ScheduleId
impl ReadColumn for ScheduleId
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for SequenceId
impl ReadColumn for SequenceId
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for TableId
impl ReadColumn for TableId
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for Packed<i128>
impl ReadColumn for Packed<i128>
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for Packed<u128>
impl ReadColumn for Packed<u128>
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for ProductValue
impl ReadColumn for ProductValue
fn is_compatible_type(ty: &AlgebraicTypeLayout) -> bool
unsafe fn unchecked_read_column( row_ref: RowRef<'_>, layout: &ProductTypeElementLayout, ) -> Self
Source§impl ReadColumn for SumTag
SAFETY: is_compatible_type only returns true for sum types,
and any sum value stores the tag first in BFLATN.
impl ReadColumn for SumTag
SAFETY: is_compatible_type only returns true for sum types,
and any sum value stores the tag first in BFLATN.