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