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