|
41 | 41 | #include"catalog/pg_namespace.h"
|
42 | 42 | #include"commands/cluster.h"
|
43 | 43 | #include"commands/defrem.h"
|
| 44 | +#include"commands/tablecmds.h" |
44 | 45 | #include"commands/vacuum.h"
|
45 | 46 | #include"miscadmin.h"
|
46 | 47 | #include"nodes/makefuncs.h"
|
@@ -91,7 +92,8 @@ static void vac_truncate_clog(TransactionId frozenXID,
|
91 | 92 | MultiXactIdminMulti,
|
92 | 93 | TransactionIdlastSaneFrozenXid,
|
93 | 94 | MultiXactIdlastSaneMinMulti);
|
94 |
| -staticboolvacuum_rel(Oidrelid,RangeVar*relation,VacuumParams*params); |
| 95 | +staticboolvacuum_rel(Oidrelid,RangeVar*relation,VacuumParams*params, |
| 96 | +boolskip_privs); |
95 | 97 | staticdoublecompute_parallel_delay(void);
|
96 | 98 | staticVacOptValueget_vacoptval_from_boolean(DefElem*def);
|
97 | 99 | staticboolvac_tid_reaped(ItemPointeritemptr,void*state);
|
@@ -501,7 +503,7 @@ vacuum(List *relations, VacuumParams *params,
|
501 | 503 |
|
502 | 504 | if (params->options&VACOPT_VACUUM)
|
503 | 505 | {
|
504 |
| -if (!vacuum_rel(vrel->oid,vrel->relation,params)) |
| 506 | +if (!vacuum_rel(vrel->oid,vrel->relation,params, false)) |
505 | 507 | continue;
|
506 | 508 | }
|
507 | 509 |
|
@@ -598,11 +600,13 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple,
|
598 | 600 | * - the role owns the relation
|
599 | 601 | * - the role owns the current database and the relation is not shared
|
600 | 602 | * - the role has been granted the MAINTAIN privilege on the relation
|
| 603 | + * - the role has privileges to vacuum/analyze any of the relation's |
| 604 | + * partition ancestors |
601 | 605 | *----------
|
602 | 606 | */
|
603 |
| -if (object_ownercheck(RelationRelationId,relid,GetUserId())|| |
604 |
| -(object_ownercheck(DatabaseRelationId,MyDatabaseId,GetUserId())&& !reltuple->relisshared)|| |
605 |
| -pg_class_aclcheck(relid,GetUserId(),ACL_MAINTAIN)==ACLCHECK_OK) |
| 607 | +if ((object_ownercheck(DatabaseRelationId,MyDatabaseId,GetUserId())&& !reltuple->relisshared)|| |
| 608 | +pg_class_aclcheck(relid,GetUserId(),ACL_MAINTAIN)==ACLCHECK_OK|| |
| 609 | +has_partition_ancestor_privs(relid,GetUserId(),ACL_MAINTAIN)) |
606 | 610 | return true;
|
607 | 611 |
|
608 | 612 | relname=NameStr(reltuple->relname);
|
@@ -1828,7 +1832,7 @@ vac_truncate_clog(TransactionId frozenXID,
|
1828 | 1832 | *At entry and exit, we are not inside a transaction.
|
1829 | 1833 | */
|
1830 | 1834 | staticbool
|
1831 |
| -vacuum_rel(Oidrelid,RangeVar*relation,VacuumParams*params) |
| 1835 | +vacuum_rel(Oidrelid,RangeVar*relation,VacuumParams*params,boolskip_privs) |
1832 | 1836 | {
|
1833 | 1837 | LOCKMODElmode;
|
1834 | 1838 | Relationrel;
|
@@ -1915,7 +1919,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
|
1915 | 1919 | * happen across multiple transactions where privileges could have changed
|
1916 | 1920 | * in-between. Make sure to only generate logs for VACUUM in this case.
|
1917 | 1921 | */
|
1918 |
| -if (!vacuum_is_permitted_for_relation(RelationGetRelid(rel), |
| 1922 | +if (!skip_privs&& |
| 1923 | +!vacuum_is_permitted_for_relation(RelationGetRelid(rel), |
1919 | 1924 | rel->rd_rel,
|
1920 | 1925 | params->options&VACOPT_VACUUM))
|
1921 | 1926 | {
|
@@ -2089,7 +2094,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
|
2089 | 2094 | * totally unimportant for toast relations.
|
2090 | 2095 | */
|
2091 | 2096 | if (toast_relid!=InvalidOid)
|
2092 |
| -vacuum_rel(toast_relid,NULL,params); |
| 2097 | +vacuum_rel(toast_relid,NULL,params, true); |
2093 | 2098 |
|
2094 | 2099 | /*
|
2095 | 2100 | * Now release the session-level lock on the main table.
|
|