PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_shdepend.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
#include "catalog/pg_default_acl.h"
#include "catalog/pg_event_trigger.h"
#include "catalog/pg_extension.h"
#include "catalog/pg_foreign_data_wrapper.h"
#include "catalog/pg_foreign_server.h"
#include "catalog/pg_language.h"
#include "catalog/pg_largeobject.h"
#include "catalog/pg_largeobject_metadata.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_shdepend.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_subscription.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_type.h"
#include "catalog/pg_user_mapping.h"
#include "commands/alter.h"
#include "commands/dbcommands.h"
#include "commands/collationcmds.h"
#include "commands/conversioncmds.h"
#include "commands/defrem.h"
#include "commands/event_trigger.h"
#include "commands/extension.h"
#include "commands/policy.h"
#include "commands/proclang.h"
#include "commands/publicationcmds.h"
#include "commands/schemacmds.h"
#include "commands/subscriptioncmds.h"
#include "commands/tablecmds.h"
#include "commands/typecmds.h"
#include "storage/lmgr.h"
#include "miscadmin.h"
#include "utils/acl.h"
#include "utils/fmgroids.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
Include dependency graph for pg_shdepend.c:

Go to the source code of this file.

Data Structures

struct  remoteDep
 

Macros

#define MAX_REPORTED_DEPS   100
 

Enumerations

enum  SharedDependencyObjectType { LOCAL_OBJECT, SHARED_OBJECT, REMOTE_OBJECT }
 

Functions

static void getOidListDiff (Oid *list1, int *nlist1, Oid *list2, int *nlist2)
 
static Oid classIdGetDbId (Oid classId)
 
static void shdepChangeDep (Relation sdepRel, Oid classid, Oid objid, int32 objsubid, Oid refclassid, Oid refobjid, SharedDependencyType deptype)
 
