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