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_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 70 of file pg_shdepend.c.

Function Documentation

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

Definition at line 303 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().

304 {
305  Relation sdepRel;
306 
308 
309  /* Adjust the SHARED_DEPENDENCY_OWNER entry */
310  shdepChangeDep(sdepRel,
311  classId, objectId, 0,
312  AuthIdRelationId, newOwnerId,
314 
315  /*----------
316  * There should never be a SHARED_DEPENDENCY_ACL entry for the owner,
317  * so get rid of it if there is one. This can happen if the new owner
318  * was previously granted some rights to the object.
319  *
320  * This step is analogous to aclnewowner's removal of duplicate entries
321  * in the ACL. We have to do it to handle this scenario:
322  * A grants some rights on an object to B
323  * ALTER OWNER changes the object's owner to B
324  * ALTER OWNER changes the object's owner to C
325  * The third step would remove all mention of B from the object's ACL,
326  * but we'd still have a SHARED_DEPENDENCY_ACL for B if we did not do
327  * things this way.
328  *
329  * The rule against having a SHARED_DEPENDENCY_ACL entry for the owner
330  * allows us to fix things up in just this one place, without having
331  * to make the various ALTER OWNER routines each know about it.
332  *----------
333  */
334  shdepDropDependency(sdepRel, classId, objectId, 0, true,
335  AuthIdRelationId, newOwnerId,
337 
338  heap_close(sdepRel, RowExclusiveLock);
339 }
#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:193
#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:899
bool checkSharedDependencies ( Oid  classId,
Oid  objectId,
char **  detail_msg,
char **  detail_log_msg 
)

Definition at line 521 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().

523 {
524  Relation sdepRel;
525  ScanKeyData key[2];
526  SysScanDesc scan;
527  HeapTuple tup;
528  int numReportedDeps = 0;
529  int numNotReportedDeps = 0;
530  int numNotReportedDbs = 0;
531  List *remDeps = NIL;
532  ListCell *cell;
533  ObjectAddress object;
534  StringInfoData descs;
535  StringInfoData alldescs;
536 
537  /*
538  * We limit the number of dependencies reported to the client to
539  * MAX_REPORTED_DEPS, since client software may not deal well with
540  * enormous error strings. The server log always gets a full report.
541  */
542 #define MAX_REPORTED_DEPS 100
543 
544  initStringInfo(&descs);
545  initStringInfo(&alldescs);
546 
548 
549  ScanKeyInit(&key[0],
551  BTEqualStrategyNumber, F_OIDEQ,
552  ObjectIdGetDatum(classId));
553  ScanKeyInit(&key[1],
555  BTEqualStrategyNumber, F_OIDEQ,
556  ObjectIdGetDatum(objectId));
557 
558  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
559  NULL, 2, key);
560 
561  while (HeapTupleIsValid(tup = systable_getnext(scan)))
562  {
563  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tup);
564 
565  /* This case can be dispatched quickly */
566  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
567  {
568  object.classId = classId;
569  object.objectId = objectId;
570  object.objectSubId = 0;
571  ereport(ERROR,
572  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
573  errmsg("cannot drop %s because it is required by the database system",
574  getObjectDescription(&object))));
575  }
576 
577  object.classId = sdepForm->classid;
578  object.objectId = sdepForm->objid;
579  object.objectSubId = sdepForm->objsubid;
580 
581  /*
582  * If it's a dependency local to this database or it's a shared
583  * object, describe it.
584  *
585  * If it's a remote dependency, keep track of it so we can report the
586  * number of them later.
587  */
588  if (sdepForm->dbid == MyDatabaseId)
589  {
590  if (numReportedDeps < MAX_REPORTED_DEPS)
591  {
592  numReportedDeps++;
593  storeObjectDescription(&descs, LOCAL_OBJECT, &object,
594  sdepForm->deptype, 0);
595  }
596  else
597  numNotReportedDeps++;
598  storeObjectDescription(&alldescs, LOCAL_OBJECT, &object,
599  sdepForm->deptype, 0);
600  }
601  else if (sdepForm->dbid == InvalidOid)
602  {
603  if (numReportedDeps < MAX_REPORTED_DEPS)
604  {
605  numReportedDeps++;
606  storeObjectDescription(&descs, SHARED_OBJECT, &object,
607  sdepForm->deptype, 0);
608  }
609  else
610  numNotReportedDeps++;
611  storeObjectDescription(&alldescs, SHARED_OBJECT, &object,
612  sdepForm->deptype, 0);
613  }
614  else
615  {
616  /* It's not local nor shared, so it must be remote. */
617  remoteDep *dep;
618  bool stored = false;
619 
620  /*
621  * XXX this info is kept on a simple List. Maybe it's not good
622  * for performance, but using a hash table seems needlessly
623  * complex. The expected number of databases is not high anyway,
624  * I suppose.
625  */
626  foreach(cell, remDeps)
627  {
628  dep = lfirst(cell);
629  if (dep->dbOid == sdepForm->dbid)
630  {
631  dep->count++;
632  stored = true;
633  break;
634  }
635  }
636  if (!stored)
637  {
638  dep = (remoteDep *) palloc(sizeof(remoteDep));
639  dep->dbOid = sdepForm->dbid;
640  dep->count = 1;
641  remDeps = lappend(remDeps, dep);
642  }
643  }
644  }
645 
646  systable_endscan(scan);
647 
648  heap_close(sdepRel, AccessShareLock);
649 
650  /*
651  * Summarize dependencies in remote databases.
652  */
653  foreach(cell, remDeps)
654  {
655  remoteDep *dep = lfirst(cell);
656 
657  object.classId = DatabaseRelationId;
658  object.objectId = dep->dbOid;
659  object.objectSubId = 0;
660 
661  if (numReportedDeps < MAX_REPORTED_DEPS)
662  {
663  numReportedDeps++;
664  storeObjectDescription(&descs, REMOTE_OBJECT, &object,
666  }
667  else
668  numNotReportedDbs++;
669  storeObjectDescription(&alldescs, REMOTE_OBJECT, &object,
671  }
672 
673  list_free_deep(remDeps);
674 
675  if (descs.len == 0)
676  {
677  pfree(descs.data);
678  pfree(alldescs.data);
679  *detail_msg = *detail_log_msg = NULL;
680  return false;
681  }
682 
683  if (numNotReportedDeps > 0)
684  appendStringInfo(&descs, ngettext("\nand %d other object "
685  "(see server log for list)",
686  "\nand %d other objects "
687  "(see server log for list)",
688  numNotReportedDeps),
689  numNotReportedDeps);
690  if (numNotReportedDbs > 0)
691  appendStringInfo(&descs, ngettext("\nand objects in %d other database "
692  "(see server log for list)",
693  "\nand objects in %d other databases "
694  "(see server log for list)",
695  numNotReportedDbs),
696  numNotReportedDbs);
697 
698  *detail_msg = descs.data;
699  *detail_log_msg = alldescs.data;
700  return true;
701 }
#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:493
#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:1059
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:322
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
void pfree(void *pointer)
Definition: mcxt.c:992
#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:515
#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:226
#define lfirst(lc)
Definition: pg_list.h:106
void * palloc(Size size)
Definition: mcxt.c:891
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:224
Definition: pg_list.h:45
#define BTEqualStrategyNumber
Definition: stratnum.h:31
static Oid classIdGetDbId ( Oid  classId)
static

Definition at line 965 of file pg_shdepend.c.

References InvalidOid, IsSharedRelation(), and MyDatabaseId.

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

966 {
967  Oid dbId;
968 
969  if (IsSharedRelation(classId))
970  dbId = InvalidOid;
971  else
972  dbId = MyDatabaseId;
973 
974  return dbId;
975 }
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 710 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().

711 {
712  Relation sdepRel;
713  TupleDesc sdepDesc;
714  ScanKeyData key[1];
715  SysScanDesc scan;
716  HeapTuple tup;
717  CatalogIndexState indstate;
719  bool nulls[Natts_pg_shdepend];
720  bool replace[Natts_pg_shdepend];
721 
723  sdepDesc = RelationGetDescr(sdepRel);
724 
725  indstate = CatalogOpenIndexes(sdepRel);
726 
727  /* Scan all entries with dbid = templateDbId */
728  ScanKeyInit(&key[0],
730  BTEqualStrategyNumber, F_OIDEQ,
731  ObjectIdGetDatum(templateDbId));
732 
733  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
734  NULL, 1, key);
735 
736  /* Set up to copy the tuples except for inserting newDbId */
737  memset(values, 0, sizeof(values));
738  memset(nulls, false, sizeof(nulls));
739  memset(replace, false, sizeof(replace));
740 
741  replace[Anum_pg_shdepend_dbid - 1] = true;
742  values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(newDbId);
743 
744  /*
745  * Copy the entries of the original database, changing the database Id to
746  * that of the new database. Note that because we are not copying rows
747  * with dbId == 0 (ie, rows describing dependent shared objects) we won't
748  * copy the ownership dependency of the template database itself; this is
749  * what we want.
750  */
751  while (HeapTupleIsValid(tup = systable_getnext(scan)))
752  {
753  HeapTuple newtup;
754 
755  newtup = heap_modify_tuple(tup, sdepDesc, values, nulls, replace);
756  CatalogTupleInsertWithInfo(sdepRel, newtup, indstate);
757 
758  heap_freetuple(newtup);
759  }
760 
761  systable_endscan(scan);
762 
763  CatalogCloseIndexes(indstate);
764  heap_close(sdepRel, RowExclusiveLock);
765 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define SharedDependDependerIndexId
Definition: indexing.h:222
#define SharedDependRelationId
Definition: pg_shdepend.h:29
#define RelationGetDescr(relation)
Definition: rel.h:425
#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:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_shdepend_dbid
Definition: pg_shdepend.h:71
uintptr_t Datum
Definition: postgres.h:374
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
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 822 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().

823 {
824  Relation sdepRel;
825 
827 
828  shdepDropDependency(sdepRel, classId, objectId, objectSubId,
829  (objectSubId == 0),
832 
833  heap_close(sdepRel, RowExclusiveLock);
834 }
#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:899
void dropDatabaseDependencies ( Oid  databaseId)

Definition at line 774 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().

775 {
776  Relation sdepRel;
777  ScanKeyData key[1];
778  SysScanDesc scan;
779  HeapTuple tup;
780 
782 
783  /*
784  * First, delete all the entries that have the database Oid in the dbid
785  * field.
786  */
787  ScanKeyInit(&key[0],
789  BTEqualStrategyNumber, F_OIDEQ,
790  ObjectIdGetDatum(databaseId));
791  /* We leave the other index fields unspecified */
792 
793  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
794  NULL, 1, key);
795 
796  while (HeapTupleIsValid(tup = systable_getnext(scan)))
797  {
798  CatalogTupleDelete(sdepRel, &tup->t_self);
799  }
800 
801  systable_endscan(scan);
802 
803  /* Now delete all entries corresponding to the database itself */
804  shdepDropDependency(sdepRel, DatabaseRelationId, databaseId, 0, true,
807 
808  heap_close(sdepRel, RowExclusiveLock);
809 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define SharedDependDependerIndexId
Definition: indexing.h:222
#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:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
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:899
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
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 350 of file pg_shdepend.c.

Referenced by updateAclDependencies().

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

Definition at line 1110 of file pg_shdepend.c.

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

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

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

Definition at line 158 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().

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

Definition at line 114 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().

117 {
118  Relation sdepRel;
119 
120  /*
121  * Objects in pg_shdepend can't have SubIds.
122  */
123  Assert(depender->objectSubId == 0);
124  Assert(referenced->objectSubId == 0);
125 
126  /*
127  * During bootstrap, do nothing since pg_shdepend may not exist yet.
128  * initdb will fill in appropriate pg_shdepend entries after bootstrap.
129  */
131  return;
132 
134 
135  /* If the referenced object is pinned, do nothing. */
136  if (!isSharedObjectPinned(referenced->classId, referenced->objectId,
137  sdepRel))
138  {
139  shdepAddDependency(sdepRel, depender->classId, depender->objectId,
140  depender->objectSubId,
141  referenced->classId, referenced->objectId,
142  deptype);
143  }
144 
145  heap_close(sdepRel, RowExclusiveLock);
146 }
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1110
#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:844
#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:670
#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 844 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().

848 {
849  HeapTuple tup;
851  bool nulls[Natts_pg_shdepend];
852 
853  /*
854  * Make sure the object doesn't go away while we record the dependency on
855  * it. DROP routines should lock the object exclusively before they check
856  * shared dependencies.
857  */
858  shdepLockAndCheckObject(refclassId, refobjId);
859 
860  memset(nulls, false, sizeof(nulls));
861 
862  /*
863  * Form the new tuple and record the dependency.
864  */
865  values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(classIdGetDbId(classId));
866  values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classId);
867  values[Anum_pg_shdepend_objid - 1] = ObjectIdGetDatum(objectId);
868  values[Anum_pg_shdepend_objsubid - 1] = Int32GetDatum(objsubId);
869 
870  values[Anum_pg_shdepend_refclassid - 1] = ObjectIdGetDatum(refclassId);
871  values[Anum_pg_shdepend_refobjid - 1] = ObjectIdGetDatum(refobjId);
872  values[Anum_pg_shdepend_deptype - 1] = CharGetDatum(deptype);
873 
874  tup = heap_form_tuple(sdepRel->rd_att, values, nulls);
875 
876  CatalogTupleInsert(sdepRel, tup);
877 
878  /* clean up */
879  heap_freetuple(tup);
880 }
#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:515
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
void shdepLockAndCheckObject(Oid classId, Oid objectId)
Definition: pg_shdepend.c:986
#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:374
TupleDesc rd_att
Definition: rel.h:114
static Oid classIdGetDbId(Oid classId)
Definition: pg_shdepend.c:965
#define CharGetDatum(X)
Definition: postgres.h:424
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define Int32GetDatum(X)
Definition: postgres.h:487
#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 193 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().

197 {
198  Oid dbid = classIdGetDbId(classid);
199  HeapTuple oldtup = NULL;
200  HeapTuple scantup;
201  ScanKeyData key[4];
202  SysScanDesc scan;
203 
204  /*
205  * Make sure the new referenced object doesn't go away while we record the
206  * dependency.
207  */
208  shdepLockAndCheckObject(refclassid, refobjid);
209 
210  /*
211  * Look for a previous entry
212  */
213  ScanKeyInit(&key[0],
215  BTEqualStrategyNumber, F_OIDEQ,
216  ObjectIdGetDatum(dbid));
217  ScanKeyInit(&key[1],
219  BTEqualStrategyNumber, F_OIDEQ,
220  ObjectIdGetDatum(classid));
221  ScanKeyInit(&key[2],
223  BTEqualStrategyNumber, F_OIDEQ,
224  ObjectIdGetDatum(objid));
225  ScanKeyInit(&key[3],
227  BTEqualStrategyNumber, F_INT4EQ,
228  Int32GetDatum(objsubid));
229 
230  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
231  NULL, 4, key);
232 
233  while ((scantup = systable_getnext(scan)) != NULL)
234  {
235  /* Ignore if not of the target dependency type */
236  if (((Form_pg_shdepend) GETSTRUCT(scantup))->deptype != deptype)
237  continue;
238  /* Caller screwed up if multiple matches */
239  if (oldtup)
240  elog(ERROR,
241  "multiple pg_shdepend entries for object %u/%u/%d deptype %c",
242  classid, objid, objsubid, deptype);
243  oldtup = heap_copytuple(scantup);
244  }
245 
246  systable_endscan(scan);
247 
248  if (isSharedObjectPinned(refclassid, refobjid, sdepRel))
249  {
250  /* No new entry needed, so just delete existing entry if any */
251  if (oldtup)
252  CatalogTupleDelete(sdepRel, &oldtup->t_self);
253  }
254  else if (oldtup)
255  {
256  /* Need to update existing entry */
257  Form_pg_shdepend shForm = (Form_pg_shdepend) GETSTRUCT(oldtup);
258 
259  /* Since oldtup is a copy, we can just modify it in-memory */
260  shForm->refclassid = refclassid;
261  shForm->refobjid = refobjid;
262 
263  CatalogTupleUpdate(sdepRel, &oldtup->t_self, oldtup);
264  }
265  else
266  {
267  /* Need to insert new entry */
269  bool nulls[Natts_pg_shdepend];
270 
271  memset(nulls, false, sizeof(nulls));
272 
273  values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(dbid);
274  values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classid);
275  values[Anum_pg_shdepend_objid - 1] = ObjectIdGetDatum(objid);
276  values[Anum_pg_shdepend_objsubid - 1] = Int32GetDatum(objsubid);
277 
278  values[Anum_pg_shdepend_refclassid - 1] = ObjectIdGetDatum(refclassid);
279  values[Anum_pg_shdepend_refobjid - 1] = ObjectIdGetDatum(refobjid);
280  values[Anum_pg_shdepend_deptype - 1] = CharGetDatum(deptype);
281 
282  /*
283  * we are reusing oldtup just to avoid declaring a new variable, but
284  * it's certainly a new tuple
285  */
286  oldtup = heap_form_tuple(RelationGetDescr(sdepRel), values, nulls);
287  CatalogTupleInsert(sdepRel, oldtup);
288  }
289 
290  if (oldtup)
291  heap_freetuple(oldtup);
292 }
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:493
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SharedDependDependerIndexId
Definition: indexing.h:222
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1110
#define RelationGetDescr(relation)
Definition: rel.h:425
#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:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define Anum_pg_shdepend_refobjid
Definition: pg_shdepend.h:76
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#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:986
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:374
#define NULL
Definition: c.h:226
static Oid classIdGetDbId(Oid classId)
Definition: pg_shdepend.c:965
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define CharGetDatum(X)
Definition: postgres.h:424
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define Int32GetDatum(X)
Definition: postgres.h:487
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 899 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().

