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