Expand description
PropertyValue — the typed value of a vertex/edge property.
§Why the wire form is what it is
This type used to be #[serde(untagged)]: a value serialized as
bare JSON and deserialized by trying the variants in order. That is
exactly right for Null | Bool | Long | Float | Text | Json, whose
JSON shapes are already distinct, and it is the shape every existing
client, every stored RocksDB record, and every .ant file on disk
is written in.
It cannot express the SQL types. DECIMAL, DATE, TIME,
TIMESTAMP, UUID and BLOB all serialize as JSON strings, so an
untagged decode of "2024-03-01" cannot tell a DATE from a TEXT
that happens to look like one — the type is lost on the first
round-trip. Storing a type you cannot read back is not parity.
So the encoding is split by variant:
- The six legacy variants serialize exactly as before — bare
null,true,42,1.5,"hi",{...}. Byte-identical output, byte-identical parsing. Old records read back unchanged and old clients see no difference, because for these values there IS no difference. - The SQL-parity variants serialize as a tagged envelope,
{"$ant":"decimal","v":"12.34"}. Self-describing, so the type survives store →.ant→ store, and unambiguous, so it can never be confused with aTextthat looks similar.
An object is only read as an envelope when it has exactly the two
keys $ant and v AND $ant names a known type. Anything else is
a Json value, so a caller’s own document containing a $ant field
is still stored as their document (there is a test for precisely
this).
§The compatibility surface
/public/v1 is the OpenSPG/KAG-compatible API and must keep
emitting what it always emitted, so it projects through
PropertyValue::to_compat_json, which flattens the typed variants
back to the bare scalars they would have been stored as before this
existed. The Antares-native API uses PropertyValue::to_json and
sees the real types.
Enums§
- Property
Value - Typed property value, at SQL fidelity.