Skip to content
Open
3 changes: 3 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@

# wal2json
/wal2json/ @cloudnative-pg/maintainers @NiccoloFei @solidDoWant

# pg-ivm
/pg-ivm/ @shusaan @cloudnative-pg/maintainers @NiccoloFei
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ from a trusted, auditable repository
| :--- | :--- | :--- | :--- |
| **[pgAudit](pgaudit)** | PostgreSQL audit extension | [github.com/pgaudit/pgaudit](https://github.com/pgaudit/pgaudit) | CNPG maintainers |
| **[pg_crash](pg-crash)** | **Disruptive** fault injection and chaos engineering extension | [github.com/cybertec-postgresql/pg_crash](https://github.com/cybertec-postgresql/pg_crash) | CNPG maintainers |
| **[pg_ivm](pg_ivm)** | Incremental View Maintenance for PostgreSQL | [github.com/sraoss/pg_ivm](https://github.com/sraoss/pg_ivm) |
| **[pgvector](pgvector)** | Vector similarity search for PostgreSQL | [github.com/pgvector/pgvector](https://github.com/pgvector/pgvector) | CNPG maintainers |
| **[PostGIS](postgis)** | Geospatial database extension for PostgreSQL | [postgis.net/](https://postgis.net/) | CNPG maintainers |
| **[TimescaleDB Apache-2 Edition](timescaledb-oss)** | Time-series database for PostgreSQL (open source version) | [github.com/timescale/timescaledb/](https://github.com/timescale/timescaledb/) | @shusaan |
Expand Down
28 changes: 28 additions & 0 deletions pg-ivm/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: Copyright © contributors to CloudNativePG, established as CloudNativePG a Series of LF Projects, LLC.
# SPDX-License-Identifier: Apache-2.0

ARG BASE=ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
FROM $BASE AS builder

ARG PG_MAJOR
ARG EXT_VERSION

USER 0

RUN apt-get update && \
apt-get install -y --no-install-recommends "postgresql-${PG_MAJOR}-pg-ivm=${EXT_VERSION}"

FROM scratch
ARG PG_MAJOR

# Licenses
COPY --from=builder /usr/share/doc/postgresql-${PG_MAJOR}-pg-ivm/copyright /licenses/postgresql-${PG_MAJOR}-pg-ivm/

# Libraries
COPY --from=builder /usr/lib/postgresql/${PG_MAJOR}/lib/pg_ivm* /lib/
COPY --from=builder /usr/lib/postgresql/${PG_MAJOR}/lib/bitcode/ /lib/bitcode/

# Share
COPY --from=builder /usr/share/postgresql/${PG_MAJOR}/extension/pg_ivm* /share/extension/

USER 65532:65532
84 changes: 84 additions & 0 deletions pg-ivm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# `pg_ivm`

[pg_ivm](https://github.com/sraoss/pg_ivm) is an open-source extension
that provides **Incremental View Maintenance (IVM)** for PostgreSQL, allowing
materialized views to be updated incrementally when base tables change.

## Usage

### 1. Add the pg_ivm extension image to your Cluster

Define the `pg_ivm` extension under the `postgresql.extensions` section of
your `Cluster` resource. For example:

```yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-pg-ivm
spec:
imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
instances: 1

storage:
size: 1Gi

postgresql:
extensions:
- name: pg_ivm
image:
# renovate: suite=trixie-pgdg depName=postgresql-18-pg-ivm
reference: ghcr.io/cloudnative-pg/pg-ivm:1.13-18-trixie
```

### 2. Enable the extension in a database

You can install `pg_ivm` in a specific database by creating or updating a
`Database` resource. For example, to enable it in the `app` database:

```yaml
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: cluster-pg-ivm-app
spec:
name: app
owner: app
cluster:
name: cluster-pg-ivm
extensions:
- name: pg_ivm
# renovate: suite=trixie-pgdg depName=postgresql-18-pg-ivm extractVersion=^(?<version>\d+\.\d+)
version: '1.13'
```

### 3. Verify installation

Once the database is ready, connect to it with `psql` and run:

```sql
\dx
```

You should see `pg_ivm` listed among the installed extensions.

## Maintainers

This container image is maintained by @shuusan.

---

## Licenses and Copyright

This container image contains software that may be licensed under various
open-source licenses.

All relevant license and copyright information for the `pg_ivm` extension
and its dependencies are bundled within the image at:

```text
/licenses/
```

By using this image, you agree to comply with the terms of the licenses
contained therein.
35 changes: 35 additions & 0 deletions pg-ivm/metadata.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
metadata = {
name = "pg-ivm"
sql_name = "pg_ivm"
image_name = "pg-ivm"
licenses = ["PostgreSQL"]
shared_preload_libraries = []
postgresql_parameters = {}
extension_control_path = []
dynamic_library_path = []
ld_library_path = []
bin_path = []
env = {}
auto_update_os_libs = false
required_extensions = []
create_extension = true

versions = {
trixie = {
"18" = {
// renovate: suite=trixie-pgdg depName=postgresql-18-pg-ivm
package = "1.13-1.pgdg13+1"
// renovate: suite=trixie-pgdg depName=postgresql-18-pg-ivm extractVersion=^(?<version>\d+\.\d+)
sql = "1.13"
}
}
bookworm = {
"18" = {
// renovate: suite=bookworm-pgdg depName=postgresql-18-pg-ivm
package = "1.13-1.pgdg12+1"
// renovate: suite=bookworm-pgdg depName=postgresql-18-pg-ivm extractVersion=^(?<version>\d+\.\d+)
sql = "1.13"
}
}
}
}
28 changes: 28 additions & 0 deletions pg-ivm/test/chainsaw-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: verify-pg-ivm-extension
spec:
timeouts:
apply: 5s
assert: 3m
delete: 30s
description: Verify pg_ivm extension is properly installed
steps:
- name: Create a Cluster with the extension
try:
- apply:
file: cluster.yaml
- apply:
file: database.yaml
- assert:
file: cluster-assert.yaml
- assert:
file: database-assert.yaml

- name: Verify extension is installed
try:
- apply:
file: check-extension.yaml
- assert:
file: check-extension-assert.yaml
6 changes: 6 additions & 0 deletions pg-ivm/test/check-extension-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: batch/v1
kind: Job
metadata:
name: extension-installed
status:
succeeded: 1
33 changes: 33 additions & 0 deletions pg-ivm/test/check-extension.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apiVersion: batch/v1
kind: Job
metadata:
name: extension-installed
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: data-test
env:
- name: EXT_VERSION
value: ($values.version)
- name: DB_URI
valueFrom:
secretKeyRef:
name: (join('-', [$values.name, 'app']))
key: uri
image: alpine/psql:latest
command: ['sh', '-c']
args:
- |
set -e
DB_URI=$(echo $DB_URI | sed "s|/\*|/|")
test "$(psql "$DB_URI" -tAc "SELECT EXISTS (SELECT FROM pg_catalog.pg_extension WHERE extname = 'pg_ivm' AND extversion = '${EXT_VERSION}')" -q)" = "t"
psql "$DB_URI" -c "DROP TABLE IF EXISTS test_ivm CASCADE;"
psql "$DB_URI" -c "DROP TABLE IF EXISTS base_table CASCADE;"
psql "$DB_URI" -c "CREATE TABLE base_table (id INT PRIMARY KEY, value TEXT);"
psql "$DB_URI" -c "INSERT INTO base_table VALUES (1, 'test');"
psql "$DB_URI" -c "SELECT pgivm.create_immv('test_ivm', 'SELECT * FROM base_table');"
test "$(psql "$DB_URI" -tAc "SELECT COUNT(*) FROM test_ivm" -q)" = "1"
psql "$DB_URI" -c "INSERT INTO base_table VALUES (2, 'test2');"
test "$(psql "$DB_URI" -tAc "SELECT COUNT(*) FROM test_ivm" -q)" = "2"
8 changes: 8 additions & 0 deletions pg-ivm/test/cluster-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: ($values.name)
status:
readyInstances: 1
phase: Cluster in healthy state
image: ($values.pg_image)
15 changes: 15 additions & 0 deletions pg-ivm/test/cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: ($values.name)
spec:
imageName: ($values.pg_image)
instances: 1

storage:
size: 1Gi

postgresql:
parameters: ($values.postgresql_parameters)
shared_preload_libraries: ($values.shared_preload_libraries)
extensions: ($values.extensions)
10 changes: 10 additions & 0 deletions pg-ivm/test/database-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: (join('-', [$values.name, 'app']))
status:
applied: true
extensions:
- applied: true
name: ($values.sql_name)
observedGeneration: 1
12 changes: 12 additions & 0 deletions pg-ivm/test/database.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: (join('-', [$values.name, 'app']))
spec:
name: app
owner: app
cluster:
name: ($values.name)
extensions:
- name: ($values.sql_name)
version: ($values.version)