Skip to content

Commit b96115a

Browse files
committed
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
1 parent 5a9167c commit b96115a

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

src/backend/commands/matview.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,9 +801,12 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
801801
*
802802
* ExecRefreshMatView() checks that after taking the exclusive lock on the
803803
* matview. So at least one unique index is guaranteed to exist here
804-
* because the lock is still being held; so an Assert seems sufficient.
804+
* because the lock is still being held. (One known exception is if a
805+
* function called as part of refreshing the matview drops the index.
806+
* That's a pretty silly thing to do.)
805807
*/
806-
Assert(foundUniqueIndex);
808+
if (!foundUniqueIndex)
809+
elog(ERROR, "could not find suitable unique index on materialized view");
807810

808811
appendStringInfoString(&querybuf,
809812
" AND newdata.* OPERATOR(pg_catalog.*=) mv.*) "

src/test/regress/expected/matview.out

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,22 @@ REFRESH MATERIALIZED VIEW mvtest_mv_foo;
572572
REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_foo;
573573
DROP OWNED BY regress_user_mvtest CASCADE;
574574
DROP ROLE regress_user_mvtest;
575+
-- Concurrent refresh requires a unique index on the materialized
576+
-- view. Test what happens if it's dropped during the refresh.
577+
CREATE OR REPLACE FUNCTION mvtest_drop_the_index()
578+
RETURNS bool AS $$
579+
BEGIN
580+
EXECUTE 'DROP INDEX IF EXISTS mvtest_drop_idx';
581+
RETURN true;
582+
END;
583+
$$ LANGUAGE plpgsql;
584+
CREATE MATERIALIZED VIEW drop_idx_matview AS
585+
SELECT 1 as i WHERE mvtest_drop_the_index();
586+
NOTICE: index "mvtest_drop_idx" does not exist, skipping
587+
CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview (i);
588+
REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview;
589+
ERROR: could not find suitable unique index on materialized view
590+
DROP MATERIALIZED VIEW drop_idx_matview; -- clean up
575591
-- make sure that create WITH NO DATA works via SPI
576592
BEGIN;
577593
CREATE FUNCTION mvtest_func()

src/test/regress/sql/matview.sql

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,23 @@ REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv_foo;
231231
DROP OWNED BY regress_user_mvtest CASCADE;
232232
DROP ROLE regress_user_mvtest;
233233

234+
-- Concurrent refresh requires a unique index on the materialized
235+
-- view. Test what happens if it's dropped during the refresh.
236+
CREATE OR REPLACE FUNCTION mvtest_drop_the_index()
237+
RETURNS bool AS $$
238+
BEGIN
239+
EXECUTE 'DROP INDEX IF EXISTS mvtest_drop_idx';
240+
RETURN true;
241+
END;
242+
$$ LANGUAGE plpgsql;
243+
244+
CREATE MATERIALIZED VIEW drop_idx_matview AS
245+
SELECT 1 as i WHERE mvtest_drop_the_index();
246+
247+
CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview (i);
248+
REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview;
249+
DROP MATERIALIZED VIEW drop_idx_matview; -- clean up
250+
234251
-- make sure that create WITH NO DATA works via SPI
235252
BEGIN;
236253
CREATE FUNCTION mvtest_func()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy