Type mapping¶
crates/rowx-postgres/src/types.rs is the only OID-to-Python table. rowx_postgres._core.type_table() exports it, and
rowx_postgres/_types.py is the typed view the checker and the row plan read. No other file may hard-code OID to
Python mappings. The generated rows are Postgres type mapping. This page is the rules that table does
not spell out.
Codec dispatch uses the tokio_postgres::types::Type from Statement::params() and Column::type_(), not the bare
OID. tokio-postgres resolves non-builtin OIDs at prepare time. rowx then resolves recursively: a domain uses its base
codec, an enum uses the text-label codec, and an array uses its element codec.
Result columns arrive with the base type OID for domains. Parameters and array elements carry the domain OID, so a binary array encode writes the element OID as declared.
Leaves the annotation chooses¶
- Intervals.
datetime.timedeltais the default and raises when the value has a non-zero months component.rowx_postgres.Interval(months,days,microseconds) is a second leaf for the sameintervalcolumn. The annotation picks the codec. Parameters accept bothIntervalandtimedelta. - Network.
IPv4Interface | IPv6Interface(inet) andIPv4Network | IPv6Network(cidr) are the only multi-member unions the row-type grammar admits, each as one leaf. Aninetwith a full-length mask decodes to an interface whose network is the host. Extraction checks the interface types before the address types, because the interfaces are subclasses, andstrlast. - Ranges.
rowx_postgres.Range[T]is a frozen dataclass withlower,upper,lower_inc,upper_incandempty. Canonical forms follow the server, so[1,5]ofint4rangedecodes as[1, 6).Tmust be the subtype's leaf. Arrays of ranges arelist[Range[T]]. A bound whose scalar form is text is still sent in binary (Binary arrays and ranges). - Money. Results are always binary, so
moneydecodes as the int8 minor unitscash_sendwrites.rowx_postgres.Moneyholds no scale, becauselc_monetarycan change mid-session.Money.to_decimal(scale)takes the scale explicitly. A rendered string is a cast totext. cube.rowx_postgres.Cube(lower_left, upper_right)keeps both corners. The codec writes the point flag when the corners are equal and decodes a point to two equal corners. Corners of different lengths are anEncodeError.- Geometric types are fixed-layout binary dataclasses in
rowx_postgres:Point,Line,LineSegment,Box,Path,PolygonandCircle.PathandPolygonholdtuple[Point, ...], andPathhas aclosedflag. - Extensions match by name and owning extension. Describe resolves
pg_depend(deptype = 'e') topg_extension.extnameonce per connection and OID, caches that with the statement cache, and the runtime codec reuses the map. A same-named type owned by no extension, or by another extension, isunsupported-type.citextuses the same rule.hstoreisdict[str, str | None].ltreeandlqueryarestr. - JSON.
jsonandjsonbaccept any leaf annotation (Rules). A boundstrbecomes a JSON string; to bind raw JSON text, write{s}::jsonb. Values are alwaysjson.dumps-ed, ASCII-only. - Encoding. Binary wherever the server has a
*_send/*_recvpair, because results are always binary. Scalarnumeric,timetz,json,jsonb, enum labels anduuidfromstrmay use text as a scalar. Inside an array or range those values use binary element encoders. A type withpg_type.typsend = 0(for exampleaclitem) cannot be read and isunsupported-type.
Decode errors¶
DecodeError, each with a hint to cast to text:
date,timestamportimestamptzthat is ±infinity, or whose year is outside 1..9999;intervalwith a non-zero months component when the leaf istimedelta, or ±infinity;- a range whose bounds are ±infinity for a
dateortimestampsubtype. ARangeusesNoneonly for an unbounded side.
timetz stores the zone as seconds west of UTC, so the decoder negates it. A naive time or datetime bound to
an aware column, or the reverse, is an EncodeError. date does not accept datetime. int parameters are never
bool. An int bound to float4 or float8 that is larger than 2^53 loses precision. Decimal('sNaN') is an
EncodeError.
Unsupported types¶
Any other type is unsupported-type in the checker and DecodeError at runtime. Examples: records and composites,
multiranges, xml, tsvector/tsquery, pg_lsn, xid/xid8/tid, the reg* types, jsonpath and aclitem.
Records wait for named fields inside a row (#297), because describe
reports only the record pseudo-type. Adding a supported type means appending a row to types.rs and regenerating
the table.
Parameters¶
None(SQL NULL) is accepted for every parameter. Parameter nullability is never checked.- Array element nullability matches SQLx.
list[int]matchesint4[], andlist[int | None]is also accepted. This is the only relaxation of exact matching, and it applies at every nesting level.strandbytesare never treated as sequences. - Extracting parameters.
boolis checked beforeint, anddatetimebeforedate, because they are subclasses.