postgresql-types: Precise PostgreSQL types representation and driver-agnostic codecs

[ codecs, library, mit, postgresql ] [ Propose Tags ] [ Report a vulnerability ]

This package provides a Haskell representation of PostgreSQL data types, with mappings to and from both binary and textual formats of the PostgreSQL wire protocol. The types are implemented in their canonical forms, directly corresponding to their PostgreSQL counterparts. The philosophy is that nuance matters, so all special values are represented without data loss or compromise.

The types presented by this package do not necessarily have direct mappings to common Haskell types. Canonicalizing conversions and smart constructors are provided to address this.

For example, any text value from PostgreSQL produces a valid Data.Text.Text value in Haskell, but not every Haskell Data.Text.Text value produces a valid PostgreSQL text, because PostgreSQL does not allow NUL bytes in text fields, whereas Haskell's Data.Text.Text does. In the case of dates, the supported date ranges may differ between PostgreSQL and Haskell's "time" library. Therefore, conversions between these types and common Haskell types may be partial and may fail if the data cannot be represented in the target type.

All types supply Test.QuickCheck.Arbitrary instances that cover the full range of valid PostgreSQL values. Every type is property-tested to validate round-trip conversions between binary and textual formats against PostgreSQL versions 9 to 18.

The library can be used as the basis for various PostgreSQL libraries. Ecosystem integration adapters are available for:


[Skip to Readme]

Modules

[Last Documentation]

  • PostgresqlTypes
    • PostgresqlTypes.Bit
    • PostgresqlTypes.Bool
    • PostgresqlTypes.Box
    • PostgresqlTypes.Bpchar
    • PostgresqlTypes.Bytea
    • PostgresqlTypes.Char
    • PostgresqlTypes.Cidr
    • PostgresqlTypes.Circle
    • PostgresqlTypes.Date
    • PostgresqlTypes.Float4
    • PostgresqlTypes.Float8
    • PostgresqlTypes.Hstore
    • PostgresqlTypes.Inet
    • PostgresqlTypes.Int2
    • PostgresqlTypes.Int4
    • PostgresqlTypes.Int8
    • PostgresqlTypes.Interval
    • PostgresqlTypes.Json
    • PostgresqlTypes.Jsonb
    • PostgresqlTypes.Line
    • PostgresqlTypes.Lseg
    • PostgresqlTypes.Macaddr
    • PostgresqlTypes.Macaddr8
    • PostgresqlTypes.Money
    • PostgresqlTypes.Multirange
    • PostgresqlTypes.Numeric
    • PostgresqlTypes.Oid
    • PostgresqlTypes.Path
    • PostgresqlTypes.Point
    • PostgresqlTypes.Polygon
    • PostgresqlTypes.Range
    • PostgresqlTypes.Text
    • PostgresqlTypes.Time
    • PostgresqlTypes.Timestamp
    • PostgresqlTypes.Timestamptz
    • PostgresqlTypes.Timetz
    • PostgresqlTypes.Uuid
    • PostgresqlTypes.Varbit
    • PostgresqlTypes.Varchar

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1, 0.1.1, 0.1.1.1
Dependencies aeson (>=2.2 && <3), attoparsec (>=0.14 && <0.19), base (>=4.11 && <5), bytestring (>=0.10 && <0.13), containers (>=0.6 && <0.9), hashable (>=1.3 && <2), invariant (>=0.6.4 && <0.7), jsonifier (>=0.2.1.3 && <0.3), mtl (>=2.2 && <3), postgresql-libpq (>=0.10 && <0.12), postgresql-types, postgresql-types-algebra (>=0.1 && <0.2), profunctors (>=5.6 && <5.7), ptr-peeker (>=0.1 && <0.2), ptr-poker (>=0.1.3 && <0.2), QuickCheck (>=2.14 && <3), quickcheck-extras (>=0.1 && <0.2), quickcheck-instances (>=0.3.33 && <0.4), scientific (>=0.3 && <1), tagged (>=0.8.9 && <0.9), text (>=1.2 && <3), text-builder (>=1.0.0.4 && <1.1), time (>=1.12 && <2), transformers (>=0.5 && <0.7), uuid (>=1.3 && <2), vector (>=0.13 && <0.14) [details]
License MIT
Copyright (c) 2025, Nikita Volkov
Author Nikita Volkov <nikita.y.volkov@mail.ru>
Maintainer Nikita Volkov <nikita.y.volkov@mail.ru>
Uploaded by NikitaVolkov at 2026-01-22T21:20:32Z
Category PostgreSQL, Codecs
Home page https://github.com/nikita-volkov/postgresql-types
Bug tracker https://github.com/nikita-volkov/postgresql-types/issues
Source repo head: git clone https://github.com/nikita-volkov/postgresql-types
Distributions
Reverse Dependencies 1 direct, 0 indirect [details]
Downloads 4 total (4 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs not available [build log]
All reported builds failed as of 2026-01-22 [all 2 reports]

Readme for postgresql-types-0.1

[back to package description]

postgresql-types

Hackage Continuous Haddock

Precise Haskell representations of PostgreSQL data types with mappings to and from both binary and textual formats.

Status

In active development, but already working and exhaustively tested.

Key Features

Ecosystem Integration

Adapter packages provide integrations for major PostgreSQL client libraries:

Supported Types

This package provides support for nearly all PostgreSQL data types, including:

  • Numeric types: Int2, Int4, Int8, Float4, Float8, Numeric, Money, Oid
  • Character types: Char, Varchar, Text, Bpchar
  • Boolean type: Bool
  • Binary data: Bytea
  • Date/time types: Date, Time, Timestamp, Timestamptz, Timetz, Interval
  • Network address types: Inet, Cidr, Macaddr, Macaddr8
  • Geometric types: Point, Line, Lseg, Box, Path, Polygon, Circle
  • Bit string types: Bit, Varbit
  • UUID type: Uuid
  • JSON types: Json, Jsonb
  • Key-value types: Hstore
  • Range types: Range (supporting int4range, int8range, numrange, tsrange, tstzrange, daterange)
  • Multirange types: Multirange (supporting int4multirange, int8multirange, etc.)
  • Array types for all of the above

For detailed information about each type, see the package documentation.

Type Safety & Valid Ranges

All PostgreSQL types are represented with hidden constructors, ensuring that only valid PostgreSQL values can be constructed. This design prevents invalid data from being represented at the type level.

Values can only be created through explicit constructor functions, guaranteeing adherence to PostgreSQL's constraints (e.g., dates within PostgreSQL's supported range, text without NUL bytes).

