* Performs the necessary checks to ensure that the current user has priveleges to * perform the compact operation on the collection, also checks if the realtion to be vacuumed * is available for exclusive access locking */
| 173 | * is available for exclusive access locking |
| 174 | */ |
| 175 | static void |
| 176 | ValidateLocksAndCheckAccess(MongoCollection *collection) |
| 177 | { |
| 178 | /* |
| 179 | * Check if the current user is permitted to perform VACUUM FULL on the collection. |
| 180 | */ |
| 181 | HeapTuple tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(collection->relationId)); |
| 182 | if (!HeapTupleIsValid(tuple)) |
| 183 | { |
| 184 | ereport(ERROR, ( |
| 185 | errcode(ERRCODE_DOCUMENTDB_INTERNALERROR), |
| 186 | errmsg( |
| 187 | "Cannot find relation in cache while performing compact on collection %s.%s", |
| 188 | collection->name.databaseName, |
| 189 | collection->name.collectionName), |
| 190 | errdetail_log( |
| 191 | "Cannot find relation in cache while performing compact on collection %s.%s", |
| 192 | collection->name.databaseName, collection->name.collectionName))); |
| 193 | } |
| 194 | Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); |
| 195 | |
| 196 | bits32 options = VACOPT_VACUUM | VACOPT_FULL; |
| 197 | bool userCanVacuum = false; |
| 198 | #if PG_VERSION_NUM >= 170000 |
| 199 | userCanVacuum = vacuum_is_permitted_for_relation(collection->relationId, |
| 200 | classForm, options); |
| 201 | #else |
| 202 | userCanVacuum = vacuum_is_relation_owner(collection->relationId, |
| 203 | classForm, options); |
| 204 | #endif |
| 205 | ReleaseSysCache(tuple); |
| 206 | |
| 207 | if (!userCanVacuum) |
| 208 | { |
| 209 | ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
| 210 | errmsg( |
| 211 | "permisson denied for performing compact on collection %s.%s", |
| 212 | collection->name.databaseName, |
| 213 | collection->name.collectionName), |
| 214 | errdetail_log( |
| 215 | "permisson denied for performing compact on collection %s.%s", |
| 216 | collection->name.databaseName, |
| 217 | collection->name.collectionName))); |
| 218 | } |
| 219 | |
| 220 | /* Now checking if the collection is available for exclusive locking : |
| 221 | * - To validate early if only 1 vacuum is running on the collection. |
| 222 | * |
| 223 | * Immediately unlock the table to avoid deadlock situation with VACUUM FULL. |
| 224 | */ |
| 225 | if (ConditionalLockRelationOid(collection->relationId, AccessExclusiveLock)) |
| 226 | { |
| 227 | UnlockRelationOid(collection->relationId, AccessExclusiveLock); |
| 228 | } |
| 229 | else |
| 230 | { |
| 231 | /* Throw conflicting operations in progress */ |
| 232 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_LOCATION17308), |