1 /*-------------------------------------------------------------------------
2  *
3  * pg_constraint.h
4  *	  definition of the "constraint" system catalog (pg_constraint)
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/pg_constraint.h
11  *
12  * NOTES
13  *	  The Catalog.pm module reads this file and derives schema
14  *	  information.
15  *
16  *-------------------------------------------------------------------------
17  */
18 #ifndef PG_CONSTRAINT_H
19 #define PG_CONSTRAINT_H
20 
21 #include "catalog/genbki.h"
22 #include "catalog/pg_constraint_d.h"
23 
24 #include "catalog/dependency.h"
25 #include "nodes/pg_list.h"
26 
27 /* ----------------
28  *		pg_constraint definition.  cpp turns this into
29  *		typedef struct FormData_pg_constraint
30  * ----------------
31  */
32 CATALOG(pg_constraint,2606,ConstraintRelationId)
33 {
34 	/*
35 	 * conname + connamespace is deliberately not unique; we allow, for
36 	 * example, the same name to be used for constraints of different
37 	 * relations.  This is partly for backwards compatibility with past
38 	 * Postgres practice, and partly because we don't want to have to obtain a
39 	 * global lock to generate a globally unique name for a nameless
40 	 * constraint.  We associate a namespace with constraint names only for
41 	 * SQL-spec compatibility.
42 	 *
43 	 * However, we do require conname to be unique among the constraints of a
44 	 * single relation or domain.  This is enforced by a unique index on
45 	 * conrelid + contypid + conname.
46 	 */
47 	NameData	conname;		/* name of this constraint */
48 	Oid			connamespace;	/* OID of namespace containing constraint */
49 	char		contype;		/* constraint type; see codes below */
50 	bool		condeferrable;	/* deferrable constraint? */
51 	bool		condeferred;	/* deferred by default? */
52 	bool		convalidated;	/* constraint has been validated? */
53 
54 	/*
55 	 * conrelid and conkey are only meaningful if the constraint applies to a
56 	 * specific relation (this excludes domain constraints and assertions).
57 	 * Otherwise conrelid is 0 and conkey is NULL.
58 	 */
59 	Oid			conrelid;		/* relation this constraint constrains */
60 
61 	/*
62 	 * contypid links to the pg_type row for a domain if this is a domain
63 	 * constraint.  Otherwise it's 0.
64 	 *
65 	 * For SQL-style global ASSERTIONs, both conrelid and contypid would be
66 	 * zero. This is not presently supported, however.
67 	 */
68 	Oid			contypid;		/* domain this constraint constrains */
69 
70 	/*
71 	 * conindid links to the index supporting the constraint, if any;
72 	 * otherwise it's 0.  This is used for unique, primary-key, and exclusion
73 	 * constraints, and less obviously for foreign-key constraints (where the
74 	 * index is a unique index on the referenced relation's referenced
75 	 * columns).  Notice that the index is on conrelid in the first case but
76 	 * confrelid in the second.
77 	 */
78 	Oid			conindid;		/* index supporting this constraint */
79 
80 	/*
81 	 * If this constraint is on a partition inherited from a partitioned
82 	 * table, this is the OID of the corresponding constraint in the parent.
83 	 */
84 	Oid			conparentid;
85 
86 	/*
87 	 * These fields, plus confkey, are only meaningful for a foreign-key
88 	 * constraint.  Otherwise confrelid is 0 and the char fields are spaces.
89 	 */
90 	Oid			confrelid;		/* relation referenced by foreign key */
91 	char		confupdtype;	/* foreign key's ON UPDATE action */
92 	char		confdeltype;	/* foreign key's ON DELETE action */
93 	char		confmatchtype;	/* foreign key's match type */
94 
95 	/* Has a local definition (hence, do not drop when coninhcount is 0) */
96 	bool		conislocal;
97 
98 	/* Number of times inherited from direct parent relation(s) */
99 	int32		coninhcount;
100 
101 	/* Has a local definition and cannot be inherited */
102 	bool		connoinherit;
103 
104 #ifdef CATALOG_VARLEN			/* variable-length fields start here */
105 
106 	/*
107 	 * Columns of conrelid that the constraint applies to, if known (this is
108 	 * NULL for trigger constraints)
109 	 */
110 	int16		conkey[1];
111 
112 	/*
113 	 * If a foreign key, the referenced columns of confrelid
114 	 */
115 	int16		confkey[1];
116 
117 	/*
118 	 * If a foreign key, the OIDs of the PK = FK equality operators for each
119 	 * column of the constraint
120 	 */
121 	Oid			conpfeqop[1];
122 
123 	/*
124 	 * If a foreign key, the OIDs of the PK = PK equality operators for each
125 	 * column of the constraint (i.e., equality for the referenced columns)
126 	 */
127 	Oid			conppeqop[1];
128 
129 	/*
130 	 * If a foreign key, the OIDs of the FK = FK equality operators for each
131 	 * column of the constraint (i.e., equality for the referencing columns)
132 	 */
133 	Oid			conffeqop[1];
134 
135 	/*
136 	 * If an exclusion constraint, the OIDs of the exclusion operators for
137 	 * each column of the constraint
138 	 */
139 	Oid			conexclop[1];
140 
141 	/*
142 	 * If a check constraint, nodeToString representation of expression
143 	 */
144 	pg_node_tree conbin;
145 
146 	/*
147 	 * If a check constraint, source-text representation of expression
148 	 */
149 	text		consrc;
150 #endif
151 } FormData_pg_constraint;
152 
153 /* ----------------
154  *		Form_pg_constraint corresponds to a pointer to a tuple with
155  *		the format of pg_constraint relation.
156  * ----------------
157  */
158 typedef FormData_pg_constraint *Form_pg_constraint;
159 
160 #ifdef EXPOSE_TO_CLIENT_CODE
161 
162 /* Valid values for contype */
163 #define CONSTRAINT_CHECK			'c'
164 #define CONSTRAINT_FOREIGN			'f'
165 #define CONSTRAINT_PRIMARY			'p'
166 #define CONSTRAINT_UNIQUE			'u'
167 #define CONSTRAINT_TRIGGER			't'
168 #define CONSTRAINT_EXCLUSION		'x'
169 
170 /*
171  * Valid values for confupdtype and confdeltype are the FKCONSTR_ACTION_xxx
172  * constants defined in parsenodes.h.  Valid values for confmatchtype are
173  * the FKCONSTR_MATCH_xxx constants defined in parsenodes.h.
174  */
175 
176 #endif							/* EXPOSE_TO_CLIENT_CODE */
177 
178 /*
179  * Identify constraint type for lookup purposes
180  */
181 typedef enum ConstraintCategory
182 {
183 	CONSTRAINT_RELATION,
184 	CONSTRAINT_DOMAIN,
185 	CONSTRAINT_ASSERTION		/* for future expansion */
186 } ConstraintCategory;
187 
188 /*
189  * Used when cloning a foreign key constraint to a partition, so that the
190  * caller can optionally set up a verification pass for it.
191  */
192 typedef struct ClonedConstraint
193 {
194 	Oid			relid;
195 	Oid			refrelid;
196 	Oid			conindid;
197 	Oid			conid;
198 	Constraint *constraint;
199 } ClonedConstraint;
200 
201 
202 extern Oid CreateConstraintEntry(const char *constraintName,
203 					  Oid constraintNamespace,
204 					  char constraintType,
205 					  bool isDeferrable,
206 					  bool isDeferred,
207 					  bool isValidated,
208 					  Oid parentConstrId,
209 					  Oid relId,
210 					  const int16 *constraintKey,
211 					  int constraintNKeys,
212 					  int constraintNTotalKeys,
213 					  Oid domainId,
214 					  Oid indexRelId,
215 					  Oid foreignRelId,
216 					  const int16 *foreignKey,
217 					  const Oid *pfEqOp,
218 					  const Oid *ppEqOp,
219 					  const Oid *ffEqOp,
220 					  int foreignNKeys,
221 					  char foreignUpdateType,
222 					  char foreignDeleteType,
223 					  char foreignMatchType,
224 					  const Oid *exclOp,
225 					  Node *conExpr,
226 					  const char *conBin,
227 					  const char *conSrc,
228 					  bool conIsLocal,
229 					  int conInhCount,
230 					  bool conNoInherit,
231 					  bool is_internal);
232 
233 extern void RemoveConstraintById(Oid conId);
234 extern void RenameConstraintById(Oid conId, const char *newname);
235 
236 extern bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId,
237 					 const char *conname);
238 extern bool ConstraintNameExists(const char *conname, Oid namespaceid);
239 extern char *ChooseConstraintName(const char *name1, const char *name2,
240 					 const char *label, Oid namespaceid,
241 					 List *others);
242 
243 extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
244 						  Oid newNspId, bool isType, ObjectAddresses *objsMoved);
245 extern void ConstraintSetParentConstraint(Oid childConstrId,
246 							  Oid parentConstrId);
247 extern Oid	get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok);
248 extern Bitmapset *get_relation_constraint_attnos(Oid relid, const char *conname,
249 							   bool missing_ok, Oid *constraintOid);
250 extern Oid	get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok);
251 extern Oid	get_relation_idx_constraint_oid(Oid relationId, Oid indexId);
252 
253 extern Bitmapset *get_primary_key_attnos(Oid relid, bool deferrableOk,
254 					   Oid *constraintOid);
255 extern void DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
256 						   AttrNumber *conkey, AttrNumber *confkey,
257 						   Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs);
258 
259 extern bool check_functional_grouping(Oid relid,
260 						  Index varno, Index varlevelsup,
261 						  List *grouping_columns,
262 						  List **constraintDeps);
263 
264 #endif							/* PG_CONSTRAINT_H */
265