80 #include "utils/fmgroids.h" 98 #define DEPFLAG_ORIGINAL 0x0001 99 #define DEPFLAG_NORMAL 0x0002 100 #define DEPFLAG_AUTO 0x0004 101 #define DEPFLAG_INTERNAL 0x0008 102 #define DEPFLAG_PARTITION 0x0010 103 #define DEPFLAG_EXTENSION 0x0020 104 #define DEPFLAG_REVERSE 0x0040 105 #define DEPFLAG_IS_PART 0x0080 106 #define DEPFLAG_SUBOBJECT 0x0100 152 ConstraintRelationId,
153 ConversionRelationId,
154 AttrDefaultRelationId,
156 LargeObjectRelationId,
158 OperatorClassRelationId,
159 OperatorFamilyRelationId,
160 AccessMethodRelationId,
161 AccessMethodOperatorRelationId,
162 AccessMethodProcedureRelationId,
166 StatisticExtRelationId,
168 TSDictionaryRelationId,
169 TSTemplateRelationId,
173 TableSpaceRelationId,
174 ForeignDataWrapperRelationId,
175 ForeignServerRelationId,
176 UserMappingRelationId,
177 DefaultAclRelationId,
179 EventTriggerRelationId,
181 PublicationRelationId,
182 PublicationRelRelationId,
183 SubscriptionRelationId,
235 for (i = 0; i < targetObjects->
numrefs; i++)
239 bool original =
false;
260 for (i = 0; i < targetObjects->
numrefs; i++)
399 for (i = 0; i < objects->
numrefs; i++)
454 Anum_pg_depend_classid,
458 Anum_pg_depend_objid,
462 Anum_pg_depend_objsubid,
477 otherObject.
classId = foundDep->refclassid;
478 otherObject.
objectId = foundDep->refobjid;
481 depversion =
heap_getattr(tup, Anum_pg_depend_refobjversion,
491 bool nulls[Natts_pg_depend];
492 bool replaces[Natts_pg_depend];
494 memset(values, 0,
sizeof(values));
495 memset(nulls,
false,
sizeof(nulls));
496 memset(replaces,
false,
sizeof(replaces));
499 values[Anum_pg_depend_refobjversion - 1] =
502 nulls[Anum_pg_depend_refobjversion - 1] =
true;
503 replaces[Anum_pg_depend_refobjversion - 1] =
true;
566 int numDependentObjects;
567 int maxDependentObjects;
613 Anum_pg_depend_classid,
617 Anum_pg_depend_objid,
624 Anum_pg_depend_objsubid,
639 memset(&owningObject, 0,
sizeof(owningObject));
640 memset(&partitionObject, 0,
sizeof(partitionObject));
646 otherObject.
classId = foundDep->refclassid;
647 otherObject.
objectId = foundDep->refobjid;
662 switch (foundDep->deptype)
690 otherObject.
classId == ExtensionRelationId &&
718 if (pendingObjects &&
739 owningObject = otherObject;
824 elog(
ERROR,
"deletion of owning object %s failed to delete %s",
845 partitionObject = otherObject;
855 partitionObject = otherObject;
871 elog(
ERROR,
"incorrect use of PIN dependency with %s",
875 elog(
ERROR,
"unrecognized dependency type '%c' for %s",
899 (
errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
900 errmsg(
"cannot drop %s because %s requires it",
902 errhint(
"You can drop %s instead.", otherObjDesc)));
913 maxDependentObjects = 128;
916 numDependentObjects = 0;
919 Anum_pg_depend_refclassid,
923 Anum_pg_depend_refobjid,
929 Anum_pg_depend_refobjsubid,
945 otherObject.
classId = foundDep->classid;
946 otherObject.
objectId = foundDep->objid;
983 switch (foundDep->deptype)
1009 (
errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1010 errmsg(
"cannot drop %s because it is required by the database system",
1015 elog(
ERROR,
"unrecognized dependency type '%c' for %s",
1022 if (numDependentObjects >= maxDependentObjects)
1025 maxDependentObjects *= 2;
1031 dependentObjects[numDependentObjects].
obj = otherObject;
1032 dependentObjects[numDependentObjects].
subflags = subflags;
1033 numDependentObjects++;
1043 if (numDependentObjects > 1)
1044 qsort((
void *) dependentObjects, numDependentObjects,
1053 mystack.
flags = objflags;
1054 mystack.
next = stack;
1056 for (
int i = 0;
i < numDependentObjects;
i++)
1069 pfree(dependentObjects);
1112 int numReportedClient = 0;
1113 int numNotReportedClient = 0;
1126 for (i = 0; i < targetObjects->
numrefs; i++)
1138 (
errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1139 errmsg(
"cannot drop %s because %s requires it",
1141 errhint(
"You can drop %s instead.", otherObjDesc)));
1159 #define MAX_REPORTED_DEPS 100 1168 for (i = targetObjects->
numrefs - 1; i >= 0; i--)
1201 (
errmsg(
"drop auto-cascades to %s",
1212 if (clientdetail.
len != 0)
1215 objDesc, otherDesc);
1216 numReportedClient++;
1219 numNotReportedClient++;
1221 if (logdetail.
len != 0)
1224 objDesc, otherDesc);
1233 if (clientdetail.
len != 0)
1237 numReportedClient++;
1240 numNotReportedClient++;
1242 if (logdetail.
len != 0)
1251 if (numNotReportedClient > 0)
1253 "(see server log for list)",
1254 "\nand %d other objects " 1255 "(see server log for list)",
1256 numNotReportedClient),
1257 numNotReportedClient);
1263 (
errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1264 errmsg(
"cannot drop %s because other objects depend on it",
1268 errhint(
"Use DROP ... CASCADE to drop the dependent objects too.")));
1271 (
errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1272 errmsg(
"cannot drop desired object(s) because other objects depend on them"),
1275 errhint(
"Use DROP ... CASCADE to drop the dependent objects too.")));
1277 else if (numReportedClient > 1)
1282 "drop cascades to %d other objects",
1283 numReportedClient + numNotReportedClient,
1284 numReportedClient + numNotReportedClient),
1288 else if (numReportedClient == 1)
1321 elog(
ERROR,
"cache lookup failed for %s %u",
1344 elog(
ERROR,
"could not find tuple for %s %u",
1394 if (flags & PERFORM_DELETION_CONCURRENTLY)
1405 Anum_pg_depend_classid,
1409 Anum_pg_depend_objid,
1415 Anum_pg_depend_objsubid,
1473 if (relKind == RELKIND_INDEX ||
1474 relKind == RELKIND_PARTITIONED_INDEX)
1495 if (relKind == RELKIND_SEQUENCE)
1582 elog(
ERROR,
"global objects cannot be deleted by doDeletion");
1605 if (object->
classId == RelationRelationId)
1634 if (object->
classId == RelationRelationId)
1649 bool record_version)
1658 foreach(lc, collations)
1739 bool record_version)
1747 MemSet(&rte, 0,
sizeof(rte));
1751 rte.
relkind = RELKIND_RELATION;
1763 if ((behavior != self_behavior || reverse_self) &&
1775 for (oldref = 0; oldref < context.
addrs->
numrefs; oldref++)
1779 if (thisobj->
classId == RelationRelationId &&
1807 for (selfref = 0; selfref < self_addrs->
numrefs; selfref++)
1892 foreach(lc, collations)
1943 case REGPROCEDUREOID:
1951 case REGOPERATOROID:
1979 case REGDICTIONARYOID:
1987 case REGNAMESPACEOID:
2001 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2002 errmsg(
"constant of the type %s cannot be used here",
2096 elog(
ERROR,
"already-planned subqueries not supported");
2206 foreach(l, rcexpr->
opnos)
2290 foreach(lc, query->
rtable)
2344 elog(
ERROR,
"invalid resultRelation %d",
2472 priorobj = addrs->
refs;
2474 for (oldref = 1; oldref < addrs->
numrefs; oldref++)
2500 *priorobj = *thisobj;
2586 "object_classes[] must cover all ObjectClasses");
2660 *itemextra = *extra;
2675 for (i = addrs->
numrefs - 1; i >= 0; i--)
2700 bool result =
false;
2703 for (i = addrs->
numrefs - 1; i >= 0; i--)
2773 bool result =
false;
2776 for (stackptr = stack; stackptr; stackptr = stackptr->
next)
2869 if (object->
classId != RelationRelationId &&
2871 elog(
ERROR,
"invalid non-zero objectSubId for object class %u",
2876 case RelationRelationId:
2880 case ProcedureRelationId:
2883 case TypeRelationId:
2886 case CastRelationId:
2889 case CollationRelationId:
2892 case ConstraintRelationId:
2895 case ConversionRelationId:
2898 case AttrDefaultRelationId:
2901 case LanguageRelationId:
2904 case LargeObjectRelationId:
2907 case OperatorRelationId:
2910 case OperatorClassRelationId:
2913 case OperatorFamilyRelationId:
2916 case AccessMethodRelationId:
2919 case AccessMethodOperatorRelationId:
2922 case AccessMethodProcedureRelationId:
2925 case RewriteRelationId:
2928 case TriggerRelationId:
2931 case NamespaceRelationId:
2934 case StatisticExtRelationId:
2937 case TSParserRelationId:
2940 case TSDictionaryRelationId:
2943 case TSTemplateRelationId:
2946 case TSConfigRelationId:
2949 case AuthIdRelationId:
2952 case DatabaseRelationId:
2955 case TableSpaceRelationId:
2958 case ForeignDataWrapperRelationId:
2961 case ForeignServerRelationId:
2964 case UserMappingRelationId:
2967 case DefaultAclRelationId:
2970 case ExtensionRelationId:
2973 case EventTriggerRelationId:
2976 case PolicyRelationId:
2979 case PublicationRelationId:
2982 case PublicationRelRelationId:
2985 case SubscriptionRelationId:
2988 case TransformRelationId:
3011 Anum_pg_init_privs_objoid,
3015 Anum_pg_init_privs_classoid,
3019 Anum_pg_init_privs_objsubid,
static void findDependentObjects(const ObjectAddress *object, int objflags, int flags, ObjectAddressStack *stack, ObjectAddresses *targetObjects, const ObjectAddresses *pendingObjects, Relation *depRel)
void RemoveTriggerById(Oid trigOid)
#define DEPFLAG_SUBOBJECT
Oid CurrentExtensionObject
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
static int object_address_comparator(const void *a, const void *b)
#define DEPFLAG_PARTITION
#define IsA(nodeptr, _type_)
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
void table_close(Relation relation, LOCKMODE lockmode)
int errhint(const char *fmt,...)
void systable_endscan(SysScanDesc sysscan)
void index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode)
static void add_exact_object_address_extra(const ObjectAddress *object, const ObjectAddressExtra *extra, ObjectAddresses *addrs)
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
void RemoveStatisticsById(Oid statsOid)
AttrNumber get_object_attnum_oid(Oid class_id)
static void deleteOneObject(const ObjectAddress *object, Relation *depRel, int32 flags)
#define RelationGetDescr(relation)
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
bool trackDroppedObjectsNeeded(void)
void sort_object_addresses(ObjectAddresses *addrs)
void RemoveExtensionById(Oid extId)
char get_rel_relkind(Oid relid)
#define DatumGetObjectId(X)
void recordDependencyOnCollations(ObjectAddress *myself, List *collations, bool record_version)
bool(* VisitDependenciesOfCB)(const ObjectAddress *otherObject, const char *version, char **new_version, void *data)
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
#define QTW_EXAMINE_SORTGROUP
#define PERFORM_DELETION_SKIP_ORIGINAL
void ReleaseDeletionLock(const ObjectAddress *object)
void DeleteSecurityLabel(const ObjectAddress *object)
Oid get_object_oid_index(Oid class_id)
int errcode(int sqlerrcode)
#define MemSet(start, val, len)
#define InitPrivsObjIndexId
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
void RemovePublicationRelById(Oid proid)
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
ObjectAddresses * new_object_addresses(void)
void free_object_addresses(ObjectAddresses *addrs)
void heap_freetuple(HeapTuple htup)
void RemoveTypeById(Oid typeOid)
ObjectClass getObjectClass(const ObjectAddress *object)
#define OidIsValid(objectId)
struct ObjectAddressStack * next
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
#define FirstNormalObjectId
bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
void RemoveOperatorById(Oid operOid)
#define PERFORM_DELETION_CONCURRENTLY
#define StaticAssertStmt(condition, errmessage)
HeapTuple systable_getnext(SysScanDesc sysscan)
#define SearchSysCacheExists1(cacheId, key1)
Oid get_typ_typrelid(Oid typid)
void pfree(void *pointer)
void appendStringInfo(StringInfo str, const char *fmt,...)
#define ObjectIdGetDatum(X)
static const Oid object_classes[]
void RemoveTSConfigurationById(Oid cfgId)
static void * list_nth(const List *list, int n)
int get_object_catcache_oid(Oid class_id)
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool reverse_self, bool record_version)
const ObjectAddress * object
bool message_level_is_interesting(int elevel)
void RemovePolicyById(Oid policy_id)
static bool object_address_present_add_flags(const ObjectAddress *object, int flags, ObjectAddresses *addrs)
struct ObjectAddressStack ObjectAddressStack
int errdetail(const char *fmt,...)
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
void RemoveAttributeById(Oid relid, AttrNumber attnum)
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
static void reportDependentObjects(const ObjectAddresses *targetObjects, DropBehavior behavior, int flags, const ObjectAddress *origObject)
int errdetail_log(const char *fmt,...)
FormData_pg_depend * Form_pg_depend
void DeleteSequenceTuple(Oid relid)
void visitDependenciesOf(const ObjectAddress *object, VisitDependenciesOfCB callback, void *userdata)
#define DependDependerIndexId
void RemoveAttrDefaultById(Oid attrdefId)
#define rt_fetch(rangetable_index, rangetable)
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior, bool record_version)
void LargeObjectDrop(Oid loid)
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
#define DependReferenceIndexId
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
bool EventTriggerSupportsObjectClass(ObjectClass objclass)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
#define heap_getattr(tup, attnum, tupleDesc, isnull)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
#define ngettext(s, p, n)
#define TextDatumGetCString(d)
void AcquireDeletionLock(const ObjectAddress *object, int flags)
void CommandCounterIncrement(void)
void ReleaseSysCache(HeapTuple tuple)
static void DropObjectById(const ObjectAddress *object)
#define ereport(elevel,...)
#define DEPFLAG_EXTENSION
List * lcons(void *datum, List *list)
int errmsg_internal(const char *fmt,...)
#define ShareUpdateExclusiveLock
#define HeapTupleIsValid(tuple)
#define Assert(condition)
#define PERFORM_DELETION_QUIETLY
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Oid exprType(const Node *expr)
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
static int list_length(const List *l)
void EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool normal)
static void doDeletion(const ObjectAddress *object, int flags)
void * repalloc(void *pointer, Size size)
#define InvalidAttrNumber
#define ObjectAddressSet(addr, class_id, object_id)
void RemoveFunctionById(Oid funcOid)
const char * get_object_class_descr(Oid class_id)
static Datum values[MAXATTR]
ObjectAddressExtra * extras
#define AccessExclusiveLock
List * GetTypeCollations(Oid typeoid)
int errmsg(const char *fmt,...)
void RemoveRewriteRuleById(Oid ruleOid)
#define PERFORM_DELETION_CONCURRENT_LOCK
static void DeleteInitPrivs(const ObjectAddress *object)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
#define CStringGetTextDatum(s)
static void deleteObjectsInList(ObjectAddresses *targetObjects, Relation *depRel, int flags)
void performMultipleDeletions(const ObjectAddresses *objects, DropBehavior behavior, int flags)
#define MAX_REPORTED_DEPS
#define qsort(a, b, c, d)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
static bool stack_address_present_add_flags(const ObjectAddress *object, int flags, ObjectAddressStack *stack)
Relation table_open(Oid relationId, LOCKMODE lockmode)
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Oid getBaseType(Oid typid)
#define PERFORM_DELETION_SKIP_EXTENSIONS
void heap_drop_with_catalog(Oid relid)
static void add_object_address(ObjectClass oclass, Oid objectId, int32 subId, ObjectAddresses *addrs)
void RemoveConstraintById(Oid conId)
#define InvokeObjectDropHookArg(classId, objectId, subId, dropflags)
#define BTEqualStrategyNumber
List * list_delete_first(List *list)
#define PERFORM_DELETION_INTERNAL
#define QTW_IGNORE_JOINALIASES