1 /*-------------------------------------------------------------------------
4 * Routines to support inter-object dependencies.
7 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.20 2003/02/07 01:33:06 tgl Exp $
13 *-------------------------------------------------------------------------
17 #include "access/genam.h"
18 #include "access/heapam.h"
19 #include "catalog/catname.h"
20 #include "catalog/dependency.h"
21 #include "catalog/heap.h"
22 #include "catalog/index.h"
23 #include "catalog/indexing.h"
24 #include "catalog/namespace.h"
25 #include "catalog/pg_attrdef.h"
26 #include "catalog/pg_cast.h"
27 #include "catalog/pg_constraint.h"
28 #include "catalog/pg_conversion.h"
29 #include "catalog/pg_depend.h"
30 #include "catalog/pg_language.h"
31 #include "catalog/pg_opclass.h"
32 #include "catalog/pg_rewrite.h"
33 #include "catalog/pg_trigger.h"
34 #include "commands/comment.h"
35 #include "commands/defrem.h"
36 #include "commands/proclang.h"
37 #include "commands/schemacmds.h"
38 #include "commands/trigger.h"
39 #include "commands/typecmds.h"
40 #include "lib/stringinfo.h"
41 #include "miscadmin.h"
42 #include "optimizer/clauses.h"
43 #include "parser/parsetree.h"
44 #include "rewrite/rewriteRemove.h"
45 #include "utils/builtins.h"
46 #include "utils/fmgroids.h"
47 #include "utils/lsyscache.h"
48 #include "utils/syscache.h"
51 /* This enum covers all system catalogs whose OIDs can appear in classid. */
52 typedef enum ObjectClasses
54 OCLASS_CLASS, /* pg_class */
55 OCLASS_PROC, /* pg_proc */
56 OCLASS_TYPE, /* pg_type */
57 OCLASS_CAST, /* pg_cast */
58 OCLASS_CONSTRAINT, /* pg_constraint */
59 OCLASS_CONVERSION, /* pg_conversion */
60 OCLASS_DEFAULT, /* pg_attrdef */
61 OCLASS_LANGUAGE, /* pg_language */
62 OCLASS_OPERATOR, /* pg_operator */
63 OCLASS_OPCLASS, /* pg_opclass */
64 OCLASS_REWRITE, /* pg_rewrite */
65 OCLASS_TRIGGER, /* pg_trigger */
66 OCLASS_SCHEMA, /* pg_namespace */
67 MAX_OCLASS /* MUST BE LAST */
70 /* expansible list of ObjectAddresses */
73 ObjectAddress *refs; /* => palloc'd array */
74 int numrefs; /* current number of references */
75 int maxrefs; /* current size of palloc'd array */
78 /* for find_expr_references_walker */
81 ObjectAddresses addrs; /* addresses being accumulated */
82 List *rtables; /* list of rangetables to resolve Vars */
83 } find_expr_references_context;
87 * Because not all system catalogs have predetermined OIDs, we build a table
88 * mapping between ObjectClasses and OIDs. This is done at most once per
89 * backend run, to minimize lookup overhead.
91 static bool object_classes_initialized = false;
92 static Oid object_classes[MAX_OCLASS];
95 static void findAutoDeletableObjects(const ObjectAddress *object,
96 ObjectAddresses *oktodelete,
98 static bool recursiveDeletion(const ObjectAddress *object,
99 DropBehavior behavior,
100 const ObjectAddress *callingObject,
101 ObjectAddresses *oktodelete,
103 static bool deleteDependentObjects(const ObjectAddress *object,
104 const char *objDescription,
105 DropBehavior behavior,
106 ObjectAddresses *oktodelete,
108 static void doDeletion(const ObjectAddress *object);
109 static bool find_expr_references_walker(Node *node,
110 find_expr_references_context *context);
111 static void eliminate_duplicate_dependencies(ObjectAddresses *addrs);
112 static int object_address_comparator(const void *a, const void *b);
113 static void init_object_addresses(ObjectAddresses *addrs);
114 static void add_object_address(ObjectClasses oclass, Oid objectId, int32 subId,
115 ObjectAddresses *addrs);
116 static void add_exact_object_address(const ObjectAddress *object,
117 ObjectAddresses *addrs);
118 static bool object_address_present(const ObjectAddress *object,
119 ObjectAddresses *addrs);
120 static void term_object_addresses(ObjectAddresses *addrs);
121 static void init_object_classes(void);
122 static ObjectClasses getObjectClass(const ObjectAddress *object);
123 static char *getObjectDescription(const ObjectAddress *object);
124 static void getRelationDescription(StringInfo buffer, Oid relid);
128 * performDeletion: attempt to drop the specified object. If CASCADE
129 * behavior is specified, also drop any dependent objects (recursively).
130 * If RESTRICT behavior is specified, error out if there are any dependent
131 * objects, except for those that should be implicitly dropped anyway
132 * according to the dependency type.
134 * This is the outer control routine for all forms of DROP that drop objects
135 * that can participate in dependencies.
138 performDeletion(const ObjectAddress *object,
139 DropBehavior behavior)
141 char *objDescription;
143 ObjectAddresses oktodelete;
146 * Get object description for possible use in failure message. Must do
147 * this before deleting it ...
149 objDescription = getObjectDescription(object);
152 * We save some cycles by opening pg_depend just once and passing the
153 * Relation pointer down to all the recursive deletion steps.
155 depRel = heap_openr(DependRelationName, RowExclusiveLock);
158 * Construct a list of objects that are reachable by AUTO or INTERNAL
159 * dependencies from the target object. These should be deleted silently,
160 * even if the actual deletion pass first reaches one of them via a
161 * non-auto dependency.
163 init_object_addresses(&oktodelete);
165 findAutoDeletableObjects(object, &oktodelete, depRel);
167 if (!recursiveDeletion(object, behavior, NULL, &oktodelete, depRel))
168 elog(ERROR, "Cannot drop %s because other objects depend on it"
169 "\n\tUse DROP ... CASCADE to drop the dependent objects too",
172 term_object_addresses(&oktodelete);
174 heap_close(depRel, RowExclusiveLock);
176 pfree(objDescription);
181 * deleteWhatDependsOn: attempt to drop everything that depends on the
182 * specified object, though not the object itself. Behavior is always
185 * This is currently used only to clean out the contents of a schema
186 * (namespace): the passed object is a namespace.
189 deleteWhatDependsOn(const ObjectAddress *object)
191 char *objDescription;
193 ObjectAddresses oktodelete;
196 * Get object description for possible use in failure messages
198 objDescription = getObjectDescription(object);
201 * We save some cycles by opening pg_depend just once and passing the
202 * Relation pointer down to all the recursive deletion steps.
204 depRel = heap_openr(DependRelationName, RowExclusiveLock);
207 * Construct a list of objects that are reachable by AUTO or INTERNAL
208 * dependencies from the target object. These should be deleted silently,
209 * even if the actual deletion pass first reaches one of them via a
210 * non-auto dependency.
212 init_object_addresses(&oktodelete);
214 findAutoDeletableObjects(object, &oktodelete, depRel);
217 * Now invoke only step 2 of recursiveDeletion: just recurse to the
218 * stuff dependent on the given object.
220 if (!deleteDependentObjects(object, objDescription,
221 DROP_CASCADE, &oktodelete, depRel))
222 elog(ERROR, "Failed to drop all objects depending on %s",
226 * We do not need CommandCounterIncrement here, since if step 2 did
227 * anything then each recursive call will have ended with one.
230 term_object_addresses(&oktodelete);
232 heap_close(depRel, RowExclusiveLock);
234 pfree(objDescription);
239 * findAutoDeletableObjects: find all objects that are reachable by AUTO or
240 * INTERNAL dependency paths from the given object. Add them all to the
241 * oktodelete list. Note that the originally given object will also be
244 * depRel is the already-open pg_depend relation.
247 findAutoDeletableObjects(const ObjectAddress *object,
248 ObjectAddresses *oktodelete,
255 ObjectAddress otherObject;
258 * If this object is already in oktodelete, then we already visited it;
259 * don't do so again (this prevents infinite recursion if there's a loop
260 * in pg_depend). Otherwise, add it.
262 if (object_address_present(object, oktodelete))
264 add_exact_object_address(object, oktodelete);
267 * Scan pg_depend records that link to this object, showing the things
268 * that depend on it. For each one that is AUTO or INTERNAL, visit the
269 * referencing object.
271 * When dropping a whole object (subId = 0), find pg_depend records for
272 * its sub-objects too.
274 ScanKeyEntryInitialize(&key[0], 0x0,
275 Anum_pg_depend_refclassid, F_OIDEQ,
276 ObjectIdGetDatum(object->classId));
277 ScanKeyEntryInitialize(&key[1], 0x0,
278 Anum_pg_depend_refobjid, F_OIDEQ,
279 ObjectIdGetDatum(object->objectId));
280 if (object->objectSubId != 0)
282 ScanKeyEntryInitialize(&key[2], 0x0,
283 Anum_pg_depend_refobjsubid, F_INT4EQ,
284 Int32GetDatum(object->objectSubId));
290 scan = systable_beginscan(depRel, DependReferenceIndex, true,
291 SnapshotNow, nkeys, key);
293 while (HeapTupleIsValid(tup = systable_getnext(scan)))
295 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
297 switch (foundDep->deptype)
299 case DEPENDENCY_NORMAL:
302 case DEPENDENCY_AUTO:
303 case DEPENDENCY_INTERNAL:
305 otherObject.classId = foundDep->classid;
306 otherObject.objectId = foundDep->objid;
307 otherObject.objectSubId = foundDep->objsubid;
308 findAutoDeletableObjects(&otherObject, oktodelete, depRel);
312 * For a PIN dependency we just elog immediately; there
313 * won't be any others to examine, and we aren't ever
314 * going to let the user delete it.
316 elog(ERROR, "Cannot drop %s because it is required by the database system",
317 getObjectDescription(object));
320 elog(ERROR, "findAutoDeletableObjects: unknown dependency type '%c' for %s",
321 foundDep->deptype, getObjectDescription(object));
326 systable_endscan(scan);
331 * recursiveDeletion: delete a single object for performDeletion, plus
332 * (recursively) anything that depends on it.
334 * Returns TRUE if successful, FALSE if not.
336 * callingObject is NULL at the outer level, else identifies the object that
337 * we recursed from (the reference object that someone else needs to delete).
339 * oktodelete is a list of objects verified deletable (ie, reachable by one
340 * or more AUTO or INTERNAL dependencies from the original target).
342 * depRel is the already-open pg_depend relation.
345 * In RESTRICT mode, we perform all the deletions anyway, but elog a NOTICE
346 * and return FALSE if we find a restriction violation. performDeletion
347 * will then abort the transaction to nullify the deletions. We have to
348 * do it this way to (a) report all the direct and indirect dependencies
349 * while (b) not going into infinite recursion if there's a cycle.
351 * This is even more complex than one could wish, because it is possible for
352 * the same pair of objects to be related by both NORMAL and AUTO/INTERNAL
353 * dependencies. Also, we might have a situation where we've been asked to
354 * delete object A, and objects B and C both have AUTO dependencies on A,
355 * but B also has a NORMAL dependency on C. (Since any of these paths might
356 * be indirect, we can't prevent these scenarios, but must cope instead.)
357 * If we visit C before B then we would mistakenly decide that the B->C link
358 * should prevent the restricted drop from occurring. To handle this, we make
359 * a pre-scan to find all the objects that are auto-deletable from A. If we
360 * visit C first, but B is present in the oktodelete list, then we make no
361 * complaint but recurse to delete B anyway. (Note that in general we must
362 * delete B before deleting C; the drop routine for B may try to access C.)
364 * Note: in the case where the path to B is traversed first, we will not
365 * see the NORMAL dependency when we reach C, because of the pg_depend
366 * removals done in step 1. The oktodelete list is necessary just
367 * to make the behavior independent of the order in which pg_depend
368 * entries are visited.
371 recursiveDeletion(const ObjectAddress *object,
372 DropBehavior behavior,
373 const ObjectAddress *callingObject,
374 ObjectAddresses *oktodelete,
378 char *objDescription;
383 ObjectAddress otherObject;
384 ObjectAddress owningObject;
385 bool amOwned = false;
388 * Get object description for possible use in messages. Must do this
389 * before deleting it ...
391 objDescription = getObjectDescription(object);
394 * Step 1: find and remove pg_depend records that link from this
395 * object to others. We have to do this anyway, and doing it first
396 * ensures that we avoid infinite recursion in the case of cycles.
397 * Also, some dependency types require extra processing here.
399 * When dropping a whole object (subId = 0), remove all pg_depend records
400 * for its sub-objects too.
402 ScanKeyEntryInitialize(&key[0], 0x0,
403 Anum_pg_depend_classid, F_OIDEQ,
404 ObjectIdGetDatum(object->classId));
405 ScanKeyEntryInitialize(&key[1], 0x0,
406 Anum_pg_depend_objid, F_OIDEQ,
407 ObjectIdGetDatum(object->objectId));
408 if (object->objectSubId != 0)
410 ScanKeyEntryInitialize(&key[2], 0x0,
411 Anum_pg_depend_objsubid, F_INT4EQ,
412 Int32GetDatum(object->objectSubId));
418 scan = systable_beginscan(depRel, DependDependerIndex, true,
419 SnapshotNow, nkeys, key);
421 while (HeapTupleIsValid(tup = systable_getnext(scan)))
423 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
425 otherObject.classId = foundDep->refclassid;
426 otherObject.objectId = foundDep->refobjid;
427 otherObject.objectSubId = foundDep->refobjsubid;
429 switch (foundDep->deptype)
431 case DEPENDENCY_NORMAL:
432 case DEPENDENCY_AUTO:
435 case DEPENDENCY_INTERNAL:
438 * This object is part of the internal implementation of
439 * another object. We have three cases:
441 * 1. At the outermost recursion level, disallow the DROP.
442 * (We just elog here, rather than proceeding, since no
443 * other dependencies are likely to be interesting.)
445 if (callingObject == NULL)
447 char *otherObjDesc = getObjectDescription(&otherObject);
449 elog(ERROR, "Cannot drop %s because %s requires it"
450 "\n\tYou may drop %s instead",
451 objDescription, otherObjDesc, otherObjDesc);
455 * 2. When recursing from the other end of this
456 * dependency, it's okay to continue with the deletion.
457 * This holds when recursing from a whole object that
458 * includes the nominal other end as a component, too.
460 if (callingObject->classId == otherObject.classId &&
461 callingObject->objectId == otherObject.objectId &&
462 (callingObject->objectSubId == otherObject.objectSubId ||
463 callingObject->objectSubId == 0))
467 * 3. When recursing from anyplace else, transform this
468 * deletion request into a delete of the other object.
469 * (This will be an error condition iff RESTRICT mode.) In
470 * this case we finish deleting my dependencies except for
471 * the INTERNAL link, which will be needed to cause the
472 * owning object to recurse back to me.
474 if (amOwned) /* shouldn't happen */
475 elog(ERROR, "recursiveDeletion: multiple INTERNAL dependencies for %s",
477 owningObject = otherObject;
479 /* "continue" bypasses the simple_heap_delete call below */
484 * Should not happen; PIN dependencies should have zeroes
485 * in the depender fields...
487 elog(ERROR, "recursiveDeletion: incorrect use of PIN dependency with %s",
491 elog(ERROR, "recursiveDeletion: unknown dependency type '%c' for %s",
492 foundDep->deptype, objDescription);
496 simple_heap_delete(depRel, &tup->t_self);
499 systable_endscan(scan);
502 * CommandCounterIncrement here to ensure that preceding changes are
503 * all visible; in particular, that the above deletions of pg_depend
504 * entries are visible. That prevents infinite recursion in case of a
505 * dependency loop (which is perfectly legal).
507 CommandCounterIncrement();
510 * If we found we are owned by another object, ask it to delete itself
511 * instead of proceeding. Complain if RESTRICT mode, unless the other
512 * object is in oktodelete.
516 if (object_address_present(&owningObject, oktodelete))
517 elog(DEBUG1, "Drop auto-cascades to %s",
518 getObjectDescription(&owningObject));
519 else if (behavior == DROP_RESTRICT)
521 elog(NOTICE, "%s depends on %s",
522 getObjectDescription(&owningObject),
527 elog(NOTICE, "Drop cascades to %s",
528 getObjectDescription(&owningObject));
530 if (!recursiveDeletion(&owningObject, behavior,
535 pfree(objDescription);
541 * Step 2: scan pg_depend records that link to this object, showing
542 * the things that depend on it. Recursively delete those things.
543 * Note it's important to delete the dependent objects
544 * before the referenced one, since the deletion routines might do
545 * things like try to update the pg_class record when deleting a check
548 if (!deleteDependentObjects(object, objDescription,
549 behavior, oktodelete, depRel))
553 * We do not need CommandCounterIncrement here, since if step 2 did
554 * anything then each recursive call will have ended with one.
558 * Step 3: delete the object itself.
563 * Delete any comments associated with this object. (This is a
564 * convenient place to do it instead of having every object type know
567 DeleteComments(object->objectId, object->classId, object->objectSubId);
570 * CommandCounterIncrement here to ensure that preceding changes are
573 CommandCounterIncrement();
578 pfree(objDescription);
585 * deleteDependentObjects - find and delete objects that depend on 'object'
587 * Scan pg_depend records that link to the given object, showing
588 * the things that depend on it. Recursively delete those things. (We
589 * don't delete the pg_depend records here, as the recursive call will
590 * do that.) Note it's important to delete the dependent objects
591 * before the referenced one, since the deletion routines might do
592 * things like try to update the pg_class record when deleting a check
595 * When dropping a whole object (subId = 0), find pg_depend records for
596 * its sub-objects too.
598 * object: the object to find dependencies on
599 * objDescription: description of object (only used for error messages)
600 * behavior: desired drop behavior
601 * oktodelete: stuff that's AUTO-deletable
602 * depRel: already opened pg_depend relation
604 * Returns TRUE if all is well, false if any problem found.
606 * NOTE: because we are using SnapshotNow, if a recursive call deletes
607 * any pg_depend tuples that our scan hasn't yet visited, we will not
608 * see them as good when we do visit them. This is essential for
609 * correct behavior if there are multiple dependency paths between two
610 * objects --- else we might try to delete an already-deleted object.
613 deleteDependentObjects(const ObjectAddress *object,
614 const char *objDescription,
615 DropBehavior behavior,
616 ObjectAddresses *oktodelete,
624 ObjectAddress otherObject;
626 ScanKeyEntryInitialize(&key[0], 0x0,
627 Anum_pg_depend_refclassid, F_OIDEQ,
628 ObjectIdGetDatum(object->classId));
629 ScanKeyEntryInitialize(&key[1], 0x0,
630 Anum_pg_depend_refobjid, F_OIDEQ,
631 ObjectIdGetDatum(object->objectId));
632 if (object->objectSubId != 0)
634 ScanKeyEntryInitialize(&key[2], 0x0,
635 Anum_pg_depend_refobjsubid, F_INT4EQ,
636 Int32GetDatum(object->objectSubId));
642 scan = systable_beginscan(depRel, DependReferenceIndex, true,
643 SnapshotNow, nkeys, key);
645 while (HeapTupleIsValid(tup = systable_getnext(scan)))
647 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
649 otherObject.classId = foundDep->classid;
650 otherObject.objectId = foundDep->objid;
651 otherObject.objectSubId = foundDep->objsubid;
653 switch (foundDep->deptype)
655 case DEPENDENCY_NORMAL:
657 * Perhaps there was another dependency path that would
658 * have allowed silent deletion of the otherObject, had
659 * we only taken that path first.
660 * In that case, act like this link is AUTO, too.
662 if (object_address_present(&otherObject, oktodelete))
663 elog(DEBUG1, "Drop auto-cascades to %s",
664 getObjectDescription(&otherObject));
665 else if (behavior == DROP_RESTRICT)
667 elog(NOTICE, "%s depends on %s",
668 getObjectDescription(&otherObject),
673 elog(NOTICE, "Drop cascades to %s",
674 getObjectDescription(&otherObject));
676 if (!recursiveDeletion(&otherObject, behavior,
681 case DEPENDENCY_AUTO:
682 case DEPENDENCY_INTERNAL:
685 * We propagate the DROP without complaint even in the
686 * RESTRICT case. (However, normal dependencies on the
687 * component object could still cause failure.)
689 elog(DEBUG1, "Drop auto-cascades to %s",
690 getObjectDescription(&otherObject));
692 if (!recursiveDeletion(&otherObject, behavior,
700 * For a PIN dependency we just elog immediately; there
701 * won't be any others to report.
703 elog(ERROR, "Cannot drop %s because it is required by the database system",
707 elog(ERROR, "recursiveDeletion: unknown dependency type '%c' for %s",
708 foundDep->deptype, objDescription);
713 systable_endscan(scan);
720 * doDeletion: actually delete a single object
723 doDeletion(const ObjectAddress *object)
725 switch (getObjectClass(object))
729 char relKind = get_rel_relkind(object->objectId);
731 if (relKind == RELKIND_INDEX)
733 Assert(object->objectSubId == 0);
734 index_drop(object->objectId);
738 if (object->objectSubId != 0)
739 RemoveAttributeById(object->objectId,
740 object->objectSubId);
742 heap_drop_with_catalog(object->objectId);
748 RemoveFunctionById(object->objectId);
752 RemoveTypeById(object->objectId);
756 DropCastById(object->objectId);
759 case OCLASS_CONSTRAINT:
760 RemoveConstraintById(object->objectId);
763 case OCLASS_CONVERSION:
764 RemoveConversionById(object->objectId);
768 RemoveAttrDefaultById(object->objectId);
771 case OCLASS_LANGUAGE:
772 DropProceduralLanguageById(object->objectId);
775 case OCLASS_OPERATOR:
776 RemoveOperatorById(object->objectId);
780 RemoveOpClassById(object->objectId);
784 RemoveRewriteRuleById(object->objectId);
788 RemoveTriggerById(object->objectId);
792 RemoveSchemaById(object->objectId);
796 elog(ERROR, "doDeletion: Unsupported object class %u",
802 * recordDependencyOnExpr - find expression dependencies
804 * This is used to find the dependencies of rules, constraint expressions,
807 * Given an expression or query in node-tree form, find all the objects
808 * it refers to (tables, columns, operators, functions, etc). Record
809 * a dependency of the specified type from the given depender object
810 * to each object mentioned in the expression.
812 * rtable is the rangetable to be used to interpret Vars with varlevelsup=0.
813 * It can be NIL if no such variables are expected.
815 * XXX is it important to create dependencies on the datatypes mentioned in
816 * the expression? In most cases this would be redundant (eg, a ref to an
817 * operator indirectly references its input and output datatypes), but I'm
818 * not quite convinced there are no cases where we need it.
821 recordDependencyOnExpr(const ObjectAddress *depender,
822 Node *expr, List *rtable,
823 DependencyType behavior)
825 find_expr_references_context context;
827 init_object_addresses(&context.addrs);
829 /* Set up interpretation for Vars at varlevelsup = 0 */
830 context.rtables = makeList1(rtable);
832 /* Scan the expression tree for referenceable objects */
833 find_expr_references_walker(expr, &context);
835 /* Remove any duplicates */
836 eliminate_duplicate_dependencies(&context.addrs);
839 recordMultipleDependencies(depender,
840 context.addrs.refs, context.addrs.numrefs,
843 term_object_addresses(&context.addrs);
847 * Recursively search an expression tree for object references.
849 * Note: we avoid creating references to columns of tables that participate
850 * in an SQL JOIN construct, but are not actually used anywhere in the query.
851 * To do so, we do not scan the joinaliasvars list of a join RTE while
852 * scanning the query rangetable, but instead scan each individual entry
853 * of the alias list when we find a reference to it.
856 find_expr_references_walker(Node *node,
857 find_expr_references_context *context)
863 Var *var = (Var *) node;
869 /* Find matching rtable entry, or complain if not found */
870 levelsup = var->varlevelsup;
871 rtables = context->rtables;
876 rtables = lnext(rtables);
879 elog(ERROR, "find_expr_references_walker: bogus varlevelsup %d",
881 rtable = lfirst(rtables);
882 if (var->varno <= 0 || var->varno > length(rtable))
883 elog(ERROR, "find_expr_references_walker: bogus varno %d",
885 rte = rt_fetch(var->varno, rtable);
886 if (rte->rtekind == RTE_RELATION)
888 /* If it's a plain relation, reference this column */
889 /* NB: this code works for whole-row Var with attno 0, too */
890 add_object_address(OCLASS_CLASS, rte->relid, var->varattno,
893 else if (rte->rtekind == RTE_JOIN)
895 /* Scan join output column to add references to join inputs */
898 /* We must make the context appropriate for join's level */
899 save_rtables = context->rtables;
900 context->rtables = rtables;
901 if (var->varattno <= 0 ||
902 var->varattno > length(rte->joinaliasvars))
903 elog(ERROR, "find_expr_references_walker: bogus varattno %d",
905 find_expr_references_walker((Node *) nth(var->varattno - 1,
908 context->rtables = save_rtables;
912 if (IsA(node, FuncExpr))
914 FuncExpr *funcexpr = (FuncExpr *) node;
916 add_object_address(OCLASS_PROC, funcexpr->funcid, 0,
918 /* fall through to examine arguments */
920 if (IsA(node, OpExpr))
922 OpExpr *opexpr = (OpExpr *) node;
924 add_object_address(OCLASS_OPERATOR, opexpr->opno, 0,
926 /* fall through to examine arguments */
928 if (IsA(node, DistinctExpr))
930 DistinctExpr *distinctexpr = (DistinctExpr *) node;
932 add_object_address(OCLASS_OPERATOR, distinctexpr->opno, 0,
934 /* fall through to examine arguments */
936 if (IsA(node, Aggref))
938 Aggref *aggref = (Aggref *) node;
940 add_object_address(OCLASS_PROC, aggref->aggfnoid, 0,
942 /* fall through to examine arguments */
944 if (IsA(node, SubLink))
946 SubLink *sublink = (SubLink *) node;
949 foreach(opid, sublink->operOids)
951 add_object_address(OCLASS_OPERATOR, (Oid) lfirsti(opid), 0,
954 /* fall through to examine arguments */
956 if (is_subplan(node))
958 /* Extra work needed here if we ever need this case */
959 elog(ERROR, "find_expr_references_walker: already-planned subqueries not supported");
961 if (IsA(node, Query))
963 /* Recurse into RTE subquery or not-yet-planned sublink subquery */
964 Query *query = (Query *) node;
969 * Add whole-relation refs for each plain relation mentioned in
970 * the subquery's rtable. (Note: query_tree_walker takes care of
971 * recursing into RTE_FUNCTION and RTE_SUBQUERY RTEs, so no need
972 * to do that here. But keep it from looking at join alias lists.)
974 foreach(rtable, query->rtable)
976 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rtable);
978 if (rte->rtekind == RTE_RELATION)
979 add_object_address(OCLASS_CLASS, rte->relid, 0,
983 /* Examine substructure of query */
984 context->rtables = lcons(query->rtable, context->rtables);
985 result = query_tree_walker(query,
986 find_expr_references_walker,
988 QTW_IGNORE_JOINALIASES);
989 context->rtables = lnext(context->rtables);
992 return expression_tree_walker(node, find_expr_references_walker,
997 * Given an array of dependency references, eliminate any duplicates.
1000 eliminate_duplicate_dependencies(ObjectAddresses *addrs)
1002 ObjectAddress *priorobj;
1006 if (addrs->numrefs <= 1)
1007 return; /* nothing to do */
1009 /* Sort the refs so that duplicates are adjacent */
1010 qsort((void *) addrs->refs, addrs->numrefs, sizeof(ObjectAddress),
1011 object_address_comparator);
1014 priorobj = addrs->refs;
1016 for (oldref = 1; oldref < addrs->numrefs; oldref++)
1018 ObjectAddress *thisobj = addrs->refs + oldref;
1020 if (priorobj->classId == thisobj->classId &&
1021 priorobj->objectId == thisobj->objectId)
1023 if (priorobj->objectSubId == thisobj->objectSubId)
1024 continue; /* identical, so drop thisobj */
1027 * If we have a whole-object reference and a reference to a
1028 * part of the same object, we don't need the whole-object
1029 * reference (for example, we don't need to reference both
1030 * table foo and column foo.bar). The whole-object reference
1031 * will always appear first in the sorted list.
1033 if (priorobj->objectSubId == 0)
1035 /* replace whole ref with partial */
1036 priorobj->objectSubId = thisobj->objectSubId;
1040 /* Not identical, so add thisobj to output set */
1042 priorobj->classId = thisobj->classId;
1043 priorobj->objectId = thisobj->objectId;
1044 priorobj->objectSubId = thisobj->objectSubId;
1048 addrs->numrefs = newrefs;
1052 * qsort comparator for ObjectAddress items
1055 object_address_comparator(const void *a, const void *b)
1057 const ObjectAddress *obja = (const ObjectAddress *) a;
1058 const ObjectAddress *objb = (const ObjectAddress *) b;
1060 if (obja->classId < objb->classId)
1062 if (obja->classId > objb->classId)
1064 if (obja->objectId < objb->objectId)
1066 if (obja->objectId > objb->objectId)
1070 * We sort the subId as an unsigned int so that 0 will come first. See
1071 * logic in eliminate_duplicate_dependencies.
1073 if ((unsigned int) obja->objectSubId < (unsigned int) objb->objectSubId)
1075 if ((unsigned int) obja->objectSubId > (unsigned int) objb->objectSubId)
1081 * Routines for handling an expansible array of ObjectAddress items.
1083 * init_object_addresses: initialize an ObjectAddresses array.
1086 init_object_addresses(ObjectAddresses *addrs)
1088 /* Initialize array to empty */
1090 addrs->maxrefs = 32; /* arbitrary initial array size */
1091 addrs->refs = (ObjectAddress *)
1092 palloc(addrs->maxrefs * sizeof(ObjectAddress));
1094 /* Initialize object_classes[] if not done yet */
1095 /* This will be needed by add_object_address() */
1096 if (!object_classes_initialized)
1097 init_object_classes();
1101 * Add an entry to an ObjectAddresses array.
1103 * It is convenient to specify the class by ObjectClass rather than directly
1107 add_object_address(ObjectClasses oclass, Oid objectId, int32 subId,
1108 ObjectAddresses *addrs)
1110 ObjectAddress *item;
1112 /* enlarge array if needed */
1113 if (addrs->numrefs >= addrs->maxrefs)
1115 addrs->maxrefs *= 2;
1116 addrs->refs = (ObjectAddress *)
1117 repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
1119 /* record this item */
1120 item = addrs->refs + addrs->numrefs;
1121 item->classId = object_classes[oclass];
1122 item->objectId = objectId;
1123 item->objectSubId = subId;
1128 * Add an entry to an ObjectAddresses array.
1130 * As above, but specify entry exactly.
1133 add_exact_object_address(const ObjectAddress *object,
1134 ObjectAddresses *addrs)
1136 ObjectAddress *item;
1138 /* enlarge array if needed */
1139 if (addrs->numrefs >= addrs->maxrefs)
1141 addrs->maxrefs *= 2;
1142 addrs->refs = (ObjectAddress *)
1143 repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
1145 /* record this item */
1146 item = addrs->refs + addrs->numrefs;
1152 * Test whether an object is present in an ObjectAddresses array.
1154 * We return "true" if object is a subobject of something in the array, too.
1157 object_address_present(const ObjectAddress *object,
1158 ObjectAddresses *addrs)
1162 for (i = addrs->numrefs - 1; i >= 0; i--)
1164 ObjectAddress *thisobj = addrs->refs + i;
1166 if (object->classId == thisobj->classId &&
1167 object->objectId == thisobj->objectId)
1169 if (object->objectSubId == thisobj->objectSubId ||
1170 thisobj->objectSubId == 0)
1179 * Clean up when done with an ObjectAddresses array.
1182 term_object_addresses(ObjectAddresses *addrs)
1188 * Initialize the object_classes[] table.
1190 * Although some of these OIDs aren't compile-time constants, they surely
1191 * shouldn't change during a backend's run. So, we look them up the
1192 * first time through and then cache them.
1195 init_object_classes(void)
1197 object_classes[OCLASS_CLASS] = RelOid_pg_class;
1198 object_classes[OCLASS_PROC] = RelOid_pg_proc;
1199 object_classes[OCLASS_TYPE] = RelOid_pg_type;
1200 object_classes[OCLASS_CAST] = get_system_catalog_relid(CastRelationName);
1201 object_classes[OCLASS_CONSTRAINT] = get_system_catalog_relid(ConstraintRelationName);
1202 object_classes[OCLASS_CONVERSION] = get_system_catalog_relid(ConversionRelationName);
1203 object_classes[OCLASS_DEFAULT] = get_system_catalog_relid(AttrDefaultRelationName);
1204 object_classes[OCLASS_LANGUAGE] = get_system_catalog_relid(LanguageRelationName);
1205 object_classes[OCLASS_OPERATOR] = get_system_catalog_relid(OperatorRelationName);
1206 object_classes[OCLASS_OPCLASS] = get_system_catalog_relid(OperatorClassRelationName);
1207 object_classes[OCLASS_REWRITE] = get_system_catalog_relid(RewriteRelationName);
1208 object_classes[OCLASS_TRIGGER] = get_system_catalog_relid(TriggerRelationName);
1209 object_classes[OCLASS_SCHEMA] = get_system_catalog_relid(NamespaceRelationName);
1210 object_classes_initialized = true;
1214 * Determine the class of a given object identified by objectAddress.
1216 * This function is needed just because some of the system catalogs do
1217 * not have hardwired-at-compile-time OIDs.
1219 static ObjectClasses
1220 getObjectClass(const ObjectAddress *object)
1222 /* Easy for the bootstrapped catalogs... */
1223 switch (object->classId)
1225 case RelOid_pg_class:
1226 /* caller must check objectSubId */
1227 return OCLASS_CLASS;
1229 case RelOid_pg_proc:
1230 Assert(object->objectSubId == 0);
1233 case RelOid_pg_type:
1234 Assert(object->objectSubId == 0);
1239 * Handle cases where catalog's OID is not hardwired.
1241 if (!object_classes_initialized)
1242 init_object_classes();
1244 if (object->classId == object_classes[OCLASS_CAST])
1246 Assert(object->objectSubId == 0);
1249 if (object->classId == object_classes[OCLASS_CONSTRAINT])
1251 Assert(object->objectSubId == 0);
1252 return OCLASS_CONSTRAINT;
1254 if (object->classId == object_classes[OCLASS_CONVERSION])
1256 Assert(object->objectSubId == 0);
1257 return OCLASS_CONVERSION;
1259 if (object->classId == object_classes[OCLASS_DEFAULT])
1261 Assert(object->objectSubId == 0);
1262 return OCLASS_DEFAULT;
1264 if (object->classId == object_classes[OCLASS_LANGUAGE])
1266 Assert(object->objectSubId == 0);
1267 return OCLASS_LANGUAGE;
1269 if (object->classId == object_classes[OCLASS_OPERATOR])
1271 Assert(object->objectSubId == 0);
1272 return OCLASS_OPERATOR;
1274 if (object->classId == object_classes[OCLASS_OPCLASS])
1276 Assert(object->objectSubId == 0);
1277 return OCLASS_OPCLASS;
1279 if (object->classId == object_classes[OCLASS_REWRITE])
1281 Assert(object->objectSubId == 0);
1282 return OCLASS_REWRITE;
1284 if (object->classId == object_classes[OCLASS_TRIGGER])
1286 Assert(object->objectSubId == 0);
1287 return OCLASS_TRIGGER;
1289 if (object->classId == object_classes[OCLASS_SCHEMA])
1291 Assert(object->objectSubId == 0);
1292 return OCLASS_SCHEMA;
1295 elog(ERROR, "getObjectClass: Unknown object class %u",
1297 return OCLASS_CLASS; /* keep compiler quiet */
1301 * getObjectDescription: build an object description for messages
1303 * The result is a palloc'd string.
1306 getObjectDescription(const ObjectAddress *object)
1308 StringInfoData buffer;
1310 initStringInfo(&buffer);
1312 switch (getObjectClass(object))
1315 getRelationDescription(&buffer, object->objectId);
1316 if (object->objectSubId != 0)
1317 appendStringInfo(&buffer, " column %s",
1318 get_attname(object->objectId,
1319 object->objectSubId));
1323 appendStringInfo(&buffer, "function %s",
1324 format_procedure(object->objectId));
1328 appendStringInfo(&buffer, "type %s",
1329 format_type_be(object->objectId));
1335 ScanKeyData skey[1];
1338 Form_pg_cast castForm;
1340 castDesc = heap_openr(CastRelationName, AccessShareLock);
1342 ScanKeyEntryInitialize(&skey[0], 0x0,
1343 ObjectIdAttributeNumber, F_OIDEQ,
1344 ObjectIdGetDatum(object->objectId));
1346 rcscan = systable_beginscan(castDesc, CastOidIndex, true,
1347 SnapshotNow, 1, skey);
1349 tup = systable_getnext(rcscan);
1351 if (!HeapTupleIsValid(tup))
1352 elog(ERROR, "getObjectDescription: Cast %u does not exist",
1355 castForm = (Form_pg_cast) GETSTRUCT(tup);
1357 appendStringInfo(&buffer, "cast from %s to %s",
1358 format_type_be(castForm->castsource),
1359 format_type_be(castForm->casttarget));
1361 systable_endscan(rcscan);
1362 heap_close(castDesc, AccessShareLock);
1366 case OCLASS_CONSTRAINT:
1369 ScanKeyData skey[1];
1372 Form_pg_constraint con;
1374 conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
1376 ScanKeyEntryInitialize(&skey[0], 0x0,
1377 ObjectIdAttributeNumber, F_OIDEQ,
1378 ObjectIdGetDatum(object->objectId));
1380 rcscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
1381 SnapshotNow, 1, skey);
1383 tup = systable_getnext(rcscan);
1385 if (!HeapTupleIsValid(tup))
1386 elog(ERROR, "getObjectDescription: Constraint %u does not exist",
1389 con = (Form_pg_constraint) GETSTRUCT(tup);
1391 if (OidIsValid(con->conrelid))
1393 appendStringInfo(&buffer, "constraint %s on ",
1394 NameStr(con->conname));
1395 getRelationDescription(&buffer, con->conrelid);
1399 appendStringInfo(&buffer, "constraint %s",
1400 NameStr(con->conname));
1403 systable_endscan(rcscan);
1404 heap_close(conDesc, AccessShareLock);
1408 case OCLASS_CONVERSION:
1412 conTup = SearchSysCache(CONOID,
1413 ObjectIdGetDatum(object->objectId),
1415 if (!HeapTupleIsValid(conTup))
1416 elog(ERROR, "getObjectDescription: Conversion %u does not exist",
1418 appendStringInfo(&buffer, "conversion %s",
1419 NameStr(((Form_pg_conversion) GETSTRUCT(conTup))->conname));
1420 ReleaseSysCache(conTup);
1424 case OCLASS_DEFAULT:
1426 Relation attrdefDesc;
1427 ScanKeyData skey[1];
1430 Form_pg_attrdef attrdef;
1431 ObjectAddress colobject;
1433 attrdefDesc = heap_openr(AttrDefaultRelationName, AccessShareLock);
1435 ScanKeyEntryInitialize(&skey[0], 0x0,
1436 ObjectIdAttributeNumber, F_OIDEQ,
1437 ObjectIdGetDatum(object->objectId));
1439 adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndex, true,
1440 SnapshotNow, 1, skey);
1442 tup = systable_getnext(adscan);
1444 if (!HeapTupleIsValid(tup))
1445 elog(ERROR, "getObjectDescription: Default %u does not exist",
1448 attrdef = (Form_pg_attrdef) GETSTRUCT(tup);
1450 colobject.classId = RelOid_pg_class;
1451 colobject.objectId = attrdef->adrelid;
1452 colobject.objectSubId = attrdef->adnum;
1454 appendStringInfo(&buffer, "default for %s",
1455 getObjectDescription(&colobject));
1457 systable_endscan(adscan);
1458 heap_close(attrdefDesc, AccessShareLock);
1462 case OCLASS_LANGUAGE:
1466 langTup = SearchSysCache(LANGOID,
1467 ObjectIdGetDatum(object->objectId),
1469 if (!HeapTupleIsValid(langTup))
1470 elog(ERROR, "getObjectDescription: Language %u does not exist",
1472 appendStringInfo(&buffer, "language %s",
1473 NameStr(((Form_pg_language) GETSTRUCT(langTup))->lanname));
1474 ReleaseSysCache(langTup);
1478 case OCLASS_OPERATOR:
1479 appendStringInfo(&buffer, "operator %s",
1480 format_operator(object->objectId));
1483 case OCLASS_OPCLASS:
1486 Form_pg_opclass opcForm;
1491 opcTup = SearchSysCache(CLAOID,
1492 ObjectIdGetDatum(object->objectId),
1494 if (!HeapTupleIsValid(opcTup))
1495 elog(ERROR, "cache lookup of opclass %u failed",
1497 opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
1499 /* Qualify the name if not visible in search path */
1500 if (OpclassIsVisible(object->objectId))
1503 nspname = get_namespace_name(opcForm->opcnamespace);
1505 appendStringInfo(&buffer, "operator class %s",
1506 quote_qualified_identifier(nspname,
1507 NameStr(opcForm->opcname)));
1509 amTup = SearchSysCache(AMOID,
1510 ObjectIdGetDatum(opcForm->opcamid),
1512 if (!HeapTupleIsValid(amTup))
1513 elog(ERROR, "syscache lookup for AM %u failed",
1515 amForm = (Form_pg_am) GETSTRUCT(amTup);
1517 appendStringInfo(&buffer, " for %s",
1518 NameStr(amForm->amname));
1520 ReleaseSysCache(amTup);
1521 ReleaseSysCache(opcTup);
1525 case OCLASS_REWRITE:
1528 ScanKeyData skey[1];
1531 Form_pg_rewrite rule;
1533 ruleDesc = heap_openr(RewriteRelationName, AccessShareLock);
1535 ScanKeyEntryInitialize(&skey[0], 0x0,
1536 ObjectIdAttributeNumber, F_OIDEQ,
1537 ObjectIdGetDatum(object->objectId));
1539 rcscan = systable_beginscan(ruleDesc, RewriteOidIndex, true,
1540 SnapshotNow, 1, skey);
1542 tup = systable_getnext(rcscan);
1544 if (!HeapTupleIsValid(tup))
1545 elog(ERROR, "getObjectDescription: Rule %u does not exist",
1548 rule = (Form_pg_rewrite) GETSTRUCT(tup);
1550 appendStringInfo(&buffer, "rule %s on ",
1551 NameStr(rule->rulename));
1552 getRelationDescription(&buffer, rule->ev_class);
1554 systable_endscan(rcscan);
1555 heap_close(ruleDesc, AccessShareLock);
1559 case OCLASS_TRIGGER:
1562 ScanKeyData skey[1];
1565 Form_pg_trigger trig;
1567 trigDesc = heap_openr(TriggerRelationName, AccessShareLock);
1569 ScanKeyEntryInitialize(&skey[0], 0x0,
1570 ObjectIdAttributeNumber, F_OIDEQ,
1571 ObjectIdGetDatum(object->objectId));
1573 tgscan = systable_beginscan(trigDesc, TriggerOidIndex, true,
1574 SnapshotNow, 1, skey);
1576 tup = systable_getnext(tgscan);
1578 if (!HeapTupleIsValid(tup))
1579 elog(ERROR, "getObjectDescription: Trigger %u does not exist",
1582 trig = (Form_pg_trigger) GETSTRUCT(tup);
1584 appendStringInfo(&buffer, "trigger %s on ",
1585 NameStr(trig->tgname));
1586 getRelationDescription(&buffer, trig->tgrelid);
1588 systable_endscan(tgscan);
1589 heap_close(trigDesc, AccessShareLock);
1597 nspname = get_namespace_name(object->objectId);
1599 elog(ERROR, "getObjectDescription: Schema %u does not exist",
1601 appendStringInfo(&buffer, "schema %s", nspname);
1606 appendStringInfo(&buffer, "unknown object %u %u %d",
1609 object->objectSubId);
1617 * subroutine for getObjectDescription: describe a relation
1620 getRelationDescription(StringInfo buffer, Oid relid)
1623 Form_pg_class relForm;
1627 relTup = SearchSysCache(RELOID,
1628 ObjectIdGetDatum(relid),
1630 if (!HeapTupleIsValid(relTup))
1631 elog(ERROR, "cache lookup of relation %u failed", relid);
1632 relForm = (Form_pg_class) GETSTRUCT(relTup);
1634 /* Qualify the name if not visible in search path */
1635 if (RelationIsVisible(relid))
1638 nspname = get_namespace_name(relForm->relnamespace);
1640 relname = quote_qualified_identifier(nspname, NameStr(relForm->relname));
1642 switch (relForm->relkind)
1644 case RELKIND_RELATION:
1645 appendStringInfo(buffer, "table %s",
1649 appendStringInfo(buffer, "index %s",
1652 case RELKIND_SPECIAL:
1653 appendStringInfo(buffer, "special system relation %s",
1656 case RELKIND_SEQUENCE:
1657 appendStringInfo(buffer, "sequence %s",
1660 case RELKIND_UNCATALOGED:
1661 appendStringInfo(buffer, "uncataloged table %s",
1664 case RELKIND_TOASTVALUE:
1665 appendStringInfo(buffer, "toast table %s",
1669 appendStringInfo(buffer, "view %s",
1672 case RELKIND_COMPOSITE_TYPE:
1673 appendStringInfo(buffer, "composite type %s",
1677 /* shouldn't get here */
1678 appendStringInfo(buffer, "relation %s",
1683 ReleaseSysCache(relTup);