Skip to content

Add extension_requires() and extension_requires_are() - #372

Draft
jnasbyupgrade wants to merge 6 commits into
theory:mainfrom
jnasbyupgrade:add-extension-requires
Draft

Add extension_requires() and extension_requires_are()#372
jnasbyupgrade wants to merge 6 commits into
theory:mainfrom
jnasbyupgrade:add-extension-requires

Conversation

@jnasbyupgrade

@jnasbyupgrade jnasbyupgrade commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Proposes two new assertion functions for verifying an extension's declared dependencies (its control file requires), analogous to the existing has_extension() / extensions_are() pair:

  • extension_requires( extension, required_extension[, description] ) — asserts that extension requires required_extension.
  • extension_requires_are( extension, requires[][, description] ) — asserts the exact set of extensions that extension requires, with Extra/Missing diagnostics like extensions_are().

Both are backed by a new internal helper, _extension_requires(name), which reads the requirement from pg_depend/pg_extension (the runtime record of what actually got pulled in via CREATE EXTENSION ... REQUIRES), not pg_available_extensions. Both guard on the target extension not being installed, failing the same way has_extension() does rather than reporting a confusing all-missing diff.

Test plan

Manually verified against earthdistance (which requires cube):

  • extension_requires('earthdistance', 'cube') passes
  • extension_requires('earthdistance', 'citext') fails
  • extension_requires_are('earthdistance', ARRAY['cube']) passes
  • extension_requires_are('earthdistance', ARRAY['citext']) fails with Extra/Missing diagnostics
  • Both fail like has_extension() when the base extension doesn't exist
  • No automated test coverage yet — pending API sign-off

Proposed API for verifying an extension's declared dependencies, pulled
from pg_extension/pg_depend (not pg_available_extensions). Both guard on
the target extension not being installed the same way has_extension()
does.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jnasbyupgrade

jnasbyupgrade commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

@theory any comments on the proposed API before I finish this?

There's also 2 more fields from pg_extension that might make sense to have functions for; extnamespace and extrelocatable. Maybe extversion as well, though that seems less valuable (if anything I'd think people would want to look in pg_available_extensions for version info...).

There's also extconfig and extcondition (controls for tables marked as configuration), but IMO those should have a different API than this.

One other interesting bit... Claude originally mentioned in the docs that the new functions only look at pg_extension and not what's actually in the control file. I ripped that out since existing docs never mention that, but maybe it's worth clarifying to people that these functions are only looking at what's actually installed in the database, not what's available on-disk.

@jnasbyupgrade
jnasbyupgrade force-pushed the add-extension-requires branch from 4a1b678 to 4bfad39 Compare August 10, 2026 16:53
Adds doc/pgtap.mmd entries mirroring has_extension()/extensions_are()
so the proposed API is easy to review alongside the SQL.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jnasbyupgrade
jnasbyupgrade force-pushed the add-extension-requires branch from 4bfad39 to 458e439 Compare August 10, 2026 16:55
jnasbyupgrade and others added 4 commits August 10, 2026 11:56
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Existing extension docs don't characterize control file vs. runtime
state, so drop that contrast here too and just describe what the
function checks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…re() doc

Not verified against a real test run; will replace with output copied
from test/expected/extension.out once that coverage exists.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@theory

theory commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Any chance you can provide an LLM-free PR?

@theory theory left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will need an upgrade script and patch. Function names seem fine.

Comment thread doc/pgtap.md
# citext
# isn

### `extension_requires_are()` ###

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest dropping _are(). Oh, you have that for checking a single requirement. Fine I guess, if semantically clumsy.

Comment thread doc/pgtap.md
recorded by PostgreSQL when `:extension` was created. If `:extension`
itself does not exist, the test fails the same way `has_extension()` does.
If the test description is omitted, it will be set to "Extension
`:extension` should require extension `:required_extension`". Example:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use backticks for names. Follow existing patterns.

Comment thread sql/pgtap.sql.in
Comment on lines +10359 to +10370
IF NOT _ext_exists($1) THEN
RETURN fail($3) || E'\n' || diag(
' Extension ' || quote_ident($1) || ' does not exist'
);
END IF;

RETURN _are(
'required extensions',
ARRAY( SELECT _extension_requires($1) EXCEPT SELECT unnest($2) ),
ARRAY( SELECT unnest($2) EXCEPT SELECT _extension_requires($1) ),
$3
);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a single query execution instead of multiple? Have _extension_requires() return NULL instead of an empty array if the extension doesn't exist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants