pub enum Value {
Null(DataType),
Integer(i64),
Float(f64),
Text(SmartString),
Boolean(bool),
Timestamp(DateTime<Utc>),
Extension(CompactArc<[u8]>),
}Expand description
A runtime value with type information
Each variant carries its data directly, avoiding the need for interface indirection or separate value references.
§Memory Layout (16 bytes)
Value is exactly 16 bytes due to niche optimization:
- Text(SmartString): 16 bytes with niches in tag byte (values 17-255 unused)
- Extension(CompactArc<u8>): 8 bytes (thin pointer), leaving niche bytes free
- Rust stores Value’s discriminant in SmartString’s niche values
§Extension Variant
The Extension variant is a catch-all for all complex types (JSON, Vector, Blob, etc.)
It stores a single CompactArc<[u8]> (8 bytes) where byte[0] is the DataType tag
and byte[1..] is the payload. This keeps Value at exactly 7 variants forever —
new types are added by extending DataType (a 1-byte #[repr(u8)] enum).
Note: Text uses SmartString for inline storage of strings up to 15 bytes.
Longer strings use Arc<str> for O(1) clone and sharing.
Variants§
Null(DataType)
NULL value with optional type hint
Integer(i64)
64-bit signed integer
Float(f64)
64-bit floating point
Text(SmartString)
UTF-8 text string (SmartString: inline ≤15 bytes, Arc for larger)
Boolean(bool)
Boolean value
Timestamp(DateTime<Utc>)
Timestamp (UTC)
Extension(CompactArc<[u8]>)
Extension type: byte[0] = DataType tag, byte[1..] = payload
- Json:
byte[0]=6,byte[1..]=UTF-8 bytes (access viaas_json()) - Vector:
byte[0]=7,byte[1..]=packed LE f32 bytes (access viaas_vector_f32()) - Future types (Blob, Array, etc.) add DataType variants, not Value variants
Implementations§
Source§impl Value
impl Value
Sourcepub fn null_unknown() -> Self
pub fn null_unknown() -> Self
Create a NULL value with unknown type
Sourcepub fn text(value: impl Into<String>) -> Self
pub fn text(value: impl Into<String>) -> Self
Create a text value
Uses SmartString::from_string_shared() for heap strings to enable
O(1) clone via Arc<str>. This allows string sharing between
Arena, Index, and VersionStore.
Sourcepub fn text_arc(value: Arc<str>) -> Self
pub fn text_arc(value: Arc<str>) -> Self
Create a text value from Arc<str> (zero-copy for heap strings)
Preserves the Arc reference for O(1) clone and sharing.
Sourcepub fn vector(data: Vec<f32>) -> Self
pub fn vector(data: Vec<f32>) -> Self
Create a vector value from f32 data (stored as packed LE f32 bytes in Extension)
Sourcepub fn try_vector_from_bytes(raw_f32_bytes: CompactArc<[u8]>) -> Result<Self>
pub fn try_vector_from_bytes(raw_f32_bytes: CompactArc<[u8]>) -> Result<Self>
Create a vector value from pre-packed little-endian f32 bytes.
Sourcepub fn uuid_v7() -> Self
pub fn uuid_v7() -> Self
Create a new UUIDv7 value.
UUIDv7 is time-ordered, which makes it much friendlier for primary-key B-tree indexes than fully random UUIDv4 values.
Sourcepub fn try_decimal(unscaled: i128, precision: u8, scale: u8) -> Result<Self>
pub fn try_decimal(unscaled: i128, precision: u8, scale: u8) -> Result<Self>
Create an exact decimal value.
Payload layout:
- byte 0:
DataType::Decimaltag; - bytes 1..17: little-endian
i128unscaled integer; - byte 17: precision;
- byte 18: scale.
Sourcepub fn date(days_since_unix_epoch: i32) -> Self
pub fn date(days_since_unix_epoch: i32) -> Self
Create a calendar date value from days since Unix epoch.
Sourcepub fn try_external(
type_ref: ExternalTypeRef,
payload: impl AsRef<[u8]>,
) -> Result<Self>
pub fn try_external( type_ref: ExternalTypeRef, payload: impl AsRef<[u8]>, ) -> Result<Self>
Create a typed external value from canonical plugin codec bytes.
Semantic codec validation is performed by the admitted plugin host at SQL/wire ingress. This constructor enforces the context-free envelope bounds shared by WAL and immutable artifact readers.
Sourcepub fn logical_type(&self) -> LogicalTypeRef
pub fn logical_type(&self) -> LogicalTypeRef
Return the complete built-in or external logical type identity.
Sourcepub fn is_external(&self) -> bool
pub fn is_external(&self) -> bool
Return whether this value carries the reserved external-type envelope.
This intentionally checks only the marker. Full envelope validation is
owned by Value::as_external and the row/WAL/file admission paths.
Sourcepub fn as_external(&self) -> Option<ExternalValueRef<'_>>
pub fn as_external(&self) -> Option<ExternalValueRef<'_>>
Borrow the external envelope without exposing its compact storage.
Sourcepub fn validate_shape(&self) -> Result<()>
pub fn validate_shape(&self) -> Result<()>
Validate the physical shape of a value before it crosses a row, WAL or file-format admission boundary.
Sourcepub fn as_int64(&self) -> Option<i64>
pub fn as_int64(&self) -> Option<i64>
Extract as i64, with type coercion
Returns None if:
- Value is NULL
- Conversion is not possible
Sourcepub fn as_float64(&self) -> Option<f64>
pub fn as_float64(&self) -> Option<f64>
Extract as f64, with type coercion
Sourcepub fn as_boolean(&self) -> Option<bool>
pub fn as_boolean(&self) -> Option<bool>
Extract as boolean, with type coercion
Sourcepub fn as_timestamp(&self) -> Option<DateTime<Utc>>
pub fn as_timestamp(&self) -> Option<DateTime<Utc>>
Extract as DateTime<Utc>
Sourcepub fn as_vector_f32(&self) -> Option<Vec<f32>>
pub fn as_vector_f32(&self) -> Option<Vec<f32>>
Extract vector as Vec<f32> (reads packed LE f32 bytes from Extension payload)
Sourcepub fn as_uuid_bytes(&self) -> Option<[u8; 16]>
pub fn as_uuid_bytes(&self) -> Option<[u8; 16]>
Extract UUID as raw 16 bytes.
Sourcepub fn as_decimal_parts(&self) -> Option<(i128, u8, u8)>
pub fn as_decimal_parts(&self) -> Option<(i128, u8, u8)>
Extract exact decimal parts: (unscaled, precision, scale).
Sourcepub fn as_date_days(&self) -> Option<i32>
pub fn as_date_days(&self) -> Option<i32>
Extract calendar date as days since Unix epoch.
Sourcepub fn as_bytes_value(&self) -> Option<&[u8]>
pub fn as_bytes_value(&self) -> Option<&[u8]>
Extract raw bytes from a BYTES/BLOB/BINARY value.
Sourcepub fn compare(&self, other: &Value) -> Result<Ordering>
pub fn compare(&self, other: &Value) -> Result<Ordering>
Compare two values for ordering
Returns:
- Ok(Ordering::Less) if self < other
- Ok(Ordering::Equal) if self == other
- Ok(Ordering::Greater) if self > other
- Err if comparison is not possible
Sourcepub fn from_typed(value: Option<&dyn Any>, data_type: DataType) -> Result<Self>
pub fn from_typed(value: Option<&dyn Any>, data_type: DataType) -> Result<Self>
Create a Value from a typed value with explicit data type
Sourcepub fn coerce_to_type(&self, target_type: DataType) -> Value
pub fn coerce_to_type(&self, target_type: DataType) -> Value
Coerce this value to the target data type
Type coercion rules:
- Integer column receiving Float → converts to Integer
- Float column receiving Integer → converts to Float
- Text column receiving any type → converts to Text
- Timestamp column receiving String → parses timestamp
- JSON column receiving valid JSON string → stores as JSON
- Boolean column receiving Integer/String → converts to Boolean
Returns the coerced value, or NULL if coercion fails.
Sourcepub fn try_coerce_to_type(&self, target_type: DataType) -> Result<Value>
pub fn try_coerce_to_type(&self, target_type: DataType) -> Result<Value>
Checked coercion to the target data type.
This is the strict counterpart to Value::coerce_to_type. It preserves
the normal SQL rule that NULL casts to typed NULL, but treats
non-NULL-to-NULL conversion as a runtime type error. Use this for explicit
SQL CAST and other user-visible expression evaluation boundaries where
silently producing NULL would hide bad data.
Sourcepub fn into_coerce_to_type(self, target_type: DataType) -> Value
pub fn into_coerce_to_type(self, target_type: DataType) -> Value
Coerce value to target type, consuming self OPTIMIZATION: Avoids clone when types already match
Trait Implementations§
impl Eq for Value
Source§impl FromIterator<Value> for Row
impl FromIterator<Value> for Row
Source§impl Ord for Value
Total ordering implementation for Value
impl Ord for Value
Total ordering implementation for Value
This is required for using Value as a key in BTreeMap/BTreeSet. The ordering is defined as follows:
- NULLs are always ordered first (smallest)
- Numeric types (Integer, Float) are compared by numeric value (consistent with PartialEq)
- Other different data types are ordered by their type discriminant
- Same data types use their natural ordering
IMPORTANT: This ordering MUST be consistent with PartialEq. Since Integer(5) == Float(5.0) per PartialEq, we must ensure Integer(5).cmp(&Float(5.0)) == Ordering::Equal. Violating this contract causes BTreeMap corruption.
Note: This differs from SQL NULL semantics where NULL comparisons return UNKNOWN. This ordering is only for internal index structure.