904 {
905  ScanKeyData key[4];
906  int nkeys;
907  SysScanDesc scan;
908  HeapTuple tup;
909 
910  /* Scan for entries matching the dependent object */
911  ScanKeyInit(&key[0],
913  BTEqualStrategyNumber, F_OIDEQ,
914  ObjectIdGetDatum(classIdGetDbId(classId)));
915  ScanKeyInit(&key[1],
917  BTEqualStrategyNumber, F_OIDEQ,
918  ObjectIdGetDatum(classId));
919  ScanKeyInit(&key[2],
921  BTEqualStrategyNumber, F_OIDEQ,
922  ObjectIdGetDatum(objectId));
923  if (drop_subobjects)
924  nkeys = 3;
925  else
926  {
927  ScanKeyInit(&key[3],
929  BTEqualStrategyNumber, F_INT4EQ,
930  Int32GetDatum(objsubId));
931  nkeys = 4;
932  }
933 
934  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
935  NULL, nkeys, key);
936 
937  while (HeapTupleIsValid(tup = systable_getnext(scan)))
938  {
939  Form_pg_shdepend shdepForm = (Form_pg_shdepend) GETSTRUCT(tup);
940 
941  /* Filter entries according to additional parameters */
942  if (OidIsValid(refclassId) && shdepForm->refclassid != refclassId)
943  continue;
944  if (OidIsValid(refobjId) && shdepForm->refobjid != refobjId)
945  continue;
946  if (deptype != SHARED_DEPENDENCY_INVALID &&
947  shdepForm->deptype != deptype)
948  continue;
949 
950  /* OK, delete it */
951  CatalogTupleDelete(sdepRel, &tup->t_self);
952  }
953 
954  systable_endscan(scan);
955 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SharedDependDependerIndexId
Definition: indexing.h:222
#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:533
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
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:226
static Oid classIdGetDbId(Oid classId)
Definition: pg_shdepend.c:965
#define Int32GetDatum(X)
Definition: postgres.h:487
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 1162 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().

