diff options
Diffstat (limited to '')
-rw-r--r-- | src/backend/commands/matview.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index d1ee106..a5f8972 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -656,13 +656,35 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1)))); } + /* + * Create the temporary "diff" table. + * + * Temporarily switch out of the SECURITY_RESTRICTED_OPERATION context, + * because you cannot create temp tables in SRO context. For extra + * paranoia, add the composite type column only after switching back to + * SRO context. + */ SetUserIdAndSecContext(relowner, save_sec_context | SECURITY_LOCAL_USERID_CHANGE); + resetStringInfo(&querybuf); + appendStringInfo(&querybuf, + "CREATE TEMP TABLE %s (tid pg_catalog.tid)", + diffname); + if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY) + elog(ERROR, "SPI_exec failed: %s", querybuf.data); + SetUserIdAndSecContext(relowner, + save_sec_context | SECURITY_RESTRICTED_OPERATION); + resetStringInfo(&querybuf); + appendStringInfo(&querybuf, + "ALTER TABLE %s ADD COLUMN newdata %s", + diffname, tempname); + if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY) + elog(ERROR, "SPI_exec failed: %s", querybuf.data); - /* Start building the query for creating the diff table. */ + /* Start building the query for populating the diff table. */ resetStringInfo(&querybuf); appendStringInfo(&querybuf, - "CREATE TEMP TABLE %s AS " + "INSERT INTO %s " "SELECT mv.ctid AS tid, newdata.*::%s AS newdata " "FROM %s mv FULL JOIN %s newdata ON (", diffname, tempname, matviewname, tempname); @@ -782,22 +804,22 @@ 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.*) " "WHERE newdata.* IS NULL OR mv.* IS NULL " "ORDER BY tid"); - /* Create the temporary "diff" table. */ - if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY) + /* Populate the temporary "diff" table. */ + if (SPI_exec(querybuf.data, 0) != SPI_OK_INSERT) elog(ERROR, "SPI_exec failed: %s", querybuf.data); - SetUserIdAndSecContext(relowner, - save_sec_context | SECURITY_RESTRICTED_OPERATION); - /* * We have no further use for data from the "full-data" temp table, but we * must keep it around because its type is referenced from the diff table. |