Skip to content

Updating an Existing Check

Say the huge-tables check from the worked example needs its rationale reworded, its backing function swapped for an improved version, or its run number changed — anything short of moving it to a different namespace or category, which is immutable (copy it into the new one instead, and inactivate the original if that's genuinely needed — see Copying an Existing Check):

SELECT pghf.update_check(
    p_check_id       => 'X01-001',
    p_check_name     => 'Tables over 50GB',
    p_routine        => 'pghf.chk_custom_huge_tables(uuid)'::regprocedure,
    p_result_type    => 'integer',
    p_rationale      => 'Updated rationale text here.',
    p_run_number     => NULL,  -- NULL = leave unchanged; pass a new int to renumber
    p_result_unit    => 'count',
    p_numeric_direction => 'lower_is_better',
    p_perfect_value  => '0'::jsonb,
    p_is_builtin     => false,
    p_description    => 'Flags any table exceeding 50GB total size.'
);

Updating a check is the mirror image of creating one: it fails if the check ID does NOT already exist — use pghf.create_check() to add a new one instead. It's a full replace of every field shown above except the run number, not a partial patch — there's no way to distinguish "leave this empty field unchanged" from "set it to empty" otherwise — so re-supply every value, not only the one that changed. This example works because X01-001 is a check under your own X namespace.

Built-in checks are a different story — their definition is locked

Everything shown above is compared against the check's current stored value; if calling the update function on a built-in check would actually change any of it, the call raises an error instead of applying the edit:

ERROR:  cannot modify the definition of built-in check PGHF11-009 — PGHF check definitions are
locked and get overwritten by the next pghf.seed_data() call/version update regardless; use
pghf.copy_check('PGHF11-009', ...) to customize your own copy under your own namespace instead.
You can still activate/inactivate PGHF11-009 via p_is_active, and pghf.set_threshold() still
works on it directly.

This isn't arbitrary — the framework's own seeding function resets a built-in check's display name, backing function, rationale, and so on back to whatever the installed version ships, on every single call, including the one that runs automatically the moment a future version is installed. See Resetting to Defaults in the User Guide. A hand-edit to a built-in check's definition was always going to be silently thrown away the next time that happens; this lock just makes that fact loud and immediate instead of a surprise weeks later.

Two things are deliberately not locked, even on a built-in check:

  • Activating and inactivating it — you can still turn any built-in check on or off with the update function; see Inactivating a Check. This isn't a definition edit — a call that only changes whether it's active, with every other field re-supplied unchanged, always succeeds regardless of namespace.
  • Thresholds — setting a threshold works directly against any check, built-ins included, exactly as it always has. Thresholds are your own deployment's tuning, not part of what a check fundamentally is, so they were never part of this lock in the first place.

If you actually need to change what a built-in check measures, names itself, or explains — copy it. Cloning it into your own namespace (next section) gives you a completely ordinary check with no lock at all: edit it with the update function as many times as you like.

Continue to Copying an Existing Check.