1163 {
1164  Relation sdepRel;
1165  ListCell *cell;
1166  ObjectAddresses *deleteobjs;
1167 
1168  deleteobjs = new_object_addresses();
1169 
1170  /*
1171  * We don't need this strong a lock here, but we'll call routines that
1172  * acquire RowExclusiveLock. Better get that right now to avoid potential
1173  * deadlock failures.
1174  */
1176 
1177  /*
1178  * For each role, find the dependent objects and drop them using the
1179  * regular (non-shared) dependency management.
1180  */
1181  foreach(cell, roleids)
1182  {
1183  Oid roleid = lfirst_oid(cell);
1184  ScanKeyData key[2];
1185  SysScanDesc scan;
1186  HeapTuple tuple;
1187 
1188  /* Doesn't work for pinned objects */
1189  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1190  {
1191  ObjectAddress obj;
1192 
1193  obj.classId = AuthIdRelationId;
1194  obj.objectId = roleid;
1195  obj.objectSubId = 0;
1196 
1197  ereport(ERROR,
1198  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1199  errmsg("cannot drop objects owned by %s because they are "
1200  "required by the database system",
1201  getObjectDescription(&obj))));
1202  }
1203 
1204  ScanKeyInit(&key[0],
1206  BTEqualStrategyNumber, F_OIDEQ,
1208  ScanKeyInit(&key[1],
1210  BTEqualStrategyNumber, F_OIDEQ,
1211  ObjectIdGetDatum(roleid));
1212 
1213  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1214  NULL, 2, key);
1215 
1216  while ((tuple = systable_getnext(scan)) != NULL)
1217  {
1218  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1219  ObjectAddress obj;
1220 
1221  /*
1222  * We only operate on shared objects and objects in the current
1223  * database
1224  */
1225  if (sdepForm->dbid != MyDatabaseId &&
1226  sdepForm->dbid != InvalidOid)
1227  continue;
1228 
1229  switch (sdepForm->deptype)
1230  {
1231  /* Shouldn't happen */
1232  case SHARED_DEPENDENCY_PIN:
1234  elog(ERROR, "unexpected dependency type");
1235  break;
1236  case SHARED_DEPENDENCY_ACL:
1237  RemoveRoleFromObjectACL(roleid,
1238  sdepForm->classid,
1239  sdepForm->objid);
1240  break;
1242  /* If unable to remove role from policy, remove policy. */
1243  if (!RemoveRoleFromObjectPolicy(roleid,
1244  sdepForm->classid,
1245  sdepForm->objid))
1246  {
1247  obj.classId = sdepForm->classid;
1248  obj.objectId = sdepForm->objid;
1249  obj.objectSubId = sdepForm->objsubid;
1250  add_exact_object_address(&obj, deleteobjs);
1251  }
1252  break;
1254  /* If a local object, save it for deletion below */
1255  if (sdepForm->dbid == MyDatabaseId)
1256  {
1257  obj.classId = sdepForm->classid;
1258  obj.objectId = sdepForm->objid;
1259  obj.objectSubId = sdepForm->objsubid;
1260  add_exact_object_address(&obj, deleteobjs);
1261  }
1262  break;
1263  }
1264  }
1265 
1266  systable_endscan(scan);
1267  }
1268 
1269  /* the dependency mechanism does the actual work */
1270  performMultipleDeletions(deleteobjs, behavior, 0);
1271 
1272  heap_close(sdepRel, RowExclusiveLock);
1273 
1274  free_object_addresses(deleteobjs);
1275 }
#define Anum_pg_shdepend_refclassid
Definition: pg_shdepend.h:75
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1110
#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:2081
#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:2026
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2297
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:322
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:410
#define Anum_pg_shdepend_refobjid
Definition: pg_shdepend.h:76
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#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:226
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:360
#define elog
Definition: elog.h:219
#define SharedDependReferenceIndexId
Definition: indexing.h:224
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define lfirst_oid(lc)
Definition: pg_list.h:108
void shdepLockAndCheckObject ( Oid  classId,
Oid  objectId 
)

