From 3f19e176ae0f55a653d62e1504dbe5ad8c1006a0 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Thu, 14 Apr 2022 22:11:06 +0200 Subject: Have CLUSTER ignore partitions not owned by caller If a partitioned table has partitions owned by roles other than the owner of the partitioned table, don't include them in the to-be- clustered list. This is similar to what VACUUM FULL does (except we do it sooner, because there is no reason to postpone it). Add a simple test to verify that only owned partitions are clustered. While at it, change memory context switch-and-back to occur once per partition instead of outside of the loop. Author: Justin Pryzby Reviewed-by: Zhihong Yu Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/20220411140609.GF26620@telsasoft.com --- src/backend/commands/cluster.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/backend/commands/cluster.c') diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 0f0a6e9f018..d8a6d43d959 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -1647,10 +1647,8 @@ get_tables_to_cluster(MemoryContext cluster_context) * Given an index on a partitioned table, return a list of RelToCluster for * all the children leaves tables/indexes. * - * Caller must hold lock on the table containing the index. - * * Like expand_vacuum_rel, but here caller must hold AccessExclusiveLock - * on the table already. + * on the table containing the index. */ static List * get_tables_to_cluster_partitioned(MemoryContext cluster_context, Oid indexOid) @@ -1663,9 +1661,6 @@ get_tables_to_cluster_partitioned(MemoryContext cluster_context, Oid indexOid) /* Do not lock the children until they're processed */ inhoids = find_all_inheritors(indexOid, NoLock, NULL); - /* Use a permanent memory context for the result list */ - old_context = MemoryContextSwitchTo(cluster_context); - foreach(lc, inhoids) { Oid indexrelid = lfirst_oid(lc); @@ -1676,12 +1671,22 @@ get_tables_to_cluster_partitioned(MemoryContext cluster_context, Oid indexOid) if (get_rel_relkind(indexrelid) != RELKIND_INDEX) continue; + /* Silently skip partitions which the user has no access to. */ + if (!pg_class_ownercheck(relid, GetUserId()) && + (!pg_database_ownercheck(MyDatabaseId, GetUserId()) || + IsSharedRelation(relid))) + continue; + + /* Use a permanent memory context for the result list */ + old_context = MemoryContextSwitchTo(cluster_context); + rtc = (RelToCluster *) palloc(sizeof(RelToCluster)); rtc->tableOid = relid; rtc->indexOid = indexrelid; rtcs = lappend(rtcs, rtc); + + MemoryContextSwitchTo(old_context); } - MemoryContextSwitchTo(old_context); return rtcs; } -- cgit v1.2.3