Type-Safe Constructors

The library provides three types of functions for working with PostgreSQL types:

  • Normalizing constructors (prefix: normalizeFrom*) - Always succeed by clamping or canonicalizing input values to valid ranges
  • Refining constructors (prefix: refineFrom*) - Return Maybe, failing if the input is out of range
  • Accessor functions (prefix: to*) - Extract values from PostgreSQL types to common Haskell types

This approach ensures that:

  • Type constructors remain hidden to protect invariants
  • All conversions are explicit and type-safe
  • Invalid data is either rejected or canonicalized (e.g., removing NUL bytes from text, clamping dates to valid range)
  • Round-trip properties are maintained via accessor functions

Complete Range Coverage with Property Testing

Every type implements Arbitrary instances that simulate the complete range of valid PostgreSQL values, not just convenient Haskell subsets. For example:

  • Date generates values spanning PostgreSQL's full range: 4713 BC to 5874897 AD
  • Text generates strings excluding NUL characters (as PostgreSQL doesn't allow them)
  • Circle generates circles with non-negative radii
  • Numeric covers arbitrary-precision numbers including edge cases

This comprehensive approach to test data generation ensures that the library is tested against the actual constraints and edge cases of PostgreSQL, not just typical use cases.

Exhaustive Testing

The library employs a rigorous multi-layered testing strategy:

Unit Tests

  • Encoder/Decoder Round-trips: Every type is tested for round-trip fidelity through both binary and textual encodings
  • Constructor Properties: All constructor functions are validated for proper normalization and refinement behavior using property-based testing
  • Cross-format Validation: Binary encoders are tested against textual decoders and vice versa

Integration Tests

  • Real PostgreSQL Validation: Tests run against actual PostgreSQL servers (versions 9 through 18)
  • Four-way Round-trip Matrix: Each value is tested through all four combinations:
    1. Text encoding → Text decoding
    2. Text encoding → Binary decoding
    3. Binary encoding → Text decoding
    4. Binary encoding → Binary decoding
  • Server Canonical Form: All encodings are validated by sending values to PostgreSQL and verifying the server produces the expected output
  • Array Support: Every type is tested both as a scalar and as array elements
  • Metadata Validation: Type OIDs are verified against the PostgreSQL system catalog

This comprehensive testing model provides confidence that the library correctly handles all PostgreSQL types across all encoding formats and PostgreSQL versions.