diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2024-02-05 11:01:30 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2024-02-05 11:03:43 +0200 |
commit | a45c950ae35e53de4007c9dd0991d5005a4bee7b (patch) | |
tree | b578e715712036aeb5ba4eecd4e9d6c60cfc4ac1 | |
parent | f4f2883521fc3f81765ab82eab2ffa31574f0a07 (diff) | |
download | postgresql-a45c950ae35e53de4007c9dd0991d5005a4bee7b.tar.gz postgresql-a45c950ae35e53de4007c9dd0991d5005a4bee7b.zip |
Fix assertion if index is dropped during REFRESH CONCURRENTLY
When assertions are disabled, the built SQL statement is invalid and
you get a "syntax error". So this isn't a serious problem, but let's
avoid the assertion failure.
Backpatch to all supported versions.
Reviewed-by: Noah Misch
-rw-r--r-- | src/backend/commands/matview.c | 7 | ||||
-rw-r--r-- | src/test/regress/expected/matview.out | 16 | ||||
-rw-r--r-- | src/test/regress/sql/matview.sql | 17 |
3 files changed, 38 insertions, 2 deletions
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 0aa0a749dab..0ab8ba1a58d 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -803,9 +803,12 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, * * ExecRefreshMatView() checks that after taking the exclusive lock on the * matview. So at least one unique index is guaranteed to exist here - * because the lock is still being held; so an Assert seems sufficient. + * because the lock is still being held. (One known exception is if a + * function called as part of refreshing the matview drops the index. + * That's a pretty silly thing to do.) */ - Assert(foundUniqueIndex); + if (!foundUniqueIndex) + elog(ERROR, "could not find suitable unique index on materialized view"); appendStringInfoString(&querybuf, " AND newdata.* OPERATOR(pg_catalog.*=) mv.*) " diff --git a/src/test/regress/expected/matview.out b/src/test/regress/expected/matview.out index c109d97635b..e811e1a049b 100644 --- a/src/test/regress/expected/matview.out +++ b/src/test/regress/expected/matview.out @@ -572,6 +572,22 @@ REFRESH MATERIALIZED VIEW mvtest_mv_foo; REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_foo; DROP OWNED BY regress_user_mvtest CASCADE; DROP ROLE regress_user_mvtest; +-- Concurrent refresh requires a unique index on the materialized +-- view. Test what happens if it's dropped during the refresh. +CREATE OR REPLACE FUNCTION mvtest_drop_the_index() + RETURNS bool AS $$ +BEGIN + EXECUTE 'DROP INDEX IF EXISTS mvtest_drop_idx'; + RETURN true; +END; +$$ LANGUAGE plpgsql; +CREATE MATERIALIZED VIEW drop_idx_matview AS + SELECT 1 as i WHERE mvtest_drop_the_index(); +NOTICE: index "mvtest_drop_idx" does not exist, skipping +CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview (i); +REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview; +ERROR: could not find suitable unique index on materialized view +DROP MATERIALIZED VIEW drop_idx_matview; -- clean up -- make sure that create WITH NO DATA works via SPI BEGIN; CREATE FUNCTION mvtest_func() diff --git a/src/test/regress/sql/matview.sql b/src/test/regress/sql/matview.sql index 68b9ccfd452..543e0a6d73a 100644 --- a/src/test/regress/sql/matview.sql +++ b/src/test/regress/sql/matview.sql @@ -231,6 +231,23 @@ REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_foo; DROP OWNED BY regress_user_mvtest CASCADE; DROP ROLE regress_user_mvtest; +-- Concurrent refresh requires a unique index on the materialized +-- view. Test what happens if it's dropped during the refresh. +CREATE OR REPLACE FUNCTION mvtest_drop_the_index() + RETURNS bool AS $$ +BEGIN + EXECUTE 'DROP INDEX IF EXISTS mvtest_drop_idx'; + RETURN true; +END; +$$ LANGUAGE plpgsql; + +CREATE MATERIALIZED VIEW drop_idx_matview AS + SELECT 1 as i WHERE mvtest_drop_the_index(); + +CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview (i); +REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview; +DROP MATERIALIZED VIEW drop_idx_matview; -- clean up + -- make sure that create WITH NO DATA works via SPI BEGIN; CREATE FUNCTION mvtest_func() |