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