1 /*-------------------------------------------------------------------------
2  *
3  * dependency.h
4  *	  Routines to support inter-object dependencies.
5  *
6  *
7  * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * src/include/catalog/dependency.h
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef DEPENDENCY_H
15 #define DEPENDENCY_H
16 
17 #include "catalog/objectaddress.h"
18 
19 
20 /*
21  * Precise semantics of a dependency relationship are specified by the
22  * DependencyType code (which is stored in a "char" field in pg_depend,
23  * so we assign ASCII-code values to the enumeration members).
24  *
25  * In all cases, a dependency relationship indicates that the referenced
26  * object may not be dropped without also dropping the dependent object.
27  * However, there are several subflavors:
28  *
29  * DEPENDENCY_NORMAL ('n'): normal relationship between separately-created
30  * objects.  The dependent object may be dropped without affecting the
31  * referenced object.  The referenced object may only be dropped by
32  * specifying CASCADE, in which case the dependent object is dropped too.
33  * Example: a table column has a normal dependency on its datatype.
34  *
35  * DEPENDENCY_AUTO ('a'): the dependent object can be dropped separately
36  * from the referenced object, and should be automatically dropped
37  * (regardless of RESTRICT or CASCADE mode) if the referenced object
38  * is dropped.
39  * Example: a named constraint on a table is made auto-dependent on
40  * the table, so that it will go away if the table is dropped.
41  *
42  * DEPENDENCY_INTERNAL ('i'): the dependent object was created as part
43  * of creation of the referenced object, and is really just a part of
44  * its internal implementation.  A DROP of the dependent object will be
45  * disallowed outright (we'll tell the user to issue a DROP against the
46  * referenced object, instead).  A DROP of the referenced object will be
47  * propagated through to drop the dependent object whether CASCADE is
48  * specified or not.
49  * Example: a trigger that's created to enforce a foreign-key constraint
50  * is made internally dependent on the constraint's pg_constraint entry.
51  *
52  * DEPENDENCY_INTERNAL_AUTO ('I'): the dependent object was created as
53  * part of creation of the referenced object, and is really just a part
54  * of its internal implementation.  A DROP of the dependent object will
55  * be disallowed outright (we'll tell the user to issue a DROP against the
56  * referenced object, instead).  While a regular internal dependency will
57  * prevent the dependent object from being dropped while any such
58  * dependencies remain, DEPENDENCY_INTERNAL_AUTO will allow such a drop as
59  * long as the object can be found by following any of such dependencies.
60  * Example: an index on a partition is made internal-auto-dependent on
61  * both the partition itself as well as on the index on the parent
62  * partitioned table; so the partition index is dropped together with
63  * either the partition it indexes, or with the parent index it is attached
64  * to.
65 
66  * DEPENDENCY_EXTENSION ('e'): the dependent object is a member of the
67  * extension that is the referenced object.  The dependent object can be
68  * dropped only via DROP EXTENSION on the referenced object.  Functionally
69  * this dependency type acts the same as an internal dependency, but it's
70  * kept separate for clarity and to simplify pg_dump.
71  *
72  * DEPENDENCY_AUTO_EXTENSION ('x'): the dependent object is not a member
73  * of the extension that is the referenced object (and so should not be
74  * ignored by pg_dump), but cannot function without the extension and
75  * should be dropped when the extension itself is.  The dependent object
76  * may be dropped on its own as well.
77  *
78  * DEPENDENCY_PIN ('p'): there is no dependent object; this type of entry
79  * is a signal that the system itself depends on the referenced object,
80  * and so that object must never be deleted.  Entries of this type are
81  * created only during initdb.  The fields for the dependent object
82  * contain zeroes.
83  *
84  * Other dependency flavors may be needed in future.
85  */
86 
87 typedef enum DependencyType
88 {
89 	DEPENDENCY_NORMAL = 'n',
90 	DEPENDENCY_AUTO = 'a',
91 	DEPENDENCY_INTERNAL = 'i',
92 	DEPENDENCY_INTERNAL_AUTO = 'I',
93 	DEPENDENCY_EXTENSION = 'e',
94 	DEPENDENCY_AUTO_EXTENSION = 'x',
95 	DEPENDENCY_PIN = 'p'
96 } DependencyType;
97 
98 /*
99  * There is also a SharedDependencyType enum type that determines the exact
100  * semantics of an entry in pg_shdepend.  Just like regular dependency entries,
101  * any pg_shdepend entry means that the referenced object cannot be dropped
102  * unless the dependent object is dropped at the same time.  There are some
103  * additional rules however:
104  *
105  * (a) For a SHARED_DEPENDENCY_PIN entry, there is no dependent object --
106  * rather, the referenced object is an essential part of the system.  This
107  * applies to the initdb-created superuser.  Entries of this type are only
108  * created by initdb; objects in this category don't need further pg_shdepend
109  * entries if more objects come to depend on them.
110  *
111  * (b) a SHARED_DEPENDENCY_OWNER entry means that the referenced object is
112  * the role owning the dependent object.  The referenced object must be
113  * a pg_authid entry.
114  *
115  * (c) a SHARED_DEPENDENCY_ACL entry means that the referenced object is
116  * a role mentioned in the ACL field of the dependent object.  The referenced
117  * object must be a pg_authid entry.  (SHARED_DEPENDENCY_ACL entries are not
118  * created for the owner of an object; hence two objects may be linked by
119  * one or the other, but not both, of these dependency types.)
120  *
121  * (d) a SHARED_DEPENDENCY_POLICY entry means that the referenced object is
122  * a role mentioned in a policy object.  The referenced object must be a
123  * pg_authid entry.
124  *
125  * (e) a SHARED_DEPENDENCY_TABLESPACE entry means that the referenced
126  * object is a tablespace mentioned in a relation without storage.  The
127  * referenced object must be a pg_tablespace entry.  (Relations that have
128  * storage don't need this: they are protected by the existence of a physical
129  * file in the tablespace.)
130  *
131  * SHARED_DEPENDENCY_INVALID is a value used as a parameter in internal
132  * routines, and is not valid in the catalog itself.
133  */
134 typedef enum SharedDependencyType
135 {
136 	SHARED_DEPENDENCY_PIN = 'p',
137 	SHARED_DEPENDENCY_OWNER = 'o',
138 	SHARED_DEPENDENCY_ACL = 'a',
139 	SHARED_DEPENDENCY_POLICY = 'r',
140 	SHARED_DEPENDENCY_TABLESPACE = 't',
141 	SHARED_DEPENDENCY_INVALID = 0
142 } SharedDependencyType;
143 
144 /* expansible list of ObjectAddresses (private in dependency.c) */
145 typedef struct ObjectAddresses ObjectAddresses;
146 
147 /*
148  * This enum covers all system catalogs whose OIDs can appear in
149  * pg_depend.classId or pg_shdepend.classId.  Keep object_classes[] in sync.
150  */
151 typedef enum ObjectClass
152 {
153 	OCLASS_CLASS,				/* pg_class */
154 	OCLASS_PROC,				/* pg_proc */
155 	OCLASS_TYPE,				/* pg_type */
156 	OCLASS_CAST,				/* pg_cast */
157 	OCLASS_COLLATION,			/* pg_collation */
158 	OCLASS_CONSTRAINT,			/* pg_constraint */
159 	OCLASS_CONVERSION,			/* pg_conversion */
160 	OCLASS_DEFAULT,				/* pg_attrdef */
161 	OCLASS_LANGUAGE,			/* pg_language */
162 	OCLASS_LARGEOBJECT,			/* pg_largeobject */
163 	OCLASS_OPERATOR,			/* pg_operator */
164 	OCLASS_OPCLASS,				/* pg_opclass */
165 	OCLASS_OPFAMILY,			/* pg_opfamily */
166 	OCLASS_AM,					/* pg_am */
167 	OCLASS_AMOP,				/* pg_amop */
168 	OCLASS_AMPROC,				/* pg_amproc */
169 	OCLASS_REWRITE,				/* pg_rewrite */
170 	OCLASS_TRIGGER,				/* pg_trigger */
171 	OCLASS_SCHEMA,				/* pg_namespace */
172 	OCLASS_STATISTIC_EXT,		/* pg_statistic_ext */
173 	OCLASS_TSPARSER,			/* pg_ts_parser */
174 	OCLASS_TSDICT,				/* pg_ts_dict */
175 	OCLASS_TSTEMPLATE,			/* pg_ts_template */
176 	OCLASS_TSCONFIG,			/* pg_ts_config */
177 	OCLASS_ROLE,				/* pg_authid */
178 	OCLASS_DATABASE,			/* pg_database */
179 	OCLASS_TBLSPACE,			/* pg_tablespace */
180 	OCLASS_FDW,					/* pg_foreign_data_wrapper */
181 	OCLASS_FOREIGN_SERVER,		/* pg_foreign_server */
182 	OCLASS_USER_MAPPING,		/* pg_user_mapping */
183 	OCLASS_DEFACL,				/* pg_default_acl */
184 	OCLASS_EXTENSION,			/* pg_extension */
185 	OCLASS_EVENT_TRIGGER,		/* pg_event_trigger */
186 	OCLASS_POLICY,				/* pg_policy */
187 	OCLASS_PUBLICATION,			/* pg_publication */
188 	OCLASS_PUBLICATION_REL,		/* pg_publication_rel */
189 	OCLASS_SUBSCRIPTION,		/* pg_subscription */
190 	OCLASS_TRANSFORM			/* pg_transform */
191 } ObjectClass;
192 
193 #define LAST_OCLASS		OCLASS_TRANSFORM
194 
195 /* flag bits for performDeletion/performMultipleDeletions: */
196 #define PERFORM_DELETION_INTERNAL			0x0001	/* internal action */
197 #define PERFORM_DELETION_CONCURRENTLY		0x0002	/* concurrent drop */
198 #define PERFORM_DELETION_QUIETLY			0x0004	/* suppress notices */
199 #define PERFORM_DELETION_SKIP_ORIGINAL		0x0008	/* keep original obj */
200 #define PERFORM_DELETION_SKIP_EXTENSIONS	0x0010	/* keep extensions */
201 
202 
203 /* in dependency.c */
204 
205 extern void AcquireDeletionLock(const ObjectAddress *object, int flags);
206 
207 extern void ReleaseDeletionLock(const ObjectAddress *object);
208 
209 extern void performDeletion(const ObjectAddress *object,
210 				DropBehavior behavior, int flags);
211 
212 extern void performMultipleDeletions(const ObjectAddresses *objects,
213 						 DropBehavior behavior, int flags);
214 
215 extern void recordDependencyOnExpr(const ObjectAddress *depender,
216 					   Node *expr, List *rtable,
217 					   DependencyType behavior);
218 
219 extern void recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
220 								Node *expr, Oid relId,
221 								DependencyType behavior,
222 								DependencyType self_behavior,
223 								bool reverse_self);
224 
225 extern ObjectClass getObjectClass(const ObjectAddress *object);
226 
227 extern ObjectAddresses *new_object_addresses(void);
228 
229 extern void add_exact_object_address(const ObjectAddress *object,
230 						 ObjectAddresses *addrs);
231 
232 extern bool object_address_present(const ObjectAddress *object,
233 					   const ObjectAddresses *addrs);
234 
235 extern void record_object_address_dependencies(const ObjectAddress *depender,
236 								   ObjectAddresses *referenced,
237 								   DependencyType behavior);
238 
239 extern void free_object_addresses(ObjectAddresses *addrs);
240 
241 /* in pg_depend.c */
242 
243 extern void recordDependencyOn(const ObjectAddress *depender,
244 				   const ObjectAddress *referenced,
245 				   DependencyType behavior);
246 
247 extern void recordMultipleDependencies(const ObjectAddress *depender,
248 						   const ObjectAddress *referenced,
249 						   int nreferenced,
250 						   DependencyType behavior);
251 
252 extern void recordDependencyOnCurrentExtension(const ObjectAddress *object,
253 								   bool isReplace);
254 
255 extern long deleteDependencyRecordsFor(Oid classId, Oid objectId,
256 						   bool skipExtensionDeps);
257 
258 extern long deleteDependencyRecordsForClass(Oid classId, Oid objectId,
259 								Oid refclassId, char deptype);
260 
261 extern long changeDependencyFor(Oid classId, Oid objectId,
262 					Oid refClassId, Oid oldRefObjectId,
263 					Oid newRefObjectId);
264 
265 extern Oid	getExtensionOfObject(Oid classId, Oid objectId);
266 extern List *getAutoExtensionsOfObject(Oid classId, Oid objectId);
267 
268 extern bool sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId);
269 extern List *getOwnedSequences(Oid relid, AttrNumber attnum);
270 extern Oid	getOwnedSequence(Oid relid, AttrNumber attnum);
271 
272 extern Oid	get_constraint_index(Oid constraintId);
273 
274 extern Oid	get_index_constraint(Oid indexId);
275 
276 /* in pg_shdepend.c */
277 
278 extern void recordSharedDependencyOn(ObjectAddress *depender,
279 						 ObjectAddress *referenced,
280 						 SharedDependencyType deptype);
281 
282 extern void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId,
283 								 int32 objectSubId);
284 
285 extern void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner);
286 
287 extern void changeDependencyOnOwner(Oid classId, Oid objectId,
288 						Oid newOwnerId);
289 
290 extern void recordDependencyOnTablespace(Oid classId, Oid objectId,
291 										 Oid tablespace);
292 
293 extern void changeDependencyOnTablespace(Oid classId, Oid objectId,
294 										 Oid newTablespaceId);
295 
296 extern void updateAclDependencies(Oid classId, Oid objectId, int32 objectSubId,
297 					  Oid ownerId,
298 					  int noldmembers, Oid *oldmembers,
299 					  int nnewmembers, Oid *newmembers);
300 
301 extern bool checkSharedDependencies(Oid classId, Oid objectId,
302 						char **detail_msg, char **detail_log_msg);
303 
304 extern void shdepLockAndCheckObject(Oid classId, Oid objectId);
305 
306 extern void copyTemplateDependencies(Oid templateDbId, Oid newDbId);
307 
308 extern void dropDatabaseDependencies(Oid databaseId);
309 
310 extern void shdepDropOwned(List *relids, DropBehavior behavior);
311 
312 extern void shdepReassignOwned(List *relids, Oid newrole);
313 
314 #endif							/* DEPENDENCY_H */
315