pg_value

test Package Version Hex Docs

PostgreSQL data types, binary encoders, and binary decoders for Gleam. Designed to be used by PostgreSQL client libraries. Currently used by pgl.

Supported Types

PostgreSQL TypeValue VariantGleam Type
booleanBoolBool
smallint, integer, bigint, oidIntInt
real, double precisionFloatFloat
text, varchar, char(n)/bpchar, nameTextString
byteaByteaBitArray
uuidUuidBitArray
timeTimegleam/time/calendar.TimeOfDay
dateDategleam/time/calendar.Date
timestampTimestampgleam/time/timestamp.Timestamp
timestamptzTimestamptzgleam/time/timestamp.Timestamp + gleam/time/duration.Duration
intervalIntervalpg_value/interval.Interval
json, jsonbJsongleam/json.Json
hstoreHstoreDict(String, Option(String))
enum typesEnumString
arraysArrayList(Value)
Null

The text path covers char(n) (bpchar). The internal single-byte "char" type (charsend, oid 18) is also handled as text.

Usage

import gleam/json
import gleam/option.{None, Some}
import pg_value

// Construct values
let params = [
  pg_value.int(42),
  pg_value.text("hello"),
  pg_value.bool(True),
  pg_value.null,
  pg_value.json(json.object([#("key", json.string("value"))])),
  pg_value.array([1, 2, 3], of: pg_value.int),
  pg_value.nullable(pg_value.text, Some("present")),
  pg_value.nullable(pg_value.text, None),
]

Encoding

Values are encoded to PostgreSQL’s binary wire format using TypeInfo from the database connection:

let assert Ok(encoded) = pg_value.encode(pg_value.int(10), int4_type_info)

Decoding

Binary data from PostgreSQL is decoded into Dynamic values, which can then be decoded into typed data using gleam/dynamic/decode:

let assert Ok(dynamic_value) = pg_value.decode(bits, int4_type_info)

Typed decoders are provided for time types and intervals:

Notes

timestamptz convention

When encoding a Timestamptz, the Timestamp is treated as a wall-clock time in the given zone and the offset is subtracted to produce the UTC instant on the wire. Decoding always yields the UTC instant with no offset, so decode(encode(Timestamptz(ts, offset))) equals ts only when offset is zero. If your Timestamp is already an absolute UTC instant, pass a zero offset.

timestamp infinity

Finite timestamps decode to an integer microsecond Dynamic, but PostgreSQL’s infinity/-infinity decode to the strings "infinity"/"-infinity". The provided timestamp_decoder() only handles finite values; decode infinity separately (e.g. with decode.string).

Installation

gleam add pg_value@3

Development

gleam test  # Run the tests

Acknowledgements

Much thanks to pg_types for encoding and decoding logic.

Search Document