Skip to content

Fix uninstall_extension dropping prefix-named sibling extensions#314

Open
jnasbyupgrade wants to merge 1 commit into
aws:mainfrom
jnasbyupgrade:fix/uninstall-prefix-collision
Open

Fix uninstall_extension dropping prefix-named sibling extensions#314
jnasbyupgrade wants to merge 1 commit into
aws:mainfrom
jnasbyupgrade:fix/uninstall-prefix-collision

Conversation

@jnasbyupgrade

@jnasbyupgrade jnasbyupgrade commented Jul 9, 2026

Copy link
Copy Markdown

pgtle.uninstall_extension() located which extension registration functions to
drop using LIKE patterns of the forms <extname>%.control and
<extname>%.sql. Because the % immediately follows the extension name, the
patterns also matched the artifacts of any other extension whose name has
<extname> as a prefix. Uninstalling foo therefore silently dropped the
registration of foo_bar as well — no error, no warning. An extension name may
also legally contain _, which is itself a LIKE wildcard, widening the
over-match further (e.g. foo_bar also matched fooXbar). The empty-string
case is the degenerate extreme: uninstall_extension('') matched %.control
and attempted to drop every registered extension's control function.

Fix:

  • The control function is named exactly <extname>.control, so match it by
    equality instead of a pattern.
  • Script functions are named <extname>--<version>.sql and
    <extname>--<from>--<to>.sql. Since neither an extension name nor a version
    may contain --, that separator is a reliable boundary. Match them with an
    anchored regular expression (^<ext>--...\.sql$), regex-escaping the name
    and version so any metacharacters they contain are treated literally.

Switching the script match from LIKE to a regex also lets the two-arg
uninstall_extension(name, version) express "the version is one of the
---delimited tokens" precisely. This matches the documented behavior
("removes all update paths that use this extension version") and removes a
latent over-match where, e.g., version 1.1 also matched a 1.10 update
script via LIKE '%1.1%'.

The fix is delivered as a new 1.5.2 -> 1.5.3 upgrade script that replaces
both uninstall_extension overloads, so existing installs pick it up via
ALTER EXTENSION pg_tle UPDATE.

Behavior change: uninstall_extension('') and uninstall_extension('', '')
now report that the (empty-named) extension does not exist, and
uninstall_extension_if_exists('') returns false, instead of attempting to
drop an unrelated extension's functions. The pg_tle_functions_acl expected
output is updated accordingly.

Testing: added a focused block to pg_tle_management covering a prefix target
(with an update path), a longer-named sibling, an underscore decoy, and the
two-arg control-drop path; all survive/are removed as expected. Verified the
1.5.2 -> 1.5.3 upgrade path activates the fix on existing installs.

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license.

🤖 Generated with Claude Code

@jnasbyupgrade jnasbyupgrade force-pushed the fix/uninstall-prefix-collision branch from a435f9e to 8a1df95 Compare July 9, 2026 21:55
uninstall_extension() matched the functions to drop with LIKE patterns of
the forms <extname>%.control and <extname>%.sql. Because the % immediately
follows the name, the patterns also matched any other extension whose name
has <extname> as a prefix, so uninstalling 'foo' silently dropped the
registration of 'foo_bar'. Names may also contain '_' (a LIKE wildcard),
and uninstall_extension('') matched every extension's control function.

Match the control function by exact name and the script functions with an
anchored, metacharacter-escaped regular expression, delivered as a new
1.5.2 -> 1.5.3 upgrade script that replaces both uninstall_extension
overloads.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jnasbyupgrade jnasbyupgrade force-pushed the fix/uninstall-prefix-collision branch from 8a1df95 to 0082d99 Compare July 9, 2026 22:02
@jnasbyupgrade jnasbyupgrade marked this pull request as ready for review July 10, 2026 21:13
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.

1 participant