aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/ref/reindex.sgml13
-rw-r--r--src/backend/commands/indexcmds.c12
2 files changed, 21 insertions, 4 deletions
diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml
index 1c21fafb80e..47cef987d48 100644
--- a/doc/src/sgml/ref/reindex.sgml
+++ b/doc/src/sgml/ref/reindex.sgml
@@ -225,10 +225,15 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } <replacea
<para>
Reindexing a single index or table requires being the owner of that
- index or table. Reindexing a database requires being the owner of
- the database (note that the owner can therefore rebuild indexes of
- tables owned by other users). Of course, superusers can always
- reindex anything.
+ index or table. Reindexing a schema or database requires being the
+ owner of that schema or database. Note that is therefore sometimes
+ possible for non-superusers to rebuild indexes of tables owned by
+ other users. However, as a special exception, when
+ <command>REINDEX DATABASE</command>, <command>REINDEX SCHEMA</command>
+ or <command>REINDEX SYSTEM</command> is issued by a non-superuser,
+ indexes on shared catalogs will be skipped unless the user owns the
+ catalog (which typically won't be the case). Of course, superusers
+ can always reindex anything.
</para>
<para>
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index b9dad9672ef..d54c78c3527 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -2415,6 +2415,18 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
!IsSystemClass(relid, classtuple))
continue;
+ /*
+ * The table can be reindexed if the user is superuser, the table
+ * owner, or the database/schema owner (but in the latter case, only
+ * if it's not a shared relation). pg_class_ownercheck includes the
+ * superuser case, and depending on objectKind we already know that
+ * the user has permission to run REINDEX on this database or schema
+ * per the permission checks at the beginning of this routine.
+ */
+ if (classtuple->relisshared &&
+ !pg_class_ownercheck(relid, GetUserId()))
+ continue;
+
/* Save the list of relation OIDs in private context */
old = MemoryContextSwitchTo(private_context);