fix: use DROP MAPPING instead of deleting from pg_ts_config_map

The pre-upgrade hook failed with 'permission denied for table
pg_ts_config_map' because the migration runs as prosodyDBuser (a
non-superuser), and pg_ts_config_map is a PostgreSQL system catalog that
only superusers can DELETE from.

Replace the direct 'delete from pg_ts_config_map where ...' with the
equivalent non-superuser DDL 'ALTER TEXT SEARCH CONFIGURATION ... DROP
MAPPING IF EXISTS FOR <token types>', enumerating every token type the
block re-adds. Verified against postgres:15 as a non-superuser role: the
DELETE reproduces the exact error, DROP MAPPING IF EXISTS succeeds, and
the drop+re-add round-trip is idempotent across repeated runs.

Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
This commit is contained in:
2026-07-15 17:59:12 +02:00
parent b51bc373d3
commit 386f36d133
@@ -1280,9 +1280,15 @@ end $$;
-- Reconcile mappings idempotently: remove all existing mappings for this
-- configuration, then re-add the desired set (only if the dictionary exists).
-- NOTE: do NOT delete from pg_ts_config_map directly — it is a PostgreSQL
-- system catalog and only writable by superusers. ALTER ... DROP MAPPING
-- IF EXISTS is the non-superuser DDL that achieves the same effect.
do $$
begin
delete from pg_ts_config_map where mapcfg = (select oid from pg_ts_config where cfgname = 'english_nostop');
alter text search configuration public.english_nostop drop mapping if exists
for asciiword, word, hword_part, hword_asciipart, asciihword, hword,
numword, email, url, host, sfloat, version, hword_numpart, numhword,
url_path, file, "float", "int", uint;
if exists (select 1 from pg_ts_dict where dictname = 'english_stem_nostop') then
alter text search configuration public.english_nostop add mapping for asciiword with public.english_stem_nostop;
alter text search configuration public.english_nostop add mapping for word with public.english_stem_nostop;