Skip to content

deny UNINSTALL EXTENSION if indexes exist#508

Merged
villagestevers merged 2 commits into
villagesql:mainfrom
pyshx:issue-392-custom-index-uninstall-block
May 15, 2026
Merged

deny UNINSTALL EXTENSION if indexes exist#508
villagestevers merged 2 commits into
villagesql:mainfrom
pyshx:issue-392-custom-index-uninstall-block

Conversation

@pyshx
Copy link
Copy Markdown
Contributor

@pyshx pyshx commented May 14, 2026

Description

Adds a RESTRICT-only check in remove_extension_from_victionary that blocks UNINSTALL EXTENSION when any rows for that extension remain in villagesql.custom_indexes. Mirrors the existing check_for_columns_of_extension and check_for_sp_params_of_extension pattern — same shape, same RESTRICT semantics (no auto-cascade, no MarkForDeletion of system-table rows at uninstall).

The gap surfaced while auditing #392. The functional-index-on-custom-column case (what #392 literally asks about) is already blocked today via the column check; what wasn't enumerated was custom_indexes itself.

A note on reachability: this gap isn't reachable through SQL today — CREATE INDEX ... USING EXTENDED(...) parses but fails before writing any row (see the --error ER_VILLAGESQL_GENERIC_ERROR in mysql-test/suite/villagesql/index/t/create_index.test). This check exists defensively so it's in place before the CREATE INDEX wiring lands.

Related Issue

Part of #392. See the audit comment on the issue for the full per-object analysis and the other follow-ups.

How was this tested?

Four new gtest cases in unittest/gunit/villagesql/extension_uninstall_checks-t.cc:

  • CustomIndexPreventsExtensionUninstall — the positive case
  • OtherExtensionsIndexDoesNotPreventUninstall — name discriminator
  • VersionMismatchDoesNotPreventUninstall — version discriminator
  • NoIndexesIsAllowed — empty-list happy path

TDD shape: the first commit ships a stub returning false so CustomIndexPreventsExtensionUninstall fails (proves the predicate is wired through). The second commit replaces the stub with the real enumeration loop and adds the call site in sql_extension.cc; all four tests then pass.

Full village suite green:

./mysql-test/mysql-test-run.pl --do-suite=village --nounit-tests --parallel=auto
# 563 tests pass, 8 skipped, no failures

A functional mysql-test (custom_index_prevents_extension_uninstall.test) will be added when CREATE INDEX ... USING EXTENDED is end-to-end through VEF. Until then the unit tests pin the predicate — there's a TODO(villagesql-indexing) at the top of the test file noting this.

Checklist

  • I have signed the CLA
  • I have read CONTRIBUTING.md
  • I have added or updated tests as appropriate
  • My changes maintain compatibility with upstream MySQL 8.4

pyshx added 2 commits May 14, 2026 23:00
Stub returns false; four gtest cases pin the predicate. Real
implementation in the next commit.
Mirrors check_for_columns_of_extension: RESTRICT-only, no
MarkForDeletion. Closes the custom_indexes enumeration gap from
the villagesql#392 audit.
@pyshx pyshx changed the title veb: block UNINSTALL EXTENSION when custom indexes are outstanding deny UNINSTALL EXTENSION if indexes exist May 14, 2026
@villagestevers villagestevers self-requested a review May 14, 2026 17:49
@villagestevers villagestevers merged commit ea818d3 into villagesql:main May 15, 2026
3 of 5 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators May 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants