#[non_exhaustive]pub enum Value<'arena> {
Show 73 variants
SmallInt(i16),
Int(i32),
BigInt(i64),
Float(f64),
Real(f32),
Text(Cow<'arena, str>),
Bool(bool),
Vector(Cow<'arena, [f32]>),
Sq8Vector(Sq8Vector),
HalfVector(HalfVector),
Numeric {
scaled: i128,
scale: u16,
kind: NumericKind,
},
NumericBig(Box<BigNumeric>),
Date(i32),
Timestamp(i64),
Interval {
months: i32,
days: i32,
micros: i64,
},
Json(Cow<'arena, str>),
Bytes(Cow<'arena, [u8]>),
TextArray(Vec<Option<String>>),
IntArray(Vec<Option<i32>>),
BigIntArray(Vec<Option<i64>>),
IntervalArray(Vec<Option<IntervalSpan>>),
BoolArray(Vec<Option<bool>>),
SmallIntArray(Vec<Option<i16>>),
FloatArray(Vec<Option<f64>>),
NumericArray(Vec<Option<(i128, u16)>>),
DateArray(Vec<Option<i32>>),
TimestampArray(Vec<Option<i64>>),
TimestamptzArray(Vec<Option<i64>>),
UuidArray(Vec<Option<[u8; 16]>>),
JsonArray(Vec<Option<String>>),
JsonbArray(Vec<Option<String>>),
BytesArray(Vec<Option<Vec<u8>>>),
VarcharArray(Vec<Option<String>>),
CharArray(Vec<Option<String>>),
Multirange {
kind: RangeKind,
ranges: Vec<RangeSpan>,
},
Point(Point2D),
Lseg(Point2D, Point2D),
Path {
points: Vec<Point2D>,
closed: bool,
},
PgBox(Point2D, Point2D),
Polygon(Vec<Point2D>),
Line {
a: f64,
b: f64,
c: f64,
},
Circle {
center: Point2D,
radius: f64,
},
Inet {
family: u8,
bits: u8,
addr: [u8; 16],
},
Cidr {
family: u8,
bits: u8,
addr: [u8; 16],
},
Macaddr([u8; 6]),
Macaddr8([u8; 8]),
PgLsn(u64),
RegClass(i64, Box<str>),
RegProc(i64, Box<str>),
RegType(i64, Box<str>),
Xid(u32),
Cid(u32),
Tid(u32, u32),
BitString {
nbits: u32,
bytes: Cow<'arena, [u8]>,
},
Xml(Cow<'arena, str>),
Char1(u8),
BpChar(Cow<'arena, str>),
MoneyArray(Vec<Option<i64>>),
TsVector(Vec<TsLexeme>),
TsQuery(TsQueryAst),
Uuid([u8; 16]),
Time(i64),
Year(u16),
TimeTz {
us: i64,
offset_secs: i32,
},
Money(i64),
Hstore(Vec<(String, Option<String>)>),
IntArray2D(Vec<Vec<Option<i32>>>),
BigIntArray2D(Vec<Vec<Option<i64>>>),
TextArray2D(Vec<Vec<Option<String>>>),
BoolArray2D(Vec<Vec<Option<bool>>>),
Range {
kind: RangeKind,
lower: Option<Box<Value<'static>>>,
upper: Option<Box<Value<'static>>>,
lower_inc: bool,
upper_inc: bool,
empty: bool,
},
Composite(Vec<(String, Value<'static>)>),
Null,
}Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
SmallInt(i16)
Int(i32)
BigInt(i64)
Float(f64)
Real(f32)
v7.38 (read01, T-float4) — PG real (32-bit IEEE float).
Text(Cow<'arena, str>)
Bool(bool)
Vector(Cow<'arena, [f32]>)
Sq8Vector(Sq8Vector)
v6.0.1: 8-bit scalar-quantised vector cell. Lives in
columns declared VECTOR(N) USING SQ8. Layout per cell:
Sq8Vector { min: f32, max: f32, bytes: Vec<u8> } —
4× compression vs Vector(Vec<f32>). The wire layer
dequantises to f32 on SELECT; INSERT path quantises
incoming Vector(Vec<f32>) cells into this variant.
HalfVector(HalfVector)
v6.0.3: IEEE-754 binary16 vector cell. Lives in columns
declared VECTOR(N) USING HALF. Stores raw u16 LE bits
(2× compression vs Vector(Vec<f32>)). Wire / display
paths dequantise to f32 bit-exactly; INSERT path converts
incoming f32 vectors at the engine boundary.
Numeric
Exact fixed-point decimal. scaled holds the value as
actual * 10^scale so the storage type is always integral —
arithmetic never falls back to floating-point. v7.38 (read01, T6) —
kind classifies the value as finite (the common case, using
scaled/scale) or one of PG’s NUMERIC specials (NaN / ±Infinity),
which ignore scaled/scale (canonicalized to 0).
Fields
scale: u16v7.39 (round 271) — widened from u8. PG’s numeric carries a display scale up to 16383; at u8 a literal with 256 decimal places could not be represented at all, and the conversion aborted the query with an internal error.
kind: NumericKindNumericBig(Box<BigNumeric>)
v7.38 (read01, T3) — an exact NUMERIC whose mantissa overflows i128
(PG’s NUMERIC is unbounded). Boxed so the common finite case keeps its
small footprint; specials never take this form (they stay Numeric).
Date(i32)
Days since the Unix epoch (1970-01-01). Negative for earlier dates.
Timestamp(i64)
Microseconds since the Unix epoch (1970-01-01T00:00:00Z).
Interval
Calendar span: months + days + micros. Three fields are
required for PG byte-equal: '1 day' ≠ '24 hours' (DST,
month-boundary, and the on-wire pg_type interval are all
i64 micros + i32 days + i32 months). v7.37.5 β widened from
{months, micros}; column storage lands in the same window.
Json(Cow<'arena, str>)
v4.9 JSON — raw JSON text. No structural validation
happens at the storage layer; whatever the parser hands us
round-trips verbatim. Equality is byte-wise.
Bytes(Cow<'arena, [u8]>)
v7.10.4 BYTEA — raw binary blob. Equality is byte-wise.
Layout matches Text’s length-prefixed shape ([u32 LE len][bytes]) under tag 18; the engine accepts PG hex
literals ('\xDEADBEEF') and escape literals at the
coercion boundary.
TextArray(Vec<Option<String>>)
v7.10.9 TEXT[] — single-dimension TEXT array with
optional NULL elements. Equality is element-wise. PG’s
NULL-element comparison semantics: NULL ≠ NULL inside
arrays under =, so [NULL] != [NULL] (the engine
honours this).
IntArray(Vec<Option<i32>>)
v7.11.12 INT[] — single-dimension i32 array with optional
NULL elements. Codec mirrors TextArray with i32 LE per
element instead of length-prefixed UTF-8.
BigIntArray(Vec<Option<i64>>)
v7.11.12 BIGINT[] — single-dimension i64 array with optional
NULL elements.
IntervalArray(Vec<Option<IntervalSpan>>)
v7.37.5 β-P4 INTERVAL[] — single-dimension array of
IntervalSpan { months, days, micros } with optional NULL
elements. PG external form quotes each non-NULL element
({"1 day","24:00:00",NULL}) because interval text contains
spaces and colons. Storage codec follows the BigIntArray
shape with a 16-byte per-element body.
BoolArray(Vec<Option<bool>>)
v7.37.5 γ — single-dimension arrays of the remaining PG
scalar types. Each carries Vec<Option<T>> with the
scalar’s natural Rust shape; element NULLs are first-class
(per PG: {1,NULL,3} is a 3-element array, not a 2-element
one). Codec follows the IntervalArray shape — [u16 count] [per elem: u8 null + (non-null) scalar body].
SmallIntArray(Vec<Option<i16>>)
FloatArray(Vec<Option<f64>>)
NumericArray(Vec<Option<(i128, u16)>>)
PG NUMERIC[] — (scaled: i128, scale: u16) per element.
DateArray(Vec<Option<i32>>)
TimestampArray(Vec<Option<i64>>)
TimestamptzArray(Vec<Option<i64>>)
UuidArray(Vec<Option<[u8; 16]>>)
JsonArray(Vec<Option<String>>)
JsonbArray(Vec<Option<String>>)
BytesArray(Vec<Option<Vec<u8>>>)
VarcharArray(Vec<Option<String>>)
CharArray(Vec<Option<String>>)
Multirange
v7.37.5 δ — PG 14+ multirange. ranges is a Vec of
non-overlapping bounds spans of the shared kind. PG’s
canonical text form is {[a,b),[c,d),...} (comma-separated
ranges in braces; {} for the empty multirange). SPG’s
constructor enforces no overlap/coalescing — for now the
engine trusts the caller (mirrors PG’s _construct_array
pattern). Catalog tag 49 + 1-byte RangeKind on the dense
type-tag side; schema-less path is unreachable (multirange
is column-typed only).
Point(Point2D)
v7.37.5 ε — PG geometry scalars. Per-type Vec/struct shape;
codec body shape is described on the matching DataType
variant. PG canonical text forms:
Point (x,y)
Lseg [(x1,y1),(x2,y2)]
Path open [(x,y),(x,y),...] / closed ((x,y),(x,y),...)
Box (ux,uy),(lx,ly) (PG normalises to upper-right + lower-left)
Polygon ((x,y),(x,y),...) (implicit closed)
Line {a,b,c} (Ax + By + C = 0)
Circle <(x,y),r>
Lseg(Point2D, Point2D)
Path
closed = true is ((p,p,...)); false is [(p,p,...)].
PgBox(Point2D, Point2D)
PG box — stored as (upper_right, lower_left) (PG’s
normalised order). The engine accepts both endpoint
orderings at parse time and normalises here.
Polygon(Vec<Point2D>)
Line
Circle
Inet
v7.37.5 ζ-A — PG inet. family = 4 (IPv4) or 6 (IPv6).
bits is the netmask bit count (0..=32 for IPv4, 0..=128
for IPv6). addr is right-padded with zeros when family=4
(first 4 bytes are the address).
Cidr
v7.37.5 ζ-A — PG cidr. Same shape as Inet; CIDR’s
invariant (host bits zero) is enforced at parse / coerce.
Macaddr([u8; 6])
v7.37.5 ζ-A — PG macaddr. 6 bytes (XX:XX:XX:XX:XX:XX).
Macaddr8([u8; 8])
v7.37.5 ζ-A — PG macaddr8. 8 bytes (EUI-64).
PgLsn(u64)
v7.39 (read01 pg_lsn.c) — PG pg_lsn, a 64-bit WAL location.
RegClass(i64, Box<str>)
v7.39 (read01 ruleutils.c) — PG regclass: an OID-typed relation
reference that renders as the relation name. SPG carries BOTH
(the synthetic oid for catalog joins, the name for display) so
conrelid = 't'::regclass and 't'::regclass::text agree.
Eval-only (no column storage).
RegProc(i64, Box<str>)
v7.39 (round 342, V65) — PG regproc: an OID-typed FUNCTION
reference that renders as the function name. Same dual shape
Value::RegClass carries, and for the same reason: without the
oid half, pg_proc.oid = 'f'::regproc cannot join, and a callee
cannot tell pg_get_functiondef('f'::regproc) — which PG answers
— from pg_get_functiondef('f') — which PG rejects.
Eval-only (no column storage).
RegType(i64, Box<str>)
v7.39 (round 648) — PG regtype: an OID-typed TYPE reference
that renders as the type name. The third of the shape
Value::RegClass and Value::RegProc carry, and the one
that was missing it: ::regtype produced a plain Value::Text
holding the canonical name, so 'text'::regtype::oid tried to
parse the NAME as a number and answered invalid input syntax for type oid: "text" where PG answers 25. pg_typeof on one
said text rather than regtype for the same reason.
Eval-only (no column storage).
Xid(u32)
v7.39 (round 512) — PG xid and cid, the transaction and command
ids the xmin / xmax / cmin / cmax system columns carry.
Their own types rather than integers, because PG deliberately gives
them almost no operators: measured on PG18, xmin + 1 is “operator
does not exist: xid + integer”, xmin > 0 likewise, xmin::bigint
is “cannot cast type xid to bigint”, and there is no max(xid).
Carrying them as BigInt would quietly allow all four.
Eval-only (no column storage).
Cid(u32)
Tid(u32, u32)
v7.39 (round 511) — PG tid, the physical row identity ctid
carries: a block number and a one-based offset inside it, rendered
(block,offset).
It is a real type rather than a two-field record because the idiom
that makes ctid worth having — DELETE … WHERE ctid NOT IN (SELECT min(ctid) … GROUP BY key) — needs min() over it, and PG has no
min(record). Ordering is by block then offset, so (0,2) < (0,9) < (0,10); a text form would order those (0,10) < (0,2) < (0,9) and
the dedup would keep the wrong row.
Eval-only (no column storage).
BitString
v7.37.5 ζ-A — PG bit / bit varying. nbits is the
actual bit count; bytes is the packed representation
(big-endian within each byte; final byte right-padded
with 0s if nbits % 8 != 0).
Xml(Cow<'arena, str>)
v7.37.5 ζ-A — PG xml. Stored verbatim as a string; no
parse-time validation (matches the SPG JSON convention).
Char1(u8)
v7.37.5 ζ-A — PG "char" (internal single-byte type,
distinct from CHAR(n)).
BpChar(Cow<'arena, str>)
v7.38 (read01, T11) — PG bpchar / CHAR(n): blank-padded fixed-length
string. Stored space-padded to the declared width (as PG does + for wire
display); length / comparison / ::text / concat all ignore the trailing
blanks (handled at those sites).
MoneyArray(Vec<Option<i64>>)
v7.37.5 ζ-A — PG money[].
TsVector(Vec<TsLexeme>)
v7.12.0 tsvector — sorted-by-word, deduped lexeme set with
positions + weights. The engine enforces sort/dedup on
construction; consumers can rely on lexemes.windows(2)
being strictly ascending by word.
TsQuery(TsQueryAst)
v7.12.0 tsquery — boolean / phrase parse tree over
lexemes. Engine builds via to_tsquery family.
Uuid([u8; 16])
v7.17.0 uuid — 128-bit identifier. Stored as 16 bytes
(big-endian / network-byte order, same as RFC 4122).
Display normalises to canonical lowercase 8-4-4-4-12
hyphenated form. Equality is byte-wise.
Time(i64)
v7.17.0 Phase 3.P0-32 — PG time (without time zone) —
i64 microseconds since 00:00:00. Range 0..86_400_000_000.
Display: HH:MM:SS zero-padded, with optional .ffffff
suffix when fractional is non-zero.
Year(u16)
v7.17.0 Phase 3.P0-33 — MySQL YEAR — u16 in range
1901..=2155 plus the special zero-year sentinel 0.
Display always 4 digits zero-padded (0000 for the
sentinel; 1985/2007 otherwise).
TimeTz
v7.17.0 Phase 3.P0-34 — PG time with time zone — i64
microseconds since 00:00:00 in the LOCAL wall clock PLUS
an i32 offset-from-UTC in seconds. PG preserves the
offset on output, so the wall-clock value is NOT shifted
to UTC at storage time. Offset range: ±50400 seconds
(±14 hours).
Money(i64)
v7.17.0 Phase 3.P0-35 — PG money — i64 cents
(locale-independent storage; the en_US locale renders on
display via $N,NNN.CC).
Hstore(Vec<(String, Option<String>)>)
v7.17.0 Phase 3.P0-39 — PG hstore value: flat
text => text map with NULL value support. Insertion
order preserved on input; duplicate keys take last-write-
wins at parse time.
IntArray2D(Vec<Vec<Option<i32>>>)
v7.17.0 Phase 3.P0-40 — 2D INT matrix (row-major).
BigIntArray2D(Vec<Vec<Option<i64>>>)
v7.17.0 Phase 3.P0-40 — 2D BIGINT matrix (row-major).
TextArray2D(Vec<Vec<Option<String>>>)
v7.17.0 Phase 3.P0-40 — 2D TEXT matrix (row-major).
BoolArray2D(Vec<Vec<Option<bool>>>)
v7.39 (read01 round 75) — see DataType::BoolArray2D.
Range
v7.17.0 Phase 3.P0-38 — PG range value. One shape covers
all six builtin range types; kind pins the element type
(must match the column’s DataType::Range(kind)).
lower / upper are None for the unbounded sides;
lower_inc / upper_inc mirror the canonical PG
[ / ( / ] / ) bracket inclusivity. empty=true
supersedes all other fields (the empty range has no
bounds).
Fields
Composite(Vec<(String, Value<'static>)>)
v7.38 (read01, T9) — a composite / record value (a row(...)
constructor or a whole-row reference). Fields are (name, value); the
names are f1..fN for an anonymous row(...) or the source column
names for a table row. Transient — flows through row_to_json / to_json
and the composite text form (a,b); not a storable column type here.
Null
Implementations§
Source§impl<'arena> Value<'arena>
impl<'arena> Value<'arena>
Sourcepub fn data_type(&self) -> Option<DataType>
pub fn data_type(&self) -> Option<DataType>
Type tag, or None for NULL (unknown at value level).
pub const fn is_null(&self) -> bool
Sourcepub fn into_owned(self) -> Value<'static>
pub fn into_owned(self) -> Value<'static>
v7.37.42-arena Phase 1: lift any Value<'arena> (possibly
borrowing from a bump arena) into a fully-owned Value<'static>.
Used at boundaries that must outlive the per-query arena
(catalog write, public QueryResult emit, sqlx materialise).
For the recursive Range/Multirange variants — bounds are already
Box<Value<'static>> per Phase 1 design, so we just rebuild the
outer enum at 'static.
Sourcepub fn clone_into<'a>(&self, arena: &'a Bump) -> Value<'a>
pub fn clone_into<'a>(&self, arena: &'a Bump) -> Value<'a>
v7.37.42-arena Phase 4 — copy heap payloads into the supplied
bump arena, yielding a Value<'a> whose Cow-variant payloads
are arena-borrowed (or stay as small owned scalars for the
Copy-able variants).
Used at the catalog ↔ ephemeral boundary: a ColumnSchema.default
is Value<'static> but INSERT-time eval may want it stamped into
the per-statement arena alongside other arena-built scalars.
Allocates only into the supplied arena; the input &self keeps
its own storage. For Copy-able / nested-owned variants the
implementation falls back to clone() (the nested heap blocks
stay on the global allocator, which is fine — the boundary
requirement is just “no aliasing of caller-owned strings”).
Source§impl Value<'static>
impl Value<'static>
Sourcepub fn text<S>(s: S) -> Value<'static>
pub fn text<S>(s: S) -> Value<'static>
v7.37.42-arena Phase 1 — owned-Text constructor. The variant now
holds Cow<'arena, str>, so the previous Value::Text(String)
shape no longer compiles directly. This helper preserves the
historical ergonomics: Value::text("foo") or
Value::text(String::from("foo")).
Sourcepub const fn numeric(scaled: i128, scale: u16) -> Value<'static>
pub const fn numeric(scaled: i128, scale: u16) -> Value<'static>
v7.38 (read01, T6) — a finite NUMERIC from its fixed-point parts.
Sourcepub const fn numeric_special(kind: NumericKind) -> Value<'static>
pub const fn numeric_special(kind: NumericKind) -> Value<'static>
v7.38 (read01, T6) — a special NUMERIC (NaN / ±Infinity). The fixed-point fields are canonicalized to 0 so equal specials compare byte-identical.
Sourcepub fn json<S>(s: S) -> Value<'static>
pub fn json<S>(s: S) -> Value<'static>
v7.37.42-arena Phase 1 — owned-Json constructor (mirrors text).