Definition at line 986 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().

987 {
988  /* AccessShareLock should be OK, since we are not modifying the object */
989  LockSharedObject(classId, objectId, 0, AccessShareLock);
990 
991  switch (classId)
992  {
993  case AuthIdRelationId:
995  ereport(ERROR,
996  (errcode(ERRCODE_UNDEFINED_OBJECT),
997  errmsg("role %u was concurrently dropped",
998  objectId)));
999  break;
1000 
1001  /*
1002  * Currently, this routine need not support any other shared
1003  * object types besides roles. If we wanted to record explicit
1004  * dependencies on databases or tablespaces, we'd need code along
1005  * these lines:
1006  */
1007 #ifdef NOT_USED
1008  case TableSpaceRelationId:
1009  {
1010  /* For lack of a syscache on pg_tablespace, do this: */
1011  char *tablespace = get_tablespace_name(objectId);
1012 
1013  if (tablespace == NULL)
1014  ereport(ERROR,
1015  (errcode(ERRCODE_UNDEFINED_OBJECT),
1016  errmsg("tablespace %u was concurrently dropped",
1017  objectId)));
1018  pfree(tablespace);
1019  break;
1020  }
1021 #endif
1022 
1023  case DatabaseRelationId:
1024  {
1025  /* For lack of a syscache on pg_database, do this: */
1026  char *database = get_database_name(objectId);
1027 
1028  if (database == NULL)
1029  ereport(ERROR,
1030  (errcode(ERRCODE_UNDEFINED_OBJECT),
1031  errmsg("database %u was concurrently dropped",
1032  objectId)));
1033  pfree(database);
1034  break;
1035  }
1036 
1037 
1038  default:
1039  elog(ERROR, "unrecognized shared classId: %u", classId);
1040  }
1041 }
#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:167
void pfree(void *pointer)
Definition: mcxt.c:992
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2049
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:226
#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:1427
#define elog
Definition: elog.h:219
void shdepReassignOwned ( List roleids,
Oid  newrole 
)

