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