PostgreSQL Source Code  git master
dependency.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * dependency.c
4  * Routines to support inter-object dependencies.
5  *
6  *
7  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * IDENTIFICATION
11  * src/backend/catalog/dependency.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "access/genam.h"
18 #include "access/htup_details.h"
19 #include "access/table.h"
20 #include "access/xact.h"
21 #include "catalog/dependency.h"
22 #include "catalog/heap.h"
23 #include "catalog/index.h"
24 #include "catalog/objectaccess.h"
25 #include "catalog/pg_am.h"
26 #include "catalog/pg_amop.h"
27 #include "catalog/pg_amproc.h"
28 #include "catalog/pg_attrdef.h"
29 #include "catalog/pg_authid.h"
30 #include "catalog/pg_cast.h"
31 #include "catalog/pg_collation.h"
32 #include "catalog/pg_constraint.h"
33 #include "catalog/pg_conversion.h"
34 #include "catalog/pg_database.h"
35 #include "catalog/pg_default_acl.h"
36 #include "catalog/pg_depend.h"
38 #include "catalog/pg_extension.h"
41 #include "catalog/pg_init_privs.h"
42 #include "catalog/pg_language.h"
43 #include "catalog/pg_largeobject.h"
44 #include "catalog/pg_namespace.h"
45 #include "catalog/pg_opclass.h"
46 #include "catalog/pg_operator.h"
47 #include "catalog/pg_opfamily.h"
48 #include "catalog/pg_policy.h"
49 #include "catalog/pg_proc.h"
50 #include "catalog/pg_publication.h"
52 #include "catalog/pg_rewrite.h"
55 #include "catalog/pg_tablespace.h"
56 #include "catalog/pg_transform.h"
57 #include "catalog/pg_trigger.h"
58 #include "catalog/pg_ts_config.h"
59 #include "catalog/pg_ts_dict.h"
60 #include "catalog/pg_ts_parser.h"
61 #include "catalog/pg_ts_template.h"
62 #include "catalog/pg_type.h"
64 #include "commands/comment.h"
65 #include "commands/defrem.h"
66 #include "commands/event_trigger.h"
67 #include "commands/extension.h"
68 #include "commands/policy.h"
70 #include "commands/seclabel.h"
71 #include "commands/sequence.h"
72 #include "commands/trigger.h"
73 #include "commands/typecmds.h"
74 #include "nodes/nodeFuncs.h"
75 #include "parser/parsetree.h"
76 #include "rewrite/rewriteRemove.h"
77 #include "storage/lmgr.h"
78 #include "utils/acl.h"
79 #include "utils/builtins.h"
80 #include "utils/fmgroids.h"
81 #include "utils/guc.h"
82 #include "utils/lsyscache.h"
83 #include "utils/syscache.h"
84 
85 
86 /*
87  * Deletion processing requires additional state for each ObjectAddress that
88  * it's planning to delete. For simplicity and code-sharing we make the
89  * ObjectAddresses code support arrays with or without this extra state.
90  */
91 typedef struct
92 {
93  int flags; /* bitmask, see bit definitions below */
94  ObjectAddress dependee; /* object whose deletion forced this one */
96 
97 /* ObjectAddressExtra flag bits */
98 #define DEPFLAG_ORIGINAL 0x0001 /* an original deletion target */
99 #define DEPFLAG_NORMAL 0x0002 /* reached via normal dependency */
100 #define DEPFLAG_AUTO 0x0004 /* reached via auto dependency */
101 #define DEPFLAG_INTERNAL 0x0008 /* reached via internal dependency */
102 #define DEPFLAG_PARTITION 0x0010 /* reached via partition dependency */
103 #define DEPFLAG_EXTENSION 0x0020 /* reached via extension dependency */
104 #define DEPFLAG_REVERSE 0x0040 /* reverse internal/extension link */
105 #define DEPFLAG_IS_PART 0x0080 /* has a partition dependency */
106 #define DEPFLAG_SUBOBJECT 0x0100 /* subobject of another deletable object */
107 
108 
109 /* expansible list of ObjectAddresses */
111 {
112  ObjectAddress *refs; /* => palloc'd array */
113  ObjectAddressExtra *extras; /* => palloc'd array, or NULL if not used */
114  int numrefs; /* current number of references */
115  int maxrefs; /* current size of palloc'd array(s) */
116 };
117 
118 /* typedef ObjectAddresses appears in dependency.h */
119 
120 /* threaded list of ObjectAddresses, for recursion detection */
121 typedef struct ObjectAddressStack
122 {
123  const ObjectAddress *object; /* object being visited */
124  int flags; /* its current flag bits */
125  struct ObjectAddressStack *next; /* next outer stack level */
127 
128 /* temporary storage in findDependentObjects */
129 typedef struct
130 {
131  ObjectAddress obj; /* object to be deleted --- MUST BE FIRST */
132  int subflags; /* flags to pass down when recursing to obj */
134 
135 /* for find_expr_references_walker */
136 typedef struct
137 {
138  ObjectAddresses *addrs; /* addresses being accumulated */
139  List *rtables; /* list of rangetables to resolve Vars */
141 
142 /*
143  * This constant table maps ObjectClasses to the corresponding catalog OIDs.
144  * See also getObjectClass().
145  */
146 static const Oid object_classes[] = {
147  RelationRelationId, /* OCLASS_CLASS */
148  ProcedureRelationId, /* OCLASS_PROC */
149  TypeRelationId, /* OCLASS_TYPE */
150  CastRelationId, /* OCLASS_CAST */
151  CollationRelationId, /* OCLASS_COLLATION */
152  ConstraintRelationId, /* OCLASS_CONSTRAINT */
153  ConversionRelationId, /* OCLASS_CONVERSION */
154  AttrDefaultRelationId, /* OCLASS_DEFAULT */
155  LanguageRelationId, /* OCLASS_LANGUAGE */
156  LargeObjectRelationId, /* OCLASS_LARGEOBJECT */
157  OperatorRelationId, /* OCLASS_OPERATOR */
158  OperatorClassRelationId, /* OCLASS_OPCLASS */
159  OperatorFamilyRelationId, /* OCLASS_OPFAMILY */
160  AccessMethodRelationId, /* OCLASS_AM */
161  AccessMethodOperatorRelationId, /* OCLASS_AMOP */
162  AccessMethodProcedureRelationId, /* OCLASS_AMPROC */
163  RewriteRelationId, /* OCLASS_REWRITE */
164  TriggerRelationId, /* OCLASS_TRIGGER */
165  NamespaceRelationId, /* OCLASS_SCHEMA */
166  StatisticExtRelationId, /* OCLASS_STATISTIC_EXT */
167  TSParserRelationId, /* OCLASS_TSPARSER */
168  TSDictionaryRelationId, /* OCLASS_TSDICT */
169  TSTemplateRelationId, /* OCLASS_TSTEMPLATE */
170  TSConfigRelationId, /* OCLASS_TSCONFIG */
171  AuthIdRelationId, /* OCLASS_ROLE */
172  DatabaseRelationId, /* OCLASS_DATABASE */
173  TableSpaceRelationId, /* OCLASS_TBLSPACE */
174  ForeignDataWrapperRelationId, /* OCLASS_FDW */
175  ForeignServerRelationId, /* OCLASS_FOREIGN_SERVER */
176  UserMappingRelationId, /* OCLASS_USER_MAPPING */
177  DefaultAclRelationId, /* OCLASS_DEFACL */
178  ExtensionRelationId, /* OCLASS_EXTENSION */
179  EventTriggerRelationId, /* OCLASS_EVENT_TRIGGER */
180  PolicyRelationId, /* OCLASS_POLICY */
181  PublicationRelationId, /* OCLASS_PUBLICATION */
182  PublicationRelRelationId, /* OCLASS_PUBLICATION_REL */
183  SubscriptionRelationId, /* OCLASS_SUBSCRIPTION */
184  TransformRelationId /* OCLASS_TRANSFORM */
185 };
186 
187 
188 static void findDependentObjects(const ObjectAddress *object,
189  int objflags,
190  int flags,
191  ObjectAddressStack *stack,
192  ObjectAddresses *targetObjects,
193  const ObjectAddresses *pendingObjects,
194  Relation *depRel);
195 static void reportDependentObjects(const ObjectAddresses *targetObjects,
196  DropBehavior behavior,
197  int flags,
198  const ObjectAddress *origObject);
199 static void deleteOneObject(const ObjectAddress *object,
200  Relation *depRel, int32 flags);
201 static void doDeletion(const ObjectAddress *object, int flags);
202 static bool find_expr_references_walker(Node *node,
205 static int object_address_comparator(const void *a, const void *b);
206 static void add_object_address(ObjectClass oclass, Oid objectId, int32 subId,
207  ObjectAddresses *addrs);
208 static void add_exact_object_address_extra(const ObjectAddress *object,
209  const ObjectAddressExtra *extra,
210  ObjectAddresses *addrs);
211 static bool object_address_present_add_flags(const ObjectAddress *object,
212  int flags,
213  ObjectAddresses *addrs);
214 static bool stack_address_present_add_flags(const ObjectAddress *object,
215  int flags,
216  ObjectAddressStack *stack);
217 static void DeleteInitPrivs(const ObjectAddress *object);
218 
219 
220 /*
221  * Go through the objects given running the final actions on them, and execute
222  * the actual deletion.
223  */
224 static void
226  int flags)
227 {
228  int i;
229 
230  /*
231  * Keep track of objects for event triggers, if necessary.
232  */
234  {
235  for (i = 0; i < targetObjects->numrefs; i++)
236  {
237  const ObjectAddress *thisobj = &targetObjects->refs[i];
238  const ObjectAddressExtra *extra = &targetObjects->extras[i];
239  bool original = false;
240  bool normal = false;
241 
242  if (extra->flags & DEPFLAG_ORIGINAL)
243  original = true;
244  if (extra->flags & DEPFLAG_NORMAL)
245  normal = true;
246  if (extra->flags & DEPFLAG_REVERSE)
247  normal = true;
248 
250  {
251  EventTriggerSQLDropAddObject(thisobj, original, normal);
252  }
253  }
254  }
255 
256  /*
257  * Delete all the objects in the proper order, except that if told to, we
258  * should skip the original object(s).
259  */
260  for (i = 0; i < targetObjects->numrefs; i++)
261  {
262  ObjectAddress *thisobj = targetObjects->refs + i;
263  ObjectAddressExtra *thisextra = targetObjects->extras + i;
264 
265  if ((flags & PERFORM_DELETION_SKIP_ORIGINAL) &&
266  (thisextra->flags & DEPFLAG_ORIGINAL))
267  continue;
268 
269  deleteOneObject(thisobj, depRel, flags);
270  }
271 }
272 
273 /*
274  * performDeletion: attempt to drop the specified object. If CASCADE
275  * behavior is specified, also drop any dependent objects (recursively).
276  * If RESTRICT behavior is specified, error out if there are any dependent
277  * objects, except for those that should be implicitly dropped anyway
278  * according to the dependency type.
279  *
280  * This is the outer control routine for all forms of DROP that drop objects
281  * that can participate in dependencies. Note that performMultipleDeletions
282  * is a variant on the same theme; if you change anything here you'll likely
283  * need to fix that too.
284  *
285  * Bits in the flags argument can include:
286  *
287  * PERFORM_DELETION_INTERNAL: indicates that the drop operation is not the
288  * direct result of a user-initiated action. For example, when a temporary
289  * schema is cleaned out so that a new backend can use it, or when a column
290  * default is dropped as an intermediate step while adding a new one, that's
291  * an internal operation. On the other hand, when we drop something because
292  * the user issued a DROP statement against it, that's not internal. Currently
293  * this suppresses calling event triggers and making some permissions checks.
294  *
295  * PERFORM_DELETION_CONCURRENTLY: perform the drop concurrently. This does
296  * not currently work for anything except dropping indexes; don't set it for
297  * other object types or you may get strange results.
298  *
299  * PERFORM_DELETION_QUIETLY: reduce message level from NOTICE to DEBUG2.
300  *
301  * PERFORM_DELETION_SKIP_ORIGINAL: do not delete the specified object(s),
302  * but only what depends on it/them.
303  *
304  * PERFORM_DELETION_SKIP_EXTENSIONS: do not delete extensions, even when
305  * deleting objects that are part of an extension. This should generally
306  * be used only when dropping temporary objects.
307  *
308  * PERFORM_DELETION_CONCURRENT_LOCK: perform the drop normally but with a lock
309  * as if it were concurrent. This is used by REINDEX CONCURRENTLY.
310  *
311  */
312 void
314  DropBehavior behavior, int flags)
315 {
316  Relation depRel;
317  ObjectAddresses *targetObjects;
318 
319  /*
320  * We save some cycles by opening pg_depend just once and passing the
321  * Relation pointer down to all the recursive deletion steps.
322  */
323  depRel = table_open(DependRelationId, RowExclusiveLock);
324 
325  /*
326  * Acquire deletion lock on the target object. (Ideally the caller has
327  * done this already, but many places are sloppy about it.)
328  */
329  AcquireDeletionLock(object, 0);
330 
331  /*
332  * Construct a list of objects to delete (ie, the given object plus
333  * everything directly or indirectly dependent on it).
334  */
335  targetObjects = new_object_addresses();
336 
337  findDependentObjects(object,
339  flags,
340  NULL, /* empty stack */
341  targetObjects,
342  NULL, /* no pendingObjects */
343  &depRel);
344 
345  /*
346  * Check if deletion is allowed, and report about cascaded deletes.
347  */
348  reportDependentObjects(targetObjects,
349  behavior,
350  flags,
351  object);
352 
353  /* do the deed */
354  deleteObjectsInList(targetObjects, &depRel, flags);
355 
356  /* And clean up */
357  free_object_addresses(targetObjects);
358 
359  table_close(depRel, RowExclusiveLock);
360 }
361 
362 /*
363  * performMultipleDeletions: Similar to performDeletion, but act on multiple
364  * objects at once.
365  *
366  * The main difference from issuing multiple performDeletion calls is that the
367  * list of objects that would be implicitly dropped, for each object to be
368  * dropped, is the union of the implicit-object list for all objects. This
369  * makes each check be more relaxed.
370  */
371 void
373  DropBehavior behavior, int flags)
374 {
375  Relation depRel;
376  ObjectAddresses *targetObjects;
377  int i;
378 
379  /* No work if no objects... */
380  if (objects->numrefs <= 0)
381  return;
382 
383  /*
384  * We save some cycles by opening pg_depend just once and passing the
385  * Relation pointer down to all the recursive deletion steps.
386  */
387  depRel = table_open(DependRelationId, RowExclusiveLock);
388 
389  /*
390  * Construct a list of objects to delete (ie, the given objects plus
391  * everything directly or indirectly dependent on them). Note that
392  * because we pass the whole objects list as pendingObjects context, we
393  * won't get a failure from trying to delete an object that is internally
394  * dependent on another one in the list; we'll just skip that object and
395  * delete it when we reach its owner.
396  */
397  targetObjects = new_object_addresses();
398 
399  for (i = 0; i < objects->numrefs; i++)
400  {
401  const ObjectAddress *thisobj = objects->refs + i;
402 
403  /*
404  * Acquire deletion lock on each target object. (Ideally the caller
405  * has done this already, but many places are sloppy about it.)
406  */
407  AcquireDeletionLock(thisobj, flags);
408 
409  findDependentObjects(thisobj,
411  flags,
412  NULL, /* empty stack */
413  targetObjects,
414  objects,
415  &depRel);
416  }
417 
418  /*
419  * Check if deletion is allowed, and report about cascaded deletes.
420  *
421  * If there's exactly one object being deleted, report it the same way as
422  * in performDeletion(), else we have to be vaguer.
423  */
424  reportDependentObjects(targetObjects,
425  behavior,
426  flags,
427  (objects->numrefs == 1 ? objects->refs : NULL));
428 
429  /* do the deed */
430  deleteObjectsInList(targetObjects, &depRel, flags);
431 
432  /* And clean up */
433  free_object_addresses(targetObjects);
434 
435  table_close(depRel, RowExclusiveLock);
436 }
437 
438 /*
439  * Call a function for all objects that 'object' depend on. If the function
440  * returns true, refobjversion will be updated in the catalog.
441  */
442 void
445  void *userdata)
446 {
447  Relation depRel;
448  ScanKeyData key[3];
449  SysScanDesc scan;
450  HeapTuple tup;
451  ObjectAddress otherObject;
452 
453  ScanKeyInit(&key[0],
454  Anum_pg_depend_classid,
455  BTEqualStrategyNumber, F_OIDEQ,
456  ObjectIdGetDatum(object->classId));
457  ScanKeyInit(&key[1],
458  Anum_pg_depend_objid,
459  BTEqualStrategyNumber, F_OIDEQ,
460  ObjectIdGetDatum(object->objectId));
461  ScanKeyInit(&key[2],
462  Anum_pg_depend_objsubid,
463  BTEqualStrategyNumber, F_INT4EQ,
464  Int32GetDatum(object->objectSubId));
465 
466  depRel = table_open(DependRelationId, RowExclusiveLock);
467  scan = systable_beginscan(depRel, DependDependerIndexId, true,
468  NULL, 3, key);
469 
470  while (HeapTupleIsValid(tup = systable_getnext(scan)))
471  {
472  Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
473  char *new_version;
474  Datum depversion;
475  bool isnull;
476 
477  otherObject.classId = foundDep->refclassid;
478  otherObject.objectId = foundDep->refobjid;
479  otherObject.objectSubId = foundDep->refobjsubid;
480 
481  depversion = heap_getattr(tup, Anum_pg_depend_refobjversion,
482  RelationGetDescr(depRel), &isnull);
483 
484  /* Does the callback want to update the version? */
485  if (callback(&otherObject,
486  isnull ? NULL : TextDatumGetCString(depversion),
487  &new_version,
488  userdata))
489  {
490  Datum values[Natts_pg_depend];
491  bool nulls[Natts_pg_depend];
492  bool replaces[Natts_pg_depend];
493 
494  memset(values, 0, sizeof(values));
495  memset(nulls, false, sizeof(nulls));
496  memset(replaces, false, sizeof(replaces));
497 
498  if (new_version)
499  values[Anum_pg_depend_refobjversion - 1] =
500  CStringGetTextDatum(new_version);
501  else
502  nulls[Anum_pg_depend_refobjversion - 1] = true;
503  replaces[Anum_pg_depend_refobjversion - 1] = true;
504 
505  tup = heap_modify_tuple(tup, RelationGetDescr(depRel), values,
506  nulls, replaces);
507  CatalogTupleUpdate(depRel, &tup->t_self, tup);
508 
509  heap_freetuple(tup);
510  }
511  }
512  systable_endscan(scan);
513  table_close(depRel, RowExclusiveLock);
514 }
515 
516 /*
517  * findDependentObjects - find all objects that depend on 'object'
518  *
519  * For every object that depends on the starting object, acquire a deletion
520  * lock on the object, add it to targetObjects (if not already there),
521  * and recursively find objects that depend on it. An object's dependencies
522  * will be placed into targetObjects before the object itself; this means
523  * that the finished list's order represents a safe deletion order.
524  *
525  * The caller must already have a deletion lock on 'object' itself,
526  * but must not have added it to targetObjects. (Note: there are corner
527  * cases where we won't add the object either, and will also release the
528  * caller-taken lock. This is a bit ugly, but the API is set up this way
529  * to allow easy rechecking of an object's liveness after we lock it. See
530  * notes within the function.)
531  *
532  * When dropping a whole object (subId = 0), we find dependencies for
533  * its sub-objects too.
534  *
535  * object: the object to add to targetObjects and find dependencies on
536  * objflags: flags to be ORed into the object's targetObjects entry
537  * flags: PERFORM_DELETION_xxx flags for the deletion operation as a whole
538  * stack: list of objects being visited in current recursion; topmost item
539  * is the object that we recursed from (NULL for external callers)
540  * targetObjects: list of objects that are scheduled to be deleted
541  * pendingObjects: list of other objects slated for destruction, but
542  * not necessarily in targetObjects yet (can be NULL if none)
543  * *depRel: already opened pg_depend relation
544  *
545  * Note: objflags describes the reason for visiting this particular object
546  * at this time, and is not passed down when recursing. The flags argument
547  * is passed down, since it describes what we're doing overall.
548  */
549 static void
551  int objflags,
552  int flags,
553  ObjectAddressStack *stack,
554  ObjectAddresses *targetObjects,
555  const ObjectAddresses *pendingObjects,
556  Relation *depRel)
557 {
558  ScanKeyData key[3];
559  int nkeys;
560  SysScanDesc scan;
561  HeapTuple tup;
562  ObjectAddress otherObject;
563  ObjectAddress owningObject;
564  ObjectAddress partitionObject;
565  ObjectAddressAndFlags *dependentObjects;
566  int numDependentObjects;
567  int maxDependentObjects;
568  ObjectAddressStack mystack;
569  ObjectAddressExtra extra;
570 
571  /*
572  * If the target object is already being visited in an outer recursion
573  * level, just report the current objflags back to that level and exit.
574  * This is needed to avoid infinite recursion in the face of circular
575  * dependencies.
576  *
577  * The stack check alone would result in dependency loops being broken at
578  * an arbitrary point, ie, the first member object of the loop to be
579  * visited is the last one to be deleted. This is obviously unworkable.
580  * However, the check for internal dependency below guarantees that we
581  * will not break a loop at an internal dependency: if we enter the loop
582  * at an "owned" object we will switch and start at the "owning" object
583  * instead. We could probably hack something up to avoid breaking at an
584  * auto dependency, too, if we had to. However there are no known cases
585  * where that would be necessary.
586  */
587  if (stack_address_present_add_flags(object, objflags, stack))
588  return;
589 
590  /*
591  * It's also possible that the target object has already been completely
592  * processed and put into targetObjects. If so, again we just add the
593  * specified objflags to its entry and return.
594  *
595  * (Note: in these early-exit cases we could release the caller-taken
596  * lock, since the object is presumably now locked multiple times; but it
597  * seems not worth the cycles.)
598  */
599  if (object_address_present_add_flags(object, objflags, targetObjects))
600  return;
601 
602  /*
603  * The target object might be internally dependent on some other object
604  * (its "owner"), and/or be a member of an extension (also considered its
605  * owner). If so, and if we aren't recursing from the owning object, we
606  * have to transform this deletion request into a deletion request of the
607  * owning object. (We'll eventually recurse back to this object, but the
608  * owning object has to be visited first so it will be deleted after.) The
609  * way to find out about this is to scan the pg_depend entries that show
610  * what this object depends on.
611  */
612  ScanKeyInit(&key[0],
613  Anum_pg_depend_classid,
614  BTEqualStrategyNumber, F_OIDEQ,
615  ObjectIdGetDatum(object->classId));
616  ScanKeyInit(&key[1],
617  Anum_pg_depend_objid,
618  BTEqualStrategyNumber, F_OIDEQ,
619  ObjectIdGetDatum(object->objectId));
620  if (object->objectSubId != 0)
621  {
622  /* Consider only dependencies of this sub-object */
623  ScanKeyInit(&key[2],
624  Anum_pg_depend_objsubid,
625  BTEqualStrategyNumber, F_INT4EQ,
626  Int32GetDatum(object->objectSubId));
627  nkeys = 3;
628  }
629  else
630  {
631  /* Consider dependencies of this object and any sub-objects it has */
632  nkeys = 2;
633  }
634 
635  scan = systable_beginscan(*depRel, DependDependerIndexId, true,
636  NULL, nkeys, key);
637 
638  /* initialize variables that loop may fill */
639  memset(&owningObject, 0, sizeof(owningObject));
640  memset(&partitionObject, 0, sizeof(partitionObject));
641 
642  while (HeapTupleIsValid(tup = systable_getnext(scan)))
643  {
644  Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
645 
646  otherObject.classId = foundDep->refclassid;
647  otherObject.objectId = foundDep->refobjid;
648  otherObject.objectSubId = foundDep->refobjsubid;
649 
650  /*
651  * When scanning dependencies of a whole object, we may find rows
652  * linking sub-objects of the object to the object itself. (Normally,
653  * such a dependency is implicit, but we must make explicit ones in
654  * some cases involving partitioning.) We must ignore such rows to
655  * avoid infinite recursion.
656  */
657  if (otherObject.classId == object->classId &&
658  otherObject.objectId == object->objectId &&
659  object->objectSubId == 0)
660  continue;
661 
662  switch (foundDep->deptype)
663  {
664  case DEPENDENCY_NORMAL:
665  case DEPENDENCY_AUTO:
667  /* no problem */
668  break;
669 
671 
672  /*
673  * If told to, ignore EXTENSION dependencies altogether. This
674  * flag is normally used to prevent dropping extensions during
675  * temporary-object cleanup, even if a temp object was created
676  * during an extension script.
677  */
679  break;
680 
681  /*
682  * If the other object is the extension currently being
683  * created/altered, ignore this dependency and continue with
684  * the deletion. This allows dropping of an extension's
685  * objects within the extension's scripts, as well as corner
686  * cases such as dropping a transient object created within
687  * such a script.
688  */
689  if (creating_extension &&
690  otherObject.classId == ExtensionRelationId &&
691  otherObject.objectId == CurrentExtensionObject)
692  break;
693 
694  /* Otherwise, treat this like an internal dependency */
695  /* FALL THRU */
696 
697  case DEPENDENCY_INTERNAL:
698 
699  /*
700  * This object is part of the internal implementation of
701  * another object, or is part of the extension that is the
702  * other object. We have three cases:
703  *
704  * 1. At the outermost recursion level, we must disallow the
705  * DROP. However, if the owning object is listed in
706  * pendingObjects, just release the caller's lock and return;
707  * we'll eventually complete the DROP when we reach that entry
708  * in the pending list.
709  *
710  * Note: the above statement is true only if this pg_depend
711  * entry still exists by then; in principle, therefore, we
712  * could miss deleting an item the user told us to delete.
713  * However, no inconsistency can result: since we're at outer
714  * level, there is no object depending on this one.
715  */
716  if (stack == NULL)
717  {
718  if (pendingObjects &&
719  object_address_present(&otherObject, pendingObjects))
720  {
721  systable_endscan(scan);
722  /* need to release caller's lock; see notes below */
723  ReleaseDeletionLock(object);
724  return;
725  }
726 
727  /*
728  * We postpone actually issuing the error message until
729  * after this loop, so that we can make the behavior
730  * independent of the ordering of pg_depend entries, at
731  * least if there's not more than one INTERNAL and one
732  * EXTENSION dependency. (If there's more, we'll complain
733  * about a random one of them.) Prefer to complain about
734  * EXTENSION, since that's generally a more important
735  * dependency.
736  */
737  if (!OidIsValid(owningObject.classId) ||
738  foundDep->deptype == DEPENDENCY_EXTENSION)
739  owningObject = otherObject;
740  break;
741  }
742 
743  /*
744  * 2. When recursing from the other end of this dependency,
745  * it's okay to continue with the deletion. This holds when
746  * recursing from a whole object that includes the nominal
747  * other end as a component, too. Since there can be more
748  * than one "owning" object, we have to allow matches that are
749  * more than one level down in the stack.
750  */
751  if (stack_address_present_add_flags(&otherObject, 0, stack))
752  break;
753 
754  /*
755  * 3. Not all the owning objects have been visited, so
756  * transform this deletion request into a delete of this
757  * owning object.
758  *
759  * First, release caller's lock on this object and get
760  * deletion lock on the owning object. (We must release
761  * caller's lock to avoid deadlock against a concurrent
762  * deletion of the owning object.)
763  */
764  ReleaseDeletionLock(object);
765  AcquireDeletionLock(&otherObject, 0);
766 
767  /*
768  * The owning object might have been deleted while we waited
769  * to lock it; if so, neither it nor the current object are
770  * interesting anymore. We test this by checking the
771  * pg_depend entry (see notes below).
772  */
773  if (!systable_recheck_tuple(scan, tup))
774  {
775  systable_endscan(scan);
776  ReleaseDeletionLock(&otherObject);
777  return;
778  }
779 
780  /*
781  * One way or the other, we're done with the scan; might as
782  * well close it down before recursing, to reduce peak
783  * resource consumption.
784  */
785  systable_endscan(scan);
786 
787  /*
788  * Okay, recurse to the owning object instead of proceeding.
789  *
790  * We do not need to stack the current object; we want the
791  * traversal order to be as if the original reference had
792  * linked to the owning object instead of this one.
793  *
794  * The dependency type is a "reverse" dependency: we need to
795  * delete the owning object if this one is to be deleted, but
796  * this linkage is never a reason for an automatic deletion.
797  */
798  findDependentObjects(&otherObject,
800  flags,
801  stack,
802  targetObjects,
803  pendingObjects,
804  depRel);
805 
806  /*
807  * The current target object should have been added to
808  * targetObjects while processing the owning object; but it
809  * probably got only the flag bits associated with the
810  * dependency we're looking at. We need to add the objflags
811  * that were passed to this recursion level, too, else we may
812  * get a bogus failure in reportDependentObjects (if, for
813  * example, we were called due to a partition dependency).
814  *
815  * If somehow the current object didn't get scheduled for
816  * deletion, bleat. (That would imply that somebody deleted
817  * this dependency record before the recursion got to it.)
818  * Another idea would be to reacquire lock on the current
819  * object and resume trying to delete it, but it seems not
820  * worth dealing with the race conditions inherent in that.
821  */
822  if (!object_address_present_add_flags(object, objflags,
823  targetObjects))
824  elog(ERROR, "deletion of owning object %s failed to delete %s",
825  getObjectDescription(&otherObject, false),
826  getObjectDescription(object, false));
827 
828  /* And we're done here. */
829  return;
830 
832 
833  /*
834  * Remember that this object has a partition-type dependency.
835  * After the dependency scan, we'll complain if we didn't find
836  * a reason to delete one of its partition dependencies.
837  */
838  objflags |= DEPFLAG_IS_PART;
839 
840  /*
841  * Also remember the primary partition owner, for error
842  * messages. If there are multiple primary owners (which
843  * there should not be), we'll report a random one of them.
844  */
845  partitionObject = otherObject;
846  break;
847 
849 
850  /*
851  * Only use secondary partition owners in error messages if we
852  * find no primary owner (which probably shouldn't happen).
853  */
854  if (!(objflags & DEPFLAG_IS_PART))
855  partitionObject = otherObject;
856 
857  /*
858  * Remember that this object has a partition-type dependency.
859  * After the dependency scan, we'll complain if we didn't find
860  * a reason to delete one of its partition dependencies.
861  */
862  objflags |= DEPFLAG_IS_PART;
863  break;
864 
865  case DEPENDENCY_PIN:
866 
867  /*
868  * Should not happen; PIN dependencies should have zeroes in
869  * the depender fields...
870  */
871  elog(ERROR, "incorrect use of PIN dependency with %s",
872  getObjectDescription(object, false));
873  break;
874  default:
875  elog(ERROR, "unrecognized dependency type '%c' for %s",
876  foundDep->deptype, getObjectDescription(object, false));
877  break;
878  }
879  }
880 
881  systable_endscan(scan);
882 
883  /*
884  * If we found an INTERNAL or EXTENSION dependency when we're at outer
885  * level, complain about it now. If we also found a PARTITION dependency,
886  * we prefer to report the PARTITION dependency. This is arbitrary but
887  * seems to be more useful in practice.
888  */
889  if (OidIsValid(owningObject.classId))
890  {
891  char *otherObjDesc;
892 
893  if (OidIsValid(partitionObject.classId))
894  otherObjDesc = getObjectDescription(&partitionObject, false);
895  else
896  otherObjDesc = getObjectDescription(&owningObject, false);
897 
898  ereport(ERROR,
899  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
900  errmsg("cannot drop %s because %s requires it",
901  getObjectDescription(object, false), otherObjDesc),
902  errhint("You can drop %s instead.", otherObjDesc)));
903  }
904 
905  /*
906  * Next, identify all objects that directly depend on the current object.
907  * To ensure predictable deletion order, we collect them up in
908  * dependentObjects and sort the list before actually recursing. (The
909  * deletion order would be valid in any case, but doing this ensures
910  * consistent output from DROP CASCADE commands, which is helpful for
911  * regression testing.)
912  */
913  maxDependentObjects = 128; /* arbitrary initial allocation */
914  dependentObjects = (ObjectAddressAndFlags *)
915  palloc(maxDependentObjects * sizeof(ObjectAddressAndFlags));
916  numDependentObjects = 0;
917 
918  ScanKeyInit(&key[0],
919  Anum_pg_depend_refclassid,
920  BTEqualStrategyNumber, F_OIDEQ,
921  ObjectIdGetDatum(object->classId));
922  ScanKeyInit(&key[1],
923  Anum_pg_depend_refobjid,
924  BTEqualStrategyNumber, F_OIDEQ,
925  ObjectIdGetDatum(object->objectId));
926  if (object->objectSubId != 0)
927  {
928  ScanKeyInit(&key[2],
929  Anum_pg_depend_refobjsubid,
930  BTEqualStrategyNumber, F_INT4EQ,
931  Int32GetDatum(object->objectSubId));
932  nkeys = 3;
933  }
934  else
935  nkeys = 2;
936 
937  scan = systable_beginscan(*depRel, DependReferenceIndexId, true,
938  NULL, nkeys, key);
939 
940  while (HeapTupleIsValid(tup = systable_getnext(scan)))
941  {
942  Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
943  int subflags;
944 
945  otherObject.classId = foundDep->classid;
946  otherObject.objectId = foundDep->objid;
947  otherObject.objectSubId = foundDep->objsubid;
948 
949  /*
950  * If what we found is a sub-object of the current object, just ignore
951  * it. (Normally, such a dependency is implicit, but we must make
952  * explicit ones in some cases involving partitioning.)
953  */
954  if (otherObject.classId == object->classId &&
955  otherObject.objectId == object->objectId &&
956  object->objectSubId == 0)
957  continue;
958 
959  /*
960  * Must lock the dependent object before recursing to it.
961  */
962  AcquireDeletionLock(&otherObject, 0);
963 
964  /*
965  * The dependent object might have been deleted while we waited to
966  * lock it; if so, we don't need to do anything more with it. We can
967  * test this cheaply and independently of the object's type by seeing
968  * if the pg_depend tuple we are looking at is still live. (If the
969  * object got deleted, the tuple would have been deleted too.)
970  */
971  if (!systable_recheck_tuple(scan, tup))
972  {
973  /* release the now-useless lock */
974  ReleaseDeletionLock(&otherObject);
975  /* and continue scanning for dependencies */
976  continue;
977  }
978 
979  /*
980  * We do need to delete it, so identify objflags to be passed down,
981  * which depend on the dependency type.
982  */
983  switch (foundDep->deptype)
984  {
985  case DEPENDENCY_NORMAL:
986  subflags = DEPFLAG_NORMAL;
987  break;
988  case DEPENDENCY_AUTO:
990  subflags = DEPFLAG_AUTO;
991  break;
992  case DEPENDENCY_INTERNAL:
993  subflags = DEPFLAG_INTERNAL;
994  break;
997  subflags = DEPFLAG_PARTITION;
998  break;
1000  subflags = DEPFLAG_EXTENSION;
1001  break;
1002  case DEPENDENCY_PIN:
1003 
1004  /*
1005  * For a PIN dependency we just ereport immediately; there
1006  * won't be any others to report.
1007  */
1008  ereport(ERROR,
1009  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1010  errmsg("cannot drop %s because it is required by the database system",
1011  getObjectDescription(object, false))));
1012  subflags = 0; /* keep compiler quiet */
1013  break;
1014  default:
1015  elog(ERROR, "unrecognized dependency type '%c' for %s",
1016  foundDep->deptype, getObjectDescription(object, false));
1017  subflags = 0; /* keep compiler quiet */
1018  break;
1019  }
1020 
1021  /* And add it to the pending-objects list */
1022  if (numDependentObjects >= maxDependentObjects)
1023  {
1024  /* enlarge array if needed */
1025  maxDependentObjects *= 2;
1026  dependentObjects = (ObjectAddressAndFlags *)
1027  repalloc(dependentObjects,
1028  maxDependentObjects * sizeof(ObjectAddressAndFlags));
1029  }
1030 
1031  dependentObjects[numDependentObjects].obj = otherObject;
1032  dependentObjects[numDependentObjects].subflags = subflags;
1033  numDependentObjects++;
1034  }
1035 
1036  systable_endscan(scan);
1037 
1038  /*
1039  * Now we can sort the dependent objects into a stable visitation order.
1040  * It's safe to use object_address_comparator here since the obj field is
1041  * first within ObjectAddressAndFlags.
1042  */
1043  if (numDependentObjects > 1)
1044  qsort((void *) dependentObjects, numDependentObjects,
1045  sizeof(ObjectAddressAndFlags),
1047 
1048  /*
1049  * Now recurse to the dependent objects. We must visit them first since
1050  * they have to be deleted before the current object.
1051  */
1052  mystack.object = object; /* set up a new stack level */
1053  mystack.flags = objflags;
1054  mystack.next = stack;
1055 
1056  for (int i = 0; i < numDependentObjects; i++)
1057  {
1058  ObjectAddressAndFlags *depObj = dependentObjects + i;
1059 
1060  findDependentObjects(&depObj->obj,
1061  depObj->subflags,
1062  flags,
1063  &mystack,
1064  targetObjects,
1065  pendingObjects,
1066  depRel);
1067  }
1068 
1069  pfree(dependentObjects);
1070 
1071  /*
1072  * Finally, we can add the target object to targetObjects. Be careful to
1073  * include any flags that were passed back down to us from inner recursion
1074  * levels. Record the "dependee" as being either the most important
1075  * partition owner if there is one, else the object we recursed from, if
1076  * any. (The logic in reportDependentObjects() is such that it can only
1077  * need one of those objects.)
1078  */
1079  extra.flags = mystack.flags;
1080  if (extra.flags & DEPFLAG_IS_PART)
1081  extra.dependee = partitionObject;
1082  else if (stack)
1083  extra.dependee = *stack->object;
1084  else
1085  memset(&extra.dependee, 0, sizeof(extra.dependee));
1086  add_exact_object_address_extra(object, &extra, targetObjects);
1087 }
1088 
1089 /*
1090  * reportDependentObjects - report about dependencies, and fail if RESTRICT
1091  *
1092  * Tell the user about dependent objects that we are going to delete
1093  * (or would need to delete, but are prevented by RESTRICT mode);
1094  * then error out if there are any and it's not CASCADE mode.
1095  *
1096  * targetObjects: list of objects that are scheduled to be deleted
1097  * behavior: RESTRICT or CASCADE
1098  * flags: other flags for the deletion operation
1099  * origObject: base object of deletion, or NULL if not available
1100  * (the latter case occurs in DROP OWNED)
1101  */
1102 static void
1104  DropBehavior behavior,
1105  int flags,
1106  const ObjectAddress *origObject)
1107 {
1108  int msglevel = (flags & PERFORM_DELETION_QUIETLY) ? DEBUG2 : NOTICE;
1109  bool ok = true;
1110  StringInfoData clientdetail;
1111  StringInfoData logdetail;
1112  int numReportedClient = 0;
1113  int numNotReportedClient = 0;
1114  int i;
1115 
1116  /*
1117  * If we need to delete any partition-dependent objects, make sure that
1118  * we're deleting at least one of their partition dependencies, too. That
1119  * can be detected by checking that we reached them by a PARTITION
1120  * dependency at some point.
1121  *
1122  * We just report the first such object, as in most cases the only way to
1123  * trigger this complaint is to explicitly try to delete one partition of
1124  * a partitioned object.
1125  */
1126  for (i = 0; i < targetObjects->numrefs; i++)
1127  {
1128  const ObjectAddressExtra *extra = &targetObjects->extras[i];
1129 
1130  if ((extra->flags & DEPFLAG_IS_PART) &&
1131  !(extra->flags & DEPFLAG_PARTITION))
1132  {
1133  const ObjectAddress *object = &targetObjects->refs[i];
1134  char *otherObjDesc = getObjectDescription(&extra->dependee,
1135  false);
1136 
1137  ereport(ERROR,
1138  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1139  errmsg("cannot drop %s because %s requires it",
1140  getObjectDescription(object, false), otherObjDesc),
1141  errhint("You can drop %s instead.", otherObjDesc)));
1142  }
1143  }
1144 
1145  /*
1146  * If no error is to be thrown, and the msglevel is too low to be shown to
1147  * either client or server log, there's no need to do any of the rest of
1148  * the work.
1149  */
1150  if (behavior == DROP_CASCADE &&
1151  !message_level_is_interesting(msglevel))
1152  return;
1153 
1154  /*
1155  * We limit the number of dependencies reported to the client to
1156  * MAX_REPORTED_DEPS, since client software may not deal well with
1157  * enormous error strings. The server log always gets a full report.
1158  */
1159 #define MAX_REPORTED_DEPS 100
1160 
1161  initStringInfo(&clientdetail);
1162  initStringInfo(&logdetail);
1163 
1164  /*
1165  * We process the list back to front (ie, in dependency order not deletion
1166  * order), since this makes for a more understandable display.
1167  */
1168  for (i = targetObjects->numrefs - 1; i >= 0; i--)
1169  {
1170  const ObjectAddress *obj = &targetObjects->refs[i];
1171  const ObjectAddressExtra *extra = &targetObjects->extras[i];
1172  char *objDesc;
1173 
1174  /* Ignore the original deletion target(s) */
1175  if (extra->flags & DEPFLAG_ORIGINAL)
1176  continue;
1177 
1178  /* Also ignore sub-objects; we'll report the whole object elsewhere */
1179  if (extra->flags & DEPFLAG_SUBOBJECT)
1180  continue;
1181 
1182  objDesc = getObjectDescription(obj, false);
1183 
1184  /*
1185  * If, at any stage of the recursive search, we reached the object via
1186  * an AUTO, INTERNAL, PARTITION, or EXTENSION dependency, then it's
1187  * okay to delete it even in RESTRICT mode.
1188  */
1189  if (extra->flags & (DEPFLAG_AUTO |
1193  {
1194  /*
1195  * auto-cascades are reported at DEBUG2, not msglevel. We don't
1196  * try to combine them with the regular message because the
1197  * results are too confusing when client_min_messages and
1198  * log_min_messages are different.
1199  */
1200  ereport(DEBUG2,
1201  (errmsg_internal("drop auto-cascades to %s",
1202  objDesc)));
1203  }
1204  else if (behavior == DROP_RESTRICT)
1205  {
1206  char *otherDesc = getObjectDescription(&extra->dependee,
1207  false);
1208 
1209  if (numReportedClient < MAX_REPORTED_DEPS)
1210  {
1211  /* separate entries with a newline */
1212  if (clientdetail.len != 0)
1213  appendStringInfoChar(&clientdetail, '\n');
1214  appendStringInfo(&clientdetail, _("%s depends on %s"),
1215  objDesc, otherDesc);
1216  numReportedClient++;
1217  }
1218  else
1219  numNotReportedClient++;
1220  /* separate entries with a newline */
1221  if (logdetail.len != 0)
1222  appendStringInfoChar(&logdetail, '\n');
1223  appendStringInfo(&logdetail, _("%s depends on %s"),
1224  objDesc, otherDesc);
1225  pfree(otherDesc);
1226  ok = false;
1227  }
1228  else
1229  {
1230  if (numReportedClient < MAX_REPORTED_DEPS)
1231  {
1232  /* separate entries with a newline */
1233  if (clientdetail.len != 0)
1234  appendStringInfoChar(&clientdetail, '\n');
1235  appendStringInfo(&clientdetail, _("drop cascades to %s"),
1236  objDesc);
1237  numReportedClient++;
1238  }
1239  else
1240  numNotReportedClient++;
1241  /* separate entries with a newline */
1242  if (logdetail.len != 0)
1243  appendStringInfoChar(&logdetail, '\n');
1244  appendStringInfo(&logdetail, _("drop cascades to %s"),
1245  objDesc);
1246  }
1247 
1248  pfree(objDesc);
1249  }
1250 
1251  if (numNotReportedClient > 0)
1252  appendStringInfo(&clientdetail, ngettext("\nand %d other object "
1253  "(see server log for list)",
1254  "\nand %d other objects "
1255  "(see server log for list)",
1256  numNotReportedClient),
1257  numNotReportedClient);
1258 
1259  if (!ok)
1260  {
1261  if (origObject)
1262  ereport(ERROR,
1263  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1264  errmsg("cannot drop %s because other objects depend on it",
1265  getObjectDescription(origObject, false)),
1266  errdetail("%s", clientdetail.data),
1267  errdetail_log("%s", logdetail.data),
1268  errhint("Use DROP ... CASCADE to drop the dependent objects too.")));
1269  else
1270  ereport(ERROR,
1271  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1272  errmsg("cannot drop desired object(s) because other objects depend on them"),
1273  errdetail("%s", clientdetail.data),
1274  errdetail_log("%s", logdetail.data),
1275  errhint("Use DROP ... CASCADE to drop the dependent objects too.")));
1276  }
1277  else if (numReportedClient > 1)
1278  {
1279  ereport(msglevel,
1280  /* translator: %d always has a value larger than 1 */
1281  (errmsg_plural("drop cascades to %d other object",
1282  "drop cascades to %d other objects",
1283  numReportedClient + numNotReportedClient,
1284  numReportedClient + numNotReportedClient),
1285  errdetail("%s", clientdetail.data),
1286  errdetail_log("%s", logdetail.data)));
1287  }
1288  else if (numReportedClient == 1)
1289  {
1290  /* we just use the single item as-is */
1291  ereport(msglevel,
1292  (errmsg_internal("%s", clientdetail.data)));
1293  }
1294 
1295  pfree(clientdetail.data);
1296  pfree(logdetail.data);
1297 }
1298 
1299 /*
1300  * Drop an object by OID. Works for most catalogs, if no special processing
1301  * is needed.
1302  */
1303 static void
1305 {
1306  int cacheId;
1307  Relation rel;
1308  HeapTuple tup;
1309 
1310  cacheId = get_object_catcache_oid(object->classId);
1311 
1312  rel = table_open(object->classId, RowExclusiveLock);
1313 
1314  /*
1315  * Use the system cache for the oid column, if one exists.
1316  */
1317  if (cacheId >= 0)
1318  {
1319  tup = SearchSysCache1(cacheId, ObjectIdGetDatum(object->objectId));
1320  if (!HeapTupleIsValid(tup))
1321  elog(ERROR, "cache lookup failed for %s %u",
1322  get_object_class_descr(object->classId), object->objectId);
1323 
1324  CatalogTupleDelete(rel, &tup->t_self);
1325 
1326  ReleaseSysCache(tup);
1327  }
1328  else
1329  {
1330  ScanKeyData skey[1];
1331  SysScanDesc scan;
1332 
1333  ScanKeyInit(&skey[0],
1334  get_object_attnum_oid(object->classId),
1335  BTEqualStrategyNumber, F_OIDEQ,
1336  ObjectIdGetDatum(object->objectId));
1337 
1338  scan = systable_beginscan(rel, get_object_oid_index(object->classId), true,
1339  NULL, 1, skey);
1340 
1341  /* we expect exactly one match */
1342  tup = systable_getnext(scan);
1343  if (!HeapTupleIsValid(tup))
1344  elog(ERROR, "could not find tuple for %s %u",
1345  get_object_class_descr(object->classId), object->objectId);
1346 
1347  CatalogTupleDelete(rel, &tup->t_self);
1348 
1349  systable_endscan(scan);
1350  }
1351 
1353 }
1354 
1355 /*
1356  * deleteOneObject: delete a single object for performDeletion.
1357  *
1358  * *depRel is the already-open pg_depend relation.
1359  */
1360 static void
1361 deleteOneObject(const ObjectAddress *object, Relation *depRel, int flags)
1362 {
1363  ScanKeyData key[3];
1364  int nkeys;
1365  SysScanDesc scan;
1366  HeapTuple tup;
1367 
1368  /* DROP hook of the objects being removed */
1369  InvokeObjectDropHookArg(object->classId, object->objectId,
1370  object->objectSubId, flags);
1371 
1372  /*
1373  * Close depRel if we are doing a drop concurrently. The object deletion
1374  * subroutine will commit the current transaction, so we can't keep the
1375  * relation open across doDeletion().
1376  */
1377  if (flags & PERFORM_DELETION_CONCURRENTLY)
1378  table_close(*depRel, RowExclusiveLock);
1379 
1380  /*
1381  * Delete the object itself, in an object-type-dependent way.
1382  *
1383  * We used to do this after removing the outgoing dependency links, but it
1384  * seems just as reasonable to do it beforehand. In the concurrent case
1385  * we *must* do it in this order, because we can't make any transactional
1386  * updates before calling doDeletion() --- they'd get committed right
1387  * away, which is not cool if the deletion then fails.
1388  */
1389  doDeletion(object, flags);
1390 
1391  /*
1392  * Reopen depRel if we closed it above
1393  */
1394  if (flags & PERFORM_DELETION_CONCURRENTLY)
1395  *depRel = table_open(DependRelationId, RowExclusiveLock);
1396 
1397  /*
1398  * Now remove any pg_depend records that link from this object to others.
1399  * (Any records linking to this object should be gone already.)
1400  *
1401  * When dropping a whole object (subId = 0), remove all pg_depend records
1402  * for its sub-objects too.
1403  */
1404  ScanKeyInit(&key[0],
1405  Anum_pg_depend_classid,
1406  BTEqualStrategyNumber, F_OIDEQ,
1407  ObjectIdGetDatum(object->classId));
1408  ScanKeyInit(&key[1],
1409  Anum_pg_depend_objid,
1410  BTEqualStrategyNumber, F_OIDEQ,
1411  ObjectIdGetDatum(object->objectId));
1412  if (object->objectSubId != 0)
1413  {
1414  ScanKeyInit(&key[2],
1415  Anum_pg_depend_objsubid,
1416  BTEqualStrategyNumber, F_INT4EQ,
1417  Int32GetDatum(object->objectSubId));
1418  nkeys = 3;
1419  }
1420  else
1421  nkeys = 2;
1422 
1423  scan = systable_beginscan(*depRel, DependDependerIndexId, true,
1424  NULL, nkeys, key);
1425 
1426  while (HeapTupleIsValid(tup = systable_getnext(scan)))
1427  {
1428  CatalogTupleDelete(*depRel, &tup->t_self);
1429  }
1430 
1431  systable_endscan(scan);
1432 
1433  /*
1434  * Delete shared dependency references related to this object. Again, if
1435  * subId = 0, remove records for sub-objects too.
1436  */
1438  object->objectSubId);
1439 
1440 
1441  /*
1442  * Delete any comments, security labels, or initial privileges associated
1443  * with this object. (This is a convenient place to do these things,
1444  * rather than having every object type know to do it.)
1445  */
1446  DeleteComments(object->objectId, object->classId, object->objectSubId);
1447  DeleteSecurityLabel(object);
1448  DeleteInitPrivs(object);
1449 
1450  /*
1451  * CommandCounterIncrement here to ensure that preceding changes are all
1452  * visible to the next deletion step.
1453  */
1455 
1456  /*
1457  * And we're done!
1458  */
1459 }
1460 
1461 /*
1462  * doDeletion: actually delete a single object
1463  */
1464 static void
1465 doDeletion(const ObjectAddress *object, int flags)
1466 {
1467  switch (getObjectClass(object))
1468  {
1469  case OCLASS_CLASS:
1470  {
1471  char relKind = get_rel_relkind(object->objectId);
1472 
1473  if (relKind == RELKIND_INDEX ||
1474  relKind == RELKIND_PARTITIONED_INDEX)
1475  {
1476  bool concurrent = ((flags & PERFORM_DELETION_CONCURRENTLY) != 0);
1477  bool concurrent_lock_mode = ((flags & PERFORM_DELETION_CONCURRENT_LOCK) != 0);
1478 
1479  Assert(object->objectSubId == 0);
1480  index_drop(object->objectId, concurrent, concurrent_lock_mode);
1481  }
1482  else
1483  {
1484  if (object->objectSubId != 0)
1485  RemoveAttributeById(object->objectId,
1486  object->objectSubId);
1487  else
1489  }
1490 
1491  /*
1492  * for a sequence, in addition to dropping the heap, also
1493  * delete pg_sequence tuple
1494  */
1495  if (relKind == RELKIND_SEQUENCE)
1496  DeleteSequenceTuple(object->objectId);
1497  break;
1498  }
1499 
1500  case OCLASS_PROC:
1501  RemoveFunctionById(object->objectId);
1502  break;
1503 
1504  case OCLASS_TYPE:
1505  RemoveTypeById(object->objectId);
1506  break;
1507 
1508  case OCLASS_CONSTRAINT:
1509  RemoveConstraintById(object->objectId);
1510  break;
1511 
1512  case OCLASS_DEFAULT:
1514  break;
1515 
1516  case OCLASS_LARGEOBJECT:
1517  LargeObjectDrop(object->objectId);
1518  break;
1519 
1520  case OCLASS_OPERATOR:
1521  RemoveOperatorById(object->objectId);
1522  break;
1523 
1524  case OCLASS_REWRITE:
1526  break;
1527 
1528  case OCLASS_TRIGGER:
1529  RemoveTriggerById(object->objectId);
1530  break;
1531 
1532  case OCLASS_STATISTIC_EXT:
1533  RemoveStatisticsById(object->objectId);
1534  break;
1535 
1536  case OCLASS_TSCONFIG:
1538  break;
1539 
1540  case OCLASS_EXTENSION:
1541  RemoveExtensionById(object->objectId);
1542  break;
1543 
1544  case OCLASS_POLICY:
1545  RemovePolicyById(object->objectId);
1546  break;
1547 
1550  break;
1551 
1552  case OCLASS_CAST:
1553  case OCLASS_COLLATION:
1554  case OCLASS_CONVERSION:
1555  case OCLASS_LANGUAGE:
1556  case OCLASS_OPCLASS:
1557  case OCLASS_OPFAMILY:
1558  case OCLASS_AM:
1559  case OCLASS_AMOP:
1560  case OCLASS_AMPROC:
1561  case OCLASS_SCHEMA:
1562  case OCLASS_TSPARSER:
1563  case OCLASS_TSDICT:
1564  case OCLASS_TSTEMPLATE:
1565  case OCLASS_FDW:
1566  case OCLASS_FOREIGN_SERVER:
1567  case OCLASS_USER_MAPPING:
1568  case OCLASS_DEFACL:
1569  case OCLASS_EVENT_TRIGGER:
1570  case OCLASS_PUBLICATION:
1571  case OCLASS_TRANSFORM:
1572  DropObjectById(object);
1573  break;
1574 
1575  /*
1576  * These global object types are not supported here.
1577  */
1578  case OCLASS_ROLE:
1579  case OCLASS_DATABASE:
1580  case OCLASS_TBLSPACE:
1581  case OCLASS_SUBSCRIPTION:
1582  elog(ERROR, "global objects cannot be deleted by doDeletion");
1583  break;
1584 
1585  /*
1586  * There's intentionally no default: case here; we want the
1587  * compiler to warn if a new OCLASS hasn't been handled above.
1588  */
1589  }
1590 }
1591 
1592 /*
1593  * AcquireDeletionLock - acquire a suitable lock for deleting an object
1594  *
1595  * Accepts the same flags as performDeletion (though currently only
1596  * PERFORM_DELETION_CONCURRENTLY does anything).
1597  *
1598  * We use LockRelation for relations, LockDatabaseObject for everything
1599  * else. Shared-across-databases objects are not currently supported
1600  * because no caller cares, but could be modified to use LockSharedObject.
1601  */
1602 void
1604 {
1605  if (object->classId == RelationRelationId)
1606  {
1607  /*
1608  * In DROP INDEX CONCURRENTLY, take only ShareUpdateExclusiveLock on
1609  * the index for the moment. index_drop() will promote the lock once
1610  * it's safe to do so. In all other cases we need full exclusive
1611  * lock.
1612  */
1613  if (flags & PERFORM_DELETION_CONCURRENTLY)
1615  else
1617  }
1618  else
1619  {
1620  /* assume we should lock the whole object not a sub-object */
1621  LockDatabaseObject(object->classId, object->objectId, 0,
1623  }
1624 }
1625 
1626 /*
1627  * ReleaseDeletionLock - release an object deletion lock
1628  *
1629  * Companion to AcquireDeletionLock.
1630  */
1631 void
1633 {
1634  if (object->classId == RelationRelationId)
1636  else
1637  /* assume we should lock the whole object not a sub-object */
1638  UnlockDatabaseObject(object->classId, object->objectId, 0,
1640 }
1641 
1642 /*
1643  * Record dependencies on a list of collations, optionally with their current
1644  * version.
1645  */
1646 void
1648  List *collations,
1649  bool record_version)
1650 {
1651  ObjectAddresses *addrs;
1652  ListCell *lc;
1653 
1654  if (list_length(collations) == 0)
1655  return;
1656 
1657  addrs = new_object_addresses();
1658  foreach(lc, collations)
1659  {
1660  ObjectAddress referenced;
1661 
1662  ObjectAddressSet(referenced, CollationRelationId, lfirst_oid(lc));
1663 
1664  add_exact_object_address(&referenced, addrs);
1665  }
1666 
1668  recordMultipleDependencies(myself, addrs->refs, addrs->numrefs,
1669  DEPENDENCY_NORMAL, record_version);
1670 
1671  free_object_addresses(addrs);
1672 }
1673 
1674 /*
1675  * recordDependencyOnExpr - find expression dependencies
1676  *
1677  * This is used to find the dependencies of rules, constraint expressions,
1678  * etc.
1679  *
1680  * Given an expression or query in node-tree form, find all the objects
1681  * it refers to (tables, columns, operators, functions, etc). Record
1682  * a dependency of the specified type from the given depender object
1683  * to each object mentioned in the expression.
1684  *
1685  * rtable is the rangetable to be used to interpret Vars with varlevelsup=0.
1686  * It can be NIL if no such variables are expected.
1687  */
1688 void
1690  Node *expr, List *rtable,
1691  DependencyType behavior)
1692 {
1694 
1695  context.addrs = new_object_addresses();
1696 
1697  /* Set up interpretation for Vars at varlevelsup = 0 */
1698  context.rtables = list_make1(rtable);
1699 
1700  /* Scan the expression tree for referenceable objects */
1701  find_expr_references_walker(expr, &context);
1702 
1703  /* Remove any duplicates */
1705 
1706  /* And record 'em */
1707  recordMultipleDependencies(depender,
1708  context.addrs->refs,
1709  context.addrs->numrefs,
1710  behavior,
1711  false);
1712 
1713  free_object_addresses(context.addrs);
1714 }
1715 
1716 /*
1717  * recordDependencyOnSingleRelExpr - find expression dependencies
1718  *
1719  * As above, but only one relation is expected to be referenced (with
1720  * varno = 1 and varlevelsup = 0). Pass the relation OID instead of a
1721  * range table. An additional frammish is that dependencies on that
1722  * relation's component columns will be marked with 'self_behavior',
1723  * whereas 'behavior' is used for everything else; also, if 'reverse_self'
1724  * is true, those dependencies are reversed so that the columns are made
1725  * to depend on the table not vice versa.
1726  *
1727  * NOTE: the caller should ensure that a whole-table dependency on the
1728  * specified relation is created separately, if one is needed. In particular,
1729  * a whole-row Var "relation.*" will not cause this routine to emit any
1730  * dependency item. This is appropriate behavior for subexpressions of an
1731  * ordinary query, so other cases need to cope as necessary.
1732  */
1733 void
1735  Node *expr, Oid relId,
1736  DependencyType behavior,
1737  DependencyType self_behavior,
1738  bool reverse_self,
1739  bool record_version)
1740 {
1742  RangeTblEntry rte;
1743 
1744  context.addrs = new_object_addresses();
1745 
1746  /* We gin up a rather bogus rangetable list to handle Vars */
1747  MemSet(&rte, 0, sizeof(rte));
1748  rte.type = T_RangeTblEntry;
1749  rte.rtekind = RTE_RELATION;
1750  rte.relid = relId;
1751  rte.relkind = RELKIND_RELATION; /* no need for exactness here */
1753 
1754  context.rtables = list_make1(list_make1(&rte));
1755 
1756  /* Scan the expression tree for referenceable objects */
1757  find_expr_references_walker(expr, &context);
1758 
1759  /* Remove any duplicates */
1761 
1762  /* Separate self-dependencies if necessary */
1763  if ((behavior != self_behavior || reverse_self) &&
1764  context.addrs->numrefs > 0)
1765  {
1766  ObjectAddresses *self_addrs;
1767  ObjectAddress *outobj;
1768  int oldref,
1769  outrefs;
1770 
1771  self_addrs = new_object_addresses();
1772 
1773  outobj = context.addrs->refs;
1774  outrefs = 0;
1775  for (oldref = 0; oldref < context.addrs->numrefs; oldref++)
1776  {
1777  ObjectAddress *thisobj = context.addrs->refs + oldref;
1778 
1779  if (thisobj->classId == RelationRelationId &&
1780  thisobj->objectId == relId)
1781  {
1782  /* Move this ref into self_addrs */
1783  add_exact_object_address(thisobj, self_addrs);
1784  }
1785  else
1786  {
1787  /* Keep it in context.addrs */
1788  *outobj = *thisobj;
1789  outobj++;
1790  outrefs++;
1791  }
1792  }
1793  context.addrs->numrefs = outrefs;
1794 
1795  /* Record the self-dependencies with the appropriate direction */
1796  if (!reverse_self)
1797  recordMultipleDependencies(depender,
1798  self_addrs->refs,
1799  self_addrs->numrefs,
1800  self_behavior,
1801  record_version);
1802  else
1803  {
1804  /* Can't use recordMultipleDependencies, so do it the hard way */
1805  int selfref;
1806 
1807  for (selfref = 0; selfref < self_addrs->numrefs; selfref++)
1808  {
1809  ObjectAddress *thisobj = self_addrs->refs + selfref;
1810 
1811  recordDependencyOn(thisobj, depender, self_behavior);
1812  }
1813  }
1814 
1815  free_object_addresses(self_addrs);
1816  }
1817 
1818  /* Record the external dependencies */
1819  recordMultipleDependencies(depender,
1820  context.addrs->refs,
1821  context.addrs->numrefs,
1822  behavior,
1823  record_version);
1824 
1825  free_object_addresses(context.addrs);
1826 }
1827 
1828 /*
1829  * Recursively search an expression tree for object references.
1830  *
1831  * Note: in many cases we do not need to create dependencies on the datatypes
1832  * involved in an expression, because we'll have an indirect dependency via
1833  * some other object. For instance Var nodes depend on a column which depends
1834  * on the datatype, and OpExpr nodes depend on the operator which depends on
1835  * the datatype. However we do need a type dependency if there is no such
1836  * indirect dependency, as for example in Const and CoerceToDomain nodes.
1837  *
1838  * Collations are handled primarily by recording the inputcollid's of node
1839  * types that have them, as those are the ones that are semantically
1840  * significant during expression evaluation. We also record the collation of
1841  * CollateExpr nodes, since those will be needed to print such nodes even if
1842  * they don't really affect semantics. Collations of leaf nodes such as Vars
1843  * can be ignored on the grounds that if they're not default, they came from
1844  * the referenced object (e.g., a table column), so the dependency on that
1845  * object is enough. (Note: in a post-const-folding expression tree, a
1846  * CollateExpr's collation could have been absorbed into a Const or
1847  * RelabelType node. While ruleutils.c prints such collations for clarity,
1848  * we may ignore them here as they have no semantic effect.)
1849  */
1850 static bool
1853 {
1854  if (node == NULL)
1855  return false;
1856  if (IsA(node, Var))
1857  {
1858  Var *var = (Var *) node;
1859  List *rtable;
1860  RangeTblEntry *rte;
1861 
1862  /* Find matching rtable entry, or complain if not found */
1863  if (var->varlevelsup >= list_length(context->rtables))
1864  elog(ERROR, "invalid varlevelsup %d", var->varlevelsup);
1865  rtable = (List *) list_nth(context->rtables, var->varlevelsup);
1866  if (var->varno <= 0 || var->varno > list_length(rtable))
1867  elog(ERROR, "invalid varno %d", var->varno);
1868  rte = rt_fetch(var->varno, rtable);
1869 
1870  /*
1871  * A whole-row Var references no specific columns, so adds no new
1872  * dependency. (We assume that there is a whole-table dependency
1873  * arising from each underlying rangetable entry. While we could
1874  * record such a dependency when finding a whole-row Var that
1875  * references a relation directly, it's quite unclear how to extend
1876  * that to whole-row Vars for JOINs, so it seems better to leave the
1877  * responsibility with the range table. Note that this poses some
1878  * risks for identifying dependencies of stand-alone expressions:
1879  * whole-table references may need to be created separately.)
1880  */
1881  if (var->varattno == InvalidAttrNumber)
1882  return false;
1883  if (rte->rtekind == RTE_RELATION)
1884  {
1885  /* If it's a plain relation, reference this column */
1887  context->addrs);
1888  }
1889 
1890  /*
1891  * Vars referencing other RTE types require no additional work. In
1892  * particular, a join alias Var can be ignored, because it must
1893  * reference a merged USING column. The relevant join input columns
1894  * will also be referenced in the join qual, and any type coercion
1895  * functions involved in the alias expression will be dealt with when
1896  * we scan the RTE itself.
1897  */
1898  return false;
1899  }
1900  else if (IsA(node, Const))
1901  {
1902  Const *con = (Const *) node;
1903  Oid objoid;
1904 
1905  /* A constant must depend on the constant's datatype */
1907  context->addrs);
1908 
1909  /*
1910  * If it's a regclass or similar literal referring to an existing
1911  * object, add a reference to that object. (Currently, only the
1912  * regclass and regconfig cases have any likely use, but we may as
1913  * well handle all the OID-alias datatypes consistently.)
1914  */
1915  if (!con->constisnull)
1916  {
1917  switch (con->consttype)
1918  {
1919  case REGPROCOID:
1920  case REGPROCEDUREOID:
1921  objoid = DatumGetObjectId(con->constvalue);
1923  ObjectIdGetDatum(objoid)))
1924  add_object_address(OCLASS_PROC, objoid, 0,
1925  context->addrs);
1926  break;
1927  case REGOPEROID:
1928  case REGOPERATOROID:
1929  objoid = DatumGetObjectId(con->constvalue);
1931  ObjectIdGetDatum(objoid)))
1933  context->addrs);
1934  break;
1935  case REGCLASSOID:
1936  objoid = DatumGetObjectId(con->constvalue);
1938  ObjectIdGetDatum(objoid)))
1939  add_object_address(OCLASS_CLASS, objoid, 0,
1940  context->addrs);
1941  break;
1942  case REGTYPEOID:
1943  objoid = DatumGetObjectId(con->constvalue);
1945  ObjectIdGetDatum(objoid)))
1946  add_object_address(OCLASS_TYPE, objoid, 0,
1947  context->addrs);
1948  break;
1949  case REGCONFIGOID:
1950  objoid = DatumGetObjectId(con->constvalue);
1952  ObjectIdGetDatum(objoid)))
1954  context->addrs);
1955  break;
1956  case REGDICTIONARYOID:
1957  objoid = DatumGetObjectId(con->constvalue);
1959  ObjectIdGetDatum(objoid)))
1960  add_object_address(OCLASS_TSDICT, objoid, 0,
1961  context->addrs);
1962  break;
1963 
1964  case REGNAMESPACEOID:
1965  objoid = DatumGetObjectId(con->constvalue);
1967  ObjectIdGetDatum(objoid)))
1968  add_object_address(OCLASS_SCHEMA, objoid, 0,
1969  context->addrs);
1970  break;
1971 
1972  /*
1973  * Dependencies for regrole should be shared among all
1974  * databases, so explicitly inhibit to have dependencies.
1975  */
1976  case REGROLEOID:
1977  ereport(ERROR,
1978  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1979  errmsg("constant of the type %s cannot be used here",
1980  "regrole")));
1981  break;
1982  }
1983  }
1984  return false;
1985  }
1986  else if (IsA(node, Param))
1987  {
1988  Param *param = (Param *) node;
1989 
1990  /* A parameter must depend on the parameter's datatype */
1992  context->addrs);
1993  }
1994  else if (IsA(node, FuncExpr))
1995  {
1996  FuncExpr *funcexpr = (FuncExpr *) node;
1997 
1998  add_object_address(OCLASS_PROC, funcexpr->funcid, 0,
1999  context->addrs);
2000  if (OidIsValid(funcexpr->inputcollid))
2002  context->addrs);
2003  /* fall through to examine arguments */
2004  }
2005  else if (IsA(node, OpExpr))
2006  {
2007  OpExpr *opexpr = (OpExpr *) node;
2008 
2010  context->addrs);
2011  if (OidIsValid(opexpr->inputcollid))
2013  context->addrs);
2014  /* fall through to examine arguments */
2015  }
2016  else if (IsA(node, DistinctExpr))
2017  {
2018  DistinctExpr *distinctexpr = (DistinctExpr *) node;
2019 
2020  add_object_address(OCLASS_OPERATOR, distinctexpr->opno, 0,
2021  context->addrs);
2022  if (OidIsValid(distinctexpr->inputcollid))
2024  context->addrs);
2025  /* fall through to examine arguments */
2026  }
2027  else if (IsA(node, NullIfExpr))
2028  {
2029  NullIfExpr *nullifexpr = (NullIfExpr *) node;
2030 
2031  add_object_address(OCLASS_OPERATOR, nullifexpr->opno, 0,
2032  context->addrs);
2033  if (OidIsValid(nullifexpr->inputcollid))
2035  context->addrs);
2036  /* fall through to examine arguments */
2037  }
2038  else if (IsA(node, ScalarArrayOpExpr))
2039  {
2040  ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
2041 
2043  context->addrs);
2044  if (OidIsValid(opexpr->inputcollid))
2046  context->addrs);
2047  /* fall through to examine arguments */
2048  }
2049  else if (IsA(node, Aggref))
2050  {
2051  Aggref *aggref = (Aggref *) node;
2052 
2054  context->addrs);
2055  if (OidIsValid(aggref->inputcollid))
2057  context->addrs);
2058  /* fall through to examine arguments */
2059  }
2060  else if (IsA(node, WindowFunc))
2061  {
2062  WindowFunc *wfunc = (WindowFunc *) node;
2063 
2065  context->addrs);
2066  if (OidIsValid(wfunc->inputcollid))
2068  context->addrs);
2069  /* fall through to examine arguments */
2070  }
2071  else if (IsA(node, SubscriptingRef))
2072  {
2073  SubscriptingRef *sbsref = (SubscriptingRef *) node;
2074 
2075  /*
2076  * The refexpr should provide adequate dependency on refcontainertype,
2077  * and that type in turn depends on refelemtype. However, a custom
2078  * subscripting handler might set refrestype to something different
2079  * from either of those, in which case we'd better record it.
2080  */
2081  if (sbsref->refrestype != sbsref->refcontainertype &&
2082  sbsref->refrestype != sbsref->refelemtype)
2084  context->addrs);
2085  /* fall through to examine arguments */
2086  }
2087  else if (IsA(node, SubPlan))
2088  {
2089  /* Extra work needed here if we ever need this case */
2090  elog(ERROR, "already-planned subqueries not supported");
2091  }
2092  else if (IsA(node, FieldSelect))
2093  {
2094  FieldSelect *fselect = (FieldSelect *) node;
2095  Oid argtype = getBaseType(exprType((Node *) fselect->arg));
2096  Oid reltype = get_typ_typrelid(argtype);
2097 
2098  /*
2099  * We need a dependency on the specific column named in FieldSelect,
2100  * assuming we can identify the pg_class OID for it. (Probably we
2101  * always can at the moment, but in future it might be possible for
2102  * argtype to be RECORDOID.) If we can make a column dependency then
2103  * we shouldn't need a dependency on the column's type; but if we
2104  * can't, make a dependency on the type, as it might not appear
2105  * anywhere else in the expression.
2106  */
2107  if (OidIsValid(reltype))
2108  add_object_address(OCLASS_CLASS, reltype, fselect->fieldnum,
2109  context->addrs);
2110  else
2112  context->addrs);
2113  }
2114  else if (IsA(node, FieldStore))
2115  {
2116  FieldStore *fstore = (FieldStore *) node;
2117  Oid reltype = get_typ_typrelid(fstore->resulttype);
2118 
2119  /* similar considerations to FieldSelect, but multiple column(s) */
2120  if (OidIsValid(reltype))
2121  {
2122  ListCell *l;
2123 
2124  foreach(l, fstore->fieldnums)
2126  context->addrs);
2127  }
2128  else
2130  context->addrs);
2131  }
2132  else if (IsA(node, RelabelType))
2133  {
2134  RelabelType *relab = (RelabelType *) node;
2135 
2136  /* since there is no function dependency, need to depend on type */
2138  context->addrs);
2139  }
2140  else if (IsA(node, CoerceViaIO))
2141  {
2142  CoerceViaIO *iocoerce = (CoerceViaIO *) node;
2143 
2144  /* since there is no exposed function, need to depend on type */
2146  context->addrs);
2147  }
2148  else if (IsA(node, ArrayCoerceExpr))
2149  {
2150  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
2151 
2152  /* as above, depend on type */
2154  context->addrs);
2155  /* fall through to examine arguments */
2156  }
2157  else if (IsA(node, ConvertRowtypeExpr))
2158  {
2159  ConvertRowtypeExpr *cvt = (ConvertRowtypeExpr *) node;
2160 
2161  /* since there is no function dependency, need to depend on type */
2163  context->addrs);
2164  }
2165  else if (IsA(node, CollateExpr))
2166  {
2167  CollateExpr *coll = (CollateExpr *) node;
2168 
2170  context->addrs);
2171  }
2172  else if (IsA(node, RowExpr))
2173  {
2174  RowExpr *rowexpr = (RowExpr *) node;
2175 
2177  context->addrs);
2178  }
2179  else if (IsA(node, RowCompareExpr))
2180  {
2181  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2182  ListCell *l;
2183 
2184  foreach(l, rcexpr->opnos)
2185  {
2187  context->addrs);
2188  }
2189  foreach(l, rcexpr->opfamilies)
2190  {
2192  context->addrs);
2193  }
2194  foreach(l, rcexpr->inputcollids)
2195  {
2196  Oid inputcollid = lfirst_oid(l);
2197 
2198  if (OidIsValid(inputcollid))
2199  add_object_address(OCLASS_COLLATION, inputcollid, 0,
2200  context->addrs);
2201  }
2202  /* fall through to examine arguments */
2203  }
2204  else if (IsA(node, MinMaxExpr))
2205  {
2206  MinMaxExpr *mmexpr = (MinMaxExpr *) node;
2207 
2208  /* minmaxtype will match one of the inputs, so no need to record it */
2209  if (OidIsValid(mmexpr->inputcollid))
2211  context->addrs);
2212  /* fall through to examine arguments */
2213  }
2214  else if (IsA(node, CoerceToDomain))
2215  {
2216  CoerceToDomain *cd = (CoerceToDomain *) node;
2217 
2219  context->addrs);
2220  }
2221  else if (IsA(node, NextValueExpr))
2222  {
2223  NextValueExpr *nve = (NextValueExpr *) node;
2224 
2226  context->addrs);
2227  }
2228  else if (IsA(node, OnConflictExpr))
2229  {
2230  OnConflictExpr *onconflict = (OnConflictExpr *) node;
2231 
2232  if (OidIsValid(onconflict->constraint))
2234  context->addrs);
2235  /* fall through to examine arguments */
2236  }
2237  else if (IsA(node, SortGroupClause))
2238  {
2239  SortGroupClause *sgc = (SortGroupClause *) node;
2240 
2242  context->addrs);
2243  if (OidIsValid(sgc->sortop))
2245  context->addrs);
2246  return false;
2247  }
2248  else if (IsA(node, WindowClause))
2249  {
2250  WindowClause *wc = (WindowClause *) node;
2251 
2252  if (OidIsValid(wc->startInRangeFunc))
2254  context->addrs);
2255  if (OidIsValid(wc->endInRangeFunc))
2257  context->addrs);
2258  if (OidIsValid(wc->inRangeColl))
2260  context->addrs);
2261  /* fall through to examine substructure */
2262  }
2263  else if (IsA(node, CTECycleClause))
2264  {
2265  CTECycleClause *cc = (CTECycleClause *) node;
2266 
2267  if (OidIsValid(cc->cycle_mark_type))
2269  context->addrs);
2272  context->addrs);
2273  if (OidIsValid(cc->cycle_mark_neop))
2275  context->addrs);
2276  /* fall through to examine substructure */
2277  }
2278  else if (IsA(node, Query))
2279  {
2280  /* Recurse into RTE subquery or not-yet-planned sublink subquery */
2281  Query *query = (Query *) node;
2282  ListCell *lc;
2283  bool result;
2284 
2285  /*
2286  * Add whole-relation refs for each plain relation mentioned in the
2287  * subquery's rtable, and ensure we add refs for any type-coercion
2288  * functions used in join alias lists.
2289  *
2290  * Note: query_tree_walker takes care of recursing into RTE_FUNCTION
2291  * RTEs, subqueries, etc, so no need to do that here. But we must
2292  * tell it not to visit join alias lists, or we'll add refs for join
2293  * input columns whether or not they are actually used in our query.
2294  *
2295  * Note: we don't need to worry about collations mentioned in
2296  * RTE_VALUES or RTE_CTE RTEs, because those must just duplicate
2297  * collations referenced in other parts of the Query. We do have to
2298  * worry about collations mentioned in RTE_FUNCTION, but we take care
2299  * of those when we recurse to the RangeTblFunction node(s).
2300  */
2301  foreach(lc, query->rtable)
2302  {
2303  RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
2304 
2305  switch (rte->rtekind)
2306  {
2307  case RTE_RELATION:
2309  context->addrs);
2310  break;
2311  case RTE_JOIN:
2312 
2313  /*
2314  * Examine joinaliasvars entries only for merged JOIN
2315  * USING columns. Only those entries could contain
2316  * type-coercion functions. Also, their join input
2317  * columns must be referenced in the join quals, so this
2318  * won't accidentally add refs to otherwise-unused join
2319  * input columns. (We want to ref the type coercion
2320  * functions even if the merged column isn't explicitly
2321  * used anywhere, to protect possible expansion of the
2322  * join RTE as a whole-row var, and because it seems like
2323  * a bad idea to allow dropping a function that's present
2324  * in our query tree, whether or not it could get called.)
2325  */
2326  context->rtables = lcons(query->rtable, context->rtables);
2327  for (int i = 0; i < rte->joinmergedcols; i++)
2328  {
2329  Node *aliasvar = list_nth(rte->joinaliasvars, i);
2330 
2331  if (!IsA(aliasvar, Var))
2332  find_expr_references_walker(aliasvar, context);
2333  }
2334  context->rtables = list_delete_first(context->rtables);
2335  break;
2336  default:
2337  break;
2338  }
2339  }
2340 
2341  /*
2342  * If the query is an INSERT or UPDATE, we should create a dependency
2343  * on each target column, to prevent the specific target column from
2344  * being dropped. Although we will visit the TargetEntry nodes again
2345  * during query_tree_walker, we won't have enough context to do this
2346  * conveniently, so do it here.
2347  */
2348  if (query->commandType == CMD_INSERT ||
2349  query->commandType == CMD_UPDATE)
2350  {
2351  RangeTblEntry *rte;
2352 
2353  if (query->resultRelation <= 0 ||
2354  query->resultRelation > list_length(query->rtable))
2355  elog(ERROR, "invalid resultRelation %d",
2356  query->resultRelation);
2357  rte = rt_fetch(query->resultRelation, query->rtable);
2358  if (rte->rtekind == RTE_RELATION)
2359  {
2360  foreach(lc, query->targetList)
2361  {
2362  TargetEntry *tle = (TargetEntry *) lfirst(lc);
2363 
2364  if (tle->resjunk)
2365  continue; /* ignore junk tlist items */
2367  context->addrs);
2368  }
2369  }
2370  }
2371 
2372  /*
2373  * Add dependencies on constraints listed in query's constraintDeps
2374  */
2375  foreach(lc, query->constraintDeps)
2376  {
2378  context->addrs);
2379  }
2380 
2381  /* Examine substructure of query */
2382  context->rtables = lcons(query->rtable, context->rtables);
2383  result = query_tree_walker(query,
2385  (void *) context,
2388  context->rtables = list_delete_first(context->rtables);
2389  return result;
2390  }
2391  else if (IsA(node, SetOperationStmt))
2392  {
2393  SetOperationStmt *setop = (SetOperationStmt *) node;
2394 
2395  /* we need to look at the groupClauses for operator references */
2396  find_expr_references_walker((Node *) setop->groupClauses, context);
2397  /* fall through to examine child nodes */
2398  }
2399  else if (IsA(node, RangeTblFunction))
2400  {
2401  RangeTblFunction *rtfunc = (RangeTblFunction *) node;
2402  ListCell *ct;
2403 
2404  /*
2405  * Add refs for any datatypes and collations used in a column
2406  * definition list for a RECORD function. (For other cases, it should
2407  * be enough to depend on the function itself.)
2408  */
2409  foreach(ct, rtfunc->funccoltypes)
2410  {
2412  context->addrs);
2413  }
2414  foreach(ct, rtfunc->funccolcollations)
2415  {
2416  Oid collid = lfirst_oid(ct);
2417 
2418  if (OidIsValid(collid))
2420  context->addrs);
2421  }
2422  }
2423  else if (IsA(node, TableFunc))
2424  {
2425  TableFunc *tf = (TableFunc *) node;
2426  ListCell *ct;
2427 
2428  /*
2429  * Add refs for the datatypes and collations used in the TableFunc.
2430  */
2431  foreach(ct, tf->coltypes)
2432  {
2434  context->addrs);
2435  }
2436  foreach(ct, tf->colcollations)
2437  {
2438  Oid collid = lfirst_oid(ct);
2439 
2440  if (OidIsValid(collid))
2442  context->addrs);
2443  }
2444  }
2445  else if (IsA(node, TableSampleClause))
2446  {
2447  TableSampleClause *tsc = (TableSampleClause *) node;
2448 
2450  context->addrs);
2451  /* fall through to examine arguments */
2452  }
2453 
2455  (void *) context);
2456 }
2457 
2458 /*
2459  * Given an array of dependency references, eliminate any duplicates.
2460  */
2461 static void
2463 {
2464  ObjectAddress *priorobj;
2465  int oldref,
2466  newrefs;
2467 
2468  /*
2469  * We can't sort if the array has "extra" data, because there's no way to
2470  * keep it in sync. Fortunately that combination of features is not
2471  * needed.
2472  */
2473  Assert(!addrs->extras);
2474 
2475  if (addrs->numrefs <= 1)
2476  return; /* nothing to do */
2477 
2478  /* Sort the refs so that duplicates are adjacent */
2479  qsort((void *) addrs->refs, addrs->numrefs, sizeof(ObjectAddress),
2481 
2482  /* Remove dups */
2483  priorobj = addrs->refs;
2484  newrefs = 1;
2485  for (oldref = 1; oldref < addrs->numrefs; oldref++)
2486  {
2487  ObjectAddress *thisobj = addrs->refs + oldref;
2488 
2489  if (priorobj->classId == thisobj->classId &&
2490  priorobj->objectId == thisobj->objectId)
2491  {
2492  if (priorobj->objectSubId == thisobj->objectSubId)
2493  continue; /* identical, so drop thisobj */
2494 
2495  /*
2496  * If we have a whole-object reference and a reference to a part
2497  * of the same object, we don't need the whole-object reference
2498  * (for example, we don't need to reference both table foo and
2499  * column foo.bar). The whole-object reference will always appear
2500  * first in the sorted list.
2501  */
2502  if (priorobj->objectSubId == 0)
2503  {
2504  /* replace whole ref with partial */
2505  priorobj->objectSubId = thisobj->objectSubId;
2506  continue;
2507  }
2508  }
2509  /* Not identical, so add thisobj to output set */
2510  priorobj++;
2511  *priorobj = *thisobj;
2512  newrefs++;
2513  }
2514 
2515  addrs->numrefs = newrefs;
2516 }
2517 
2518 /*
2519  * qsort comparator for ObjectAddress items
2520  */
2521 static int
2522 object_address_comparator(const void *a, const void *b)
2523 {
2524  const ObjectAddress *obja = (const ObjectAddress *) a;
2525  const ObjectAddress *objb = (const ObjectAddress *) b;
2526 
2527  /*
2528  * Primary sort key is OID descending. Most of the time, this will result
2529  * in putting newer objects before older ones, which is likely to be the
2530  * right order to delete in.
2531  */
2532  if (obja->objectId > objb->objectId)
2533  return -1;
2534  if (obja->objectId < objb->objectId)
2535  return 1;
2536 
2537  /*
2538  * Next sort on catalog ID, in case identical OIDs appear in different
2539  * catalogs. Sort direction is pretty arbitrary here.
2540  */
2541  if (obja->classId < objb->classId)
2542  return -1;
2543  if (obja->classId > objb->classId)
2544  return 1;
2545 
2546  /*
2547  * Last, sort on object subId.
2548  *
2549  * We sort the subId as an unsigned int so that 0 (the whole object) will
2550  * come first. This is essential for eliminate_duplicate_dependencies,
2551  * and is also the best order for findDependentObjects.
2552  */
2553  if ((unsigned int) obja->objectSubId < (unsigned int) objb->objectSubId)
2554  return -1;
2555  if ((unsigned int) obja->objectSubId > (unsigned int) objb->objectSubId)
2556  return 1;
2557  return 0;
2558 }
2559 
2560 /*
2561  * Routines for handling an expansible array of ObjectAddress items.
2562  *
2563  * new_object_addresses: create a new ObjectAddresses array.
2564  */
2567 {
2568  ObjectAddresses *addrs;
2569 
2570  addrs = palloc(sizeof(ObjectAddresses));
2571 
2572  addrs->numrefs = 0;
2573  addrs->maxrefs = 32;
2574  addrs->refs = (ObjectAddress *)
2575  palloc(addrs->maxrefs * sizeof(ObjectAddress));
2576  addrs->extras = NULL; /* until/unless needed */
2577 
2578  return addrs;
2579 }
2580 
2581 /*
2582  * Add an entry to an ObjectAddresses array.
2583  *
2584  * It is convenient to specify the class by ObjectClass rather than directly
2585  * by catalog OID.
2586  */
2587 static void
2588 add_object_address(ObjectClass oclass, Oid objectId, int32 subId,
2589  ObjectAddresses *addrs)
2590 {
2591  ObjectAddress *item;
2592 
2593  /*
2594  * Make sure object_classes is kept up to date with the ObjectClass enum.
2595  */
2597  "object_classes[] must cover all ObjectClasses");
2598 
2599  /* enlarge array if needed */
2600  if (addrs->numrefs >= addrs->maxrefs)
2601  {
2602  addrs->maxrefs *= 2;
2603  addrs->refs = (ObjectAddress *)
2604  repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
2605  Assert(!addrs->extras);
2606  }
2607  /* record this item */
2608  item = addrs->refs + addrs->numrefs;
2609  item->classId = object_classes[oclass];
2610  item->objectId = objectId;
2611  item->objectSubId = subId;
2612  addrs->numrefs++;
2613 }
2614 
2615 /*
2616  * Add an entry to an ObjectAddresses array.
2617  *
2618  * As above, but specify entry exactly.
2619  */
2620 void
2622  ObjectAddresses *addrs)
2623 {
2624  ObjectAddress *item;
2625 
2626  /* enlarge array if needed */
2627  if (addrs->numrefs >= addrs->maxrefs)
2628  {
2629  addrs->maxrefs *= 2;
2630  addrs->refs = (ObjectAddress *)
2631  repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
2632  Assert(!addrs->extras);
2633  }
2634  /* record this item */
2635  item = addrs->refs + addrs->numrefs;
2636  *item = *object;
2637  addrs->numrefs++;
2638 }
2639 
2640 /*
2641  * Add an entry to an ObjectAddresses array.
2642  *
2643  * As above, but specify entry exactly and provide some "extra" data too.
2644  */
2645 static void
2647  const ObjectAddressExtra *extra,
2648  ObjectAddresses *addrs)
2649 {
2650  ObjectAddress *item;
2651  ObjectAddressExtra *itemextra;
2652 
2653  /* allocate extra space if first time */
2654  if (!addrs->extras)
2655  addrs->extras = (ObjectAddressExtra *)
2656  palloc(addrs->maxrefs * sizeof(ObjectAddressExtra));
2657 
2658  /* enlarge array if needed */
2659  if (addrs->numrefs >= addrs->maxrefs)
2660  {
2661  addrs->maxrefs *= 2;
2662  addrs->refs = (ObjectAddress *)
2663  repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
2664  addrs->extras = (ObjectAddressExtra *)
2665  repalloc(addrs->extras, addrs->maxrefs * sizeof(ObjectAddressExtra));
2666  }
2667  /* record this item */
2668  item = addrs->refs + addrs->numrefs;
2669  *item = *object;
2670  itemextra = addrs->extras + addrs->numrefs;
2671  *itemextra = *extra;
2672  addrs->numrefs++;
2673 }
2674 
2675 /*
2676  * Test whether an object is present in an ObjectAddresses array.
2677  *
2678  * We return "true" if object is a subobject of something in the array, too.
2679  */
2680 bool
2682  const ObjectAddresses *addrs)
2683 {
2684  int i;
2685 
2686  for (i = addrs->numrefs - 1; i >= 0; i--)
2687  {
2688  const ObjectAddress *thisobj = addrs->refs + i;
2689 
2690  if (object->classId == thisobj->classId &&
2691  object->objectId == thisobj->objectId)
2692  {
2693  if (object->objectSubId == thisobj->objectSubId ||
2694  thisobj->objectSubId == 0)
2695  return true;
2696  }
2697  }
2698 
2699  return false;
2700 }
2701 
2702 /*
2703  * As above, except that if the object is present then also OR the given
2704  * flags into its associated extra data (which must exist).
2705  */
2706 static bool
2708  int flags,
2709  ObjectAddresses *addrs)
2710 {
2711  bool result = false;
2712  int i;
2713 
2714  for (i = addrs->numrefs - 1; i >= 0; i--)
2715  {
2716  ObjectAddress *thisobj = addrs->refs + i;
2717 
2718  if (object->classId == thisobj->classId &&
2719  object->objectId == thisobj->objectId)
2720  {
2721  if (object->objectSubId == thisobj->objectSubId)
2722  {
2723  ObjectAddressExtra *thisextra = addrs->extras + i;
2724 
2725  thisextra->flags |= flags;
2726  result = true;
2727  }
2728  else if (thisobj->objectSubId == 0)
2729  {
2730  /*
2731  * We get here if we find a need to delete a column after
2732  * having already decided to drop its whole table. Obviously
2733  * we no longer need to drop the subobject, so report that we
2734  * found the subobject in the array. But don't plaster its
2735  * flags on the whole object.
2736  */
2737  result = true;
2738  }
2739  else if (object->objectSubId == 0)
2740  {
2741  /*
2742  * We get here if we find a need to delete a whole table after
2743  * having already decided to drop one of its columns. We
2744  * can't report that the whole object is in the array, but we
2745  * should mark the subobject with the whole object's flags.
2746  *
2747  * It might seem attractive to physically delete the column's
2748  * array entry, or at least mark it as no longer needing
2749  * separate deletion. But that could lead to, e.g., dropping
2750  * the column's datatype before we drop the table, which does
2751  * not seem like a good idea. This is a very rare situation
2752  * in practice, so we just take the hit of doing a separate
2753  * DROP COLUMN action even though we know we're gonna delete
2754  * the table later.
2755  *
2756  * What we can do, though, is mark this as a subobject so that
2757  * we don't report it separately, which is confusing because
2758  * it's unpredictable whether it happens or not. But do so
2759  * only if flags != 0 (flags == 0 is a read-only probe).
2760  *
2761  * Because there could be other subobjects of this object in
2762  * the array, this case means we always have to loop through
2763  * the whole array; we cannot exit early on a match.
2764  */
2765  ObjectAddressExtra *thisextra = addrs->extras + i;
2766 
2767  if (flags)
2768  thisextra->flags |= (flags | DEPFLAG_SUBOBJECT);
2769  }
2770  }
2771  }
2772 
2773  return result;
2774 }
2775 
2776 /*
2777  * Similar to above, except we search an ObjectAddressStack.
2778  */
2779 static bool
2781  int flags,
2782  ObjectAddressStack *stack)
2783 {
2784  bool result = false;
2785  ObjectAddressStack *stackptr;
2786 
2787  for (stackptr = stack; stackptr; stackptr = stackptr->next)
2788  {
2789  const ObjectAddress *thisobj = stackptr->object;
2790 
2791  if (object->classId == thisobj->classId &&
2792  object->objectId == thisobj->objectId)
2793  {
2794  if (object->objectSubId == thisobj->objectSubId)
2795  {
2796  stackptr->flags |= flags;
2797  result = true;
2798  }
2799  else if (thisobj->objectSubId == 0)
2800  {
2801  /*
2802  * We're visiting a column with whole table already on stack.
2803  * As in object_address_present_add_flags(), we can skip
2804  * further processing of the subobject, but we don't want to
2805  * propagate flags for the subobject to the whole object.
2806  */
2807  result = true;
2808  }
2809  else if (object->objectSubId == 0)
2810  {
2811  /*
2812  * We're visiting a table with column already on stack. As in
2813  * object_address_present_add_flags(), we should propagate
2814  * flags for the whole object to each of its subobjects.
2815  */
2816  if (flags)
2817  stackptr->flags |= (flags | DEPFLAG_SUBOBJECT);
2818  }
2819  }
2820  }
2821 
2822  return result;
2823 }
2824 
2825 /*
2826  * Record multiple dependencies from an ObjectAddresses array, after first
2827  * removing any duplicates.
2828  */
2829 void
2831  ObjectAddresses *referenced,
2832  DependencyType behavior)
2833 {
2835  recordMultipleDependencies(depender,
2836  referenced->refs, referenced->numrefs,
2837  behavior,
2838  false);
2839 }
2840 
2841 /*
2842  * Sort the items in an ObjectAddresses array.
2843  *
2844  * The major sort key is OID-descending, so that newer objects will be listed
2845  * first in most cases. This is primarily useful for ensuring stable outputs
2846  * from regression tests; it's not recommended if the order of the objects is
2847  * determined by user input, such as the order of targets in a DROP command.
2848  */
2849 void
2851 {
2852  if (addrs->numrefs > 1)
2853  qsort((void *) addrs->refs, addrs->numrefs,
2854  sizeof(ObjectAddress),
2856 }
2857 
2858 /*
2859  * Clean up when done with an ObjectAddresses array.
2860  */
2861 void
2863 {
2864  pfree(addrs->refs);
2865  if (addrs->extras)
2866  pfree(addrs->extras);
2867  pfree(addrs);
2868 }
2869 
2870 /*
2871  * Determine the class of a given object identified by objectAddress.
2872  *
2873  * This function is essentially the reverse mapping for the object_classes[]
2874  * table. We implement it as a function because the OIDs aren't consecutive.
2875  */
2878 {
2879  /* only pg_class entries can have nonzero objectSubId */
2880  if (object->classId != RelationRelationId &&
2881  object->objectSubId != 0)
2882  elog(ERROR, "invalid non-zero objectSubId for object class %u",
2883  object->classId);
2884 
2885  switch (object->classId)
2886  {
2887  case RelationRelationId:
2888  /* caller must check objectSubId */
2889  return OCLASS_CLASS;
2890 
2891  case ProcedureRelationId:
2892  return OCLASS_PROC;
2893 
2894  case TypeRelationId:
2895  return OCLASS_TYPE;
2896 
2897  case CastRelationId:
2898  return OCLASS_CAST;
2899 
2900  case CollationRelationId:
2901  return OCLASS_COLLATION;
2902 
2903  case ConstraintRelationId:
2904  return OCLASS_CONSTRAINT;
2905 
2906  case ConversionRelationId:
2907  return OCLASS_CONVERSION;
2908 
2909  case AttrDefaultRelationId:
2910  return OCLASS_DEFAULT;
2911 
2912  case LanguageRelationId:
2913  return OCLASS_LANGUAGE;
2914 
2915  case LargeObjectRelationId:
2916  return OCLASS_LARGEOBJECT;
2917 
2918  case OperatorRelationId:
2919  return OCLASS_OPERATOR;
2920 
2921  case OperatorClassRelationId:
2922  return OCLASS_OPCLASS;
2923 
2924  case OperatorFamilyRelationId:
2925  return OCLASS_OPFAMILY;
2926 
2927  case AccessMethodRelationId:
2928  return OCLASS_AM;
2929 
2930  case AccessMethodOperatorRelationId:
2931  return OCLASS_AMOP;
2932 
2933  case AccessMethodProcedureRelationId:
2934  return OCLASS_AMPROC;
2935 
2936  case RewriteRelationId:
2937  return OCLASS_REWRITE;
2938 
2939  case TriggerRelationId:
2940  return OCLASS_TRIGGER;
2941 
2942  case NamespaceRelationId:
2943  return OCLASS_SCHEMA;
2944 
2945  case StatisticExtRelationId:
2946  return OCLASS_STATISTIC_EXT;
2947 
2948  case TSParserRelationId:
2949  return OCLASS_TSPARSER;
2950 
2951  case TSDictionaryRelationId:
2952  return OCLASS_TSDICT;
2953 
2954  case TSTemplateRelationId:
2955  return OCLASS_TSTEMPLATE;
2956 
2957  case TSConfigRelationId:
2958  return OCLASS_TSCONFIG;
2959 
2960  case AuthIdRelationId:
2961  return OCLASS_ROLE;
2962 
2963  case DatabaseRelationId:
2964  return OCLASS_DATABASE;
2965 
2966  case TableSpaceRelationId:
2967  return OCLASS_TBLSPACE;
2968 
2969  case ForeignDataWrapperRelationId:
2970  return OCLASS_FDW;
2971 
2972  case ForeignServerRelationId:
2973  return OCLASS_FOREIGN_SERVER;
2974 
2975  case UserMappingRelationId:
2976  return OCLASS_USER_MAPPING;
2977 
2978  case DefaultAclRelationId:
2979  return OCLASS_DEFACL;
2980 
2981  case ExtensionRelationId:
2982  return OCLASS_EXTENSION;
2983 
2984  case EventTriggerRelationId:
2985  return OCLASS_EVENT_TRIGGER;
2986 
2987  case PolicyRelationId:
2988  return OCLASS_POLICY;
2989 
2990  case PublicationRelationId:
2991  return OCLASS_PUBLICATION;
2992 
2993  case PublicationRelRelationId:
2994  return OCLASS_PUBLICATION_REL;
2995 
2996  case SubscriptionRelationId:
2997  return OCLASS_SUBSCRIPTION;
2998 
2999  case TransformRelationId:
3000  return OCLASS_TRANSFORM;
3001  }
3002 
3003  /* shouldn't get here */
3004  elog(ERROR, "unrecognized object class: %u", object->classId);
3005  return OCLASS_CLASS; /* keep compiler quiet */
3006 }
3007 
3008 /*
3009  * delete initial ACL for extension objects
3010  */
3011 static void
3013 {
3014  Relation relation;
3015  ScanKeyData key[3];
3016  SysScanDesc scan;
3017  HeapTuple oldtuple;
3018 
3019  relation = table_open(InitPrivsRelationId, RowExclusiveLock);
3020 
3021  ScanKeyInit(&key[0],
3022  Anum_pg_init_privs_objoid,
3023  BTEqualStrategyNumber, F_OIDEQ,
3024  ObjectIdGetDatum(object->objectId));
3025  ScanKeyInit(&key[1],
3026  Anum_pg_init_privs_classoid,
3027  BTEqualStrategyNumber, F_OIDEQ,
3028  ObjectIdGetDatum(object->classId));
3029  ScanKeyInit(&key[2],
3030  Anum_pg_init_privs_objsubid,
3031  BTEqualStrategyNumber, F_INT4EQ,
3032  Int32GetDatum(object->objectSubId));
3033 
3034  scan = systable_beginscan(relation, InitPrivsObjIndexId, true,
3035  NULL, 3, key);
3036 
3037  while (HeapTupleIsValid(oldtuple = systable_getnext(scan)))
3038  CatalogTupleDelete(relation, &oldtuple->t_self);
3039 
3040  systable_endscan(scan);
3041 
3042  table_close(relation, RowExclusiveLock);
3043 }
Datum constvalue
Definition: primnodes.h:219
static void findDependentObjects(const ObjectAddress *object, int objflags, int flags, ObjectAddressStack *stack, ObjectAddresses *targetObjects, const ObjectAddresses *pendingObjects, Relation *depRel)
Definition: dependency.c:550
void RemoveTriggerById(Oid trigOid)
Definition: trigger.c:1227
#define DEPFLAG_SUBOBJECT
Definition: dependency.c:106
Oid CurrentExtensionObject
Definition: extension.c:72
DependencyType
Definition: dependency.h:31
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2355
static int object_address_comparator(const void *a, const void *b)
Definition: dependency.c:2522
#define DEPFLAG_PARTITION
Definition: dependency.c:102
#define IsA(nodeptr, _type_)
Definition: nodes.h:590
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
List * joinaliasvars
Definition: parsenodes.h:1070
Index varlevelsup
Definition: primnodes.h:196
int errhint(const char *fmt,...)
Definition: elog.c:1156
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:595
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
void index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode)
Definition: index.c:2256
static void add_exact_object_address_extra(const ObjectAddress *object, const ObjectAddressExtra *extra, ObjectAddresses *addrs)
Definition: dependency.c:2646
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1851
void RemoveStatisticsById(Oid statsOid)
Definition: statscmds.c:693
AttrNumber get_object_attnum_oid(Oid class_id)
static void deleteOneObject(const ObjectAddress *object, Relation *depRel, int32 flags)
#define RelationGetDescr(relation)
Definition: rel.h:483
Oid resulttype
Definition: primnodes.h:800
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1019
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:200
bool trackDroppedObjectsNeeded(void)
void sort_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2850
void RemoveExtensionById(Oid extId)
Definition: extension.c:1875
ObjectAddresses * addrs
Definition: dependency.c:138
List * constraintDeps
Definition: parsenodes.h:180
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1974
#define DatumGetObjectId(X)
Definition: postgres.h:544
void recordDependencyOnCollations(ObjectAddress *myself, List *collations, bool record_version)
Definition: dependency.c:1647
bool(* VisitDependenciesOfCB)(const ObjectAddress *otherObject, const char *version, char **new_version, void *data)
Definition: dependency.h:191
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
Definition: dependency.c:2830
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
Definition: dependency.c:2681
Oid resulttype
Definition: primnodes.h:871
#define QTW_EXAMINE_SORTGROUP
Definition: nodeFuncs.h:30
List * opfamilies
Definition: primnodes.h:1108
#define PERFORM_DELETION_SKIP_ORIGINAL
Definition: dependency.h:144
void ReleaseDeletionLock(const ObjectAddress *object)
Definition: dependency.c:1632
int resultRelation
Definition: parsenodes.h:130
void DeleteSecurityLabel(const ObjectAddress *object)
Definition: seclabel.c:520
#define LAST_OCLASS
Definition: dependency.h:138
Oid endInRangeFunc
Definition: parsenodes.h:1385
#define AccessShareLock
Definition: lockdefs.h:36
Oid inputcollid
Definition: primnodes.h:326
Oid get_object_oid_index(Oid class_id)
Definition: nodes.h:539
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MemSet(start, val, len)
Definition: c.h:1008
AttrNumber varattno
Definition: primnodes.h:191
Expr * arg
Definition: primnodes.h:798
#define InitPrivsObjIndexId
Definition: pg_init_privs.h:69
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
void RemovePublicationRelById(Oid proid)
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:46
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2621
#define lengthof(array)
Definition: c.h:734
#define DEPFLAG_REVERSE
Definition: dependency.c:104
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2566
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2862
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:186
void RemoveTypeById(Oid typeOid)
Definition: typecmds.c:656
ObjectClass getObjectClass(const ObjectAddress *object)
Definition: dependency.c:2877
#define OidIsValid(objectId)
Definition: c.h:710
struct ObjectAddressStack * next
Definition: dependency.c:125
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2462
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
List * colcollations
Definition: primnodes.h:92
signed int int32
Definition: c.h:429
List * targetList
Definition: parsenodes.h:150
bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
Definition: genam.c:561
void RemoveOperatorById(Oid operOid)
Definition: operatorcmds.c:364
#define PERFORM_DELETION_CONCURRENTLY
Definition: dependency.h:142
#define list_make1(x1)
Definition: pg_list.h:206
ObjectAddress obj
Definition: dependency.c:131
Oid consttype
Definition: primnodes.h:215
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:918
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
Oid get_typ_typrelid(Oid typid)
Definition: lsyscache.c:2678
void pfree(void *pointer)
Definition: mcxt.c:1169
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
bool resjunk
Definition: primnodes.h:1451
List * rtable
Definition: parsenodes.h:147
Oid funcid
Definition: primnodes.h:495
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
#define DEPFLAG_ORIGINAL
Definition: dependency.c:98
#define DEPFLAG_IS_PART
Definition: dependency.c:105
static const Oid object_classes[]
Definition: dependency.c:146
#define DEPFLAG_AUTO
Definition: dependency.c:100
#define lfirst_int(lc)
Definition: pg_list.h:170
void RemoveTSConfigurationById(Oid cfgId)
Definition: tsearchcmds.c:1061
static void * list_nth(const List *list, int n)
Definition: pg_list.h:278
int get_object_catcache_oid(Oid class_id)
ItemPointerData t_self
Definition: htup.h:65
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool reverse_self, bool record_version)
Definition: dependency.c:1734
const ObjectAddress * object
Definition: dependency.c:123
#define DEPFLAG_INTERNAL
Definition: dependency.c:101
#define DEBUG2
Definition: elog.h:24
bool message_level_is_interesting(int elevel)
Definition: elog.c:270
void RemovePolicyById(Oid policy_id)
Definition: policy.c:334
static bool object_address_present_add_flags(const ObjectAddress *object, int flags, ObjectAddresses *addrs)
Definition: dependency.c:2707
struct ObjectAddressStack ObjectAddressStack
ObjectAddress * refs
Definition: dependency.c:112
ObjectClass
Definition: dependency.h:96
#define RowExclusiveLock
Definition: lockdefs.h:38
int errdetail(const char *fmt,...)
Definition: elog.c:1042
AttrNumber resno
Definition: primnodes.h:1445
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
Definition: dependency.c:1689
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:976
void RemoveAttributeById(Oid relid, AttrNumber attnum)
Definition: heap.c:1662
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
Definition: dependency.c:313
static void reportDependentObjects(const ObjectAddresses *targetObjects, DropBehavior behavior, int flags, const ObjectAddress *origObject)
Definition: dependency.c:1103
int errdetail_log(const char *fmt,...)
Definition: elog.c:1090
Oid resulttype
Definition: primnodes.h:830
Oid winfnoid
Definition: primnodes.h:386
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:76
void DeleteSequenceTuple(Oid relid)
Definition: sequence.c:526
void visitDependenciesOf(const ObjectAddress *object, VisitDependenciesOfCB callback, void *userdata)
Definition: dependency.c:443
#define DependDependerIndexId
Definition: pg_depend.h:81
void RemoveAttrDefaultById(Oid attrdefId)
Definition: heap.c:1832
#define rt_fetch(rangetable_index, rangetable)
Definition: parsetree.h:31
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior, bool record_version)
Definition: pg_depend.c:63
void LargeObjectDrop(Oid loid)
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
Definition: pg_shdepend.c:1001
#define DependReferenceIndexId
Definition: pg_depend.h:83
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:997
bool EventTriggerSupportsObjectClass(ObjectClass objclass)
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
Index varno
Definition: primnodes.h:189
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:761
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
#define ngettext(s, p, n)
Definition: c.h:1182
#define TextDatumGetCString(d)
Definition: builtins.h:83
void AcquireDeletionLock(const ObjectAddress *object, int flags)
Definition: dependency.c:1603
DropBehavior
Definition: parsenodes.h:1846
uintptr_t Datum
Definition: postgres.h:411
void CommandCounterIncrement(void)
Definition: xact.c:1021
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
void DeleteComments(Oid oid, Oid classoid, int32 subid)
Definition: comment.c:325
Oid resulttype
Definition: primnodes.h:851
Oid cycle_mark_collation
Definition: parsenodes.h:1493
static void DropObjectById(const ObjectAddress *object)
Definition: dependency.c:1304
List * coltypes
Definition: primnodes.h:90
bool creating_extension
Definition: extension.c:71
Oid aggfnoid
Definition: primnodes.h:323
#define ereport(elevel,...)
Definition: elog.h:157
#define DEPFLAG_EXTENSION
Definition: dependency.c:103
#define NOTICE
Definition: elog.h:37
CmdType commandType
Definition: parsenodes.h:120
List * lcons(void *datum, List *list)
Definition: list.c:468
int errmsg_internal(const char *fmt,...)
Definition: elog.c:996
List * funccolcollations
Definition: parsenodes.h:1180
#define ShareUpdateExclusiveLock
Definition: lockdefs.h:39
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
Oid inputcollid
Definition: primnodes.h:502
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
#define PERFORM_DELETION_QUIETLY
Definition: dependency.h:143
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1904
Oid row_typeid
Definition: primnodes.h:1059
static int list_length(const List *l)
Definition: pg_list.h:149
Oid inputcollid
Definition: primnodes.h:1140
void EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool normal)
static void doDeletion(const ObjectAddress *object, int flags)
Definition: dependency.c:1465
Oid inputcollid
Definition: primnodes.h:547
Oid inputcollid
Definition: primnodes.h:389
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
#define InvalidAttrNumber
Definition: attnum.h:23
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
void RemoveFunctionById(Oid funcOid)
RTEKind rtekind
Definition: parsenodes.h:995
const char * get_object_class_descr(Oid class_id)
static Datum values[MAXATTR]
Definition: bootstrap.c:166
ObjectAddressExtra * extras
Definition: dependency.c:113
#define AccessExclusiveLock
Definition: lockdefs.h:45
#define Int32GetDatum(X)
Definition: postgres.h:523
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define DEPFLAG_NORMAL
Definition: dependency.c:99
NodeTag type
Definition: parsenodes.h:993
List * fieldnums
Definition: primnodes.h:829
void RemoveRewriteRuleById(Oid ruleOid)
Definition: rewriteRemove.c:39
#define elog(elevel,...)
Definition: elog.h:232
int i
#define PERFORM_DELETION_CONCURRENT_LOCK
Definition: dependency.h:146
static void DeleteInitPrivs(const ObjectAddress *object)
Definition: dependency.c:3012
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define CStringGetTextDatum(s)
Definition: builtins.h:82
Oid refcontainertype
Definition: primnodes.h:439
static void deleteObjectsInList(ObjectAddresses *targetObjects, Relation *depRel, int flags)
Definition: dependency.c:225
Oid opno
Definition: primnodes.h:542
void performMultipleDeletions(const ObjectAddresses *objects, DropBehavior behavior, int flags)
Definition: dependency.c:372
#define MAX_REPORTED_DEPS
#define qsort(a, b, c, d)
Definition: port.h:504
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:109
List * inputcollids
Definition: primnodes.h:1109
static bool stack_address_present_add_flags(const ObjectAddress *object, int flags, ObjectAddressStack *stack)
Definition: dependency.c:2780
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2468
#define PERFORM_DELETION_SKIP_EXTENSIONS
Definition: dependency.h:145
void heap_drop_with_catalog(Oid relid)
Definition: heap.c:1905
Definition: pg_list.h:50
static void add_object_address(ObjectClass oclass, Oid objectId, int32 subId, ObjectAddresses *addrs)
Definition: dependency.c:2588
ObjectAddress dependee
Definition: dependency.c:94
Oid startInRangeFunc
Definition: parsenodes.h:1384
void RemoveConstraintById(Oid conId)
#define _(x)
Definition: elog.c:89
Oid paramtype
Definition: primnodes.h:269
#define InvokeObjectDropHookArg(classId, objectId, subId, dropflags)
Definition: objectaccess.h:162
bool constisnull
Definition: primnodes.h:220
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define lfirst_oid(lc)
Definition: pg_list.h:171
List * list_delete_first(List *list)
Definition: list.c:875
#define PERFORM_DELETION_INTERNAL
Definition: dependency.h:141
#define QTW_IGNORE_JOINALIASES
Definition: nodeFuncs.h:23
AttrNumber fieldnum
Definition: primnodes.h:799