Definition at line 1284 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, SubscriptionRelationId, systable_beginscan(), systable_endscan(), systable_getnext(), TableSpaceRelationId, TSConfigRelationId, TSDictionaryRelationId, TypeRelationId, and UserMappingRelationId.

Referenced by ReassignOwnedObjects().

1285 {
1286  Relation sdepRel;
1287  ListCell *cell;
1288 
1289  /*
1290  * We don't need this strong a lock here, but we'll call routines that
1291  * acquire RowExclusiveLock. Better get that right now to avoid potential
1292  * deadlock problems.
1293  */
1295 
1296  foreach(cell, roleids)
1297  {
1298  SysScanDesc scan;
1299  ScanKeyData key[2];
1300  HeapTuple tuple;
1301  Oid roleid = lfirst_oid(cell);
1302 
1303  /* Refuse to work on pinned roles */
1304  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1305  {
1306  ObjectAddress obj;
1307 
1308  obj.classId = AuthIdRelationId;
1309  obj.objectId = roleid;
1310  obj.objectSubId = 0;
1311 
1312  ereport(ERROR,
1313  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1314  errmsg("cannot reassign ownership of objects owned by %s because they are required by the database system",
1315  getObjectDescription(&obj))));
1316 
1317  /*
1318  * There's no need to tell the whole truth, which is that we
1319  * didn't track these dependencies at all ...
1320  */
1321  }
1322 
1323  ScanKeyInit(&key[0],
1325  BTEqualStrategyNumber, F_OIDEQ,
1327  ScanKeyInit(&key[1],
1329  BTEqualStrategyNumber, F_OIDEQ,
1330  ObjectIdGetDatum(roleid));
1331 
1332  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1333  NULL, 2, key);
1334 
1335  while ((tuple = systable_getnext(scan)) != NULL)
1336  {
1337  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1338 
1339  /*
1340  * We only operate on shared objects and objects in the current
1341  * database
1342  */
1343  if (sdepForm->dbid != MyDatabaseId &&
1344  sdepForm->dbid != InvalidOid)
1345  continue;
1346 
1347  /* Unexpected because we checked for pins above */
1348  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
1349  elog(ERROR, "unexpected shared pin");
1350 
1351  /* We leave non-owner dependencies alone */
1352  if (sdepForm->deptype != SHARED_DEPENDENCY_OWNER)
1353  continue;
1354 
1355  /* Issue the appropriate ALTER OWNER call */
1356  switch (sdepForm->classid)
1357  {
1358  case TypeRelationId:
1359  AlterTypeOwner_oid(sdepForm->objid, newrole, true);
1360  break;
1361 
1362  case NamespaceRelationId:
1363  AlterSchemaOwner_oid(sdepForm->objid, newrole);
1364  break;
1365 
1366  case RelationRelationId:
1367 
1368  /*
1369  * Pass recursing = true so that we don't fail on indexes,
1370  * owned sequences, etc when we happen to visit them
1371  * before their parent table.
1372  */
1373  ATExecChangeOwner(sdepForm->objid, newrole, true, AccessExclusiveLock);
1374  break;
1375 
1376  case DefaultAclRelationId:
1377 
1378  /*
1379  * Ignore default ACLs; they should be handled by DROP
1380  * OWNED, not REASSIGN OWNED.
1381  */
1382  break;
1383 
1384  case UserMappingRelationId:
1385  /* ditto */
1386  break;
1387 
1389  AlterForeignServerOwner_oid(sdepForm->objid, newrole);
1390  break;
1391 
1393  AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
1394  break;
1395 
1397  AlterEventTriggerOwner_oid(sdepForm->objid, newrole);
1398  break;
1399 
1400  case PublicationRelationId:
1401  AlterPublicationOwner_oid(sdepForm->objid, newrole);
1402  break;
1403 
1405  AlterSubscriptionOwner_oid(sdepForm->objid, newrole);
1406  break;
1407 
1408  /* Generic alter owner cases */
1409  case CollationRelationId:
1410  case ConversionRelationId:
1411  case OperatorRelationId:
1412  case ProcedureRelationId:
1413  case LanguageRelationId:
1414  case LargeObjectRelationId:
1417  case ExtensionRelationId:
1418  case TableSpaceRelationId:
1419  case DatabaseRelationId:
1420  case TSConfigRelationId:
1422  {
1423  Oid classId = sdepForm->classid;
1424  Relation catalog;
1425 
1426  if (classId == LargeObjectRelationId)
1428 
1429  catalog = heap_open(classId, RowExclusiveLock);
1430 
1431  AlterObjectOwner_internal(catalog, sdepForm->objid,
1432  newrole);
1433 
1434  heap_close(catalog, NoLock);
1435  }
1436  break;
1437 
1438  default:
1439  elog(ERROR, "unexpected classid %u", sdepForm->classid);
1440  break;
1441  }
1442  /* Make sure the next iteration will see my changes */
1444  }
1445 
1446  systable_endscan(scan);
1447  }
1448 
1449  heap_close(sdepRel, RowExclusiveLock);
1450 }
#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:493
#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:1110
#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:322
#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:410
#define Anum_pg_shdepend_refobjid
Definition: pg_shdepend.h:76
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#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:843
#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:9465
void CommandCounterIncrement(void)
Definition: xact.c:921
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:226
#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:224
#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 1059 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().

