Contents
Testing and releases
Test Suite
The pg_integrity_checksums extension includes a comprehensive test suite that validates functionality at all granularity levels and ensures algorithm correctness. The tests are divided into two categories: regression tests (SQL-based) and TAP tests (Perl-based).
# Run the regression tests
make installcheck
# Run the regression and TAP tests (TAP needs the IPC::Run Perl module and the
# PostgreSQL test modules shipped with the matching server release)
make installcheck enable_tap_tests=yes PROVE=prove
If your PostgreSQL installation is not writable by you (a system package, or a
tree installed by root), run the TAP tests against a private copy: an install
tree is relocatable, so copy it, install the extension into the copy and run
prove with that copy’s bin first on PATH:
cp -a /usr/local/pgsql /tmp/pginst # or any installed PostgreSQL tree
export PG_CONFIG=/tmp/pginst/bin/pg_config
make && make install # installs into the copy
B=/tmp/pginst
mkdir -p tmp_check
TESTLOGDIR=$PWD/tmp_check/log TESTDATADIR=$PWD/tmp_check PGPORT=65432 \
PATH="$B/bin:$PATH" PG_REGRESS=$B/lib/pgxs/src/test/regress/pg_regress \
prove -I $B/lib/pgxs/src/test/perl -I . t/*.pl
On merges to main and on releases, CI runs both suites on every supported
major version (PostgreSQL 12 through 19) on Linux x86_64 and ARM64, macOS
ARM64, Windows x64, and FreeBSD amd64 and ARM64. Pull requests use a reduced
PostgreSQL 12/16/19 matrix on the same platforms; the full matrix runs after
merge. CodeQL analyzes the C and Go sources, the
Quality workflow runs ASAN/UBSAN and coverage
builds for PostgreSQL 12–19, and the
Docker workflow builds PG 12–18 images and
smoke-tests PostgreSQL 16 on pull requests. The CLI has its own
CLI workflow, the
CLI integration matrix for PostgreSQL
12–19, and independent cli-v* releases.
Logical checksums are canonical across endianness: the same schema and data produce the same logical values on little-endian and big-endian systems. Physical checksums are storage- and architecture-dependent by design.
Tests cover:
- Basic functionality at all granularity levels
- Physical and logical checksum differences
- NULL handling and type support
- MVCC behavior and concurrency
- Stability of logical checksums across physical reorganizations (VACUUM, CLUSTER, REINDEX)
- Error conditions and edge cases
- Parallel vs serial checksum consistency at table, index and database levels
- Partitioned tables and indexes (single- and multi-level, with and without primary keys)
- Safety and validation: logical index checksums work for every access method; invalid block numbers/TIDs are rejected; views/sequences/indexes are rejected by table functions; SELECT privileges and RLS are enforced; and TOAST physical checksums are computed from raw pages
- Corrupt page handling: unsafe page headers and line pointers produce clean errors; database scans skip the affected relation with a warning
- Partitioned index aggregation, including deterministic physical and logical checksums for partitioned indexes
- Canonical logical checksums: no-PK tables, duplicate rows, empty and partitioned tables, enum/numeric/array/composite/range values, all logical index AMs, expression/partial/INCLUDE indexes, and serial/parallel database consistency
- System-catalog checksums, including anyarray/aclitem values in pg_statistic and pg_attribute; Hash index logical checksums match B-tree checksums for the same input and are independent of the index AM
- DDL stability: table/column/index renames, added/dropped columns, type changes, fillfactor, index creation, TRUNCATE and enum value additions
- Cross-database portability: identical schema/data in two databases with different type, table and index OIDs produces equal logical checksums and different physical checksums
- Privilege boundaries: column-only SELECT is rejected; table SELECT is required for table, page, index, tuple and cell checksums
- TOAST, zero-column tables, all-dropped-column tables, materialized views, invalid indexes and empty partitioned indexes
- Fixed cross-version logical baselines: the same schema/data gives the same table, index, tuple and cell checksums on every supported major version
- Property/fuzz coverage of canonical encodings: numeric scale, array literals, ranges, composites and enums, plus repeated scans of random data
- Endian-stable logical checksums for arrays, composites and multiranges, with fixed baselines checked on a big-endian Linux s390x test
- FNV-1a 64-bit vectors, generic
fnv32/fnv64overloads, empty/NULL inputs, TOAST, partitioning, and serial/parallel 64-bit consistency - CLI v2 baselines:
capture --hash fnv64, verify/update inheritance and rejection of mixed-hash diffs - Streaming standby: logical table, index and database checksums match the primary after WAL replay
- Strict mode (default on): every database-level function rejects an invalid
index and a corrupt page, parallel scans follow the same rules, and
strict = offskips the relation with a warning and returns the checksum of everything else; an unlogged table on a standby behaves the same - Portability: logical checksums ignore dropped columns and the session’s
search_path, and tuple checksums with the header ignore hint bits
Building a Release
The dist target packs the current HEAD into the archive that PGXN expects
(pg_integrity_checksums-<version>.zip, with everything under a pg_integrity_checksums-<version>/
directory):
make dist
Release metadata check
The Release Metadata workflow
runs .github/scripts/check_release_metadata.py whenever the control file,
META.json, Changes or an SQL script changes. For the version in
pg_integrity_checksums.control it checks that META.json agrees, the install
script exists, the newest Changes section is for that version and is not
empty, and an upgrade script from the previous Changes version exists. You
can run it locally: python3 .github/scripts/check_release_metadata.py.
Automated releases
Pushing a v* tag runs the Release workflow,
which:
- checks that the tag,
pg_integrity_checksums.controlandMETA.jsonall carry the same version; - builds the archive with
make distand verifies its contents; - takes the release notes from the matching
Changesentry (the release fails if there is none, rather than publishing an empty note); - creates the GitHub Release and attaches the archive (tags containing
-rc,-betaor-alphaare marked as pre-releases); - uploads the archive to PGXN when the
PGXN_USERNAMEandPGXN_PASSWORDrepository secrets are configured.
Repository checks
Every relevant change runs:
actionlintfor all GitHub Actions workflows;- CLI unit tests with
-raceand a coverage upload to Codecov; - the PostgreSQL 12-19 CLI integration matrix;
- a Docker CLI image smoke test;
- a local composite-action smoke test on PostgreSQL 16.
GitHub Actions are pinned to commit SHAs and updated by Dependabot. Go dependencies are updated by Dependabot as well.