Skip to content

pgclone 4.4.2 — Constraint- and length-aware data masking

Latest

Choose a tag to compare

@valehdba valehdba released this 01 Jul 19:32
3828e16

Bug-fix release addressing issue #18. Follows 4.4.1 (issue #17) and completes the hardening of the in-line masking engine so a mask can never abort or corrupt a clone.

Highlights

A mask that would break a clone is now clamped or skipped with a WARNING (the column is left unmasked) instead of failing:

Hazard Before Now
constant/partial/hash/random_int longer than varchar(N)/char(N) ERROR: value too long for type character varying(N) Clamped with left(…, N) so it always fits
constant ('REDACTED') on an integer/numeric column ERROR: invalid input syntax for type integer Applied only if the literal is a valid number, else skipped
null on a NOT NULL column ERROR: null value … violates not-null constraint Skipped
collapsing mask (name/constant/null) or random_int on a UNIQUE/PRIMARY KEY column ERROR: duplicate key value violates unique constraint Only the injective hash is applied; others skipped
any mask on a FOREIGN KEY column broken referential integrity Skipped

pgclone.discover_sensitive() and pgclone.masking_report() now only suggest strategies the engine will actually apply: foreign-key columns are omitted, and UNIQUE/PRIMARY KEY or NOT NULL sensitive columns are steered to hash — so a generated mask file is safe to apply verbatim.

A masked view (pgclone.create_masking_policy()) enforces no table constraints, so only the type/constant checks apply there.

Masking keys and numeric columns

  • Masking numeric columns is supported via random_int / hash; a text constant on a numeric column is what used to fail and is now skipped.
  • Integer primary/unique/foreign keys generally should not be masked — no built-in strategy both fits an integer and preserves the constraint, so they are left unmasked (integer PK/UQ) or skipped (FK). For referentially-consistent key masking, apply hash to the same text column across parent and child (matching values hash identically).

Compatibility

  • No SQL signature changes — the fix is entirely in the C masking engine. sql/pgclone--4.4.1--4.4.2.sql only bumps the installed version.
  • Behavior change is limited to masks that previously crashed the clone or violated a constraint; masks that already worked are unaffected.
  • Synchronous paths only, as with the rest of the masking feature (*_async jobs ignore "mask"/"masks").
  • Pure C-string/libpq implementation; identical behavior on PostgreSQL 14–18.

Upgrade

ALTER EXTENSION pgclone UPDATE TO '4.4.2';

Or a fresh install: make install then CREATE EXTENSION pgclone;

Tests

pgTAP group 27 (12 new tests, plan 95 → 107) plus mask18_parent / mask18_child fixtures covering length clamping, constant-on-numeric, uniqueness (name skipped, hash distinct-preserving), NOT NULL and FK skips. Loopback DDL suite 47/47.

Full changelog: see CHANGELOG.md ([4.4.2]).