1064 {
1065  char *objdesc = getObjectDescription(object);
1066 
1067  /* separate entries with a newline */
1068  if (descs->len != 0)
1069  appendStringInfoChar(descs, '\n');
1070 
1071  switch (type)
1072  {
1073  case LOCAL_OBJECT:
1074  case SHARED_OBJECT:
1075  if (deptype == SHARED_DEPENDENCY_OWNER)
1076  appendStringInfo(descs, _("owner of %s"), objdesc);
1077  else if (deptype == SHARED_DEPENDENCY_ACL)
1078  appendStringInfo(descs, _("privileges for %s"), objdesc);
1079  else if (deptype == SHARED_DEPENDENCY_POLICY)
1080  appendStringInfo(descs, _("target of %s"), objdesc);
1081  else
1082  elog(ERROR, "unrecognized dependency type: %d",
1083  (int) deptype);
1084  break;
1085 
1086  case REMOTE_OBJECT:
1087  /* translator: %s will always be "database %s" */
1088  appendStringInfo(descs, ngettext("%d object in %s",
1089  "%d objects in %s",
1090  count),
1091  count, objdesc);
1092  break;
1093 
1094  default:
1095  elog(ERROR, "unrecognized object type: %d", type);
1096  }
1097 
1098  pfree(objdesc);
1099 }
char * getObjectDescription(const ObjectAddress *object)
void pfree(void *pointer)
Definition: mcxt.c:992
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 420 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().

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