static void shdepAddDependency (Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
 
static void shdepDropDependency (Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, bool drop_subobjects, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
 
static void storeObjectDescription (StringInfo descs, SharedDependencyObjectType type, ObjectAddress *object, SharedDependencyType deptype, int count)
 
static bool isSharedObjectPinned (Oid classId, Oid objectId, Relation sdepRel)
 
void recordSharedDependencyOn (ObjectAddress *depender, ObjectAddress *referenced, SharedDependencyType deptype)
 
void recordDependencyOnOwner (Oid classId, Oid objectId, Oid owner)
 
void changeDependencyOnOwner (Oid classId, Oid objectId, Oid newOwnerId)
 
void updateAclDependencies (Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
 
bool checkSharedDependencies (Oid classId, Oid objectId, char **detail_msg, char **detail_log_msg)
 
void copyTemplateDependencies (Oid templateDbId, Oid newDbId)
 
void dropDatabaseDependencies (Oid databaseId)
 
void deleteSharedDependencyRecordsFor (Oid classId, Oid objectId, int32 objectSubId)
 
void shdepLockAndCheckObject (Oid classId, Oid objectId)
 
void shdepDropOwned (List *roleids, DropBehavior behavior)
 
void shdepReassignOwned (List *roleids, Oid newrole)
 

Macro Definition Documentation

#define MAX_REPORTED_DEPS   100

Referenced by checkSharedDependencies().

Enumeration Type Documentation

Enumerator
LOCAL_OBJECT 
SHARED_OBJECT 
REMOTE_OBJECT 

Definition at line 71 of file pg_shdepend.c.

Function Documentation

void changeDependencyOnOwner ( Oid  classId,
Oid  objectId,
Oid  newOwnerId 
)

Definition at line 304 of file pg_shdepend.c.

References AuthIdRelationId, heap_close, heap_open(), RowExclusiveLock, SHARED_DEPENDENCY_ACL, SHARED_DEPENDENCY_OWNER, SharedDependRelationId, shdepChangeDep(), and shdepDropDependency().

Referenced by AlterDatabaseOwner(), AlterEventTriggerOwner_internal(), AlterForeignDataWrapperOwner_internal(), AlterForeignServerOwner_internal(), AlterObjectOwner_internal(), AlterPublicationOwner_internal(), AlterSchemaOwner_internal(), AlterSubscriptionOwner_internal(), AlterTypeOwner_oid(), and ATExecChangeOwner().

305 {
306  Relation sdepRel;
307 
309 
310  /* Adjust the SHARED_DEPENDENCY_OWNER entry */
311  shdepChangeDep(sdepRel,
312  classId, objectId, 0,
313  AuthIdRelationId, newOwnerId,
315 
316  /*----------
317  * There should never be a SHARED_DEPENDENCY_ACL entry for the owner,
318  * so get rid of it if there is one. This can happen if the new owner
319  * was previously granted some rights to the object.
320  *
321  * This step is analogous to aclnewowner's removal of duplicate entries
322  * in the ACL. We have to do it to handle this scenario:
323  * A grants some rights on an object to B
324  * ALTER OWNER changes the object's owner to B
325  * ALTER OWNER changes the object's owner to C
326  * The third step would remove all mention of B from the object's ACL,
327  * but we'd still have a SHARED_DEPENDENCY_ACL for B if we did not do
328  * things this way.
329  *
330  * The rule against having a SHARED_DEPENDENCY_ACL entry for the owner
331  * allows us to fix things up in just this one place, without having
332  * to make the various ALTER OWNER routines each know about it.
333  *----------
334  */
335  shdepDropDependency(sdepRel, classId, objectId, 0, true,
336  AuthIdRelationId, newOwnerId,
338 
339  heap_close(sdepRel, RowExclusiveLock);
340 }
#define SharedDependRelationId
Definition: pg_shdepend.h:29
static void shdepChangeDep(Relation sdepRel, Oid classid, Oid objid, int32 objsubid, Oid refclassid, Oid refobjid, SharedDependencyType deptype)
Definition: pg_shdepend.c:194
#define heap_close(r, l)
Definition: heapam.h:97
#define AuthIdRelationId
Definition: pg_authid.h:42
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, bool drop_subobjects, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:900
bool checkSharedDependencies ( Oid  classId,
Oid  objectId,
char **  detail_msg,
char **  detail_log_msg 
)

Definition at line 522 of file pg_shdepend.c.

References AccessShareLock, Anum_pg_shdepend_refclassid, Anum_pg_shdepend_refobjid, appendStringInfo(), BTEqualStrategyNumber, remoteDep::count, StringInfoData::data, DatabaseRelationId, remoteDep::dbOid, ereport, errcode(), errmsg(), ERROR, getObjectDescription(), GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, initStringInfo(), InvalidOid, lappend(), StringInfoData::len, lfirst, list_free_deep(), LOCAL_OBJECT, MAX_REPORTED_DEPS, MyDatabaseId, ngettext, NIL, NULL, ObjectIdGetDatum, palloc(), pfree(), REMOTE_OBJECT, ScanKeyInit(), SHARED_DEPENDENCY_INVALID, SHARED_DEPENDENCY_PIN, SHARED_OBJECT, SharedDependReferenceIndexId, SharedDependRelationId, storeObjectDescription(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by DropRole().

524 {
525  Relation sdepRel;
526  ScanKeyData key[2];
527  SysScanDesc scan;
528  HeapTuple tup;
529  int numReportedDeps = 0;
530  int numNotReportedDeps = 0;
531  int numNotReportedDbs = 0;
532  List *remDeps = NIL;
533  ListCell *cell;
534  ObjectAddress object;
535  StringInfoData descs;
536  StringInfoData alldescs;
537 
538  /*
539  * We limit the number of dependencies reported to the client to
540  * MAX_REPORTED_DEPS, since client software may not deal well with
541  * enormous error strings. The server log always gets a full report.
542  */
543 #define MAX_REPORTED_DEPS 100
544 
545  initStringInfo(&descs);
546  initStringInfo(&alldescs);
547 
549 
550  ScanKeyInit(&key[0],
552  BTEqualStrategyNumber, F_OIDEQ,
553  ObjectIdGetDatum(classId));
554  ScanKeyInit(&key[1],
556  BTEqualStrategyNumber, F_OIDEQ,
557  ObjectIdGetDatum(objectId));
558 
559  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
560  NULL, 2, key);
561 
562  while (HeapTupleIsValid(tup = systable_getnext(scan)))
563  {
564  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tup);
565 
566  /* This case can be dispatched quickly */
567  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
568  {
569  object.classId = classId;
570  object.objectId = objectId;
571  object.objectSubId = 0;
572  ereport(ERROR,
573  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
574  errmsg("cannot drop %s because it is required by the database system",
575  getObjectDescription(&object))));
576  }
577 
578  object.classId = sdepForm->classid;
579  object.objectId = sdepForm->objid;
580  object.objectSubId = sdepForm->objsubid;
581 
582  /*
583  * If it's a dependency local to this database or it's a shared
584  * object, describe it.
585  *
586  * If it's a remote dependency, keep track of it so we can report the
587  * number of them later.
588  */
589  if (sdepForm->dbid == MyDatabaseId)
590  {
591  if (numReportedDeps < MAX_REPORTED_DEPS)
592  {
593  numReportedDeps++;
594  storeObjectDescription(&descs, LOCAL_OBJECT, &object,
595  sdepForm->deptype, 0);
596  }
597  else
598  numNotReportedDeps++;
599  storeObjectDescription(&alldescs, LOCAL_OBJECT, &object,
600  sdepForm->deptype, 0);
601  }
602  else if (sdepForm->dbid == InvalidOid)
603  {
604  if (numReportedDeps < MAX_REPORTED_DEPS)
605  {
606  numReportedDeps++;
607  storeObjectDescription(&descs, SHARED_OBJECT, &object,
608  sdepForm->deptype, 0);
609  }
610  else
611  numNotReportedDeps++;
612  storeObjectDescription(&alldescs, SHARED_OBJECT, &object,
613  sdepForm->deptype, 0);
614  }
615  else
616  {
617  /* It's not local nor shared, so it must be remote. */
618  remoteDep *dep;
619  bool stored = false;
620 
621  /*
622  * XXX this info is kept on a simple List. Maybe it's not good
623  * for performance, but using a hash table seems needlessly
624  * complex. The expected number of databases is not high anyway,
625  * I suppose.
626  */
627  foreach(cell, remDeps)
628  {
629  dep = lfirst(cell);
630  if (dep->dbOid == sdepForm->dbid)
631  {
632  dep->count++;
633  stored = true;
634  break;
635  }
636  }
637  if (!stored)
638  {
639  dep = (remoteDep *) palloc(sizeof(remoteDep));
640  dep->dbOid = sdepForm->dbid;
641  dep->count = 1;
642  remDeps = lappend(remDeps, dep);
643  }
644  }
645  }
646 
647  systable_endscan(scan);
648 
649  heap_close(sdepRel, AccessShareLock);
650 
651  /*
652  * Summarize dependencies in remote databases.
653  */
654  foreach(cell, remDeps)
655  {
656  remoteDep *dep = lfirst(cell);
657 
658  object.classId = DatabaseRelationId;
659  object.objectId = dep->dbOid;
660  object.objectSubId = 0;
661 
662  if (numReportedDeps < MAX_REPORTED_DEPS)
663  {
664  numReportedDeps++;
665  storeObjectDescription(&descs, REMOTE_OBJECT, &object,
667  }
668  else
669  numNotReportedDbs++;
670  storeObjectDescription(&alldescs, REMOTE_OBJECT, &object,
672  }
673 
674  list_free_deep(remDeps);
675 
676  if (descs.len == 0)
677  {
678  pfree(descs.data);
679  pfree(alldescs.data);
680  *detail_msg = *detail_log_msg = NULL;
681  return false;
682  }
683 
684  if (numNotReportedDeps > 0)
685  appendStringInfo(&descs, ngettext("\nand %d other object "
686  "(see server log for list)",
687  "\nand %d other objects "
688  "(see server log for list)",
689  numNotReportedDeps),
690  numNotReportedDeps);
691  if (numNotReportedDbs > 0)
692  appendStringInfo(&descs, ngettext("\nand objects in %d other database "
693  "(see server log for list)",
694  "\nand objects in %d other databases "
695  "(see server log for list)",
696  numNotReportedDbs),
697  numNotReportedDbs);
698 
699  *detail_msg = descs.data;
700  *detail_log_msg = alldescs.data;
701  return true;
702 }
#define NIL
Definition: pg_list.h:69
#define Anum_pg_shdepend_refclassid
Definition: pg_shdepend.h:75
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SharedDependRelationId
Definition: pg_shdepend.h:29
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:64
#define DatabaseRelationId
Definition: pg_database.h:29
#define AccessShareLock
Definition: lockdefs.h:36
#define MAX_REPORTED_DEPS
static void storeObjectDescription(StringInfo descs, SharedDependencyObjectType type, ObjectAddress *object, SharedDependencyType deptype, int count)
Definition: pg_shdepend.c:1060
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void list_free_deep(List *list)
Definition: list.c:1147
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
void pfree(void *pointer)
Definition: mcxt.c:950
#define Anum_pg_shdepend_refobjid
Definition: pg_shdepend.h:76
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
List * lappend(List *list, void *datum)
Definition: list.c:128
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define ngettext(s, p, n)
Definition: c.h:127
Oid MyDatabaseId
Definition: globals.c:76
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define SharedDependReferenceIndexId
Definition: indexing.h:231
Definition: pg_list.h:45
#define BTEqualStrategyNumber
Definition: stratnum.h:31
static Oid classIdGetDbId ( Oid  classId)
static

Definition at line 966 of file pg_shdepend.c.

References InvalidOid, IsSharedRelation(), and MyDatabaseId.

Referenced by shdepAddDependency(), shdepChangeDep(), and shdepDropDependency().

967 {
968  Oid dbId;
969 
970  if (IsSharedRelation(classId))
971  dbId = InvalidOid;
972  else
973  dbId = MyDatabaseId;
974 
975  return dbId;
976 }
unsigned int Oid
Definition: postgres_ext.h:31
Oid MyDatabaseId
Definition: globals.c:76
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:219
#define InvalidOid
Definition: postgres_ext.h:36
void copyTemplateDependencies ( Oid  templateDbId,
Oid  newDbId 
)

Definition at line 711 of file pg_shdepend.c.

References Anum_pg_shdepend_dbid, BTEqualStrategyNumber, CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTupleInsertWithInfo(), heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleIsValid, Natts_pg_shdepend, NULL, ObjectIdGetDatum, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), SharedDependDependerIndexId, SharedDependRelationId, systable_beginscan(), systable_endscan(), systable_getnext(), and values.

Referenced by createdb().

712 {
713  Relation sdepRel;
714  TupleDesc sdepDesc;
715  ScanKeyData key[1];
716  SysScanDesc scan;
717  HeapTuple tup;
718  CatalogIndexState indstate;
720  bool nulls[Natts_pg_shdepend];
721  bool replace[Natts_pg_shdepend];
722 
724  sdepDesc = RelationGetDescr(sdepRel);
725 
726  indstate = CatalogOpenIndexes(sdepRel);
727 
728  /* Scan all entries with dbid = templateDbId */
729  ScanKeyInit(&key[0],
731  BTEqualStrategyNumber, F_OIDEQ,
732  ObjectIdGetDatum(templateDbId));
733 
734  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
735  NULL, 1, key);
736 
737  /* Set up to copy the tuples except for inserting newDbId */
738  memset(values, 0, sizeof(values));
739  memset(nulls, false, sizeof(nulls));
740  memset(replace, false, sizeof(replace));
741 
742  replace[Anum_pg_shdepend_dbid - 1] = true;
743  values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(newDbId);
744 
745  /*
746  * Copy the entries of the original database, changing the database Id to
747  * that of the new database. Note that because we are not copying rows
748  * with dbId == 0 (ie, rows describing dependent shared objects) we won't
749  * copy the ownership dependency of the template database itself; this is
750  * what we want.
751  */
752  while (HeapTupleIsValid(tup = systable_getnext(scan)))
753  {
754  HeapTuple newtup;
755 
756  newtup = heap_modify_tuple(tup, sdepDesc, values, nulls, replace);
757  CatalogTupleInsertWithInfo(sdepRel, newtup, indstate);
758 
759  heap_freetuple(newtup);
760  }
761 
762  systable_endscan(scan);
763 
764  CatalogCloseIndexes(indstate);
765  heap_close(sdepRel, RowExclusiveLock);
766 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define SharedDependDependerIndexId
Definition: indexing.h:229
#define SharedDependRelationId
Definition: pg_shdepend.h:29
#define RelationGetDescr(relation)
Definition: rel.h:429
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_shdepend_dbid
Definition: pg_shdepend.h:71
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:40
static Datum values[MAXATTR]
Definition: bootstrap.c:162
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:58
Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:186
#define Natts_pg_shdepend
Definition: pg_shdepend.h:70
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void deleteSharedDependencyRecordsFor ( Oid  classId,
Oid  objectId,
int32  objectSubId 
)

Definition at line 823 of file pg_shdepend.c.

References heap_close, heap_open(), InvalidOid, RowExclusiveLock, SHARED_DEPENDENCY_INVALID, SharedDependRelationId, and shdepDropDependency().

Referenced by AlterPolicy(), deleteOneObject(), DropSubscription(), DropTableSpace(), GenerateTypeDependencies(), makeConfigurationDependencies(), makeOperatorDependencies(), and RemoveRoleFromObjectPolicy().

824 {
825  Relation sdepRel;
826 
828 
829  shdepDropDependency(sdepRel, classId, objectId, objectSubId,
830  (objectSubId == 0),
833 
834  heap_close(sdepRel, RowExclusiveLock);
835 }
#define SharedDependRelationId
Definition: pg_shdepend.h:29
#define heap_close(r, l)
Definition: heapam.h:97
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, bool drop_subobjects, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:900
void dropDatabaseDependencies ( Oid  databaseId)

Definition at line 775 of file pg_shdepend.c.

References Anum_pg_shdepend_dbid, BTEqualStrategyNumber, CatalogTupleDelete(), DatabaseRelationId, heap_close, heap_open(), HeapTupleIsValid, InvalidOid, NULL, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_INVALID, SharedDependDependerIndexId, SharedDependRelationId, shdepDropDependency(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by dropdb().

776 {
777  Relation sdepRel;
778  ScanKeyData key[1];
779  SysScanDesc scan;
780  HeapTuple tup;
781 
783 
784  /*
785  * First, delete all the entries that have the database Oid in the dbid
786  * field.
787  */
788  ScanKeyInit(&key[0],
790  BTEqualStrategyNumber, F_OIDEQ,
791  ObjectIdGetDatum(databaseId));
792  /* We leave the other index fields unspecified */
793 
794  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
795  NULL, 1, key);
796 
797  while (HeapTupleIsValid(tup = systable_getnext(scan)))
798  {
799  CatalogTupleDelete(sdepRel, &tup->t_self);
800  }
801 
802  systable_endscan(scan);
803 
804  /* Now delete all entries corresponding to the database itself */
805  shdepDropDependency(sdepRel, DatabaseRelationId, databaseId, 0, true,
808 
809  heap_close(sdepRel, RowExclusiveLock);
810 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define SharedDependDependerIndexId
Definition: indexing.h:229
#define SharedDependRelationId
Definition: pg_shdepend.h:29
#define DatabaseRelationId
Definition: pg_database.h:29
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_shdepend_dbid
Definition: pg_shdepend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, bool drop_subobjects, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:900
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
static void getOidListDiff ( Oid list1,
int *  nlist1,
Oid list2,
int *  nlist2 
)
static

Definition at line 351 of file pg_shdepend.c.

Referenced by updateAclDependencies().

352 {
353  int in1,
354  in2,
355  out1,
356  out2;
357 
358  in1 = in2 = out1 = out2 = 0;
359  while (in1 < *nlist1 && in2 < *nlist2)
360  {
361  if (list1[in1] == list2[in2])
362  {
363  /* skip over duplicates */
364  in1++;
365  in2++;
366  }
367  else if (list1[in1] < list2[in2])
368  {
369  /* list1[in1] is not in list2 */
370  list1[out1++] = list1[in1++];
371  }
372  else
373  {
374  /* list2[in2] is not in list1 */
375  list2[out2++] = list2[in2++];
376  }
377  }
378 
379  /* any remaining list1 entries are not in list2 */
380  while (in1 < *nlist1)
381  {
382  list1[out1++] = list1[in1++];
383  }
384 
385  /* any remaining list2 entries are not in list1 */
386  while (in2 < *nlist2)
387  {
388  list2[out2++] = list2[in2++];
389  }
390 
391  *nlist1 = out1;
392  *nlist2 = out2;
393 }
static bool isSharedObjectPinned ( Oid  classId,
Oid  objectId,
Relation  sdepRel 
)
static

Definition at line 1111 of file pg_shdepend.c.

References Anum_pg_shdepend_refclassid, Anum_pg_shdepend_refobjid, BTEqualStrategyNumber, GETSTRUCT, HeapTupleIsValid, NULL, ObjectIdGetDatum, result, ScanKeyInit(), SHARED_DEPENDENCY_PIN, SharedDependReferenceIndexId, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by recordSharedDependencyOn(), shdepChangeDep(), shdepDropOwned(), shdepReassignOwned(), and updateAclDependencies().

1112 {
1113  bool result = false;
1114  ScanKeyData key[2];
1115  SysScanDesc scan;
1116  HeapTuple tup;
1117 
1118  ScanKeyInit(&key[0],
1120  BTEqualStrategyNumber, F_OIDEQ,
1121  ObjectIdGetDatum(classId));
1122  ScanKeyInit(&key[1],
1124  BTEqualStrategyNumber, F_OIDEQ,
1125  ObjectIdGetDatum(objectId));
1126 
1127  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1128  NULL, 2, key);
1129 
1130  /*
1131  * Since we won't generate additional pg_shdepend entries for pinned
1132  * objects, there can be at most one entry referencing a pinned object.
1133  * Hence, it's sufficient to look at the first returned tuple; we don't
1134  * need to loop.
1135  */
1136  tup = systable_getnext(scan);
1137  if (HeapTupleIsValid(tup))
1138  {
1139  Form_pg_shdepend shdepForm = (Form_pg_shdepend) GETSTRUCT(tup);
1140 
1141  if (shdepForm->deptype == SHARED_DEPENDENCY_PIN)
1142  result = true;
1143  }
1144 
1145  systable_endscan(scan);
1146 
1147  return result;
1148 }
#define Anum_pg_shdepend_refclassid
Definition: pg_shdepend.h:75
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:64
return result
Definition: formatting.c:1618
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define Anum_pg_shdepend_refobjid
Definition: pg_shdepend.h:76
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define SharedDependReferenceIndexId
Definition: indexing.h:231
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void recordDependencyOnOwner ( Oid  classId,
Oid  objectId,
Oid  owner 
)

Definition at line 159 of file pg_shdepend.c.

References AuthIdRelationId, ObjectAddress::classId, ObjectAddress::objectId, ObjectAddress::objectSubId, recordSharedDependencyOn(), and SHARED_DEPENDENCY_OWNER.

Referenced by CollationCreate(), ConversionCreate(), create_proc_lang(), createdb(), CreateForeignDataWrapper(), CreateForeignServer(), CreateOpFamily(), CreatePublication(), CreateSubscription(), CreateTableSpace(), CreateUserMapping(), DefineOpClass(), GenerateTypeDependencies(), heap_create_with_catalog(), insert_event_trigger_tuple(), InsertExtensionTuple(), inv_create(), makeConfigurationDependencies(), makeDictionaryDependencies(), makeOperatorDependencies(), NamespaceCreate(), ProcedureCreate(), and SetDefaultACL().

160 {
161  ObjectAddress myself,
162  referenced;
163 
164  myself.classId = classId;
165  myself.objectId = objectId;
166  myself.objectSubId = 0;
167 
168  referenced.classId = AuthIdRelationId;
169  referenced.objectId = owner;
170  referenced.objectSubId = 0;
171 
172  recordSharedDependencyOn(&myself, &referenced, SHARED_DEPENDENCY_OWNER);
173 }
void recordSharedDependencyOn(ObjectAddress *depender, ObjectAddress *referenced, SharedDependencyType deptype)
Definition: pg_shdepend.c:115
#define AuthIdRelationId
Definition: pg_authid.h:42
void recordSharedDependencyOn ( ObjectAddress depender,
ObjectAddress referenced,
SharedDependencyType  deptype 
)

Definition at line 115 of file pg_shdepend.c.

References Assert, ObjectAddress::classId, heap_close, heap_open(), IsBootstrapProcessingMode, isSharedObjectPinned(), ObjectAddress::objectId, ObjectAddress::objectSubId, RowExclusiveLock, SharedDependRelationId, and shdepAddDependency().

Referenced by AlterPolicy(), CreatePolicy(), recordDependencyOnOwner(), and RemoveRoleFromObjectPolicy().

118 {
119  Relation sdepRel;
120 
121  /*
122  * Objects in pg_shdepend can't have SubIds.
123  */
124  Assert(depender->objectSubId == 0);
125  Assert(referenced->objectSubId == 0);
126 
127  /*
128  * During bootstrap, do nothing since pg_shdepend may not exist yet.
129  * initdb will fill in appropriate pg_shdepend entries after bootstrap.
130  */
132  return;
133 
135 
136  /* If the referenced object is pinned, do nothing. */
137  if (!isSharedObjectPinned(referenced->classId, referenced->objectId,
138  sdepRel))
139  {
140  shdepAddDependency(sdepRel, depender->classId, depender->objectId,
141  depender->objectSubId,
142  referenced->classId, referenced->objectId,
143  deptype);
144  }
145 
146  heap_close(sdepRel, RowExclusiveLock);
147 }
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1111
#define SharedDependRelationId
Definition: pg_shdepend.h:29
static void shdepAddDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:845
#define heap_close(r, l)
Definition: heapam.h:97
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define Assert(condition)
Definition: c.h:675
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
static void shdepAddDependency ( Relation  sdepRel,
Oid  classId,
Oid  objectId,
int32  objsubId,
Oid  refclassId,
Oid  refobjId,
SharedDependencyType  deptype 
)
static

Definition at line 845 of file pg_shdepend.c.

References Anum_pg_shdepend_classid, Anum_pg_shdepend_dbid, Anum_pg_shdepend_deptype, Anum_pg_shdepend_objid, Anum_pg_shdepend_objsubid, Anum_pg_shdepend_refclassid, Anum_pg_shdepend_refobjid, CatalogTupleInsert(), CharGetDatum, classIdGetDbId(), heap_form_tuple(), heap_freetuple(), Int32GetDatum, Natts_pg_shdepend, ObjectIdGetDatum, RelationData::rd_att, shdepLockAndCheckObject(), and values.

Referenced by recordSharedDependencyOn(), and updateAclDependencies().

849 {
850  HeapTuple tup;
852  bool nulls[Natts_pg_shdepend];
853 
854  /*
855  * Make sure the object doesn't go away while we record the dependency on
856  * it. DROP routines should lock the object exclusively before they check
857  * shared dependencies.
858  */
859  shdepLockAndCheckObject(refclassId, refobjId);
860 
861  memset(nulls, false, sizeof(nulls));
862 
863  /*
864  * Form the new tuple and record the dependency.
865  */
866  values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(classIdGetDbId(classId));
867  values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classId);
868  values[Anum_pg_shdepend_objid - 1] = ObjectIdGetDatum(objectId);
869  values[Anum_pg_shdepend_objsubid - 1] = Int32GetDatum(objsubId);
870 
871  values[Anum_pg_shdepend_refclassid - 1] = ObjectIdGetDatum(refclassId);
872  values[Anum_pg_shdepend_refobjid - 1] = ObjectIdGetDatum(refobjId);
873  values[Anum_pg_shdepend_deptype - 1] = CharGetDatum(deptype);
874 
875  tup = heap_form_tuple(sdepRel->rd_att, values, nulls);
876 
877  CatalogTupleInsert(sdepRel, tup);
878 
879  /* clean up */
880  heap_freetuple(tup);
881 }
#define Anum_pg_shdepend_refclassid
Definition: pg_shdepend.h:75
#define Anum_pg_shdepend_objsubid
Definition: pg_shdepend.h:74
#define Anum_pg_shdepend_classid
Definition: pg_shdepend.h:72
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#define Anum_pg_shdepend_refobjid
Definition: pg_shdepend.h:76
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
void shdepLockAndCheckObject(Oid classId, Oid objectId)
Definition: pg_shdepend.c:987
#define Anum_pg_shdepend_deptype
Definition: pg_shdepend.h:77
#define Anum_pg_shdepend_dbid
Definition: pg_shdepend.h:71
#define Anum_pg_shdepend_objid
Definition: pg_shdepend.h:73
uintptr_t Datum
Definition: postgres.h:372
TupleDesc rd_att
Definition: rel.h:115
static Oid classIdGetDbId(Oid classId)
Definition: pg_shdepend.c:966
#define CharGetDatum(X)
Definition: postgres.h:422
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define Int32GetDatum(X)
Definition: postgres.h:485
#define Natts_pg_shdepend
Definition: pg_shdepend.h:70
static void shdepChangeDep ( Relation  sdepRel,
Oid  classid,
Oid  objid,
int32  objsubid,
Oid  refclassid,
Oid  refobjid,
SharedDependencyType  deptype 
)
static

Definition at line 194 of file pg_shdepend.c.

References Anum_pg_shdepend_classid, Anum_pg_shdepend_dbid, Anum_pg_shdepend_deptype, Anum_pg_shdepend_objid, Anum_pg_shdepend_objsubid, Anum_pg_shdepend_refclassid, Anum_pg_shdepend_refobjid, BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleInsert(), CatalogTupleUpdate(), CharGetDatum, classIdGetDbId(), elog, ERROR, GETSTRUCT, heap_copytuple(), heap_form_tuple(), heap_freetuple(), Int32GetDatum, isSharedObjectPinned(), Natts_pg_shdepend, NULL, ObjectIdGetDatum, RelationGetDescr, ScanKeyInit(), SharedDependDependerIndexId, shdepLockAndCheckObject(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, and values.

Referenced by changeDependencyOnOwner().

198 {
199  Oid dbid = classIdGetDbId(classid);
200  HeapTuple oldtup = NULL;
201  HeapTuple scantup;
202  ScanKeyData key[4];
203  SysScanDesc scan;
204 
205  /*
206  * Make sure the new referenced object doesn't go away while we record the
207  * dependency.
208  */
209  shdepLockAndCheckObject(refclassid, refobjid);
210 
211  /*
212  * Look for a previous entry
213  */
214  ScanKeyInit(&key[0],
216  BTEqualStrategyNumber, F_OIDEQ,
217  ObjectIdGetDatum(dbid));
218  ScanKeyInit(&key[1],
220  BTEqualStrategyNumber, F_OIDEQ,
221  ObjectIdGetDatum(classid));
222  ScanKeyInit(&key[2],
224  BTEqualStrategyNumber, F_OIDEQ,
225  ObjectIdGetDatum(objid));
226  ScanKeyInit(&key[3],
228  BTEqualStrategyNumber, F_INT4EQ,
229  Int32GetDatum(objsubid));
230 
231  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
232  NULL, 4, key);
233 
234  while ((scantup = systable_getnext(scan)) != NULL)
235  {
236  /* Ignore if not of the target dependency type */
237  if (((Form_pg_shdepend) GETSTRUCT(scantup))->deptype != deptype)
238  continue;
239  /* Caller screwed up if multiple matches */
240  if (oldtup)
241  elog(ERROR,
242  "multiple pg_shdepend entries for object %u/%u/%d deptype %c",
243  classid, objid, objsubid, deptype);
244  oldtup = heap_copytuple(scantup);
245  }
246 
247  systable_endscan(scan);
248 
249  if (isSharedObjectPinned(refclassid, refobjid, sdepRel))
250  {
251  /* No new entry needed, so just delete existing entry if any */
252  if (oldtup)
253  CatalogTupleDelete(sdepRel, &oldtup->t_self);
254  }
255  else if (oldtup)
256  {
257  /* Need to update existing entry */
258  Form_pg_shdepend shForm = (Form_pg_shdepend) GETSTRUCT(oldtup);
259 
260  /* Since oldtup is a copy, we can just modify it in-memory */
261  shForm->refclassid = refclassid;
262  shForm->refobjid = refobjid;
263 
264  CatalogTupleUpdate(sdepRel, &oldtup->t_self, oldtup);
265  }
266  else
267  {
268  /* Need to insert new entry */
270  bool nulls[Natts_pg_shdepend];
271 
272  memset(nulls, false, sizeof(nulls));
273 
274  values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(dbid);
275  values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classid);
276  values[Anum_pg_shdepend_objid - 1] = ObjectIdGetDatum(objid);
277  values[Anum_pg_shdepend_objsubid - 1] = Int32GetDatum(objsubid);
278 
279  values[Anum_pg_shdepend_refclassid - 1] = ObjectIdGetDatum(refclassid);
280  values[Anum_pg_shdepend_refobjid - 1] = ObjectIdGetDatum(refobjid);
281  values[Anum_pg_shdepend_deptype - 1] = CharGetDatum(deptype);
282 
283  /*
284  * we are reusing oldtup just to avoid declaring a new variable, but
285  * it's certainly a new tuple
286  */
287  oldtup = heap_form_tuple(RelationGetDescr(sdepRel), values, nulls);
288  CatalogTupleInsert(sdepRel, oldtup);
289  }
290 
291  if (oldtup)
292  heap_freetuple(oldtup);
293 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
#define Anum_pg_shdepend_refclassid
Definition: pg_shdepend.h:75
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SharedDependDependerIndexId
Definition: indexing.h:229
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1111
#define RelationGetDescr(relation)
Definition: rel.h:429
#define Anum_pg_shdepend_objsubid
Definition: pg_shdepend.h:74
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:64
#define Anum_pg_shdepend_classid
Definition: pg_shdepend.h:72
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define Anum_pg_shdepend_refobjid
Definition: pg_shdepend.h:76
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
void shdepLockAndCheckObject(Oid classId, Oid objectId)
Definition: pg_shdepend.c:987
ItemPointerData t_self
Definition: htup.h:65
#define Anum_pg_shdepend_deptype
Definition: pg_shdepend.h:77
#define Anum_pg_shdepend_dbid
Definition: pg_shdepend.h:71
#define Anum_pg_shdepend_objid
Definition: pg_shdepend.h:73
uintptr_t Datum
Definition: postgres.h:372
#define NULL
Definition: c.h:229
static Oid classIdGetDbId(Oid classId)
Definition: pg_shdepend.c:966
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define CharGetDatum(X)
Definition: postgres.h:422
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define Int32GetDatum(X)
Definition: postgres.h:485
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define Natts_pg_shdepend
Definition: pg_shdepend.h:70
#define BTEqualStrategyNumber
Definition: stratnum.h:31
static void shdepDropDependency ( Relation  sdepRel,
Oid  classId,
Oid  objectId,
int32  objsubId,
bool  drop_subobjects,
Oid  refclassId,
Oid  refobjId,
SharedDependencyType  deptype 
)
static

Definition at line 900 of file pg_shdepend.c.

References Anum_pg_shdepend_classid, Anum_pg_shdepend_dbid, Anum_pg_shdepend_objid, Anum_pg_shdepend_objsubid, BTEqualStrategyNumber, CatalogTupleDelete(), classIdGetDbId(), GETSTRUCT, HeapTupleIsValid, Int32GetDatum, NULL, ObjectIdGetDatum, OidIsValid, ScanKeyInit(), SHARED_DEPENDENCY_INVALID, SharedDependDependerIndexId, systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by changeDependencyOnOwner(), deleteSharedDependencyRecordsFor(), dropDatabaseDependencies(), and updateAclDependencies().

905 {
906  ScanKeyData key[4];
907  int nkeys;
908  SysScanDesc scan;
909  HeapTuple tup;
910 
911  /* Scan for entries matching the dependent object */
912  ScanKeyInit(&key[0],
914  BTEqualStrategyNumber, F_OIDEQ,
915  ObjectIdGetDatum(classIdGetDbId(classId)));
916  ScanKeyInit(&key[1],
918  BTEqualStrategyNumber, F_OIDEQ,
919  ObjectIdGetDatum(classId));
920  ScanKeyInit(&key[2],
922  BTEqualStrategyNumber, F_OIDEQ,
923  ObjectIdGetDatum(objectId));
924  if (drop_subobjects)
925  nkeys = 3;
926  else
927  {
928  ScanKeyInit(&key[3],
930  BTEqualStrategyNumber, F_INT4EQ,
931  Int32GetDatum(objsubId));
932  nkeys = 4;
933  }
934 
935  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
936  NULL, nkeys, key);
937 
938  while (HeapTupleIsValid(tup = systable_getnext(scan)))
939  {
940  Form_pg_shdepend shdepForm = (Form_pg_shdepend) GETSTRUCT(tup);
941 
942  /* Filter entries according to additional parameters */
943  if (OidIsValid(refclassId) && shdepForm->refclassid != refclassId)
944  continue;
945  if (OidIsValid(refobjId) && shdepForm->refobjid != refobjId)
946  continue;
947  if (deptype != SHARED_DEPENDENCY_INVALID &&
948  shdepForm->deptype != deptype)
949  continue;
950 
951  /* OK, delete it */
952  CatalogTupleDelete(sdepRel, &tup->t_self);
953  }
954 
955  systable_endscan(scan);
956 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SharedDependDependerIndexId
Definition: indexing.h:229
#define Anum_pg_shdepend_objsubid
Definition: pg_shdepend.h:74
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:64
#define Anum_pg_shdepend_classid
Definition: pg_shdepend.h:72
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define OidIsValid(objectId)
Definition: c.h:538
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define Anum_pg_shdepend_dbid
Definition: pg_shdepend.h:71
#define Anum_pg_shdepend_objid
Definition: pg_shdepend.h:73
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
static Oid classIdGetDbId(Oid classId)
Definition: pg_shdepend.c:966
#define Int32GetDatum(X)
Definition: postgres.h:485
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void shdepDropOwned ( List roleids,
DropBehavior  behavior 
)

Definition at line 1163 of file pg_shdepend.c.

References add_exact_object_address(), Anum_pg_shdepend_refclassid, Anum_pg_shdepend_refobjid, AuthIdRelationId, BTEqualStrategyNumber, ObjectAddress::classId, elog, ereport, errcode(), errmsg(), ERROR, free_object_addresses(), getObjectDescription(), GETSTRUCT, heap_close, heap_open(), InvalidOid, isSharedObjectPinned(), lfirst_oid, MyDatabaseId, new_object_addresses(), NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, performMultipleDeletions(), RemoveRoleFromObjectACL(), RemoveRoleFromObjectPolicy(), RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_ACL, SHARED_DEPENDENCY_INVALID, SHARED_DEPENDENCY_OWNER, SHARED_DEPENDENCY_PIN, SHARED_DEPENDENCY_POLICY, SharedDependReferenceIndexId, SharedDependRelationId, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by DropOwnedObjects().

1164 {
1165  Relation sdepRel;
1166  ListCell *cell;
1167  ObjectAddresses *deleteobjs;
1168 
1169  deleteobjs = new_object_addresses();
1170 
1171  /*
1172  * We don't need this strong a lock here, but we'll call routines that
1173  * acquire RowExclusiveLock. Better get that right now to avoid potential
1174  * deadlock failures.
1175  */
1177 
1178  /*
1179  * For each role, find the dependent objects and drop them using the
1180  * regular (non-shared) dependency management.
1181  */
1182  foreach(cell, roleids)
1183  {
1184  Oid roleid = lfirst_oid(cell);
1185  ScanKeyData key[2];
1186  SysScanDesc scan;
1187  HeapTuple tuple;
1188 
1189  /* Doesn't work for pinned objects */
1190  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1191  {
1192  ObjectAddress obj;
1193 
1194  obj.classId = AuthIdRelationId;
1195  obj.objectId = roleid;
1196  obj.objectSubId = 0;
1197 
1198  ereport(ERROR,
1199  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1200  errmsg("cannot drop objects owned by %s because they are "
1201  "required by the database system",
1202  getObjectDescription(&obj))));
1203  }
1204 
1205  ScanKeyInit(&key[0],
1207  BTEqualStrategyNumber, F_OIDEQ,
1209  ScanKeyInit(&key[1],
1211  BTEqualStrategyNumber, F_OIDEQ,
1212  ObjectIdGetDatum(roleid));
1213 
1214  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1215  NULL, 2, key);
1216 
1217  while ((tuple = systable_getnext(scan)) != NULL)
1218  {
1219  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1220  ObjectAddress obj;
1221 
1222  /*
1223  * We only operate on shared objects and objects in the current
1224  * database
1225  */
1226  if (sdepForm->dbid != MyDatabaseId &&
1227  sdepForm->dbid != InvalidOid)
1228  continue;
1229 
1230  switch (sdepForm->deptype)
1231  {
1232  /* Shouldn't happen */
1233  case SHARED_DEPENDENCY_PIN:
1235  elog(ERROR, "unexpected dependency type");
1236  break;
1237  case SHARED_DEPENDENCY_ACL:
1238  RemoveRoleFromObjectACL(roleid,
1239  sdepForm->classid,
1240  sdepForm->objid);
1241  break;
1243  /* If unable to remove role from policy, remove policy. */
1244  if (!RemoveRoleFromObjectPolicy(roleid,
1245  sdepForm->classid,
1246  sdepForm->objid))
1247  {
1248  obj.classId = sdepForm->classid;
1249  obj.objectId = sdepForm->objid;
1250  obj.objectSubId = sdepForm->objsubid;
1251  add_exact_object_address(&obj, deleteobjs);
1252  }
1253  break;
1255  /* If a local object, save it for deletion below */
1256  if (sdepForm->dbid == MyDatabaseId)
1257  {
1258  obj.classId = sdepForm->classid;
1259  obj.objectId = sdepForm->objid;
1260  obj.objectSubId = sdepForm->objsubid;
1261  add_exact_object_address(&obj, deleteobjs);
1262  }
1263  break;
1264  }
1265  }
1266 
1267  systable_endscan(scan);
1268  }
1269 
1270  /* the dependency mechanism does the actual work */
1271  performMultipleDeletions(deleteobjs, behavior, 0);
1272 
1273  heap_close(sdepRel, RowExclusiveLock);
1274 
1275  free_object_addresses(deleteobjs);
1276 }
#define Anum_pg_shdepend_refclassid
Definition: pg_shdepend.h:75
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1111
#define SharedDependRelationId
Definition: pg_shdepend.h:29
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:64
int errcode(int sqlerrcode)
Definition: elog.c:575
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2087
#define heap_close(r, l)
Definition: heapam.h:97
void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
Definition: aclchk.c:1326
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2032
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2303
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
char * getObjectDescription(const ObjectAddress *object)
#define AuthIdRelationId
Definition: pg_authid.h:42
bool RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
Definition: policy.c:435
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define Anum_pg_shdepend_refobjid
Definition: pg_shdepend.h:76
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:122
Oid MyDatabaseId
Definition: globals.c:76
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void performMultipleDeletions(const ObjectAddresses *objects, DropBehavior behavior, int flags)
Definition: dependency.c:362
#define elog
Definition: elog.h:219
#define SharedDependReferenceIndexId
Definition: indexing.h:231
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define lfirst_oid(lc)
Definition: pg_list.h:108
void shdepLockAndCheckObject ( Oid  classId,
Oid  objectId 
)

Definition at line 987 of file pg_shdepend.c.

References AccessShareLock, AuthIdRelationId, AUTHOID, DatabaseRelationId, elog, ereport, errcode(), errmsg(), ERROR, get_database_name(), get_tablespace_name(), LockSharedObject(), NULL, ObjectIdGetDatum, pfree(), SearchSysCacheExists1, tablespace, and TableSpaceRelationId.

Referenced by AlterDatabaseSet(), AlterRoleSet(), shdepAddDependency(), and shdepChangeDep().

988 {
989  /* AccessShareLock should be OK, since we are not modifying the object */
990  LockSharedObject(classId, objectId, 0, AccessShareLock);
991 
992  switch (classId)
993  {
994  case AuthIdRelationId:
996  ereport(ERROR,
997  (errcode(ERRCODE_UNDEFINED_OBJECT),
998  errmsg("role %u was concurrently dropped",
999  objectId)));
1000  break;
1001 
1002  /*
1003  * Currently, this routine need not support any other shared
1004  * object types besides roles. If we wanted to record explicit
1005  * dependencies on databases or tablespaces, we'd need code along
1006  * these lines:
1007  */
1008 #ifdef NOT_USED
1009  case TableSpaceRelationId:
1010  {
1011  /* For lack of a syscache on pg_tablespace, do this: */
1012  char *tablespace = get_tablespace_name(objectId);
1013 
1014  if (tablespace == NULL)
1015  ereport(ERROR,
1016  (errcode(ERRCODE_UNDEFINED_OBJECT),
1017  errmsg("tablespace %u was concurrently dropped",
1018  objectId)));
1019  pfree(tablespace);
1020  break;
1021  }
1022 #endif
1023 
1024  case DatabaseRelationId:
1025  {
1026  /* For lack of a syscache on pg_database, do this: */
1027  char *database = get_database_name(objectId);
1028 
1029  if (database == NULL)
1030  ereport(ERROR,
1031  (errcode(ERRCODE_UNDEFINED_OBJECT),
1032  errmsg("database %u was concurrently dropped",
1033  objectId)));
1034  pfree(database);
1035  break;
1036  }
1037 
1038 
1039  default:
1040  elog(ERROR, "unrecognized shared classId: %u", classId);
1041  }
1042 }
#define DatabaseRelationId
Definition: pg_database.h:29
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define AuthIdRelationId
Definition: pg_authid.h:42
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
void pfree(void *pointer)
Definition: mcxt.c:950
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2048
char * tablespace
Definition: pgbench.c:146
#define ereport(elevel, rest)
Definition: elog.h:122
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:871
#define NULL
Definition: c.h:229
#define TableSpaceRelationId
Definition: pg_tablespace.h:29
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * get_tablespace_name(Oid spc_oid)
Definition: tablespace.c:1426
#define elog
Definition: elog.h:219
void shdepReassignOwned ( List roleids,
Oid  newrole 
)

Definition at line 1285 of file pg_shdepend.c.

References AccessExclusiveLock, AlterEventTriggerOwner_oid(), AlterForeignDataWrapperOwner_oid(), AlterForeignServerOwner_oid(), AlterObjectOwner_internal(), AlterPublicationOwner_oid(), AlterSchemaOwner_oid(), AlterSubscriptionOwner_oid(), AlterTypeOwner_oid(), Anum_pg_shdepend_refclassid, Anum_pg_shdepend_refobjid, ATExecChangeOwner(), AuthIdRelationId, BTEqualStrategyNumber, ObjectAddress::classId, CollationRelationId, CommandCounterIncrement(), ConversionRelationId, DatabaseRelationId, DefaultAclRelationId, elog, ereport, errcode(), errmsg(), ERROR, EventTriggerRelationId, ExtensionRelationId, ForeignDataWrapperRelationId, ForeignServerRelationId, getObjectDescription(), GETSTRUCT, heap_close, heap_open(), InvalidOid, isSharedObjectPinned(), LanguageRelationId, LargeObjectMetadataRelationId, LargeObjectRelationId, lfirst_oid, MyDatabaseId, NamespaceRelationId, NoLock, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OperatorClassRelationId, OperatorFamilyRelationId, OperatorRelationId, ProcedureRelationId, PublicationRelationId, RelationRelationId, RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_OWNER, SHARED_DEPENDENCY_PIN, SharedDependReferenceIndexId, SharedDependRelationId, StatisticExtRelationId, SubscriptionRelationId, systable_beginscan(), systable_endscan(), systable_getnext(), TableSpaceRelationId, TSConfigRelationId, TSDictionaryRelationId, TypeRelationId, and UserMappingRelationId.

Referenced by ReassignOwnedObjects().

1286 {
1287  Relation sdepRel;
1288  ListCell *cell;
1289 
1290  /*
1291  * We don't need this strong a lock here, but we'll call routines that
1292  * acquire RowExclusiveLock. Better get that right now to avoid potential
1293  * deadlock problems.
1294  */
1296 
1297  foreach(cell, roleids)
1298  {
1299  SysScanDesc scan;
1300  ScanKeyData key[2];
1301  HeapTuple tuple;
1302  Oid roleid = lfirst_oid(cell);
1303 
1304  /* Refuse to work on pinned roles */
1305  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1306  {
1307  ObjectAddress obj;
1308 
1309  obj.classId = AuthIdRelationId;
1310  obj.objectId = roleid;
1311  obj.objectSubId = 0;
1312 
1313  ereport(ERROR,
1314  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1315  errmsg("cannot reassign ownership of objects owned by %s because they are required by the database system",
1316  getObjectDescription(&obj))));
1317 
1318  /*
1319  * There's no need to tell the whole truth, which is that we
1320  * didn't track these dependencies at all ...
1321  */
1322  }
1323 
1324  ScanKeyInit(&key[0],
1326  BTEqualStrategyNumber, F_OIDEQ,
1328  ScanKeyInit(&key[1],
1330  BTEqualStrategyNumber, F_OIDEQ,
1331  ObjectIdGetDatum(roleid));
1332 
1333  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1334  NULL, 2, key);
1335 
1336  while ((tuple = systable_getnext(scan)) != NULL)
1337  {
1338  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1339 
1340  /*
1341  * We only operate on shared objects and objects in the current
1342  * database
1343  */
1344  if (sdepForm->dbid != MyDatabaseId &&
1345  sdepForm->dbid != InvalidOid)
1346  continue;
1347 
1348  /* Unexpected because we checked for pins above */
1349  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
1350  elog(ERROR, "unexpected shared pin");
1351 
1352  /* We leave non-owner dependencies alone */
1353  if (sdepForm->deptype != SHARED_DEPENDENCY_OWNER)
1354  continue;
1355 
1356  /* Issue the appropriate ALTER OWNER call */
1357  switch (sdepForm->classid)
1358  {
1359  case TypeRelationId:
1360  AlterTypeOwner_oid(sdepForm->objid, newrole, true);
1361  break;
1362 
1363  case NamespaceRelationId:
1364  AlterSchemaOwner_oid(sdepForm->objid, newrole);
1365  break;
1366 
1367  case RelationRelationId:
1368 
1369  /*
1370  * Pass recursing = true so that we don't fail on indexes,
1371  * owned sequences, etc when we happen to visit them
1372  * before their parent table.
1373  */
1374  ATExecChangeOwner(sdepForm->objid, newrole, true, AccessExclusiveLock);
1375  break;
1376 
1377  case DefaultAclRelationId:
1378 
1379  /*
1380  * Ignore default ACLs; they should be handled by DROP
1381  * OWNED, not REASSIGN OWNED.
1382  */
1383  break;
1384 
1385  case UserMappingRelationId:
1386  /* ditto */
1387  break;
1388 
1390  AlterForeignServerOwner_oid(sdepForm->objid, newrole);
1391  break;
1392 
1394  AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
1395  break;
1396 
1398  AlterEventTriggerOwner_oid(sdepForm->objid, newrole);
1399  break;
1400 
1401  case PublicationRelationId:
1402  AlterPublicationOwner_oid(sdepForm->objid, newrole);
1403  break;
1404 
1406  AlterSubscriptionOwner_oid(sdepForm->objid, newrole);
1407  break;
1408 
1409  /* Generic alter owner cases */
1410  case CollationRelationId:
1411  case ConversionRelationId:
1412  case OperatorRelationId:
1413  case ProcedureRelationId:
1414  case LanguageRelationId:
1415  case LargeObjectRelationId:
1418  case ExtensionRelationId:
1420  case TableSpaceRelationId:
1421  case DatabaseRelationId:
1422  case TSConfigRelationId:
1424  {
1425  Oid classId = sdepForm->classid;
1426  Relation catalog;
1427 
1428  if (classId == LargeObjectRelationId)
1430 
1431  catalog = heap_open(classId, RowExclusiveLock);
1432 
1433  AlterObjectOwner_internal(catalog, sdepForm->objid,
1434  newrole);
1435 
1436  heap_close(catalog, NoLock);
1437  }
1438  break;
1439 
1440  default:
1441  elog(ERROR, "unexpected classid %u", sdepForm->classid);
1442  break;
1443  }
1444  /* Make sure the next iteration will see my changes */
1446  }
1447 
1448  systable_endscan(scan);
1449  }
1450 
1451  heap_close(sdepRel, RowExclusiveLock);
1452 }
#define NamespaceRelationId
Definition: pg_namespace.h:34
#define OperatorRelationId
Definition: pg_operator.h:32
#define Anum_pg_shdepend_refclassid
Definition: pg_shdepend.h:75
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId)
Definition: foreigncmds.c:312
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1111
#define SharedDependRelationId
Definition: pg_shdepend.h:29
void AlterSchemaOwner_oid(Oid oid, Oid newOwnerId)
Definition: schemacmds.c:297
#define ProcedureRelationId
Definition: pg_proc.h:33
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:64
#define DatabaseRelationId
Definition: pg_database.h:29
#define RelationRelationId
Definition: pg_class.h:29
void AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId)
Definition: foreigncmds.c:447
#define OperatorClassRelationId
Definition: pg_opclass.h:49
#define OperatorFamilyRelationId
Definition: pg_opfamily.h:29
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PublicationRelationId
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
#define TypeRelationId
Definition: pg_type.h:34
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define DefaultAclRelationId
char * getObjectDescription(const ObjectAddress *object)
#define AuthIdRelationId
Definition: pg_authid.h:42
#define TSConfigRelationId
Definition: pg_ts_config.h:31
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define Anum_pg_shdepend_refobjid
Definition: pg_shdepend.h:76
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define TSDictionaryRelationId
Definition: pg_ts_dict.h:31
void AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry)
Definition: typecmds.c:3321
#define SubscriptionRelationId
void AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
Definition: alter.c:865
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:122
void ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lockmode)
Definition: tablecmds.c:9479
void CommandCounterIncrement(void)
Definition: xact.c:922
Oid MyDatabaseId
Definition: globals.c:76
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define CollationRelationId
Definition: pg_collation.h:30
#define InvalidOid
Definition: postgres_ext.h:36
void AlterEventTriggerOwner_oid(Oid trigOid, Oid newOwnerId)
#define ForeignServerRelationId
#define NULL
Definition: c.h:229
#define StatisticExtRelationId
#define EventTriggerRelationId
#define LargeObjectMetadataRelationId
#define ForeignDataWrapperRelationId
#define TableSpaceRelationId
Definition: pg_tablespace.h:29
#define AccessExclusiveLock
Definition: lockdefs.h:46
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define UserMappingRelationId
void AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define LanguageRelationId
Definition: pg_language.h:29
void AlterPublicationOwner_oid(Oid subid, Oid newOwnerId)
#define elog
Definition: elog.h:219
#define SharedDependReferenceIndexId
Definition: indexing.h:231
#define ExtensionRelationId
Definition: pg_extension.h:29
#define LargeObjectRelationId
#define ConversionRelationId
Definition: pg_conversion.h:38
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define lfirst_oid(lc)
Definition: pg_list.h:108
static void storeObjectDescription ( StringInfo  descs,
SharedDependencyObjectType  type,
ObjectAddress object,
SharedDependencyType  deptype,
int  count 
)
static

