From: Álvaro Herrera <alvherre@kurilemu.de>
Subject: [PATCH v2 2/2] fixups
Date: Tue, 7 Jul 2026 18:35:28 +0200
---
src/backend/commands/repack.c | 54 ++++++++++++++++++++++-------------
1 file changed, 34 insertions(+), 20 deletions(-)
inline patch 1: src/backend/commands/repack.c (+34/-20 lines) download inline-1.patchdiff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.cindex 2879c8af574..fcc401ccdb9 100644--- a/src/backend/commands/repack.c+++ b/src/backend/commands/repack.c@@ -2152,6 +2152,10 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt)
/*
* For USING INDEX, scan pg_index to find those with indisclustered.
+ *+ * Note we don't obtain lock of any kind on the index, which means the+ * index or its owning table could be gone or change at any point. We+ * have to be extra careful when examining catalog state for them.
*/
catalog = table_open(IndexRelationId, AccessShareLock);
ScanKeyInit(&entry,
@@ -2169,7 +2173,7 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt)
index = (Form_pg_index) GETSTRUCT(tuple);
- classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(index->indrelid));+ classtup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(index->indrelid));
if (!HeapTupleIsValid(classtup))
continue;
classForm = (Form_pg_class) GETSTRUCT(classtup);
@@ -2178,11 +2182,11 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt)
if (classForm->relpersistence == RELPERSISTENCE_TEMP &&
!isTempOrTempToastNamespace(classForm->relnamespace))
{
- ReleaseSysCache(classtup);+ heap_freetuple(classtup);
continue;
}
- ReleaseSysCache(classtup);+ heap_freetuple(classtup);
/* noisily skip rels which the user can't process */
if (!repack_is_permitted_for_relation(cmd, index->indrelid,
@@ -2274,7 +2278,9 @@ get_tables_to_repack_partitioned(RepackCommand cmd, Oid relid,
if (get_rel_relkind(child_oid) != RELKIND_INDEX)
continue;
- table_oid = IndexGetRelation(child_oid, false);+ table_oid = IndexGetRelation(child_oid, true);+ if (!OidIsValid(table_oid))+ continue;
index_oid = child_oid;
}
else
@@ -2309,33 +2315,41 @@ get_tables_to_repack_partitioned(RepackCommand cmd, Oid relid,
/*
- * Return whether userid has privileges to REPACK relid. If not, this- * function emits a WARNING.+ * Return whether userid has privileges to execute REPACK on relid.+ *+ * Caller may not have a lock on the relation, so it could have been+ * dropped concurrently. In that case, silently return false.+ *+ * If the relation does exist but the user doesn't have the required+ * privs, emit a WARNING and return false. Otherwise, return true.
*/
static bool
repack_is_permitted_for_relation(RepackCommand cmd, Oid relid, Oid userid)
{
bool is_missing = false;
+ AclResult result;+ char *relname;
Assert(cmd == REPACK_COMMAND_CLUSTER || cmd == REPACK_COMMAND_REPACK);
- if (pg_class_aclcheck_ext(relid, userid, ACL_MAINTAIN, &is_missing) == ACLCHECK_OK)+ result = pg_class_aclcheck_ext(relid, userid, ACL_MAINTAIN, &is_missing);+ if (is_missing)+ return false;++ if (result == ACLCHECK_OK)
return true;
- /* Report a warning if the relation still exists. */- if (!is_missing)+ /*+ * The relation can also be dropped after we tested its ACL and before we+ * read its relname, so be careful.+ */+ relname = get_rel_name(relid);+ if (relname != NULL)
{
- char *relname;-- relname = get_rel_name(relid);- if (relname != NULL)- {- ereport(WARNING,- errmsg("permission denied to execute %s on \"%s\", skipping it",- RepackCommandAsString(cmd), relname));-- pfree(relname);- }+ ereport(WARNING,+ errmsg("permission denied to execute %s on \"%s\", skipping it",+ RepackCommandAsString(cmd), relname));+ pfree(relname);
}
return false;
--
2.47.3
--op6mnexl7cn72cto--
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: alvherre@kurilemu.de
Subject: Re: [PATCH v2 2/2] fixups
In-Reply-To: <no-message-id-1834287@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox