Skip to content

Latest commit

 

History

History
258 lines (178 loc) · 9.49 KB

File metadata and controls

258 lines (178 loc) · 9.49 KB
title PostgreSQL Types

import Snippet from '@site/src/components/Snippet';

PostgreSQL Type Support

Foundations JDBC provides comprehensive support for all PostgreSQL data types, including the many exotic types that make PostgreSQL unique.

Setting search_path

Use PgConfig.Builder.currentSchema(...) to set a comma-separated search_path at connection time — handy when your composite types, enums, or tables live in a non-public schema and you want to reference them unqualified in SQL:

var config = PgConfig.builder("host", 5432, "db", "user", "pw")
    .currentSchema("app,public")   // search_path = app, public
    .build();

This maps to PostgreSQL's currentSchema connection property. For single-schema use, ConnectionSettings.schema(...) also works but only accepts one name.

Numeric Types

PostgreSQL Type Java Type Notes
int2 / smallint Short 16-bit signed integer
int4 / integer Integer 32-bit signed integer
int8 / bigint Long 64-bit signed integer
float4 / real Float 32-bit IEEE 754
float8 / double precision Double 64-bit IEEE 754
numeric / decimal BigDecimal Arbitrary precision
money Money Currency with 2 decimal places

Boolean Type

PostgreSQL Type Java Type
bool / boolean Boolean

String Types

PostgreSQL Type Java Type Notes
text String Variable unlimited length
varchar(n) String Variable length with limit
bpchar / char(n) String Fixed-length, blank-padded
name String 63-character identifier

Binary Types

PostgreSQL Type Java Type Notes
bytea byte[] Variable-length binary

Date/Time Types {#datetime-rationale}

PostgreSQL Type Java Type Notes
date LocalDate Naive date, no zone
time LocalTime Naive time, no zone
timetz OffsetTime Time with offset (rarely used in practice)
timestamp LocalDateTime Naive timestamp, no zone
timestamptz Instant UTC instant — see note below
interval PGInterval Time duration

:::note timestamptz does not store a time zone PostgreSQL is explicit on this: for timestamp with time zone, "the value is stored internally as UTC, and the originally stated or assumed time zone is not retained" (from the PostgreSQL docs). The zone only affects how the value is rendered at read-time (always converted to the session TimeZone setting).

Because the column genuinely stores a universal instant — not a zoned value — the library maps it to java.time.Instant. Any zone information must travel alongside the value in a separate column if you need it (same data-modelling approach as Jira, GitHub, and most other systems). Using OffsetDateTime here would suggest the stored value carries an offset, which it does not.

This is the reference mapping for the whole library: DuckDB's TIMESTAMPTZ shares the same semantics and uses the same Instant mapping. SQL Server's DATETIMEOFFSET and Oracle's TIMESTAMP WITH TIME ZONE genuinely preserve offset/zone and therefore map differently — see each dialect's page for details. :::

UUID Type

PostgreSQL Type Java Type
uuid java.util.UUID

JSON Types

PostgreSQL Type Java Type Notes
json Json Stored as-is, validated on input
jsonb Jsonb Binary format, indexed, normalized

Json and Jsonb are distinct wrapper records around a String payload, so a single row with both a json and a jsonb column keeps its types straight. Wrap the raw JSON text at the edges:

new Jsonb("{\"ok\":true}")     // java
Jsonb("""{"ok":true}""")        // kotlin

A common first-run surprise is declaring val payload: String on a Kotlin data class and getting actual type is 'String', but 'Jsonb!' was expected — the Kotlin ! just marks a platform type, the fix is the wrap above.

Array Types

Any PostgreSQL type can be used as an array — call .array() on the element type. The Java representation is always List<T>:

PostgreSQL Type Java Type
int4[] List<Integer> via int4.array()
int8[] List<Long> via int8.array()
float4[] List<Float> via float4.array()
float8[] List<Double> via float8.array()
bool[] List<Boolean> via bool.array()
text[] List<String> via text.array()
uuid[] List<UUID> via uuid.array()

This works for all types — numeric.array(), timestamptz.array(), jsonb.array(), custom enum types, composite types, etc. Multi-dimensional arrays compose: .array().array() produces SQL T[][] with Java type List<List<T>>.

Composite Types

PostgreSQL composite types (row constructors and CREATE TYPE declarations) are built from a RowCodecNamed via compositeOf:

// Ad-hoc composite — for row constructors like (a, b, c) in SQL
PgType<LineItem> lineItemType = PgTypes.compositeOf(
    RowCodec.<LineItem>namedBuilder()
        .field("product_name", PgTypes.text, LineItem::productName)
        .field("quantity", PgTypes.int4, LineItem::quantity)
        .field("unit_price", PgTypes.numeric, LineItem::unitPrice)
        .build(LineItem::new));

// Named composite — for CREATE TYPE declarations (supports writes)
PgType<Address> addressType = PgTypes.compositeOf("address", addressCodec);

// Array of composites — works like any other type
PgType<List<LineItem>> lineItemArrayType = lineItemType.array();

The same RowCodecNamed codec can be reused for flat row queries, composite types, JSON-encoded columns, and query analysis.

Range Types

PostgreSQL's range types represent intervals of values with inclusive/exclusive bounds:

PostgreSQL Type Java Type Element Type
int4range Range<Integer> Integer
int8range Range<Long> Long
numrange Range<BigDecimal> BigDecimal
daterange Range<LocalDate> LocalDate
tsrange Range<LocalDateTime> LocalDateTime
tstzrange Range<Instant> Instant

Geometric Types

PostgreSQL's geometric types for 2D shapes:

PostgreSQL Type Java Type Description
point PGpoint (x, y) coordinate
line PGline Infinite line
lseg PGlseg Line segment
box PGbox Rectangular box
path PGpath Open or closed path
polygon PGpolygon Closed polygon
circle PGcircle Circle with center and radius

Network Types

Types for storing network addresses:

PostgreSQL Type Java Type Description
inet Inet IPv4 or IPv6 host address
cidr Cidr IPv4 or IPv6 network
macaddr Macaddr MAC address (6 bytes)
macaddr8 Macaddr8 MAC address (8 bytes, EUI-64)

Text Search Types

Full-text search types:

PostgreSQL Type Java Type Description
tsvector Tsvector Text search document
tsquery Tsquery Text search query

XML Type

PostgreSQL Type Java Type
xml Xml

Other Special Types

PostgreSQL Type Java Type Description
hstore Map<String, String> Key-value store
vector Vector pgvector extension
record Record Anonymous composite type

System Types

Types used internally by PostgreSQL:

PostgreSQL Type Java Type Description
oid Long Object identifier
xid Xid Transaction ID
regclass Regclass Relation name/OID
regtype Regtype Type name/OID
regproc Regproc Function name/OID

Enum Types

PostgreSQL enums are mapped to Java enums:

:::note sqlType must match the CREATE TYPE name (schema-qualified if needed) The first argument to ofEnum(sqlType, ...) is the PostgreSQL type name used to cast bound parameters. Pass exactly the name that appears in CREATE TYPE schema.color AS ENUM(...) — including the schema prefix if the type isn't in search_path. A mismatch produces type "color" does not exist on the first insert. :::

Custom Domain Types

Wrap base types with custom Java types using transform:

Nullable Types

Any type can be made nullable using .opt():