Definition at line 1060 of file pg_shdepend.c.

References _, appendStringInfo(), appendStringInfoChar(), elog, ERROR, getObjectDescription(), StringInfoData::len, LOCAL_OBJECT, ngettext, pfree(), REMOTE_OBJECT, SHARED_DEPENDENCY_ACL, SHARED_DEPENDENCY_OWNER, SHARED_DEPENDENCY_POLICY, and SHARED_OBJECT.

Referenced by checkSharedDependencies().

1065 {
1066  char *objdesc = getObjectDescription(object);
1067 
1068  /* separate entries with a newline */
1069  if (descs->len != 0)
1070  appendStringInfoChar(descs, '\n');
1071 
1072  switch (type)
1073  {
1074  case LOCAL_OBJECT:
1075  case SHARED_OBJECT:
1076  if (deptype == SHARED_DEPENDENCY_OWNER)
1077  appendStringInfo(descs, _("owner of %s"), objdesc);
1078  else if (deptype == SHARED_DEPENDENCY_ACL)
1079  appendStringInfo(descs, _("privileges for %s"), objdesc);
1080  else if (deptype == SHARED_DEPENDENCY_POLICY)
1081  appendStringInfo(descs, _("target of %s"), objdesc);
1082  else
1083  elog(ERROR, "unrecognized dependency type: %d",
1084  (int) deptype);
1085  break;
1086 
1087  case REMOTE_OBJECT:
1088  /* translator: %s will always be "database %s" */
1089  appendStringInfo(descs, ngettext("%d object in %s",
1090  "%d objects in %s",
1091  count),
1092  count, objdesc);
1093  break;
1094 
1095  default:
1096  elog(ERROR, "unrecognized object type: %d", type);
1097  }
1098 
1099  pfree(objdesc);
1100 }
char * getObjectDescription(const ObjectAddress *object)
void pfree(void *pointer)
Definition: mcxt.c:950
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define ERROR
Definition: elog.h:43
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
#define ngettext(s, p, n)
Definition: c.h:127
#define elog
Definition: elog.h:219
#define _(x)
Definition: elog.c:84
void updateAclDependencies ( Oid  classId,
Oid  objectId,
int32  objsubId,
Oid  ownerId,
int  noldmembers,
Oid oldmembers,
int  nnewmembers,
Oid newmembers 
)

