rupg_types/lib.rs
1//! The value model, `Datum`, `Vector` of 1024 values, `TypeId`, the text and binary forms of the 197 types, numeric, date and time, JSON, arrays, ranges, multiranges, `tsvector`.
2//!
3//! See `spec/07-sql-types-and-catalog.md` and `spec/22-crate-layout.md` section 22.4.
4//!
5//! A client reads the type of a column from the OID and the typmod in `RowDescription`, and it parses each value with the rules of that type. So each input function here takes what the function of PostgreSQL takes and refuses what it refuses, with the same SQLSTATE and the same message, and each output function writes the same bytes. The server at the pin is the reference.
6//!
7//! # What is here
8//!
9//! [`oid`], one constant for each type in `pg_type.dat` at the pin and for its array type, and [`TypeInfo`], the row of `pg_type` that the protocol needs. [`PgType`] is an OID with a typmod, and [`typmod`] encodes and decodes the typmod of `varchar`, `numeric` and `interval`. The row types of the shared catalogs, such as `pg_database`, come from the catalog headers and not from `pg_type.dat`, so they are not here.
10//!
11//! [`Value`], one value of any type in the engine. The expression that gives a value has its type, so the value does not carry it.
12//!
13//! The text forms of `bool`, `"char"`, `name`, `int2`, `int4`, `int8`, `oid`, `float4`, `float8`, `bytea` and `uuid`. An input function takes the string and gives the value or a [`TypeError`]. An output function appends to a buffer, so the row encoder can write a whole row into one buffer with no allocation per value. [`float8_out`] and [`float4_out`] take `extra_float_digits`: above zero they give the shortest text that reads back to the same value, and at zero or below they give the `%g` text of old servers.
14//!
15//! `text`, `varchar(n)`, `character(n)` and `json`. The text form of `text` is the string. [`varchar_in`] and [`bpchar_in`] take the typmod, refuse a value that is too long, and remove the spaces after the length. [`bpchar_in`] also pads a short value with spaces. [`varchar_coerce`] and [`bpchar_coerce`] are the length casts, which cut with no error when the cast is explicit. [`json_in`] checks the syntax with the error details of PostgreSQL and gives the string. [`Recv::text`] is the encoding check of the receive function of each string type.
16//!
17//! [`Numeric`], a `numeric` value in the layout of PostgreSQL, with [`numeric_in`], [`numeric_out`], [`numeric_recv`] and [`numeric_send`]. The input and the receive function take the typmod and round to it as PostgreSQL does. [`decimal_out`] and [`decimal_send`] write a `numeric(p, s)` value with p up to 38 that is kept as a scaled `i128`, with no allocation. [`numeric_layout`] packs a value into bytes that sort as the numbers do.
18//!
19//! `date`, `time`, `timetz`, `timestamp`, `timestamptz` and `interval` in the layout of PostgreSQL: days or microseconds since 2000-01-01, with the infinities at the ends of the integer range. The output functions take the `DateStyle` as a [`DateFormat`] and the `IntervalStyle` as an [`IntervalStyle`], and [`timestamptz_out`] takes a [`TimeZone`] that gives the offset and the abbreviation at an instant. The receive functions check the range and round to the typmod. [`date2j`] and [`j2date`] convert between a calendar date and a Julian day.
20//!
21//! The text input of the same types, [`date_in`], [`time_in`], [`timetz_in`], [`timestamp_in`], [`timestamptz_in`] and [`interval_in`], is a port of the decoder in `datetime.c`. It reads the session state from a [`DateTimeInput`]: the field order, the time zone, the zone names, the time zone abbreviations and the time of the transaction start. [`ZoneAbbrevs`] reads a file of `src/timezone/tznames`, and [`ZoneAbbrevs::postgres_default`] is the `Default` set from `vendor/postgres-19`.
22//!
23//! [`Array`], an array of any element type with up to [`MAXDIM`] dimensions and any lower bounds. [`array_in`], [`array_out`], [`array_recv`] and [`array_send`] take the function of the element type as a closure and give the errors of PostgreSQL, also the error of the element. The binary input refuses an element type that is not the expected type, and [`format_type`] gives the names in that error. `int2vector` and `oidvector` are arrays with the lower bound 0 and a text form with spaces, in [`int2vector_in`], [`oidvector_in`] and the functions beside them.
24//!
25//! [`cash_in`], [`cash_out`] and [`cash_words`] for `money`, a count of cents in an `i64`, with the symbols of the `C` locale. [`tid_in`] and [`tid_out`] for `tid`, and [`uint64_in`] for `xid8` and `oid8`. [`macaddr_in`], [`macaddr8_in`] and the other functions of `macaddr` and `macaddr8`, with the bytes of the address in a `u64`. [`bit_in`], [`bit_coerce`], [`bit_recv`] and [`bit_send`] for `bit` and `bit varying`, a string of `0` and `1`. [`geo_in`], [`geo_out`] and [`geo_recv`] for the geometric types, the bytes of the binary form. [`pg_lsn_in`] and [`pg_lsn_out`] for `pg_lsn`, a `u64`. [`snapshot_in`], [`snapshot_out`] and [`snapshot_recv`] for `pg_snapshot` and `txid_snapshot`, with the binary form of a [`Snapshot`] as the value.
26//!
27//! [`Inet`], a value of `inet` or `cidr`, with [`inet_in`], [`inet_out`], [`inet_recv`] and [`inet_send`], which take a flag for `cidr`. [`network_cmp`] is the order of the B-tree operator class.
28//!
29//! [`RegKind`], the OID alias types such as `regclass` and `regtype`. [`reg_in`] reads a number or `-` as PostgreSQL does and gives any other string as a name, and [`reg_out_oid`] writes OID 0 and an OID with no object. The catalog finds the names: it splits a name such as `schema.table` with [`qualified_name_list`] and writes the names of the objects.
30//!
31//! [`Recv`], the binary input of a `Bind` parameter, with the errors of PostgreSQL when the value is too short or too long. The binary output of the other types is the value in big-endian bytes.
32//!
33//! [`Lexeme`], one lexeme of a `tsvector` with its positions, with [`tsvector_parse`], [`tsvector_deparse`], [`tsvector_recv`] and [`tsvector_send`]. [`tsvector_cmp`] is the order of the B-tree operator class, and [`unique_positions`] puts positions in order as the input function does. [`QueryItem`], one operand or operator of a `tsquery`, with [`tsquery_parse`], [`tsquery_parse_with`] for the functions of text search that make a query, [`tsquery_deparse`], [`tsquery_recv`] and [`tsquery_send`]. [`tsquery_cmp`] is the order of the B-tree operator class. [`JsonPath`], a value of `jsonpath`, with [`jsonpath_parse`], [`jsonpath_deparse`], [`jsonpath_recv`] and [`jsonpath_send`].
34//!
35//! [`xml_in`] checks that the text of an `xml` value is well formed, as libxml2 2.9.14 checks it for PostgreSQL, and gives the same errors and warnings. [`xml_out`] writes the value with the XML declaration of PostgreSQL, and [`xml_encoding`] reads the encoding in the declaration for the receive function.
36//!
37//! [`unicode`], the four Unicode normalization forms, and [`tz`], the time zones of the IANA data.
38//!
39//! # Known differences
40//!
41//! The input functions take a string in the server encoding, which is UTF-8. The caller converts from the client encoding first.
42//!
43//! [`tz::Zone`] implements [`TimeZone`] with the rules of the IANA data, and [`tz::TzDatabase`] implements [`ZoneLookup`]. [`FixedZone`] and [`NoZones`] are for the tests and for a caller without the data.
44//!
45//! [`pg_ndistinct_in`] and [`pg_dependencies_in`] read the JSON text of the types of the extended statistics with the details of the errors of PostgreSQL, and give the bytes of the value. [`pg_ndistinct_out`] and [`pg_dependencies_out`] write the text from the bytes.
46//!
47//! PostgreSQL parses `json` by recursion and stops a deep value with `stack depth limit exceeded` when it reaches `max_stack_depth`. [`json_in`] uses no recursion and takes a value at any depth. PostgreSQL stops a deep `tsquery` in the same way. [`tsquery_parse`] gives the same error for a query with 1000 levels, as the analyzer does for an expression. [`jsonpath_parse`] has the same limit for a path.
48//!
49//! The text and binary forms are lifted from `crates/rudb-pgtypes` of tamnd/rudb at f5f7065a (spec/04 section 4.9). The `DataRow` encoder and the `Bind` decoder of that crate need the executor, so they come with rupg-server.
50
51#![forbid(unsafe_code)]
52
53mod array;
54mod arrayset;
55mod binary;
56mod bit;
57mod datetime;
58mod datum;
59mod error;
60mod float;
61mod generated;
62mod geo;
63mod json;
64mod jsonb;
65mod jsonpath;
66mod jsontree;
67mod lsn;
68mod mac;
69mod money;
70mod multirange;
71mod network;
72mod number;
73mod numeric;
74pub mod numeric_layout;
75pub mod prng;
76mod range;
77mod reg;
78mod scalar;
79mod snapshot;
80mod stats;
81mod string;
82mod tid;
83mod tsquery;
84mod tsvector;
85mod typeid;
86mod types;
87pub mod typmod;
88pub mod tz;
89pub mod unicode;
90mod value;
91mod xml;
92
93pub use array::{
94 Array, ArrayDim, MAX_ARRAY_SIZE, MAXDIM, array_in, array_out, array_recv, array_send,
95 int2vector_in, int2vector_out, int2vector_recv, int2vector_send, oidvector_in, oidvector_out,
96 oidvector_recv, oidvector_send,
97};
98pub use binary::{Recv, name_recv};
99pub use bit::{BIT_MAX_LEN, bit_bytes, bit_coerce, bit_in, bit_recv, bit_send};
100pub use datetime::{
101 Abbrev, AbbrevMeaning, DATE_INFINITY, DATE_NEGATIVE_INFINITY, DateFormat, DateOrder, DateStyle,
102 DateTimeInput, DateUnit, FixedZone, Interval, IntervalStyle, NoZones, POSTGRES_EPOCH_JDATE,
103 TIMESTAMP_INFINITY, TIMESTAMP_NEGATIVE_INFINITY, TimeZone, UNIX_EPOCH_JDATE,
104 UNIX_TO_POSTGRES_DAYS, UNIX_TO_POSTGRES_USECS, USECS_PER_DAY, USECS_PER_SEC, ZoneAbbrevs,
105 ZoneLookup, ZoneName, adjust_interval, adjust_time, adjust_timestamp, date_from_unix, date_in,
106 date_out, date_recv, date2j, decode_numeric_timezone, decode_timezone_abbrev_prefix,
107 decode_timezone_name, interval_in, interval_out, interval_recv, interval_send, j2date,
108 local_offset, time_in, time_out, time_recv, timestamp_from_unix, timestamp_in, timestamp_out,
109 timestamp_recv, timestamptz_in, timestamptz_out, timetz_in, timetz_out, timetz_recv,
110};
111pub use datum::Datum;
112pub use error::TypeError;
113pub use float::{float4_in, float4_out, float8_in, float8_out};
114pub use generated::oids as oid;
115pub use geo::{GeoKind, geo_in, geo_out, geo_recv};
116pub use json::json_in;
117pub use jsonb::{escape as json_escape, jsonb_in, jsonb_recv, jsonb_send};
118pub use jsonpath::{
119 Chain, JSONPATH_LAST, JSONPATH_REGEX_DOTALL, JSONPATH_REGEX_ICASE, JSONPATH_REGEX_MLINE,
120 JSONPATH_REGEX_QUOTE, JSONPATH_REGEX_WSPACE, JsonPath, PathItem, PathOp, RegexCheck,
121 jsonpath_deparse, jsonpath_parse, jsonpath_recv, jsonpath_regex_flags, jsonpath_send,
122};
123pub use jsontree::{
124 JsonItem, JsonNode, JsonTree, PathOp as JsonPathOp, Token as JsonToken, Tokens as JsonTokens,
125 json_index,
126};
127pub use lsn::{pg_lsn_in, pg_lsn_out};
128pub use mac::{
129 macaddr_in, macaddr_out, macaddr_recv, macaddr_to_macaddr8, macaddr8_in, macaddr8_out,
130 macaddr8_recv, macaddr8_to_macaddr,
131};
132pub use money::{cash_in, cash_out, cash_words};
133pub use multirange::{multirange_deparse, multirange_parse, multirange_recv, multirange_send};
134pub use network::{
135 Inet, NetFamily, bitncmp, bitncommon, cidr_abbrev, inet_in, inet_out, inet_recv, inet_send,
136 net_ntop, network_cmp,
137};
138pub use number::{
139 int_out, int2_in, int4_in, int8_in, oid_in, oid_out, u64_out, uint32_in, uint64_in,
140};
141pub use numeric::{
142 Numeric, NumericSign, decimal_out, decimal_send, numeric_in, numeric_out, numeric_out_sci,
143 numeric_recv, numeric_send,
144};
145pub use range::{
146 RANGE_EMPTY, RANGE_LB_INC, RANGE_LB_INF, RANGE_UB_INC, RANGE_UB_INF, Range, RangeBytes,
147 RangeText, range_deparse, range_parse, range_recv, range_send,
148};
149pub use reg::{
150 RegInput, RegKind, qualified_name_list, reg_in, reg_out_oid, split_identifier_string,
151};
152pub use scalar::{
153 ByteaOutput, NAME_MAX_BYTES, bool_in, bool_out, bytea_in, bytea_out, char_in, char_out,
154 name_in, uuid_in, uuid_out,
155};
156pub use snapshot::{Snapshot, snapshot_in, snapshot_out, snapshot_recv};
157pub use stats::{pg_dependencies_in, pg_dependencies_out, pg_ndistinct_in, pg_ndistinct_out};
158pub use string::{bpchar_coerce, bpchar_in, varchar_coerce, varchar_in};
159pub use tid::{tid_in, tid_out};
160pub use tsquery::{
161 QueryItem, TSQUERY_AND, TSQUERY_MAX_DISTANCE, TSQUERY_NOT, TSQUERY_OR, TSQUERY_PHRASE,
162 TsQueryMode, TsQueryPush, TsQueryPushVal, legacy_crc32, tsquery_bad_distance, tsquery_cmp,
163 tsquery_contains, tsquery_deparse, tsquery_join, tsquery_parse, tsquery_parse_with,
164 tsquery_recv, tsquery_send, tsquery_tree,
165};
166pub use tsvector::{
167 Lexeme, TSVECTOR_MAX_DATA, TSVECTOR_MAX_POSITIONS, TSVECTOR_MAX_WORD, limit_position,
168 position_of, ts_compare_string, tsvector_cmp, tsvector_data_len, tsvector_deparse,
169 tsvector_parse, tsvector_recv, tsvector_send, tsvector_size, unique_positions, weight_of,
170 with_weight, word_too_long,
171};
172pub use typeid::TypeId;
173pub use types::{Oid, PgType, TypeInfo, format_type};
174pub use value::{Record, Value};
175pub use xml::{
176 XmlStandalone, escape_xml, sql_name, xml_base64, xml_binhex, xml_comment, xml_concat,
177 xml_element, xml_encoding, xml_in, xml_name, xml_out, xml_pi, xml_root, xml_text,
178};