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