mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-29 22:49:41 +03:00 
			
		
		
		
	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
This commit is contained in:
		| @@ -801,9 +801,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.*) " | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user