pg_lake_iceberg

Iceberg implementation in Postgres

Overview

PackageVersionCategoryLicenseLanguage
pg_lake3.4OLAPApache-2.0C
IDExtensionBinLibLoadCreateTrustRelocSchema
2560pg_lakeYesYesYesYesNoNolake
2561pg_extension_baseNoYesYesYesNoNoextension_base
2562pg_extension_updaterNoYesYesYesNoNoextension_updater
2563pg_mapNoYesNoYesNoNomap_type
2564pg_lake_engineNoYesYesYesNoNo__lake__internal__nsp__
2565pg_lake_icebergNoYesNoYesNoNolake_iceberg
2566pg_lake_tableNoYesYesYesNoNo__pg_lake_table_writes
2567pg_lake_copyNoYesYesYesNoNopg_catalog
Relatedpg_lake_engine plpgsql pg_ducklake pg_parquet pg_duckdb aws_s3 file_fdw pg_bulkload duckdb_fdw pg_mooncake pg_fact_loader pg_clickhouse
Depended Bypg_lake_copy pg_lake_table

The control file declares pg_lake_engine; canonical metadata also retains plpgsql because the install SQL uses PL/pgSQL. plpgsql is installed by default in normal PostgreSQL databases. Extension SQL/control version is 3.4; source and DEB/RPM package version is 3.4.0.

Version

TypeRepoVersionPG VerPackageDeps
EXTPIGSTY3.41817161514pg_lakepg_lake_engine, plpgsql
RPMPIGSTY3.4.01817161514pg_lake_$v-
DEBPIGSTY3.4.01817161514postgresql-$v-pg-lake-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64N/AN/AN/AN/AN/A
el8.aarch64N/AN/AN/AN/AN/A
el9.x86_64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
el9.aarch64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
el10.x86_64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
el10.aarch64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
d12.x86_64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
d12.aarch64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
d13.x86_64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
d13.aarch64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
u22.x86_64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
u22.aarch64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
u24.x86_64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
u24.aarch64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
u26.x86_64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A
u26.aarch64PIGSTY 3.4.0PIGSTY 3.4.0PIGSTY 3.4.0N/AN/A

Build

You can build the RPM / DEB packages for pg_lake using pig build:

pig build pkg pg_lake         # build RPM / DEB packages

Install

You can install pg_lake directly. First, make sure the PGDG and PIGSTY repositories are added and enabled:

pig repo add pgsql -u          # Add repo and update cache

Install the extension using pig or apt/yum/dnf:

pig install pg_lake;          # Install for current active PG version
pig ext install -y pg_lake -v 18  # PG 18
pig ext install -y pg_lake -v 17  # PG 17
pig ext install -y pg_lake -v 16  # PG 16
dnf install -y pg_lake_18       # PG 18
dnf install -y pg_lake_17       # PG 17
dnf install -y pg_lake_16       # PG 16
apt install -y postgresql-18-pg-lake   # PG 18
apt install -y postgresql-17-pg-lake   # PG 17
apt install -y postgresql-16-pg-lake   # PG 16

Create Extension:

CREATE EXTENSION pg_lake_iceberg CASCADE;  -- requires: pg_lake_engine, plpgsql

Usage

Sources:

pg_lake_iceberg implements Iceberg metadata, snapshots, manifests, partition specifications, and catalog integration inside PostgreSQL. The familiar CREATE TABLE ... USING iceberg syntax is exposed by the dependent pg_lake_table component; users normally install both through pg_lake.

Create and Inspect an Iceberg Table

CREATE EXTENSION pg_lake CASCADE;

SET pg_lake_iceberg.default_location_prefix =
    's3://analytics-bucket/warehouse';

CREATE TABLE events (
    event_time timestamptz NOT NULL,
    user_id bigint NOT NULL,
    payload jsonb
) USING iceberg
WITH (partition_by = 'day(event_time), bucket(32, user_id)');

SELECT table_namespace, table_name, metadata_location
FROM iceberg_tables
WHERE table_name = 'events';

Inspect an Iceberg metadata file and its referenced state:

SELECT lake_iceberg.metadata(metadata_location)
FROM iceberg_tables
WHERE table_name = 'events';

SELECT f.*
FROM iceberg_tables AS t
CROSS JOIN LATERAL lake_iceberg.files(t.metadata_location) AS f
WHERE t.table_name = 'events';

Metadata and Catalog API

  • iceberg_tables: pg_catalog view combining local managed tables and external catalog entries.
  • iceberg_namespace_properties: catalog namespace properties.
  • lake_iceberg.metadata(uri): raw Iceberg metadata JSON.
  • lake_iceberg.files(uri): manifest path, content kind, data-file path/format, spec ID, record count, and file size.
  • lake_iceberg.snapshots(uri): sequence number, snapshot ID, timestamp, and manifest-list path.
  • lake_iceberg.data_file_stats(uri): per-file sequence and lower/upper bounds; execution is granted to lake_read rather than PUBLIC.
  • iceberg_catalog: version 3.4 FDW for named PostgreSQL, object-store, or REST catalog configurations.

Define a user-managed REST catalog server and keep credentials in a user mapping:

CREATE SERVER my_polaris TYPE 'rest'
FOREIGN DATA WRAPPER iceberg_catalog
OPTIONS (rest_endpoint 'https://polaris.example.com');

CREATE USER MAPPING FOR app_role SERVER my_polaris
OPTIONS (client_id 'app', client_secret 'secret');

CREATE TABLE catalog_events (id bigint)
USING iceberg
WITH (catalog = 'my_polaris');

Catalog and Storage Caveats

  • User-created catalog servers require their own USER MAPPING credentials and do not fall back to the built-in REST catalog credential GUCs.
  • The built-in postgres, object_store, and rest catalogs map to immutable extension-owned servers. Configure them through the documented GUCs rather than altering those servers.
  • External modifications to iceberg_tables are blocked by default because changing metadata behind pg_lake can break transaction and query-engine consistency.
  • Iceberg writes should be batched. Each statement can add Parquet files and snapshots; regular VACUUM compacts small files and expires data according to table/GUC policy.
  • Iceberg has narrower representations for some PostgreSQL values. The default out_of_range_values = 'error' preserves integrity; clamp silently changes out-of-range temporal values and replaces some unsupported values with NULL.

Last Modified: 2026-07-30: extension update 2026-07-30 (7219c44)