Definition at line 421 of file pg_shdepend.c.

References AuthIdRelationId, getOidListDiff(), heap_close, heap_open(), i, isSharedObjectPinned(), pfree(), RowExclusiveLock, SHARED_DEPENDENCY_ACL, SharedDependRelationId, shdepAddDependency(), and shdepDropDependency().

Referenced by ExecGrant_Attribute(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), heap_create_with_catalog(), ProcedureCreate(), and SetDefaultACL().

425 {
426  Relation sdepRel;
427  int i;
428 
429  /*
430  * Remove entries that are common to both lists; those represent existing
431  * dependencies we don't need to change.
432  *
433  * OK to overwrite the inputs since we'll pfree them anyway.
434  */
435  getOidListDiff(oldmembers, &noldmembers, newmembers, &nnewmembers);
436 
437  if (noldmembers > 0 || nnewmembers > 0)
438  {
440 
441  /* Add new dependencies that weren't already present */
442  for (i = 0; i < nnewmembers; i++)
443  {
444  Oid roleid = newmembers[i];
445 
446  /*
447  * Skip the owner: he has an OWNER shdep entry instead. (This is
448  * not just a space optimization; it makes ALTER OWNER easier. See
449  * notes in changeDependencyOnOwner.)
450  */
451  if (roleid == ownerId)
452  continue;
453 
454  /* Skip pinned roles; they don't need dependency entries */
455  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
456  continue;
457 
458  shdepAddDependency(sdepRel, classId, objectId, objsubId,
459  AuthIdRelationId, roleid,
461  }
462 
463  /* Drop no-longer-used old dependencies */
464  for (i = 0; i < noldmembers; i++)
465  {
466  Oid roleid = oldmembers[i];
467 
468  /* Skip the owner, same as above */
469  if (roleid == ownerId)
470  continue;
471 
472  /* Skip pinned roles */
473  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
474  continue;
475 
476  shdepDropDependency(sdepRel, classId, objectId, objsubId,
477  false, /* exact match on objsubId */
478  AuthIdRelationId, roleid,
480  }
481 
482  heap_close(sdepRel, RowExclusiveLock);
483  }
484 
485  if (oldmembers)
486  pfree(oldmembers);
487  if (newmembers)
488  pfree(newmembers);
489 }
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1111
#define SharedDependRelationId
Definition: pg_shdepend.h:29
static void getOidListDiff(Oid *list1, int *nlist1, Oid *list2, int *nlist2)
Definition: pg_shdepend.c:351
static void shdepAddDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:845
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
#define AuthIdRelationId
Definition: pg_authid.h:42
void pfree(void *pointer)
Definition: mcxt.c:950
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, bool drop_subobjects, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:900
int i