Move bool parameter for vacuum_rel() to option bits.
authorNathan Bossart <nathan@postgresql.org>
Tue, 20 Jun 2023 22:14:58 +0000 (15:14 -0700)
committerNathan Bossart <nathan@postgresql.org>
Tue, 20 Jun 2023 22:14:58 +0000 (15:14 -0700)
ff9618e82a introduced the skip_privs parameter, which is used to
skip privilege checks when recursing to a relation's TOAST table.
This parameter should have been added as a flag bit in
VacuumParams->options instead.

Suggested-by: Michael Paquier
Reviewed-by: Michael Paquier, Jeff Davis
Discussion: https://postgr.es/m/ZIj4v1CwqlDVJZfB%40paquier.xyz

src/backend/commands/analyze.c
src/backend/commands/vacuum.c
src/include/commands/vacuum.h

index 52ef462dba3fe92f8cf0c5d6f8f42db43231e487..fc9a371f9be790967682724e112fff9577abf7ad 100644 (file)
@@ -167,7 +167,7 @@ analyze_rel(Oid relid, RangeVar *relation,
         */
        if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel),
                                                                                  onerel->rd_rel,
-                                                                                 params->options & VACOPT_ANALYZE))
+                                                                                 params->options & ~VACOPT_VACUUM))
        {
                relation_close(onerel, ShareUpdateExclusiveLock);
                return;
index a843f9ad926e0a893d7b8372aa0b02e817c9c889..bb79de4da6a8798392d52437d5a88aab81d8c9b1 100644 (file)
@@ -115,7 +115,7 @@ static void vac_truncate_clog(TransactionId frozenXID,
                                                          TransactionId lastSaneFrozenXid,
                                                          MultiXactId lastSaneMinMulti);
 static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
-                                          bool skip_privs, BufferAccessStrategy bstrategy);
+                                          BufferAccessStrategy bstrategy);
 static double compute_parallel_delay(void);
 static VacOptValue get_vacoptval_from_boolean(DefElem *def);
 static bool vac_tid_reaped(ItemPointer itemptr, void *state);
@@ -620,8 +620,7 @@ vacuum(List *relations, VacuumParams *params, BufferAccessStrategy bstrategy,
 
                        if (params->options & VACOPT_VACUUM)
                        {
-                               if (!vacuum_rel(vrel->oid, vrel->relation, params, false,
-                                                               bstrategy))
+                               if (!vacuum_rel(vrel->oid, vrel->relation, params, bstrategy))
                                        continue;
                        }
 
@@ -712,6 +711,13 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple,
 
        Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0);
 
+       /*
+        * Privilege checks are bypassed in some cases (e.g., when recursing to a
+        * relation's TOAST table).
+        */
+       if (options & VACOPT_SKIP_PRIVS)
+               return true;
+
        /*----------
         * A role has privileges to vacuum or analyze the relation if any of the
         * following are true:
@@ -1953,7 +1959,7 @@ vac_truncate_clog(TransactionId frozenXID,
  */
 static bool
 vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
-                  bool skip_privs, BufferAccessStrategy bstrategy)
+                  BufferAccessStrategy bstrategy)
 {
        LOCKMODE        lmode;
        Relation        rel;
@@ -2040,10 +2046,9 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
         * happen across multiple transactions where privileges could have changed
         * in-between.  Make sure to only generate logs for VACUUM in this case.
         */
-       if (!skip_privs &&
-               !vacuum_is_permitted_for_relation(RelationGetRelid(rel),
+       if (!vacuum_is_permitted_for_relation(RelationGetRelid(rel),
                                                                                  rel->rd_rel,
-                                                                                 params->options & VACOPT_VACUUM))
+                                                                                 params->options & ~VACOPT_ANALYZE))
        {
                relation_close(rel, lmode);
                PopActiveSnapshot();
@@ -2229,11 +2234,16 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
        {
                VacuumParams toast_vacuum_params;
 
-               /* force VACOPT_PROCESS_MAIN so vacuum_rel() processes it */
+               /*
+                * Force VACOPT_PROCESS_MAIN so vacuum_rel() processes it.  Likewise,
+                * set VACOPT_SKIP_PRIVS since privileges on the main relation are
+                * sufficient to process it.
+                */
                memcpy(&toast_vacuum_params, params, sizeof(VacuumParams));
                toast_vacuum_params.options |= VACOPT_PROCESS_MAIN;
+               toast_vacuum_params.options |= VACOPT_SKIP_PRIVS;
 
-               vacuum_rel(toast_relid, NULL, &toast_vacuum_params, true, bstrategy);
+               vacuum_rel(toast_relid, NULL, &toast_vacuum_params, bstrategy);
        }
 
        /*
index 17e9b4f68e540a558d80e717bc19edfee4b55146..cb5b11ab31f7341d4bc9d925cf0a5074d0d68caa 100644 (file)
@@ -191,6 +191,7 @@ typedef struct VacAttrStats
 #define VACOPT_DISABLE_PAGE_SKIPPING 0x100     /* don't skip any pages */
 #define VACOPT_SKIP_DATABASE_STATS 0x200       /* skip vac_update_datfrozenxid() */
 #define VACOPT_ONLY_DATABASE_STATS 0x400       /* only vac_update_datfrozenxid() */
+#define VACOPT_SKIP_PRIVS 0x800 /* skip privilege checks */
 
 /*
  * Values used by index_cleanup and truncate params.