PostgreSQL Source Code git master
heap.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * heap.c
4 * code to create and destroy POSTGRES heap relations
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/catalog/heap.c
12 *
13 *
14 * INTERFACE ROUTINES
15 * heap_create() - Create an uncataloged heap relation
16 * heap_create_with_catalog() - Create a cataloged relation
17 * heap_drop_with_catalog() - Removes named relation from catalogs
18 *
19 * NOTES
20 * this code taken from access/heap/create.c, which contains
21 * the old heap_create_with_catalog, amcreate, and amdestroy.
22 * those routines will soon call these routines using the function
23 * manager,
24 * just like the poorly named "NewXXX" routines do. The
25 * "New" routines are all going to die soon, once and for all!
26 * -cim 1/13/91
27 *
28 *-------------------------------------------------------------------------
29 */
30#include "postgres.h"
31
32#include "access/genam.h"
33#include "access/multixact.h"
34#include "access/relation.h"
35#include "access/table.h"
36#include "access/tableam.h"
38#include "catalog/catalog.h"
39#include "catalog/heap.h"
40#include "catalog/index.h"
42#include "catalog/partition.h"
43#include "catalog/pg_am.h"
44#include "catalog/pg_attrdef.h"
48#include "catalog/pg_inherits.h"
50#include "catalog/pg_opclass.h"
55#include "catalog/pg_type.h"
56#include "catalog/storage.h"
57#include "commands/tablecmds.h"
58#include "commands/typecmds.h"
59#include "common/int.h"
60#include "miscadmin.h"
61#include "nodes/nodeFuncs.h"
62#include "optimizer/optimizer.h"
63#include "parser/parse_coerce.h"
65#include "parser/parse_expr.h"
67#include "parser/parsetree.h"
69#include "pgstat.h"
70#include "storage/lmgr.h"
71#include "storage/predicate.h"
72#include "utils/builtins.h"
73#include "utils/fmgroids.h"
74#include "utils/inval.h"
75#include "utils/lsyscache.h"
76#include "utils/syscache.h"
77
78
79/* Potentially set by pg_upgrade_support functions */
84
85static void AddNewRelationTuple(Relation pg_class_desc,
86 Relation new_rel_desc,
87 Oid new_rel_oid,
88 Oid new_type_oid,
89 Oid reloftype,
90 Oid relowner,
91 char relkind,
92 TransactionId relfrozenxid,
93 TransactionId relminmxid,
94 Datum relacl,
95 Datum reloptions);
96static ObjectAddress AddNewRelationType(const char *typeName,
97 Oid typeNamespace,
98 Oid new_rel_oid,
99 char new_rel_kind,
100 Oid ownerid,
101 Oid new_row_type,
102 Oid new_array_type);
103static void RelationRemoveInheritance(Oid relid);
104static Oid StoreRelCheck(Relation rel, const char *ccname, Node *expr,
105 bool is_enforced, bool is_validated, bool is_local,
106 int16 inhcount, bool is_no_inherit, bool is_internal);
107static void StoreConstraints(Relation rel, List *cooked_constraints,
108 bool is_internal);
109static bool MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr,
110 bool allow_merge, bool is_local,
111 bool is_enforced,
112 bool is_initially_valid,
113 bool is_no_inherit);
114static void SetRelationNumChecks(Relation rel, int numchecks);
115static Node *cookConstraint(ParseState *pstate,
116 Node *raw_constraint,
117 char *relname);
118
119
120/* ----------------------------------------------------------------
121 * XXX UGLY HARD CODED BADNESS FOLLOWS XXX
122 *
123 * these should all be moved to someplace in the lib/catalog
124 * module, if not obliterated first.
125 * ----------------------------------------------------------------
126 */
127
128
129/*
130 * Note:
131 * Should the system special case these attributes in the future?
132 * Advantage: consume much less space in the ATTRIBUTE relation.
133 * Disadvantage: special cases will be all over the place.
134 */
135
136/*
137 * The initializers below do not include trailing variable length fields,
138 * but that's OK - we're never going to reference anything beyond the
139 * fixed-size portion of the structure anyway. Fields that can default
140 * to zeroes are also not mentioned.
141 */
142
143static const FormData_pg_attribute a1 = {
144 .attname = {"ctid"},
145 .atttypid = TIDOID,
146 .attlen = sizeof(ItemPointerData),
148 .atttypmod = -1,
149 .attbyval = false,
150 .attalign = TYPALIGN_SHORT,
151 .attstorage = TYPSTORAGE_PLAIN,
152 .attnotnull = true,
153 .attislocal = true,
154};
155
156static const FormData_pg_attribute a2 = {
157 .attname = {"xmin"},
158 .atttypid = XIDOID,
159 .attlen = sizeof(TransactionId),
161 .atttypmod = -1,
162 .attbyval = true,
163 .attalign = TYPALIGN_INT,
164 .attstorage = TYPSTORAGE_PLAIN,
165 .attnotnull = true,
166 .attislocal = true,
167};
168
169static const FormData_pg_attribute a3 = {
170 .attname = {"cmin"},
171 .atttypid = CIDOID,
172 .attlen = sizeof(CommandId),
174 .atttypmod = -1,
175 .attbyval = true,
176 .attalign = TYPALIGN_INT,
177 .attstorage = TYPSTORAGE_PLAIN,
178 .attnotnull = true,
179 .attislocal = true,
180};
181
182static const FormData_pg_attribute a4 = {
183 .attname = {"xmax"},
184 .atttypid = XIDOID,
185 .attlen = sizeof(TransactionId),
187 .atttypmod = -1,
188 .attbyval = true,
189 .attalign = TYPALIGN_INT,
190 .attstorage = TYPSTORAGE_PLAIN,
191 .attnotnull = true,
192 .attislocal = true,
193};
194
195static const FormData_pg_attribute a5 = {
196 .attname = {"cmax"},
197 .atttypid = CIDOID,
198 .attlen = sizeof(CommandId),
200 .atttypmod = -1,
201 .attbyval = true,
202 .attalign = TYPALIGN_INT,
203 .attstorage = TYPSTORAGE_PLAIN,
204 .attnotnull = true,
205 .attislocal = true,
206};
207
208/*
209 * We decided to call this attribute "tableoid" rather than say
210 * "classoid" on the basis that in the future there may be more than one
211 * table of a particular class/type. In any case table is still the word
212 * used in SQL.
213 */
214static const FormData_pg_attribute a6 = {
215 .attname = {"tableoid"},
216 .atttypid = OIDOID,
217 .attlen = sizeof(Oid),
219 .atttypmod = -1,
220 .attbyval = true,
221 .attalign = TYPALIGN_INT,
222 .attstorage = TYPSTORAGE_PLAIN,
223 .attnotnull = true,
224 .attislocal = true,
225};
226
227static const FormData_pg_attribute *const SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6};
228
229/*
230 * This function returns a Form_pg_attribute pointer for a system attribute.
231 * Note that we elog if the presented attno is invalid, which would only
232 * happen if there's a problem upstream.
233 */
236{
237 if (attno >= 0 || attno < -(int) lengthof(SysAtt))
238 elog(ERROR, "invalid system attribute number %d", attno);
239 return SysAtt[-attno - 1];
240}
241
242/*
243 * If the given name is a system attribute name, return a Form_pg_attribute
244 * pointer for a prototype definition. If not, return NULL.
245 */
248{
249 int j;
250
251 for (j = 0; j < (int) lengthof(SysAtt); j++)
252 {
253 const FormData_pg_attribute *att = SysAtt[j];
254
255 if (strcmp(NameStr(att->attname), attname) == 0)
256 return att;
257 }
258
259 return NULL;
260}
261
262
263/* ----------------------------------------------------------------
264 * XXX END OF UGLY HARD CODED BADNESS XXX
265 * ---------------------------------------------------------------- */
266
267
268/* ----------------------------------------------------------------
269 * heap_create - Create an uncataloged heap relation
270 *
271 * Note API change: the caller must now always provide the OID
272 * to use for the relation. The relfilenumber may be (and in
273 * the simplest cases is) left unspecified.
274 *
275 * create_storage indicates whether or not to create the storage.
276 * However, even if create_storage is true, no storage will be
277 * created if the relkind is one that doesn't have storage.
278 *
279 * rel->rd_rel is initialized by RelationBuildLocalRelation,
280 * and is mostly zeroes at return.
281 * ----------------------------------------------------------------
282 */
285 Oid relnamespace,
286 Oid reltablespace,
287 Oid relid,
288 RelFileNumber relfilenumber,
289 Oid accessmtd,
290 TupleDesc tupDesc,
291 char relkind,
292 char relpersistence,
293 bool shared_relation,
294 bool mapped_relation,
295 bool allow_system_table_mods,
296 TransactionId *relfrozenxid,
297 MultiXactId *relminmxid,
298 bool create_storage)
299{
300 Relation rel;
301
302 /* The caller must have provided an OID for the relation. */
303 Assert(OidIsValid(relid));
304
305 /*
306 * Don't allow creating relations in pg_catalog directly, even though it
307 * is allowed to move user defined relations there. Semantics with search
308 * paths including pg_catalog are too confusing for now.
309 *
310 * But allow creating indexes on relations in pg_catalog even if
311 * allow_system_table_mods = off, upper layers already guarantee it's on a
312 * user defined relation, not a system one.
313 */
314 if (!allow_system_table_mods &&
315 ((IsCatalogNamespace(relnamespace) && relkind != RELKIND_INDEX) ||
316 IsToastNamespace(relnamespace)) &&
319 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
320 errmsg("permission denied to create \"%s.%s\"",
321 get_namespace_name(relnamespace), relname),
322 errdetail("System catalog modifications are currently disallowed.")));
323
324 *relfrozenxid = InvalidTransactionId;
325 *relminmxid = InvalidMultiXactId;
326
327 /*
328 * Force reltablespace to zero if the relation kind does not support
329 * tablespaces. This is mainly just for cleanliness' sake.
330 */
331 if (!RELKIND_HAS_TABLESPACE(relkind))
332 reltablespace = InvalidOid;
333
334 /* Don't create storage for relkinds without physical storage. */
335 if (!RELKIND_HAS_STORAGE(relkind))
336 create_storage = false;
337 else
338 {
339 /*
340 * If relfilenumber is unspecified by the caller then create storage
341 * with oid same as relid.
342 */
343 if (!RelFileNumberIsValid(relfilenumber))
344 relfilenumber = relid;
345 }
346
347 /*
348 * Never allow a pg_class entry to explicitly specify the database's
349 * default tablespace in reltablespace; force it to zero instead. This
350 * ensures that if the database is cloned with a different default
351 * tablespace, the pg_class entry will still match where CREATE DATABASE
352 * will put the physically copied relation.
353 *
354 * Yes, this is a bit of a hack.
355 */
356 if (reltablespace == MyDatabaseTableSpace)
357 reltablespace = InvalidOid;
358
359 /*
360 * build the relcache entry.
361 */
363 relnamespace,
364 tupDesc,
365 relid,
366 accessmtd,
367 relfilenumber,
368 reltablespace,
369 shared_relation,
370 mapped_relation,
371 relpersistence,
372 relkind);
373
374 /*
375 * Have the storage manager create the relation's disk file, if needed.
376 *
377 * For tables, the AM callback creates both the main and the init fork.
378 * For others, only the main fork is created; the other forks will be
379 * created on demand.
380 */
381 if (create_storage)
382 {
383 if (RELKIND_HAS_TABLE_AM(rel->rd_rel->relkind))
385 relpersistence,
386 relfrozenxid, relminmxid);
387 else if (RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
388 RelationCreateStorage(rel->rd_locator, relpersistence, true);
389 else
390 Assert(false);
391 }
392
393 /*
394 * If a tablespace is specified, removal of that tablespace is normally
395 * protected by the existence of a physical file; but for relations with
396 * no files, add a pg_shdepend entry to account for that.
397 */
398 if (!create_storage && reltablespace != InvalidOid)
399 recordDependencyOnTablespace(RelationRelationId, relid,
400 reltablespace);
401
402 /* ensure that stats are dropped if transaction aborts */
404
405 return rel;
406}
407
408/* ----------------------------------------------------------------
409 * heap_create_with_catalog - Create a cataloged relation
410 *
411 * this is done in multiple steps:
412 *
413 * 1) CheckAttributeNamesTypes() is used to make certain the tuple
414 * descriptor contains a valid set of attribute names and types
415 *
416 * 2) pg_class is opened and get_relname_relid()
417 * performs a scan to ensure that no relation with the
418 * same name already exists.
419 *
420 * 3) heap_create() is called to create the new relation on disk.
421 *
422 * 4) TypeCreate() is called to define a new type corresponding
423 * to the new relation.
424 *
425 * 5) AddNewRelationTuple() is called to register the
426 * relation in pg_class.
427 *
428 * 6) AddNewAttributeTuples() is called to register the
429 * new relation's schema in pg_attribute.
430 *
431 * 7) StoreConstraints() is called - vadim 08/22/97
432 *
433 * 8) the relations are closed and the new relation's oid
434 * is returned.
435 *
436 * ----------------------------------------------------------------
437 */
438
439/* --------------------------------
440 * CheckAttributeNamesTypes
441 *
442 * this is used to make certain the tuple descriptor contains a
443 * valid set of attribute names and datatypes. a problem simply
444 * generates ereport(ERROR) which aborts the current transaction.
445 *
446 * relkind is the relkind of the relation to be created.
447 * flags controls which datatypes are allowed, cf CheckAttributeType.
448 * --------------------------------
449 */
450void
452 int flags)
453{
454 int i;
455 int j;
456 int natts = tupdesc->natts;
457
458 /* Sanity check on column count */
459 if (natts < 0 || natts > MaxHeapAttributeNumber)
461 (errcode(ERRCODE_TOO_MANY_COLUMNS),
462 errmsg("tables can have at most %d columns",
464
465 /*
466 * first check for collision with system attribute names
467 *
468 * Skip this for a view or type relation, since those don't have system
469 * attributes.
470 */
471 if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
472 {
473 for (i = 0; i < natts; i++)
474 {
475 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
476
477 if (SystemAttributeByName(NameStr(attr->attname)) != NULL)
479 (errcode(ERRCODE_DUPLICATE_COLUMN),
480 errmsg("column name \"%s\" conflicts with a system column name",
481 NameStr(attr->attname))));
482 }
483 }
484
485 /*
486 * next check for repeated attribute names
487 */
488 for (i = 1; i < natts; i++)
489 {
490 for (j = 0; j < i; j++)
491 {
492 if (strcmp(NameStr(TupleDescAttr(tupdesc, j)->attname),
493 NameStr(TupleDescAttr(tupdesc, i)->attname)) == 0)
495 (errcode(ERRCODE_DUPLICATE_COLUMN),
496 errmsg("column name \"%s\" specified more than once",
497 NameStr(TupleDescAttr(tupdesc, j)->attname))));
498 }
499 }
500
501 /*
502 * next check the attribute types
503 */
504 for (i = 0; i < natts; i++)
505 {
507 TupleDescAttr(tupdesc, i)->atttypid,
508 TupleDescAttr(tupdesc, i)->attcollation,
509 NIL, /* assume we're creating a new rowtype */
510 flags);
511 }
512}
513
514/* --------------------------------
515 * CheckAttributeType
516 *
517 * Verify that the proposed datatype of an attribute is legal.
518 * This is needed mainly because there are types (and pseudo-types)
519 * in the catalogs that we do not support as elements of real tuples.
520 * We also check some other properties required of a table column.
521 *
522 * If the attribute is being proposed for addition to an existing table or
523 * composite type, pass a one-element list of the rowtype OID as
524 * containing_rowtypes. When checking a to-be-created rowtype, it's
525 * sufficient to pass NIL, because there could not be any recursive reference
526 * to a not-yet-existing rowtype.
527 *
528 * flags is a bitmask controlling which datatypes we allow. For the most
529 * part, pseudo-types are disallowed as attribute types, but there are some
530 * exceptions: ANYARRAYOID, RECORDOID, and RECORDARRAYOID can be allowed
531 * in some cases. (This works because values of those type classes are
532 * self-identifying to some extent. However, RECORDOID and RECORDARRAYOID
533 * are reliably identifiable only within a session, since the identity info
534 * may use a typmod that is only locally assigned. The caller is expected
535 * to know whether these cases are safe.)
536 *
537 * flags can also control the phrasing of the error messages. If
538 * CHKATYPE_IS_PARTKEY is specified, "attname" should be a partition key
539 * column number as text, not a real column name.
540 * --------------------------------
541 */
542void
544 Oid atttypid, Oid attcollation,
545 List *containing_rowtypes,
546 int flags)
547{
548 char att_typtype = get_typtype(atttypid);
549 Oid att_typelem;
550
551 /* since this function recurses, it could be driven to stack overflow */
553
554 if (att_typtype == TYPTYPE_PSEUDO)
555 {
556 /*
557 * We disallow pseudo-type columns, with the exception of ANYARRAY,
558 * RECORD, and RECORD[] when the caller says that those are OK.
559 *
560 * We don't need to worry about recursive containment for RECORD and
561 * RECORD[] because (a) no named composite type should be allowed to
562 * contain those, and (b) two "anonymous" record types couldn't be
563 * considered to be the same type, so infinite recursion isn't
564 * possible.
565 */
566 if (!((atttypid == ANYARRAYOID && (flags & CHKATYPE_ANYARRAY)) ||
567 (atttypid == RECORDOID && (flags & CHKATYPE_ANYRECORD)) ||
568 (atttypid == RECORDARRAYOID && (flags & CHKATYPE_ANYRECORD))))
569 {
570 if (flags & CHKATYPE_IS_PARTKEY)
572 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
573 /* translator: first %s is an integer not a name */
574 errmsg("partition key column %s has pseudo-type %s",
575 attname, format_type_be(atttypid))));
576 else
578 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
579 errmsg("column \"%s\" has pseudo-type %s",
580 attname, format_type_be(atttypid))));
581 }
582 }
583 else if (att_typtype == TYPTYPE_DOMAIN)
584 {
585 /*
586 * If it's a domain, recurse to check its base type.
587 */
588 CheckAttributeType(attname, getBaseType(atttypid), attcollation,
589 containing_rowtypes,
590 flags);
591 }
592 else if (att_typtype == TYPTYPE_COMPOSITE)
593 {
594 /*
595 * For a composite type, recurse into its attributes.
596 */
597 Relation relation;
598 TupleDesc tupdesc;
599 int i;
600
601 /*
602 * Check for self-containment. Eventually we might be able to allow
603 * this (just return without complaint, if so) but it's not clear how
604 * many other places would require anti-recursion defenses before it
605 * would be safe to allow tables to contain their own rowtype.
606 */
607 if (list_member_oid(containing_rowtypes, atttypid))
609 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
610 errmsg("composite type %s cannot be made a member of itself",
611 format_type_be(atttypid))));
612
613 containing_rowtypes = lappend_oid(containing_rowtypes, atttypid);
614
615 relation = relation_open(get_typ_typrelid(atttypid), AccessShareLock);
616
617 tupdesc = RelationGetDescr(relation);
618
619 for (i = 0; i < tupdesc->natts; i++)
620 {
621 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
622
623 if (attr->attisdropped)
624 continue;
625 CheckAttributeType(NameStr(attr->attname),
626 attr->atttypid, attr->attcollation,
627 containing_rowtypes,
628 flags & ~CHKATYPE_IS_PARTKEY);
629 }
630
632
633 containing_rowtypes = list_delete_last(containing_rowtypes);
634 }
635 else if (att_typtype == TYPTYPE_RANGE)
636 {
637 /*
638 * If it's a range, recurse to check its subtype.
639 */
641 get_range_collation(atttypid),
642 containing_rowtypes,
643 flags);
644 }
645 else if (OidIsValid((att_typelem = get_element_type(atttypid))))
646 {
647 /*
648 * Must recurse into array types, too, in case they are composite.
649 */
650 CheckAttributeType(attname, att_typelem, attcollation,
651 containing_rowtypes,
652 flags);
653 }
654
655 /*
656 * This might not be strictly invalid per SQL standard, but it is pretty
657 * useless, and it cannot be dumped, so we must disallow it.
658 */
659 if (!OidIsValid(attcollation) && type_is_collatable(atttypid))
660 {
661 if (flags & CHKATYPE_IS_PARTKEY)
663 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
664 /* translator: first %s is an integer not a name */
665 errmsg("no collation was derived for partition key column %s with collatable type %s",
666 attname, format_type_be(atttypid)),
667 errhint("Use the COLLATE clause to set the collation explicitly.")));
668 else
670 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
671 errmsg("no collation was derived for column \"%s\" with collatable type %s",
672 attname, format_type_be(atttypid)),
673 errhint("Use the COLLATE clause to set the collation explicitly.")));
674 }
675}
676
677/*
678 * InsertPgAttributeTuples
679 * Construct and insert a set of tuples in pg_attribute.
680 *
681 * Caller has already opened and locked pg_attribute. tupdesc contains the
682 * attributes to insert. tupdesc_extra supplies the values for certain
683 * variable-length/nullable pg_attribute fields and must contain the same
684 * number of elements as tupdesc or be NULL. The other variable-length fields
685 * of pg_attribute are always initialized to null values.
686 *
687 * indstate is the index state for CatalogTupleInsertWithInfo. It can be
688 * passed as NULL, in which case we'll fetch the necessary info. (Don't do
689 * this when inserting multiple attributes, because it's a tad more
690 * expensive.)
691 *
692 * new_rel_oid is the relation OID assigned to the attributes inserted.
693 * If set to InvalidOid, the relation OID from tupdesc is used instead.
694 */
695void
697 TupleDesc tupdesc,
698 Oid new_rel_oid,
699 const FormExtraData_pg_attribute tupdesc_extra[],
700 CatalogIndexState indstate)
701{
702 TupleTableSlot **slot;
703 TupleDesc td;
704 int nslots;
705 int natts = 0;
706 int slotCount = 0;
707 bool close_index = false;
708
709 td = RelationGetDescr(pg_attribute_rel);
710
711 /* Initialize the number of slots to use */
712 nslots = Min(tupdesc->natts,
714 slot = palloc(sizeof(TupleTableSlot *) * nslots);
715 for (int i = 0; i < nslots; i++)
717
718 while (natts < tupdesc->natts)
719 {
720 Form_pg_attribute attrs = TupleDescAttr(tupdesc, natts);
721 const FormExtraData_pg_attribute *attrs_extra = tupdesc_extra ? &tupdesc_extra[natts] : NULL;
722
723 ExecClearTuple(slot[slotCount]);
724
725 memset(slot[slotCount]->tts_isnull, false,
726 slot[slotCount]->tts_tupleDescriptor->natts * sizeof(bool));
727
728 if (new_rel_oid != InvalidOid)
729 slot[slotCount]->tts_values[Anum_pg_attribute_attrelid - 1] = ObjectIdGetDatum(new_rel_oid);
730 else
731 slot[slotCount]->tts_values[Anum_pg_attribute_attrelid - 1] = ObjectIdGetDatum(attrs->attrelid);
732
733 slot[slotCount]->tts_values[Anum_pg_attribute_attname - 1] = NameGetDatum(&attrs->attname);
734 slot[slotCount]->tts_values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(attrs->atttypid);
735 slot[slotCount]->tts_values[Anum_pg_attribute_attlen - 1] = Int16GetDatum(attrs->attlen);
736 slot[slotCount]->tts_values[Anum_pg_attribute_attnum - 1] = Int16GetDatum(attrs->attnum);
737 slot[slotCount]->tts_values[Anum_pg_attribute_atttypmod - 1] = Int32GetDatum(attrs->atttypmod);
738 slot[slotCount]->tts_values[Anum_pg_attribute_attndims - 1] = Int16GetDatum(attrs->attndims);
739 slot[slotCount]->tts_values[Anum_pg_attribute_attbyval - 1] = BoolGetDatum(attrs->attbyval);
740 slot[slotCount]->tts_values[Anum_pg_attribute_attalign - 1] = CharGetDatum(attrs->attalign);
741 slot[slotCount]->tts_values[Anum_pg_attribute_attstorage - 1] = CharGetDatum(attrs->attstorage);
742 slot[slotCount]->tts_values[Anum_pg_attribute_attcompression - 1] = CharGetDatum(attrs->attcompression);
743 slot[slotCount]->tts_values[Anum_pg_attribute_attnotnull - 1] = BoolGetDatum(attrs->attnotnull);
744 slot[slotCount]->tts_values[Anum_pg_attribute_atthasdef - 1] = BoolGetDatum(attrs->atthasdef);
745 slot[slotCount]->tts_values[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(attrs->atthasmissing);
746 slot[slotCount]->tts_values[Anum_pg_attribute_attidentity - 1] = CharGetDatum(attrs->attidentity);
747 slot[slotCount]->tts_values[Anum_pg_attribute_attgenerated - 1] = CharGetDatum(attrs->attgenerated);
748 slot[slotCount]->tts_values[Anum_pg_attribute_attisdropped - 1] = BoolGetDatum(attrs->attisdropped);
749 slot[slotCount]->tts_values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(attrs->attislocal);
750 slot[slotCount]->tts_values[Anum_pg_attribute_attinhcount - 1] = Int16GetDatum(attrs->attinhcount);
751 slot[slotCount]->tts_values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attrs->attcollation);
752 if (attrs_extra)
753 {
754 slot[slotCount]->tts_values[Anum_pg_attribute_attstattarget - 1] = attrs_extra->attstattarget.value;
755 slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = attrs_extra->attstattarget.isnull;
756
757 slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.value;
758 slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.isnull;
759 }
760 else
761 {
762 slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = true;
763 slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = true;
764 }
765
766 /*
767 * The remaining fields are not set for new columns.
768 */
769 slot[slotCount]->tts_isnull[Anum_pg_attribute_attacl - 1] = true;
770 slot[slotCount]->tts_isnull[Anum_pg_attribute_attfdwoptions - 1] = true;
771 slot[slotCount]->tts_isnull[Anum_pg_attribute_attmissingval - 1] = true;
772
773 ExecStoreVirtualTuple(slot[slotCount]);
774 slotCount++;
775
776 /*
777 * If slots are full or the end of processing has been reached, insert
778 * a batch of tuples.
779 */
780 if (slotCount == nslots || natts == tupdesc->natts - 1)
781 {
782 /* fetch index info only when we know we need it */
783 if (!indstate)
784 {
785 indstate = CatalogOpenIndexes(pg_attribute_rel);
786 close_index = true;
787 }
788
789 /* insert the new tuples and update the indexes */
790 CatalogTuplesMultiInsertWithInfo(pg_attribute_rel, slot, slotCount,
791 indstate);
792 slotCount = 0;
793 }
794
795 natts++;
796 }
797
798 if (close_index)
799 CatalogCloseIndexes(indstate);
800 for (int i = 0; i < nslots; i++)
802 pfree(slot);
803}
804
805/* --------------------------------
806 * AddNewAttributeTuples
807 *
808 * this registers the new relation's schema by adding
809 * tuples to pg_attribute.
810 * --------------------------------
811 */
812static void
814 TupleDesc tupdesc,
815 char relkind)
816{
817 Relation rel;
818 CatalogIndexState indstate;
819 int natts = tupdesc->natts;
820 ObjectAddress myself,
821 referenced;
822
823 /*
824 * open pg_attribute and its indexes.
825 */
826 rel = table_open(AttributeRelationId, RowExclusiveLock);
827
828 indstate = CatalogOpenIndexes(rel);
829
830 InsertPgAttributeTuples(rel, tupdesc, new_rel_oid, NULL, indstate);
831
832 /* add dependencies on their datatypes and collations */
833 for (int i = 0; i < natts; i++)
834 {
835 Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
836
837 /* Add dependency info */
838 ObjectAddressSubSet(myself, RelationRelationId, new_rel_oid, i + 1);
839 ObjectAddressSet(referenced, TypeRelationId, attr->atttypid);
840 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
841
842 /* The default collation is pinned, so don't bother recording it */
843 if (OidIsValid(attr->attcollation) &&
844 attr->attcollation != DEFAULT_COLLATION_OID)
845 {
846 ObjectAddressSet(referenced, CollationRelationId,
847 attr->attcollation);
848 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
849 }
850 }
851
852 /*
853 * Next we add the system attributes. Skip all for a view or type
854 * relation. We don't bother with making datatype dependencies here,
855 * since presumably all these types are pinned.
856 */
857 if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
858 {
859 TupleDesc td;
860
862
863 InsertPgAttributeTuples(rel, td, new_rel_oid, NULL, indstate);
864 FreeTupleDesc(td);
865 }
866
867 /*
868 * clean up
869 */
870 CatalogCloseIndexes(indstate);
871
873}
874
875/* --------------------------------
876 * InsertPgClassTuple
877 *
878 * Construct and insert a new tuple in pg_class.
879 *
880 * Caller has already opened and locked pg_class.
881 * Tuple data is taken from new_rel_desc->rd_rel, except for the
882 * variable-width fields which are not present in a cached reldesc.
883 * relacl and reloptions are passed in Datum form (to avoid having
884 * to reference the data types in heap.h). Pass (Datum) 0 to set them
885 * to NULL.
886 * --------------------------------
887 */
888void
890 Relation new_rel_desc,
891 Oid new_rel_oid,
892 Datum relacl,
893 Datum reloptions)
894{
895 Form_pg_class rd_rel = new_rel_desc->rd_rel;
896 Datum values[Natts_pg_class];
897 bool nulls[Natts_pg_class];
898 HeapTuple tup;
899
900 /* This is a tad tedious, but way cleaner than what we used to do... */
901 memset(values, 0, sizeof(values));
902 memset(nulls, false, sizeof(nulls));
903
904 values[Anum_pg_class_oid - 1] = ObjectIdGetDatum(new_rel_oid);
905 values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname);
906 values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace);
907 values[Anum_pg_class_reltype - 1] = ObjectIdGetDatum(rd_rel->reltype);
908 values[Anum_pg_class_reloftype - 1] = ObjectIdGetDatum(rd_rel->reloftype);
909 values[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(rd_rel->relowner);
910 values[Anum_pg_class_relam - 1] = ObjectIdGetDatum(rd_rel->relam);
911 values[Anum_pg_class_relfilenode - 1] = ObjectIdGetDatum(rd_rel->relfilenode);
912 values[Anum_pg_class_reltablespace - 1] = ObjectIdGetDatum(rd_rel->reltablespace);
913 values[Anum_pg_class_relpages - 1] = Int32GetDatum(rd_rel->relpages);
914 values[Anum_pg_class_reltuples - 1] = Float4GetDatum(rd_rel->reltuples);
915 values[Anum_pg_class_relallvisible - 1] = Int32GetDatum(rd_rel->relallvisible);
916 values[Anum_pg_class_reltoastrelid - 1] = ObjectIdGetDatum(rd_rel->reltoastrelid);
917 values[Anum_pg_class_relhasindex - 1] = BoolGetDatum(rd_rel->relhasindex);
918 values[Anum_pg_class_relisshared - 1] = BoolGetDatum(rd_rel->relisshared);
919 values[Anum_pg_class_relpersistence - 1] = CharGetDatum(rd_rel->relpersistence);
920 values[Anum_pg_class_relkind - 1] = CharGetDatum(rd_rel->relkind);
921 values[Anum_pg_class_relnatts - 1] = Int16GetDatum(rd_rel->relnatts);
922 values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks);
923 values[Anum_pg_class_relhasrules - 1] = BoolGetDatum(rd_rel->relhasrules);
924 values[Anum_pg_class_relhastriggers - 1] = BoolGetDatum(rd_rel->relhastriggers);
925 values[Anum_pg_class_relrowsecurity - 1] = BoolGetDatum(rd_rel->relrowsecurity);
926 values[Anum_pg_class_relforcerowsecurity - 1] = BoolGetDatum(rd_rel->relforcerowsecurity);
927 values[Anum_pg_class_relhassubclass - 1] = BoolGetDatum(rd_rel->relhassubclass);
928 values[Anum_pg_class_relispopulated - 1] = BoolGetDatum(rd_rel->relispopulated);
929 values[Anum_pg_class_relreplident - 1] = CharGetDatum(rd_rel->relreplident);
930 values[Anum_pg_class_relispartition - 1] = BoolGetDatum(rd_rel->relispartition);
931 values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
932 values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
933 values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
934 if (relacl != (Datum) 0)
935 values[Anum_pg_class_relacl - 1] = relacl;
936 else
937 nulls[Anum_pg_class_relacl - 1] = true;
938 if (reloptions != (Datum) 0)
939 values[Anum_pg_class_reloptions - 1] = reloptions;
940 else
941 nulls[Anum_pg_class_reloptions - 1] = true;
942
943 /* relpartbound is set by updating this tuple, if necessary */
944 nulls[Anum_pg_class_relpartbound - 1] = true;
945
946 tup = heap_form_tuple(RelationGetDescr(pg_class_desc), values, nulls);
947
948 /* finally insert the new tuple, update the indexes, and clean up */
949 CatalogTupleInsert(pg_class_desc, tup);
950
951 heap_freetuple(tup);
952}
953
954/* --------------------------------
955 * AddNewRelationTuple
956 *
957 * this registers the new relation in the catalogs by
958 * adding a tuple to pg_class.
959 * --------------------------------
960 */
961static void
963 Relation new_rel_desc,
964 Oid new_rel_oid,
965 Oid new_type_oid,
966 Oid reloftype,
967 Oid relowner,
968 char relkind,
969 TransactionId relfrozenxid,
970 TransactionId relminmxid,
971 Datum relacl,
972 Datum reloptions)
973{
974 Form_pg_class new_rel_reltup;
975
976 /*
977 * first we update some of the information in our uncataloged relation's
978 * relation descriptor.
979 */
980 new_rel_reltup = new_rel_desc->rd_rel;
981
982 /* The relation is empty */
983 new_rel_reltup->relpages = 0;
984 new_rel_reltup->reltuples = -1;
985 new_rel_reltup->relallvisible = 0;
986
987 /* Sequences always have a known size */
988 if (relkind == RELKIND_SEQUENCE)
989 {
990 new_rel_reltup->relpages = 1;
991 new_rel_reltup->reltuples = 1;
992 }
993
994 new_rel_reltup->relfrozenxid = relfrozenxid;
995 new_rel_reltup->relminmxid = relminmxid;
996 new_rel_reltup->relowner = relowner;
997 new_rel_reltup->reltype = new_type_oid;
998 new_rel_reltup->reloftype = reloftype;
999
1000 /* relispartition is always set by updating this tuple later */
1001 new_rel_reltup->relispartition = false;
1002
1003 /* fill rd_att's type ID with something sane even if reltype is zero */
1004 new_rel_desc->rd_att->tdtypeid = new_type_oid ? new_type_oid : RECORDOID;
1005 new_rel_desc->rd_att->tdtypmod = -1;
1006
1007 /* Now build and insert the tuple */
1008 InsertPgClassTuple(pg_class_desc, new_rel_desc, new_rel_oid,
1009 relacl, reloptions);
1010}
1011
1012
1013/* --------------------------------
1014 * AddNewRelationType -
1015 *
1016 * define a composite type corresponding to the new relation
1017 * --------------------------------
1018 */
1019static ObjectAddress
1020AddNewRelationType(const char *typeName,
1021 Oid typeNamespace,
1022 Oid new_rel_oid,
1023 char new_rel_kind,
1024 Oid ownerid,
1025 Oid new_row_type,
1026 Oid new_array_type)
1027{
1028 return
1029 TypeCreate(new_row_type, /* optional predetermined OID */
1030 typeName, /* type name */
1031 typeNamespace, /* type namespace */
1032 new_rel_oid, /* relation oid */
1033 new_rel_kind, /* relation kind */
1034 ownerid, /* owner's ID */
1035 -1, /* internal size (varlena) */
1036 TYPTYPE_COMPOSITE, /* type-type (composite) */
1037 TYPCATEGORY_COMPOSITE, /* type-category (ditto) */
1038 false, /* composite types are never preferred */
1039 DEFAULT_TYPDELIM, /* default array delimiter */
1040 F_RECORD_IN, /* input procedure */
1041 F_RECORD_OUT, /* output procedure */
1042 F_RECORD_RECV, /* receive procedure */
1043 F_RECORD_SEND, /* send procedure */
1044 InvalidOid, /* typmodin procedure - none */
1045 InvalidOid, /* typmodout procedure - none */
1046 InvalidOid, /* analyze procedure - default */
1047 InvalidOid, /* subscript procedure - none */
1048 InvalidOid, /* array element type - irrelevant */
1049 false, /* this is not an array type */
1050 new_array_type, /* array type if any */
1051 InvalidOid, /* domain base type - irrelevant */
1052 NULL, /* default value - none */
1053 NULL, /* default binary representation */
1054 false, /* passed by reference */
1055 TYPALIGN_DOUBLE, /* alignment - must be the largest! */
1056 TYPSTORAGE_EXTENDED, /* fully TOASTable */
1057 -1, /* typmod */
1058 0, /* array dimensions for typBaseType */
1059 false, /* Type NOT NULL */
1060 InvalidOid); /* rowtypes never have a collation */
1061}
1062
1063/* --------------------------------
1064 * heap_create_with_catalog
1065 *
1066 * creates a new cataloged relation. see comments above.
1067 *
1068 * Arguments:
1069 * relname: name to give to new rel
1070 * relnamespace: OID of namespace it goes in
1071 * reltablespace: OID of tablespace it goes in
1072 * relid: OID to assign to new rel, or InvalidOid to select a new OID
1073 * reltypeid: OID to assign to rel's rowtype, or InvalidOid to select one
1074 * reloftypeid: if a typed table, OID of underlying type; else InvalidOid
1075 * ownerid: OID of new rel's owner
1076 * accessmtd: OID of new rel's access method
1077 * tupdesc: tuple descriptor (source of column definitions)
1078 * cooked_constraints: list of precooked check constraints and defaults
1079 * relkind: relkind for new rel
1080 * relpersistence: rel's persistence status (permanent, temp, or unlogged)
1081 * shared_relation: true if it's to be a shared relation
1082 * mapped_relation: true if the relation will use the relfilenumber map
1083 * oncommit: ON COMMIT marking (only relevant if it's a temp table)
1084 * reloptions: reloptions in Datum form, or (Datum) 0 if none
1085 * use_user_acl: true if should look for user-defined default permissions;
1086 * if false, relacl is always set NULL
1087 * allow_system_table_mods: true to allow creation in system namespaces
1088 * is_internal: is this a system-generated catalog?
1089 *
1090 * Output parameters:
1091 * typaddress: if not null, gets the object address of the new pg_type entry
1092 * (this must be null if the relkind is one that doesn't get a pg_type entry)
1093 *
1094 * Returns the OID of the new relation
1095 * --------------------------------
1096 */
1097Oid
1099 Oid relnamespace,
1100 Oid reltablespace,
1101 Oid relid,
1102 Oid reltypeid,
1103 Oid reloftypeid,
1104 Oid ownerid,
1105 Oid accessmtd,
1106 TupleDesc tupdesc,
1107 List *cooked_constraints,
1108 char relkind,
1109 char relpersistence,
1110 bool shared_relation,
1111 bool mapped_relation,
1112 OnCommitAction oncommit,
1113 Datum reloptions,
1114 bool use_user_acl,
1115 bool allow_system_table_mods,
1116 bool is_internal,
1117 Oid relrewrite,
1118 ObjectAddress *typaddress)
1119{
1120 Relation pg_class_desc;
1121 Relation new_rel_desc;
1122 Acl *relacl;
1123 Oid existing_relid;
1124 Oid old_type_oid;
1125 Oid new_type_oid;
1126
1127 /* By default set to InvalidOid unless overridden by binary-upgrade */
1128 RelFileNumber relfilenumber = InvalidRelFileNumber;
1129 TransactionId relfrozenxid;
1130 MultiXactId relminmxid;
1131
1132 pg_class_desc = table_open(RelationRelationId, RowExclusiveLock);
1133
1134 /*
1135 * sanity checks
1136 */
1138
1139 /*
1140 * Validate proposed tupdesc for the desired relkind. If
1141 * allow_system_table_mods is on, allow ANYARRAY to be used; this is a
1142 * hack to allow creating pg_statistic and cloning it during VACUUM FULL.
1143 */
1144 CheckAttributeNamesTypes(tupdesc, relkind,
1145 allow_system_table_mods ? CHKATYPE_ANYARRAY : 0);
1146
1147 /*
1148 * This would fail later on anyway, if the relation already exists. But
1149 * by catching it here we can emit a nicer error message.
1150 */
1151 existing_relid = get_relname_relid(relname, relnamespace);
1152 if (existing_relid != InvalidOid)
1153 ereport(ERROR,
1154 (errcode(ERRCODE_DUPLICATE_TABLE),
1155 errmsg("relation \"%s\" already exists", relname)));
1156
1157 /*
1158 * Since we are going to create a rowtype as well, also check for
1159 * collision with an existing type name. If there is one and it's an
1160 * autogenerated array, we can rename it out of the way; otherwise we can
1161 * at least give a good error message.
1162 */
1163 old_type_oid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
1165 ObjectIdGetDatum(relnamespace));
1166 if (OidIsValid(old_type_oid))
1167 {
1168 if (!moveArrayTypeName(old_type_oid, relname, relnamespace))
1169 ereport(ERROR,
1171 errmsg("type \"%s\" already exists", relname),
1172 errhint("A relation has an associated type of the same name, "
1173 "so you must use a name that doesn't conflict "
1174 "with any existing type.")));
1175 }
1176
1177 /*
1178 * Shared relations must be in pg_global (last-ditch check)
1179 */
1180 if (shared_relation && reltablespace != GLOBALTABLESPACE_OID)
1181 elog(ERROR, "shared relations must be placed in pg_global tablespace");
1182
1183 /*
1184 * Allocate an OID for the relation, unless we were told what to use.
1185 *
1186 * The OID will be the relfilenumber as well, so make sure it doesn't
1187 * collide with either pg_class OIDs or existing physical files.
1188 */
1189 if (!OidIsValid(relid))
1190 {
1191 /* Use binary-upgrade override for pg_class.oid and relfilenumber */
1192 if (IsBinaryUpgrade)
1193 {
1194 /*
1195 * Indexes are not supported here; they use
1196 * binary_upgrade_next_index_pg_class_oid.
1197 */
1198 Assert(relkind != RELKIND_INDEX);
1199 Assert(relkind != RELKIND_PARTITIONED_INDEX);
1200
1201 if (relkind == RELKIND_TOASTVALUE)
1202 {
1203 /* There might be no TOAST table, so we have to test for it. */
1205 {
1208
1210 ereport(ERROR,
1211 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1212 errmsg("toast relfilenumber value not set when in binary upgrade mode")));
1213
1216 }
1217 }
1218 else
1219 {
1221 ereport(ERROR,
1222 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1223 errmsg("pg_class heap OID value not set when in binary upgrade mode")));
1224
1227
1228 if (RELKIND_HAS_STORAGE(relkind))
1229 {
1231 ereport(ERROR,
1232 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1233 errmsg("relfilenumber value not set when in binary upgrade mode")));
1234
1237 }
1238 }
1239 }
1240
1241 if (!OidIsValid(relid))
1242 relid = GetNewRelFileNumber(reltablespace, pg_class_desc,
1243 relpersistence);
1244 }
1245
1246 /*
1247 * Other sessions' catalog scans can't find this until we commit. Hence,
1248 * it doesn't hurt to hold AccessExclusiveLock. Do it here so callers
1249 * can't accidentally vary in their lock mode or acquisition timing.
1250 */
1252
1253 /*
1254 * Determine the relation's initial permissions.
1255 */
1256 if (use_user_acl)
1257 {
1258 switch (relkind)
1259 {
1260 case RELKIND_RELATION:
1261 case RELKIND_VIEW:
1262 case RELKIND_MATVIEW:
1263 case RELKIND_FOREIGN_TABLE:
1264 case RELKIND_PARTITIONED_TABLE:
1265 relacl = get_user_default_acl(OBJECT_TABLE, ownerid,
1266 relnamespace);
1267 break;
1268 case RELKIND_SEQUENCE:
1269 relacl = get_user_default_acl(OBJECT_SEQUENCE, ownerid,
1270 relnamespace);
1271 break;
1272 default:
1273 relacl = NULL;
1274 break;
1275 }
1276 }
1277 else
1278 relacl = NULL;
1279
1280 /*
1281 * Create the relcache entry (mostly dummy at this point) and the physical
1282 * disk file. (If we fail further down, it's the smgr's responsibility to
1283 * remove the disk file again.)
1284 *
1285 * NB: Note that passing create_storage = true is correct even for binary
1286 * upgrade. The storage we create here will be replaced later, but we
1287 * need to have something on disk in the meanwhile.
1288 */
1289 new_rel_desc = heap_create(relname,
1290 relnamespace,
1291 reltablespace,
1292 relid,
1293 relfilenumber,
1294 accessmtd,
1295 tupdesc,
1296 relkind,
1297 relpersistence,
1298 shared_relation,
1299 mapped_relation,
1300 allow_system_table_mods,
1301 &relfrozenxid,
1302 &relminmxid,
1303 true);
1304
1305 Assert(relid == RelationGetRelid(new_rel_desc));
1306
1307 new_rel_desc->rd_rel->relrewrite = relrewrite;
1308
1309 /*
1310 * Decide whether to create a pg_type entry for the relation's rowtype.
1311 * These types are made except where the use of a relation as such is an
1312 * implementation detail: toast tables, sequences and indexes.
1313 */
1314 if (!(relkind == RELKIND_SEQUENCE ||
1315 relkind == RELKIND_TOASTVALUE ||
1316 relkind == RELKIND_INDEX ||
1317 relkind == RELKIND_PARTITIONED_INDEX))
1318 {
1319 Oid new_array_oid;
1320 ObjectAddress new_type_addr;
1321 char *relarrayname;
1322
1323 /*
1324 * We'll make an array over the composite type, too. For largely
1325 * historical reasons, the array type's OID is assigned first.
1326 */
1327 new_array_oid = AssignTypeArrayOid();
1328
1329 /*
1330 * Make the pg_type entry for the composite type. The OID of the
1331 * composite type can be preselected by the caller, but if reltypeid
1332 * is InvalidOid, we'll generate a new OID for it.
1333 *
1334 * NOTE: we could get a unique-index failure here, in case someone
1335 * else is creating the same type name in parallel but hadn't
1336 * committed yet when we checked for a duplicate name above.
1337 */
1338 new_type_addr = AddNewRelationType(relname,
1339 relnamespace,
1340 relid,
1341 relkind,
1342 ownerid,
1343 reltypeid,
1344 new_array_oid);
1345 new_type_oid = new_type_addr.objectId;
1346 if (typaddress)
1347 *typaddress = new_type_addr;
1348
1349 /* Now create the array type. */
1350 relarrayname = makeArrayTypeName(relname, relnamespace);
1351
1352 TypeCreate(new_array_oid, /* force the type's OID to this */
1353 relarrayname, /* Array type name */
1354 relnamespace, /* Same namespace as parent */
1355 InvalidOid, /* Not composite, no relationOid */
1356 0, /* relkind, also N/A here */
1357 ownerid, /* owner's ID */
1358 -1, /* Internal size (varlena) */
1359 TYPTYPE_BASE, /* Not composite - typelem is */
1360 TYPCATEGORY_ARRAY, /* type-category (array) */
1361 false, /* array types are never preferred */
1362 DEFAULT_TYPDELIM, /* default array delimiter */
1363 F_ARRAY_IN, /* array input proc */
1364 F_ARRAY_OUT, /* array output proc */
1365 F_ARRAY_RECV, /* array recv (bin) proc */
1366 F_ARRAY_SEND, /* array send (bin) proc */
1367 InvalidOid, /* typmodin procedure - none */
1368 InvalidOid, /* typmodout procedure - none */
1369 F_ARRAY_TYPANALYZE, /* array analyze procedure */
1370 F_ARRAY_SUBSCRIPT_HANDLER, /* array subscript procedure */
1371 new_type_oid, /* array element type - the rowtype */
1372 true, /* yes, this is an array type */
1373 InvalidOid, /* this has no array type */
1374 InvalidOid, /* domain base type - irrelevant */
1375 NULL, /* default value - none */
1376 NULL, /* default binary representation */
1377 false, /* passed by reference */
1378 TYPALIGN_DOUBLE, /* alignment - must be the largest! */
1379 TYPSTORAGE_EXTENDED, /* fully TOASTable */
1380 -1, /* typmod */
1381 0, /* array dimensions for typBaseType */
1382 false, /* Type NOT NULL */
1383 InvalidOid); /* rowtypes never have a collation */
1384
1385 pfree(relarrayname);
1386 }
1387 else
1388 {
1389 /* Caller should not be expecting a type to be created. */
1390 Assert(reltypeid == InvalidOid);
1391 Assert(typaddress == NULL);
1392
1393 new_type_oid = InvalidOid;
1394 }
1395
1396 /*
1397 * now create an entry in pg_class for the relation.
1398 *
1399 * NOTE: we could get a unique-index failure here, in case someone else is
1400 * creating the same relation name in parallel but hadn't committed yet
1401 * when we checked for a duplicate name above.
1402 */
1403 AddNewRelationTuple(pg_class_desc,
1404 new_rel_desc,
1405 relid,
1406 new_type_oid,
1407 reloftypeid,
1408 ownerid,
1409 relkind,
1410 relfrozenxid,
1411 relminmxid,
1412 PointerGetDatum(relacl),
1413 reloptions);
1414
1415 /*
1416 * now add tuples to pg_attribute for the attributes in our new relation.
1417 */
1418 AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind);
1419
1420 /*
1421 * Make a dependency link to force the relation to be deleted if its
1422 * namespace is. Also make a dependency link to its owner, as well as
1423 * dependencies for any roles mentioned in the default ACL.
1424 *
1425 * For composite types, these dependencies are tracked for the pg_type
1426 * entry, so we needn't record them here. Likewise, TOAST tables don't
1427 * need a namespace dependency (they live in a pinned namespace) nor an
1428 * owner dependency (they depend indirectly through the parent table), nor
1429 * should they have any ACL entries. The same applies for extension
1430 * dependencies.
1431 *
1432 * Also, skip this in bootstrap mode, since we don't make dependencies
1433 * while bootstrapping.
1434 */
1435 if (relkind != RELKIND_COMPOSITE_TYPE &&
1436 relkind != RELKIND_TOASTVALUE &&
1438 {
1439 ObjectAddress myself,
1440 referenced;
1441 ObjectAddresses *addrs;
1442
1443 ObjectAddressSet(myself, RelationRelationId, relid);
1444
1445 recordDependencyOnOwner(RelationRelationId, relid, ownerid);
1446
1447 recordDependencyOnNewAcl(RelationRelationId, relid, 0, ownerid, relacl);
1448
1449 recordDependencyOnCurrentExtension(&myself, false);
1450
1451 addrs = new_object_addresses();
1452
1453 ObjectAddressSet(referenced, NamespaceRelationId, relnamespace);
1454 add_exact_object_address(&referenced, addrs);
1455
1456 if (reloftypeid)
1457 {
1458 ObjectAddressSet(referenced, TypeRelationId, reloftypeid);
1459 add_exact_object_address(&referenced, addrs);
1460 }
1461
1462 /*
1463 * Make a dependency link to force the relation to be deleted if its
1464 * access method is.
1465 *
1466 * No need to add an explicit dependency for the toast table, as the
1467 * main table depends on it. Partitioned tables may not have an
1468 * access method set.
1469 */
1470 if ((RELKIND_HAS_TABLE_AM(relkind) && relkind != RELKIND_TOASTVALUE) ||
1471 (relkind == RELKIND_PARTITIONED_TABLE && OidIsValid(accessmtd)))
1472 {
1473 ObjectAddressSet(referenced, AccessMethodRelationId, accessmtd);
1474 add_exact_object_address(&referenced, addrs);
1475 }
1476
1478 free_object_addresses(addrs);
1479 }
1480
1481 /* Post creation hook for new relation */
1482 InvokeObjectPostCreateHookArg(RelationRelationId, relid, 0, is_internal);
1483
1484 /*
1485 * Store any supplied CHECK constraints and defaults.
1486 *
1487 * NB: this may do a CommandCounterIncrement and rebuild the relcache
1488 * entry, so the relation must be valid and self-consistent at this point.
1489 * In particular, there are not yet constraints and defaults anywhere.
1490 */
1491 StoreConstraints(new_rel_desc, cooked_constraints, is_internal);
1492
1493 /*
1494 * If there's a special on-commit action, remember it
1495 */
1496 if (oncommit != ONCOMMIT_NOOP)
1497 register_on_commit_action(relid, oncommit);
1498
1499 /*
1500 * ok, the relation has been cataloged, so close our relations and return
1501 * the OID of the newly created relation.
1502 */
1503 table_close(new_rel_desc, NoLock); /* do not unlock till end of xact */
1504 table_close(pg_class_desc, RowExclusiveLock);
1505
1506 return relid;
1507}
1508
1509/*
1510 * RelationRemoveInheritance
1511 *
1512 * Formerly, this routine checked for child relations and aborted the
1513 * deletion if any were found. Now we rely on the dependency mechanism
1514 * to check for or delete child relations. By the time we get here,
1515 * there are no children and we need only remove any pg_inherits rows
1516 * linking this relation to its parent(s).
1517 */
1518static void
1520{
1521 Relation catalogRelation;
1522 SysScanDesc scan;
1524 HeapTuple tuple;
1525
1526 catalogRelation = table_open(InheritsRelationId, RowExclusiveLock);
1527
1529 Anum_pg_inherits_inhrelid,
1530 BTEqualStrategyNumber, F_OIDEQ,
1531 ObjectIdGetDatum(relid));
1532
1533 scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, true,
1534 NULL, 1, &key);
1535
1536 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1537 CatalogTupleDelete(catalogRelation, &tuple->t_self);
1538
1539 systable_endscan(scan);
1540 table_close(catalogRelation, RowExclusiveLock);
1541}
1542
1543/*
1544 * DeleteRelationTuple
1545 *
1546 * Remove pg_class row for the given relid.
1547 *
1548 * Note: this is shared by relation deletion and index deletion. It's
1549 * not intended for use anyplace else.
1550 */
1551void
1553{
1554 Relation pg_class_desc;
1555 HeapTuple tup;
1556
1557 /* Grab an appropriate lock on the pg_class relation */
1558 pg_class_desc = table_open(RelationRelationId, RowExclusiveLock);
1559
1560 tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1561 if (!HeapTupleIsValid(tup))
1562 elog(ERROR, "cache lookup failed for relation %u", relid);
1563
1564 /* delete the relation tuple from pg_class, and finish up */
1565 CatalogTupleDelete(pg_class_desc, &tup->t_self);
1566
1567 ReleaseSysCache(tup);
1568
1569 table_close(pg_class_desc, RowExclusiveLock);
1570}
1571
1572/*
1573 * DeleteAttributeTuples
1574 *
1575 * Remove pg_attribute rows for the given relid.
1576 *
1577 * Note: this is shared by relation deletion and index deletion. It's
1578 * not intended for use anyplace else.
1579 */
1580void
1582{
1583 Relation attrel;
1584 SysScanDesc scan;
1585 ScanKeyData key[1];
1586 HeapTuple atttup;
1587
1588 /* Grab an appropriate lock on the pg_attribute relation */
1589 attrel = table_open(AttributeRelationId, RowExclusiveLock);
1590
1591 /* Use the index to scan only attributes of the target relation */
1592 ScanKeyInit(&key[0],
1593 Anum_pg_attribute_attrelid,
1594 BTEqualStrategyNumber, F_OIDEQ,
1595 ObjectIdGetDatum(relid));
1596
1597 scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,
1598 NULL, 1, key);
1599
1600 /* Delete all the matching tuples */
1601 while ((atttup = systable_getnext(scan)) != NULL)
1602 CatalogTupleDelete(attrel, &atttup->t_self);
1603
1604 /* Clean up after the scan */
1605 systable_endscan(scan);
1607}
1608
1609/*
1610 * DeleteSystemAttributeTuples
1611 *
1612 * Remove pg_attribute rows for system columns of the given relid.
1613 *
1614 * Note: this is only used when converting a table to a view. Views don't
1615 * have system columns, so we should remove them from pg_attribute.
1616 */
1617void
1619{
1620 Relation attrel;
1621 SysScanDesc scan;
1622 ScanKeyData key[2];
1623 HeapTuple atttup;
1624
1625 /* Grab an appropriate lock on the pg_attribute relation */
1626 attrel = table_open(AttributeRelationId, RowExclusiveLock);
1627
1628 /* Use the index to scan only system attributes of the target relation */
1629 ScanKeyInit(&key[0],
1630 Anum_pg_attribute_attrelid,
1631 BTEqualStrategyNumber, F_OIDEQ,
1632 ObjectIdGetDatum(relid));
1633 ScanKeyInit(&key[1],
1634 Anum_pg_attribute_attnum,
1635 BTLessEqualStrategyNumber, F_INT2LE,
1636 Int16GetDatum(0));
1637
1638 scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,
1639 NULL, 2, key);
1640
1641 /* Delete all the matching tuples */
1642 while ((atttup = systable_getnext(scan)) != NULL)
1643 CatalogTupleDelete(attrel, &atttup->t_self);
1644
1645 /* Clean up after the scan */
1646 systable_endscan(scan);
1648}
1649
1650/*
1651 * RemoveAttributeById
1652 *
1653 * This is the guts of ALTER TABLE DROP COLUMN: actually mark the attribute
1654 * deleted in pg_attribute. We also remove pg_statistic entries for it.
1655 * (Everything else needed, such as getting rid of any pg_attrdef entry,
1656 * is handled by dependency.c.)
1657 */
1658void
1660{
1661 Relation rel;
1662 Relation attr_rel;
1663 HeapTuple tuple;
1664 Form_pg_attribute attStruct;
1665 char newattname[NAMEDATALEN];
1666 Datum valuesAtt[Natts_pg_attribute] = {0};
1667 bool nullsAtt[Natts_pg_attribute] = {0};
1668 bool replacesAtt[Natts_pg_attribute] = {0};
1669
1670 /*
1671 * Grab an exclusive lock on the target table, which we will NOT release
1672 * until end of transaction. (In the simple case where we are directly
1673 * dropping this column, ATExecDropColumn already did this ... but when
1674 * cascading from a drop of some other object, we may not have any lock.)
1675 */
1676 rel = relation_open(relid, AccessExclusiveLock);
1677
1678 attr_rel = table_open(AttributeRelationId, RowExclusiveLock);
1679
1680 tuple = SearchSysCacheCopy2(ATTNUM,
1681 ObjectIdGetDatum(relid),
1683 if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
1684 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1685 attnum, relid);
1686 attStruct = (Form_pg_attribute) GETSTRUCT(tuple);
1687
1688 /* Mark the attribute as dropped */
1689 attStruct->attisdropped = true;
1690
1691 /*
1692 * Set the type OID to invalid. A dropped attribute's type link cannot be
1693 * relied on (once the attribute is dropped, the type might be too).
1694 * Fortunately we do not need the type row --- the only really essential
1695 * information is the type's typlen and typalign, which are preserved in
1696 * the attribute's attlen and attalign. We set atttypid to zero here as a
1697 * means of catching code that incorrectly expects it to be valid.
1698 */
1699 attStruct->atttypid = InvalidOid;
1700
1701 /* Remove any not-null constraint the column may have */
1702 attStruct->attnotnull = false;
1703
1704 /* Unset this so no one tries to look up the generation expression */
1705 attStruct->attgenerated = '\0';
1706
1707 /*
1708 * Change the column name to something that isn't likely to conflict
1709 */
1710 snprintf(newattname, sizeof(newattname),
1711 "........pg.dropped.%d........", attnum);
1712 namestrcpy(&(attStruct->attname), newattname);
1713
1714 /* Clear the missing value */
1715 attStruct->atthasmissing = false;
1716 nullsAtt[Anum_pg_attribute_attmissingval - 1] = true;
1717 replacesAtt[Anum_pg_attribute_attmissingval - 1] = true;
1718
1719 /*
1720 * Clear the other nullable fields. This saves some space in pg_attribute
1721 * and removes no longer useful information.
1722 */
1723 nullsAtt[Anum_pg_attribute_attstattarget - 1] = true;
1724 replacesAtt[Anum_pg_attribute_attstattarget - 1] = true;
1725 nullsAtt[Anum_pg_attribute_attacl - 1] = true;
1726 replacesAtt[Anum_pg_attribute_attacl - 1] = true;
1727 nullsAtt[Anum_pg_attribute_attoptions - 1] = true;
1728 replacesAtt[Anum_pg_attribute_attoptions - 1] = true;
1729 nullsAtt[Anum_pg_attribute_attfdwoptions - 1] = true;
1730 replacesAtt[Anum_pg_attribute_attfdwoptions - 1] = true;
1731
1732 tuple = heap_modify_tuple(tuple, RelationGetDescr(attr_rel),
1733 valuesAtt, nullsAtt, replacesAtt);
1734
1735 CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
1736
1737 /*
1738 * Because updating the pg_attribute row will trigger a relcache flush for
1739 * the target relation, we need not do anything else to notify other
1740 * backends of the change.
1741 */
1742
1743 table_close(attr_rel, RowExclusiveLock);
1744
1745 RemoveStatistics(relid, attnum);
1746
1747 relation_close(rel, NoLock);
1748}
1749
1750/*
1751 * heap_drop_with_catalog - removes specified relation from catalogs
1752 *
1753 * Note that this routine is not responsible for dropping objects that are
1754 * linked to the pg_class entry via dependencies (for example, indexes and
1755 * constraints). Those are deleted by the dependency-tracing logic in
1756 * dependency.c before control gets here. In general, therefore, this routine
1757 * should never be called directly; go through performDeletion() instead.
1758 */
1759void
1761{
1762 Relation rel;
1763 HeapTuple tuple;
1764 Oid parentOid = InvalidOid,
1765 defaultPartOid = InvalidOid;
1766
1767 /*
1768 * To drop a partition safely, we must grab exclusive lock on its parent,
1769 * because another backend might be about to execute a query on the parent
1770 * table. If it relies on previously cached partition descriptor, then it
1771 * could attempt to access the just-dropped relation as its partition. We
1772 * must therefore take a table lock strong enough to prevent all queries
1773 * on the table from proceeding until we commit and send out a
1774 * shared-cache-inval notice that will make them update their partition
1775 * descriptors.
1776 */
1777 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1778 if (!HeapTupleIsValid(tuple))
1779 elog(ERROR, "cache lookup failed for relation %u", relid);
1780 if (((Form_pg_class) GETSTRUCT(tuple))->relispartition)
1781 {
1782 /*
1783 * We have to lock the parent if the partition is being detached,
1784 * because it's possible that some query still has a partition
1785 * descriptor that includes this partition.
1786 */
1787 parentOid = get_partition_parent(relid, true);
1789
1790 /*
1791 * If this is not the default partition, dropping it will change the
1792 * default partition's partition constraint, so we must lock it.
1793 */
1794 defaultPartOid = get_default_partition_oid(parentOid);
1795 if (OidIsValid(defaultPartOid) && relid != defaultPartOid)
1796 LockRelationOid(defaultPartOid, AccessExclusiveLock);
1797 }
1798
1799 ReleaseSysCache(tuple);
1800
1801 /*
1802 * Open and lock the relation.
1803 */
1804 rel = relation_open(relid, AccessExclusiveLock);
1805
1806 /*
1807 * There can no longer be anyone *else* touching the relation, but we
1808 * might still have open queries or cursors, or pending trigger events, in
1809 * our own session.
1810 */
1811 CheckTableNotInUse(rel, "DROP TABLE");
1812
1813 /*
1814 * This effectively deletes all rows in the table, and may be done in a
1815 * serializable transaction. In that case we must record a rw-conflict in
1816 * to this transaction from each transaction holding a predicate lock on
1817 * the table.
1818 */
1820
1821 /*
1822 * Delete pg_foreign_table tuple first.
1823 */
1824 if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1825 {
1826 Relation ftrel;
1827 HeapTuple fttuple;
1828
1829 ftrel = table_open(ForeignTableRelationId, RowExclusiveLock);
1830
1831 fttuple = SearchSysCache1(FOREIGNTABLEREL, ObjectIdGetDatum(relid));
1832 if (!HeapTupleIsValid(fttuple))
1833 elog(ERROR, "cache lookup failed for foreign table %u", relid);
1834
1835 CatalogTupleDelete(ftrel, &fttuple->t_self);
1836
1837 ReleaseSysCache(fttuple);
1839 }
1840
1841 /*
1842 * If a partitioned table, delete the pg_partitioned_table tuple.
1843 */
1844 if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1846
1847 /*
1848 * If the relation being dropped is the default partition itself,
1849 * invalidate its entry in pg_partitioned_table.
1850 */
1851 if (relid == defaultPartOid)
1853
1854 /*
1855 * Schedule unlinking of the relation's physical files at commit.
1856 */
1857 if (RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
1859
1860 /* ensure that stats are dropped if transaction commits */
1862
1863 /*
1864 * Close relcache entry, but *keep* AccessExclusiveLock on the relation
1865 * until transaction commit. This ensures no one else will try to do
1866 * something with the doomed relation.
1867 */
1868 relation_close(rel, NoLock);
1869
1870 /*
1871 * Remove any associated relation synchronization states.
1872 */
1874
1875 /*
1876 * Forget any ON COMMIT action for the rel
1877 */
1879
1880 /*
1881 * Flush the relation from the relcache. We want to do this before
1882 * starting to remove catalog entries, just to be certain that no relcache
1883 * entry rebuild will happen partway through. (That should not really
1884 * matter, since we don't do CommandCounterIncrement here, but let's be
1885 * safe.)
1886 */
1888
1889 /*
1890 * remove inheritance information
1891 */
1893
1894 /*
1895 * delete statistics
1896 */
1897 RemoveStatistics(relid, 0);
1898
1899 /*
1900 * delete attribute tuples
1901 */
1902 DeleteAttributeTuples(relid);
1903
1904 /*
1905 * delete relation tuple
1906 */
1907 DeleteRelationTuple(relid);
1908
1909 if (OidIsValid(parentOid))
1910 {
1911 /*
1912 * If this is not the default partition, the partition constraint of
1913 * the default partition has changed to include the portion of the key
1914 * space previously covered by the dropped partition.
1915 */
1916 if (OidIsValid(defaultPartOid) && relid != defaultPartOid)
1917 CacheInvalidateRelcacheByRelid(defaultPartOid);
1918
1919 /*
1920 * Invalidate the parent's relcache so that the partition is no longer
1921 * included in its partition descriptor.
1922 */
1924 /* keep the lock */
1925 }
1926}
1927
1928
1929/*
1930 * RelationClearMissing
1931 *
1932 * Set atthasmissing and attmissingval to false/null for all attributes
1933 * where they are currently set. This can be safely and usefully done if
1934 * the table is rewritten (e.g. by VACUUM FULL or CLUSTER) where we know there
1935 * are no rows left with less than a full complement of attributes.
1936 *
1937 * The caller must have an AccessExclusive lock on the relation.
1938 */
1939void
1941{
1942 Relation attr_rel;
1943 Oid relid = RelationGetRelid(rel);
1944 int natts = RelationGetNumberOfAttributes(rel);
1945 int attnum;
1946 Datum repl_val[Natts_pg_attribute];
1947 bool repl_null[Natts_pg_attribute];
1948 bool repl_repl[Natts_pg_attribute];
1949 Form_pg_attribute attrtuple;
1950 HeapTuple tuple,
1951 newtuple;
1952
1953 memset(repl_val, 0, sizeof(repl_val));
1954 memset(repl_null, false, sizeof(repl_null));
1955 memset(repl_repl, false, sizeof(repl_repl));
1956
1957 repl_val[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(false);
1958 repl_null[Anum_pg_attribute_attmissingval - 1] = true;
1959
1960 repl_repl[Anum_pg_attribute_atthasmissing - 1] = true;
1961 repl_repl[Anum_pg_attribute_attmissingval - 1] = true;
1962
1963
1964 /* Get a lock on pg_attribute */
1965 attr_rel = table_open(AttributeRelationId, RowExclusiveLock);
1966
1967 /* process each non-system attribute, including any dropped columns */
1968 for (attnum = 1; attnum <= natts; attnum++)
1969 {
1970 tuple = SearchSysCache2(ATTNUM,
1971 ObjectIdGetDatum(relid),
1973 if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
1974 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1975 attnum, relid);
1976
1977 attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
1978
1979 /* ignore any where atthasmissing is not true */
1980 if (attrtuple->atthasmissing)
1981 {
1982 newtuple = heap_modify_tuple(tuple, RelationGetDescr(attr_rel),
1983 repl_val, repl_null, repl_repl);
1984
1985 CatalogTupleUpdate(attr_rel, &newtuple->t_self, newtuple);
1986
1987 heap_freetuple(newtuple);
1988 }
1989
1990 ReleaseSysCache(tuple);
1991 }
1992
1993 /*
1994 * Our update of the pg_attribute rows will force a relcache rebuild, so
1995 * there's nothing else to do here.
1996 */
1997 table_close(attr_rel, RowExclusiveLock);
1998}
1999
2000/*
2001 * SetAttrMissing
2002 *
2003 * Set the missing value of a single attribute. This should only be used by
2004 * binary upgrade. Takes an AccessExclusive lock on the relation owning the
2005 * attribute.
2006 */
2007void
2008SetAttrMissing(Oid relid, char *attname, char *value)
2009{
2010 Datum valuesAtt[Natts_pg_attribute] = {0};
2011 bool nullsAtt[Natts_pg_attribute] = {0};
2012 bool replacesAtt[Natts_pg_attribute] = {0};
2013 Datum missingval;
2014 Form_pg_attribute attStruct;
2015 Relation attrrel,
2016 tablerel;
2017 HeapTuple atttup,
2018 newtup;
2019
2020 /* lock the table the attribute belongs to */
2021 tablerel = table_open(relid, AccessExclusiveLock);
2022
2023 /* Don't do anything unless it's a plain table */
2024 if (tablerel->rd_rel->relkind != RELKIND_RELATION)
2025 {
2027 return;
2028 }
2029
2030 /* Lock the attribute row and get the data */
2031 attrrel = table_open(AttributeRelationId, RowExclusiveLock);
2032 atttup = SearchSysCacheAttName(relid, attname);
2033 if (!HeapTupleIsValid(atttup))
2034 elog(ERROR, "cache lookup failed for attribute %s of relation %u",
2035 attname, relid);
2036 attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
2037
2038 /* get an array value from the value string */
2039 missingval = OidFunctionCall3(F_ARRAY_IN,
2041 ObjectIdGetDatum(attStruct->atttypid),
2042 Int32GetDatum(attStruct->atttypmod));
2043
2044 /* update the tuple - set atthasmissing and attmissingval */
2045 valuesAtt[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(true);
2046 replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true;
2047 valuesAtt[Anum_pg_attribute_attmissingval - 1] = missingval;
2048 replacesAtt[Anum_pg_attribute_attmissingval - 1] = true;
2049
2050 newtup = heap_modify_tuple(atttup, RelationGetDescr(attrrel),
2051 valuesAtt, nullsAtt, replacesAtt);
2052 CatalogTupleUpdate(attrrel, &newtup->t_self, newtup);
2053
2054 /* clean up */
2055 ReleaseSysCache(atttup);
2056 table_close(attrrel, RowExclusiveLock);
2058}
2059
2060/*
2061 * Store a check-constraint expression for the given relation.
2062 *
2063 * Caller is responsible for updating the count of constraints
2064 * in the pg_class entry for the relation.
2065 *
2066 * The OID of the new constraint is returned.
2067 */
2068static Oid
2069StoreRelCheck(Relation rel, const char *ccname, Node *expr,
2070 bool is_enforced, bool is_validated, bool is_local,
2071 int16 inhcount, bool is_no_inherit, bool is_internal)
2072{
2073 char *ccbin;
2074 List *varList;
2075 int keycount;
2076 int16 *attNos;
2077 Oid constrOid;
2078
2079 /*
2080 * Flatten expression to string form for storage.
2081 */
2082 ccbin = nodeToString(expr);
2083
2084 /*
2085 * Find columns of rel that are used in expr
2086 *
2087 * NB: pull_var_clause is okay here only because we don't allow subselects
2088 * in check constraints; it would fail to examine the contents of
2089 * subselects.
2090 */
2091 varList = pull_var_clause(expr, 0);
2092 keycount = list_length(varList);
2093
2094 if (keycount > 0)
2095 {
2096 ListCell *vl;
2097 int i = 0;
2098
2099 attNos = (int16 *) palloc(keycount * sizeof(int16));
2100 foreach(vl, varList)
2101 {
2102 Var *var = (Var *) lfirst(vl);
2103 int j;
2104
2105 for (j = 0; j < i; j++)
2106 if (attNos[j] == var->varattno)
2107 break;
2108 if (j == i)
2109 attNos[i++] = var->varattno;
2110 }
2111 keycount = i;
2112 }
2113 else
2114 attNos = NULL;
2115
2116 /*
2117 * Partitioned tables do not contain any rows themselves, so a NO INHERIT
2118 * constraint makes no sense.
2119 */
2120 if (is_no_inherit &&
2121 rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2122 ereport(ERROR,
2123 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2124 errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
2126
2127 /*
2128 * Create the Check Constraint
2129 */
2130 constrOid =
2131 CreateConstraintEntry(ccname, /* Constraint Name */
2132 RelationGetNamespace(rel), /* namespace */
2133 CONSTRAINT_CHECK, /* Constraint Type */
2134 false, /* Is Deferrable */
2135 false, /* Is Deferred */
2136 is_enforced, /* Is Enforced */
2137 is_validated,
2138 InvalidOid, /* no parent constraint */
2139 RelationGetRelid(rel), /* relation */
2140 attNos, /* attrs in the constraint */
2141 keycount, /* # key attrs in the constraint */
2142 keycount, /* # total attrs in the constraint */
2143 InvalidOid, /* not a domain constraint */
2144 InvalidOid, /* no associated index */
2145 InvalidOid, /* Foreign key fields */
2146 NULL,
2147 NULL,
2148 NULL,
2149 NULL,
2150 0,
2151 ' ',
2152 ' ',
2153 NULL,
2154 0,
2155 ' ',
2156 NULL, /* not an exclusion constraint */
2157 expr, /* Tree form of check constraint */
2158 ccbin, /* Binary form of check constraint */
2159 is_local, /* conislocal */
2160 inhcount, /* coninhcount */
2161 is_no_inherit, /* connoinherit */
2162 false, /* conperiod */
2163 is_internal); /* internally constructed? */
2164
2165 pfree(ccbin);
2166
2167 return constrOid;
2168}
2169
2170/*
2171 * Store a not-null constraint for the given relation
2172 *
2173 * The OID of the new constraint is returned.
2174 */
2175static Oid
2177 bool is_validated, bool is_local, int inhcount,
2178 bool is_no_inherit)
2179{
2180 Oid constrOid;
2181
2183
2184 constrOid =
2185 CreateConstraintEntry(nnname,
2187 CONSTRAINT_NOTNULL,
2188 false,
2189 false,
2190 true, /* Is Enforced */
2191 is_validated,
2192 InvalidOid,
2193 RelationGetRelid(rel),
2194 &attnum,
2195 1,
2196 1,
2197 InvalidOid, /* not a domain constraint */
2198 InvalidOid, /* no associated index */
2199 InvalidOid, /* Foreign key fields */
2200 NULL,
2201 NULL,
2202 NULL,
2203 NULL,
2204 0,
2205 ' ',
2206 ' ',
2207 NULL,
2208 0,
2209 ' ',
2210 NULL, /* not an exclusion constraint */
2211 NULL,
2212 NULL,
2213 is_local,
2214 inhcount,
2215 is_no_inherit,
2216 false,
2217 false);
2218 return constrOid;
2219}
2220
2221/*
2222 * Store defaults and CHECK constraints (passed as a list of CookedConstraint).
2223 *
2224 * Each CookedConstraint struct is modified to store the new catalog tuple OID.
2225 *
2226 * NOTE: only pre-cooked expressions will be passed this way, which is to
2227 * say expressions inherited from an existing relation. Newly parsed
2228 * expressions can be added later, by direct calls to StoreAttrDefault
2229 * and StoreRelCheck (see AddRelationNewConstraints()).
2230 */
2231static void
2232StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal)
2233{
2234 int numchecks = 0;
2235 ListCell *lc;
2236
2237 if (cooked_constraints == NIL)
2238 return; /* nothing to do */
2239
2240 /*
2241 * Deparsing of constraint expressions will fail unless the just-created
2242 * pg_attribute tuples for this relation are made visible. So, bump the
2243 * command counter. CAUTION: this will cause a relcache entry rebuild.
2244 */
2246
2247 foreach(lc, cooked_constraints)
2248 {
2250
2251 switch (con->contype)
2252 {
2253 case CONSTR_DEFAULT:
2254 con->conoid = StoreAttrDefault(rel, con->attnum, con->expr,
2255 is_internal, false);
2256 break;
2257 case CONSTR_CHECK:
2258 con->conoid =
2259 StoreRelCheck(rel, con->name, con->expr,
2260 con->is_enforced, !con->skip_validation,
2261 con->is_local, con->inhcount,
2262 con->is_no_inherit, is_internal);
2263 numchecks++;
2264 break;
2265
2266 default:
2267 elog(ERROR, "unrecognized constraint type: %d",
2268 (int) con->contype);
2269 }
2270 }
2271
2272 if (numchecks > 0)
2273 SetRelationNumChecks(rel, numchecks);
2274}
2275
2276/*
2277 * AddRelationNewConstraints
2278 *
2279 * Add new column default expressions and/or constraint check expressions
2280 * to an existing relation. This is defined to do both for efficiency in
2281 * DefineRelation, but of course you can do just one or the other by passing
2282 * empty lists.
2283 *
2284 * rel: relation to be modified
2285 * newColDefaults: list of RawColumnDefault structures
2286 * newConstraints: list of Constraint nodes
2287 * allow_merge: true if check constraints may be merged with existing ones
2288 * is_local: true if definition is local, false if it's inherited
2289 * is_internal: true if result of some internal process, not a user request
2290 * queryString: used during expression transformation of default values and
2291 * cooked CHECK constraints
2292 *
2293 * All entries in newColDefaults will be processed. Entries in newConstraints
2294 * will be processed only if they are CONSTR_CHECK or CONSTR_NOTNULL types.
2295 *
2296 * Returns a list of CookedConstraint nodes that shows the cooked form of
2297 * the default and constraint expressions added to the relation.
2298 *
2299 * NB: caller should have opened rel with some self-conflicting lock mode,
2300 * and should hold that lock till end of transaction; for normal cases that'll
2301 * be AccessExclusiveLock, but if caller knows that the constraint is already
2302 * enforced by some other means, it can be ShareUpdateExclusiveLock. Also, we
2303 * assume the caller has done a CommandCounterIncrement if necessary to make
2304 * the relation's catalog tuples visible.
2305 */
2306List *
2308 List *newColDefaults,
2309 List *newConstraints,
2310 bool allow_merge,
2311 bool is_local,
2312 bool is_internal,
2313 const char *queryString)
2314{
2315 List *cookedConstraints = NIL;
2316 TupleDesc tupleDesc;
2317 TupleConstr *oldconstr;
2318 int numoldchecks;
2319 ParseState *pstate;
2320 ParseNamespaceItem *nsitem;
2321 int numchecks;
2322 List *checknames;
2323 List *nnnames;
2324 Node *expr;
2325 CookedConstraint *cooked;
2326
2327 /*
2328 * Get info about existing constraints.
2329 */
2330 tupleDesc = RelationGetDescr(rel);
2331 oldconstr = tupleDesc->constr;
2332 if (oldconstr)
2333 numoldchecks = oldconstr->num_check;
2334 else
2335 numoldchecks = 0;
2336
2337 /*
2338 * Create a dummy ParseState and insert the target relation as its sole
2339 * rangetable entry. We need a ParseState for transformExpr.
2340 */
2341 pstate = make_parsestate(NULL);
2342 pstate->p_sourcetext = queryString;
2343 nsitem = addRangeTableEntryForRelation(pstate,
2344 rel,
2346 NULL,
2347 false,
2348 true);
2349 addNSItemToQuery(pstate, nsitem, true, true, true);
2350
2351 /*
2352 * Process column default expressions.
2353 */
2354 foreach_ptr(RawColumnDefault, colDef, newColDefaults)
2355 {
2356 Form_pg_attribute atp = TupleDescAttr(rel->rd_att, colDef->attnum - 1);
2357 Oid defOid;
2358
2359 expr = cookDefault(pstate, colDef->raw_default,
2360 atp->atttypid, atp->atttypmod,
2361 NameStr(atp->attname),
2362 atp->attgenerated);
2363
2364 /*
2365 * If the expression is just a NULL constant, we do not bother to make
2366 * an explicit pg_attrdef entry, since the default behavior is
2367 * equivalent. This applies to column defaults, but not for
2368 * generation expressions.
2369 *
2370 * Note a nonobvious property of this test: if the column is of a
2371 * domain type, what we'll get is not a bare null Const but a
2372 * CoerceToDomain expr, so we will not discard the default. This is
2373 * critical because the column default needs to be retained to
2374 * override any default that the domain might have.
2375 */
2376 if (expr == NULL ||
2377 (!colDef->generated &&
2378 IsA(expr, Const) &&
2379 castNode(Const, expr)->constisnull))
2380 continue;
2381
2382 /* If the DEFAULT is volatile we cannot use a missing value */
2383 if (colDef->missingMode &&
2385 colDef->missingMode = false;
2386
2387 defOid = StoreAttrDefault(rel, colDef->attnum, expr, is_internal,
2388 colDef->missingMode);
2389
2390 cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2391 cooked->contype = CONSTR_DEFAULT;
2392 cooked->conoid = defOid;
2393 cooked->name = NULL;
2394 cooked->attnum = colDef->attnum;
2395 cooked->expr = expr;
2396 cooked->is_enforced = true;
2397 cooked->skip_validation = false;
2398 cooked->is_local = is_local;
2399 cooked->inhcount = is_local ? 0 : 1;
2400 cooked->is_no_inherit = false;
2401 cookedConstraints = lappend(cookedConstraints, cooked);
2402 }
2403
2404 /*
2405 * Process constraint expressions.
2406 */
2407 numchecks = numoldchecks;
2408 checknames = NIL;
2409 nnnames = NIL;
2410 foreach_node(Constraint, cdef, newConstraints)
2411 {
2412 Oid constrOid;
2413
2414 if (cdef->contype == CONSTR_CHECK)
2415 {
2416 char *ccname;
2417
2418 if (cdef->raw_expr != NULL)
2419 {
2420 Assert(cdef->cooked_expr == NULL);
2421
2422 /*
2423 * Transform raw parsetree to executable expression, and
2424 * verify it's valid as a CHECK constraint.
2425 */
2426 expr = cookConstraint(pstate, cdef->raw_expr,
2428 }
2429 else
2430 {
2431 Assert(cdef->cooked_expr != NULL);
2432
2433 /*
2434 * Here, we assume the parser will only pass us valid CHECK
2435 * expressions, so we do no particular checking.
2436 */
2437 expr = stringToNode(cdef->cooked_expr);
2438 }
2439
2440 /*
2441 * Check name uniqueness, or generate a name if none was given.
2442 */
2443 if (cdef->conname != NULL)
2444 {
2445 ccname = cdef->conname;
2446 /* Check against other new constraints */
2447 /* Needed because we don't do CommandCounterIncrement in loop */
2448 foreach_ptr(char, chkname, checknames)
2449 {
2450 if (strcmp(chkname, ccname) == 0)
2451 ereport(ERROR,
2453 errmsg("check constraint \"%s\" already exists",
2454 ccname)));
2455 }
2456
2457 /* save name for future checks */
2458 checknames = lappend(checknames, ccname);
2459
2460 /*
2461 * Check against pre-existing constraints. If we are allowed
2462 * to merge with an existing constraint, there's no more to do
2463 * here. (We omit the duplicate constraint from the result,
2464 * which is what ATAddCheckNNConstraint wants.)
2465 */
2466 if (MergeWithExistingConstraint(rel, ccname, expr,
2467 allow_merge, is_local,
2468 cdef->is_enforced,
2469 cdef->initially_valid,
2470 cdef->is_no_inherit))
2471 continue;
2472 }
2473 else
2474 {
2475 /*
2476 * When generating a name, we want to create "tab_col_check"
2477 * for a column constraint and "tab_check" for a table
2478 * constraint. We no longer have any info about the syntactic
2479 * positioning of the constraint phrase, so we approximate
2480 * this by seeing whether the expression references more than
2481 * one column. (If the user played by the rules, the result
2482 * is the same...)
2483 *
2484 * Note: pull_var_clause() doesn't descend into sublinks, but
2485 * we eliminated those above; and anyway this only needs to be
2486 * an approximate answer.
2487 */
2488 List *vars;
2489 char *colname;
2490
2491 vars = pull_var_clause(expr, 0);
2492
2493 /* eliminate duplicates */
2494 vars = list_union(NIL, vars);
2495
2496 if (list_length(vars) == 1)
2497 colname = get_attname(RelationGetRelid(rel),
2498 ((Var *) linitial(vars))->varattno,
2499 true);
2500 else
2501 colname = NULL;
2502
2504 colname,
2505 "check",
2507 checknames);
2508
2509 /* save name for future checks */
2510 checknames = lappend(checknames, ccname);
2511 }
2512
2513 /*
2514 * OK, store it.
2515 */
2516 constrOid =
2517 StoreRelCheck(rel, ccname, expr, cdef->is_enforced,
2518 cdef->initially_valid, is_local,
2519 is_local ? 0 : 1, cdef->is_no_inherit,
2520 is_internal);
2521
2522 numchecks++;
2523
2524 cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2525 cooked->contype = CONSTR_CHECK;
2526 cooked->conoid = constrOid;
2527 cooked->name = ccname;
2528 cooked->attnum = 0;
2529 cooked->expr = expr;
2530 cooked->is_enforced = cdef->is_enforced;
2531 cooked->skip_validation = cdef->skip_validation;
2532 cooked->is_local = is_local;
2533 cooked->inhcount = is_local ? 0 : 1;
2534 cooked->is_no_inherit = cdef->is_no_inherit;
2535 cookedConstraints = lappend(cookedConstraints, cooked);
2536 }
2537 else if (cdef->contype == CONSTR_NOTNULL)
2538 {
2539 CookedConstraint *nncooked;
2540 AttrNumber colnum;
2541 int16 inhcount = is_local ? 0 : 1;
2542 char *nnname;
2543
2544 /* Determine which column to modify */
2545 colnum = get_attnum(RelationGetRelid(rel), strVal(linitial(cdef->keys)));
2546 if (colnum == InvalidAttrNumber)
2547 ereport(ERROR,
2548 errcode(ERRCODE_UNDEFINED_COLUMN),
2549 errmsg("column \"%s\" of relation \"%s\" does not exist",
2550 strVal(linitial(cdef->keys)), RelationGetRelationName(rel)));
2551 if (colnum < InvalidAttrNumber)
2552 ereport(ERROR,
2553 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2554 errmsg("cannot add not-null constraint on system column \"%s\"",
2555 strVal(linitial(cdef->keys))));
2556
2557 /*
2558 * If the column already has a not-null constraint, we don't want
2559 * to add another one; just adjust inheritance status as needed.
2560 */
2562 is_local, cdef->is_no_inherit))
2563 continue;
2564
2565 /*
2566 * If a constraint name is specified, check that it isn't already
2567 * used. Otherwise, choose a non-conflicting one ourselves.
2568 */
2569 if (cdef->conname)
2570 {
2572 RelationGetRelid(rel),
2573 cdef->conname))
2574 ereport(ERROR,
2576 errmsg("constraint \"%s\" for relation \"%s\" already exists",
2577 cdef->conname, RelationGetRelationName(rel)));
2578 nnname = cdef->conname;
2579 }
2580 else
2582 strVal(linitial(cdef->keys)),
2583 "not_null",
2585 nnnames);
2586 nnnames = lappend(nnnames, nnname);
2587
2588 constrOid =
2589 StoreRelNotNull(rel, nnname, colnum,
2590 cdef->initially_valid,
2591 is_local,
2592 inhcount,
2593 cdef->is_no_inherit);
2594
2595 nncooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2596 nncooked->contype = CONSTR_NOTNULL;
2597 nncooked->conoid = constrOid;
2598 nncooked->name = nnname;
2599 nncooked->attnum = colnum;
2600 nncooked->expr = NULL;
2601 nncooked->is_enforced = true;
2602 nncooked->skip_validation = cdef->skip_validation;
2603 nncooked->is_local = is_local;
2604 nncooked->inhcount = inhcount;
2605 nncooked->is_no_inherit = cdef->is_no_inherit;
2606
2607 cookedConstraints = lappend(cookedConstraints, nncooked);
2608 }
2609 }
2610
2611 /*
2612 * Update the count of constraints in the relation's pg_class tuple. We do
2613 * this even if there was no change, in order to ensure that an SI update
2614 * message is sent out for the pg_class tuple, which will force other
2615 * backends to rebuild their relcache entries for the rel. (This is
2616 * critical if we added defaults but not constraints.)
2617 */
2618 SetRelationNumChecks(rel, numchecks);
2619
2620 return cookedConstraints;
2621}
2622
2623/*
2624 * Check for a pre-existing check constraint that conflicts with a proposed
2625 * new one, and either adjust its conislocal/coninhcount settings or throw
2626 * error as needed.
2627 *
2628 * Returns true if merged (constraint is a duplicate), or false if it's
2629 * got a so-far-unique name, or throws error if conflict.
2630 *
2631 * XXX See MergeConstraintsIntoExisting too if you change this code.
2632 */
2633static bool
2634MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr,
2635 bool allow_merge, bool is_local,
2636 bool is_enforced,
2637 bool is_initially_valid,
2638 bool is_no_inherit)
2639{
2640 bool found;
2641 Relation conDesc;
2642 SysScanDesc conscan;
2643 ScanKeyData skey[3];
2644 HeapTuple tup;
2645
2646 /* Search for a pg_constraint entry with same name and relation */
2647 conDesc = table_open(ConstraintRelationId, RowExclusiveLock);
2648
2649 found = false;
2650
2651 ScanKeyInit(&skey[0],
2652 Anum_pg_constraint_conrelid,
2653 BTEqualStrategyNumber, F_OIDEQ,
2655 ScanKeyInit(&skey[1],
2656 Anum_pg_constraint_contypid,
2657 BTEqualStrategyNumber, F_OIDEQ,
2659 ScanKeyInit(&skey[2],
2660 Anum_pg_constraint_conname,
2661 BTEqualStrategyNumber, F_NAMEEQ,
2662 CStringGetDatum(ccname));
2663
2664 conscan = systable_beginscan(conDesc, ConstraintRelidTypidNameIndexId, true,
2665 NULL, 3, skey);
2666
2667 /* There can be at most one matching row */
2668 if (HeapTupleIsValid(tup = systable_getnext(conscan)))
2669 {
2671
2672 /* Found it. Conflicts if not identical check constraint */
2673 if (con->contype == CONSTRAINT_CHECK)
2674 {
2675 Datum val;
2676 bool isnull;
2677
2678 val = fastgetattr(tup,
2679 Anum_pg_constraint_conbin,
2680 conDesc->rd_att, &isnull);
2681 if (isnull)
2682 elog(ERROR, "null conbin for rel %s",
2685 found = true;
2686 }
2687
2688 /*
2689 * If the existing constraint is purely inherited (no local
2690 * definition) then interpret addition of a local constraint as a
2691 * legal merge. This allows ALTER ADD CONSTRAINT on parent and child
2692 * tables to be given in either order with same end state. However if
2693 * the relation is a partition, all inherited constraints are always
2694 * non-local, including those that were merged.
2695 */
2696 if (is_local && !con->conislocal && !rel->rd_rel->relispartition)
2697 allow_merge = true;
2698
2699 if (!found || !allow_merge)
2700 ereport(ERROR,
2702 errmsg("constraint \"%s\" for relation \"%s\" already exists",
2703 ccname, RelationGetRelationName(rel))));
2704
2705 /* If the child constraint is "no inherit" then cannot merge */
2706 if (con->connoinherit)
2707 ereport(ERROR,
2708 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2709 errmsg("constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"",
2710 ccname, RelationGetRelationName(rel))));
2711
2712 /*
2713 * Must not change an existing inherited constraint to "no inherit"
2714 * status. That's because inherited constraints should be able to
2715 * propagate to lower-level children.
2716 */
2717 if (con->coninhcount > 0 && is_no_inherit)
2718 ereport(ERROR,
2719 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2720 errmsg("constraint \"%s\" conflicts with inherited constraint on relation \"%s\"",
2721 ccname, RelationGetRelationName(rel))));
2722
2723 /*
2724 * If the child constraint is "not valid" then cannot merge with a
2725 * valid parent constraint.
2726 */
2727 if (is_initially_valid && con->conenforced && !con->convalidated)
2728 ereport(ERROR,
2729 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2730 errmsg("constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"",
2731 ccname, RelationGetRelationName(rel))));
2732
2733 /*
2734 * A non-enforced child constraint cannot be merged with an enforced
2735 * parent constraint. However, the reverse is allowed, where the child
2736 * constraint is enforced.
2737 */
2738 if ((!is_local && is_enforced && !con->conenforced) ||
2739 (is_local && !is_enforced && con->conenforced))
2740 ereport(ERROR,
2741 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2742 errmsg("constraint \"%s\" conflicts with NOT ENFORCED constraint on relation \"%s\"",
2743 ccname, RelationGetRelationName(rel))));
2744
2745 /* OK to update the tuple */
2747 (errmsg("merging constraint \"%s\" with inherited definition",
2748 ccname)));
2749
2750 tup = heap_copytuple(tup);
2751 con = (Form_pg_constraint) GETSTRUCT(tup);
2752
2753 /*
2754 * In case of partitions, an inherited constraint must be inherited
2755 * only once since it cannot have multiple parents and it is never
2756 * considered local.
2757 */
2758 if (rel->rd_rel->relispartition)
2759 {
2760 con->coninhcount = 1;
2761 con->conislocal = false;
2762 }
2763 else
2764 {
2765 if (is_local)
2766 con->conislocal = true;
2767 else if (pg_add_s16_overflow(con->coninhcount, 1,
2768 &con->coninhcount))
2769 ereport(ERROR,
2770 errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2771 errmsg("too many inheritance parents"));
2772 }
2773
2774 if (is_no_inherit)
2775 {
2776 Assert(is_local);
2777 con->connoinherit = true;
2778 }
2779
2780 /*
2781 * If the child constraint is required to be enforced while the parent
2782 * constraint is not, this should be allowed by marking the child
2783 * constraint as enforced. In the reverse case, an error would have
2784 * already been thrown before reaching this point.
2785 */
2786 if (is_enforced && !con->conenforced)
2787 {
2788 Assert(is_local);
2789 con->conenforced = true;
2790 con->convalidated = true;
2791 }
2792
2793 CatalogTupleUpdate(conDesc, &tup->t_self, tup);
2794 }
2795
2796 systable_endscan(conscan);
2797 table_close(conDesc, RowExclusiveLock);
2798
2799 return found;
2800}
2801
2802/*
2803 * Create the not-null constraints when creating a new relation
2804 *
2805 * These come from two sources: the 'constraints' list (of Constraint) is
2806 * specified directly by the user; the 'old_notnulls' list (of
2807 * CookedConstraint) comes from inheritance. We create one constraint
2808 * for each column, giving priority to user-specified ones, and setting
2809 * inhcount according to how many parents cause each column to get a
2810 * not-null constraint. If a user-specified name clashes with another
2811 * user-specified name, an error is raised.
2812 *
2813 * Returns a list of AttrNumber for columns that need to have the attnotnull
2814 * flag set.
2815 */
2816List *
2818 List *old_notnulls)
2819{
2820 List *givennames;
2821 List *nnnames;
2822 List *nncols = NIL;
2823
2824 /*
2825 * We track two lists of names: nnnames keeps all the constraint names,
2826 * givennames tracks user-generated names. The distinction is important,
2827 * because we must raise error for user-generated name conflicts, but for
2828 * system-generated name conflicts we just generate another.
2829 */
2830 nnnames = NIL;
2831 givennames = NIL;
2832
2833 /*
2834 * First, create all not-null constraints that are directly specified by
2835 * the user. Note that inheritance might have given us another source for
2836 * each, so we must scan the old_notnulls list and increment inhcount for
2837 * each element with identical attnum. We delete from there any element
2838 * that we process.
2839 *
2840 * We don't use foreach() here because we have two nested loops over the
2841 * constraint list, with possible element deletions in the inner one. If
2842 * we used foreach_delete_current() it could only fix up the state of one
2843 * of the loops, so it seems cleaner to use looping over list indexes for
2844 * both loops. Note that any deletion will happen beyond where the outer
2845 * loop is, so its index never needs adjustment.
2846 */
2847 for (int outerpos = 0; outerpos < list_length(constraints); outerpos++)
2848 {
2849 Constraint *constr;
2851 char *conname;
2852 int inhcount = 0;
2853
2854 constr = list_nth_node(Constraint, constraints, outerpos);
2855
2856 Assert(constr->contype == CONSTR_NOTNULL);
2857
2859 strVal(linitial(constr->keys)));
2861 ereport(ERROR,
2862 errcode(ERRCODE_UNDEFINED_COLUMN),
2863 errmsg("column \"%s\" of relation \"%s\" does not exist",
2864 strVal(linitial(constr->keys)),
2867 ereport(ERROR,
2868 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2869 errmsg("cannot add not-null constraint on system column \"%s\"",
2870 strVal(linitial(constr->keys))));
2871
2872 /*
2873 * A column can only have one not-null constraint, so discard any
2874 * additional ones that appear for columns we already saw; but check
2875 * that the NO INHERIT flags match.
2876 */
2877 for (int restpos = outerpos + 1; restpos < list_length(constraints);)
2878 {
2879 Constraint *other;
2880
2881 other = list_nth_node(Constraint, constraints, restpos);
2882 if (strcmp(strVal(linitial(constr->keys)),
2883 strVal(linitial(other->keys))) == 0)
2884 {
2885 if (other->is_no_inherit != constr->is_no_inherit)
2886 ereport(ERROR,
2887 errcode(ERRCODE_SYNTAX_ERROR),
2888 errmsg("conflicting NO INHERIT declaration for not-null constraint on column \"%s\"",
2889 strVal(linitial(constr->keys))));
2890
2891 /*
2892 * Preserve constraint name if one is specified, but raise an
2893 * error if conflicting ones are specified.
2894 */
2895 if (other->conname)
2896 {
2897 if (!constr->conname)
2898 constr->conname = pstrdup(other->conname);
2899 else if (strcmp(constr->conname, other->conname) != 0)
2900 ereport(ERROR,
2901 errcode(ERRCODE_SYNTAX_ERROR),
2902 errmsg("conflicting not-null constraint names \"%s\" and \"%s\"",
2903 constr->conname, other->conname));
2904 }
2905
2906 /* XXX do we need to verify any other fields? */
2907 constraints = list_delete_nth_cell(constraints, restpos);
2908 }
2909 else
2910 restpos++;
2911 }
2912
2913 /*
2914 * Search in the list of inherited constraints for any entries on the
2915 * same column; determine an inheritance count from that. Also, if at
2916 * least one parent has a constraint for this column, then we must not
2917 * accept a user specification for a NO INHERIT one. Any constraint
2918 * from parents that we process here is deleted from the list: we no
2919 * longer need to process it in the loop below.
2920 */
2921 foreach_ptr(CookedConstraint, old, old_notnulls)
2922 {
2923 if (old->attnum == attnum)
2924 {
2925 /*
2926 * If we get a constraint from the parent, having a local NO
2927 * INHERIT one doesn't work.
2928 */
2929 if (constr->is_no_inherit)
2930 ereport(ERROR,
2931 (errcode(ERRCODE_DATATYPE_MISMATCH),
2932 errmsg("cannot define not-null constraint on column \"%s\" with NO INHERIT",
2933 strVal(linitial(constr->keys))),
2934 errdetail("The column has an inherited not-null constraint.")));
2935
2936 inhcount++;
2937 old_notnulls = foreach_delete_current(old_notnulls, old);
2938 }
2939 }
2940
2941 /*
2942 * Determine a constraint name, which may have been specified by the
2943 * user, or raise an error if a conflict exists with another
2944 * user-specified name.
2945 */
2946 if (constr->conname)
2947 {
2948 foreach_ptr(char, thisname, givennames)
2949 {
2950 if (strcmp(thisname, constr->conname) == 0)
2951 ereport(ERROR,
2953 errmsg("constraint \"%s\" for relation \"%s\" already exists",
2954 constr->conname,
2956 }
2957
2958 conname = constr->conname;
2959 givennames = lappend(givennames, conname);
2960 }
2961 else
2964 attnum, false),
2965 "not_null",
2967 nnnames);
2968 nnnames = lappend(nnnames, conname);
2969
2970 StoreRelNotNull(rel, conname,
2971 attnum, true, true,
2972 inhcount, constr->is_no_inherit);
2973
2974 nncols = lappend_int(nncols, attnum);
2975 }
2976
2977 /*
2978 * If any column remains in the old_notnulls list, we must create a not-
2979 * null constraint marked not-local for that column. Because multiple
2980 * parents could specify a not-null constraint for the same column, we
2981 * must count how many there are and set an appropriate inhcount
2982 * accordingly, deleting elements we've already processed.
2983 *
2984 * We don't use foreach() here because we have two nested loops over the
2985 * constraint list, with possible element deletions in the inner one. If
2986 * we used foreach_delete_current() it could only fix up the state of one
2987 * of the loops, so it seems cleaner to use looping over list indexes for
2988 * both loops. Note that any deletion will happen beyond where the outer
2989 * loop is, so its index never needs adjustment.
2990 */
2991 for (int outerpos = 0; outerpos < list_length(old_notnulls); outerpos++)
2992 {
2993 CookedConstraint *cooked;
2994 char *conname = NULL;
2995 int inhcount = 1;
2996
2997 cooked = (CookedConstraint *) list_nth(old_notnulls, outerpos);
2998 Assert(cooked->contype == CONSTR_NOTNULL);
2999 Assert(cooked->name);
3000
3001 /*
3002 * Preserve the first non-conflicting constraint name we come across.
3003 */
3004 if (conname == NULL)
3005 conname = cooked->name;
3006
3007 for (int restpos = outerpos + 1; restpos < list_length(old_notnulls);)
3008 {
3009 CookedConstraint *other;
3010
3011 other = (CookedConstraint *) list_nth(old_notnulls, restpos);
3012 Assert(other->name);
3013 if (other->attnum == cooked->attnum)
3014 {
3015 if (conname == NULL)
3016 conname = other->name;
3017
3018 inhcount++;
3019 old_notnulls = list_delete_nth_cell(old_notnulls, restpos);
3020 }
3021 else
3022 restpos++;
3023 }
3024
3025 /* If we got a name, make sure it isn't one we've already used */
3026 if (conname != NULL)
3027 {
3028 foreach_ptr(char, thisname, nnnames)
3029 {
3030 if (strcmp(thisname, conname) == 0)
3031 {
3032 conname = NULL;
3033 break;
3034 }
3035 }
3036 }
3037
3038 /* and choose a name, if needed */
3039 if (conname == NULL)
3042 cooked->attnum, false),
3043 "not_null",
3045 nnnames);
3046 nnnames = lappend(nnnames, conname);
3047
3048 /* ignore the origin constraint's is_local and inhcount */
3049 StoreRelNotNull(rel, conname, cooked->attnum, true,
3050 false, inhcount, false);
3051
3052 nncols = lappend_int(nncols, cooked->attnum);
3053 }
3054
3055 return nncols;
3056}
3057
3058/*
3059 * Update the count of constraints in the relation's pg_class tuple.
3060 *
3061 * Caller had better hold exclusive lock on the relation.
3062 *
3063 * An important side effect is that a SI update message will be sent out for
3064 * the pg_class tuple, which will force other backends to rebuild their
3065 * relcache entries for the rel. Also, this backend will rebuild its
3066 * own relcache entry at the next CommandCounterIncrement.
3067 */
3068static void
3070{
3071 Relation relrel;
3072 HeapTuple reltup;
3073 Form_pg_class relStruct;
3074
3075 relrel = table_open(RelationRelationId, RowExclusiveLock);
3076 reltup = SearchSysCacheCopy1(RELOID,
3078 if (!HeapTupleIsValid(reltup))
3079 elog(ERROR, "cache lookup failed for relation %u",
3080 RelationGetRelid(rel));
3081 relStruct = (Form_pg_class) GETSTRUCT(reltup);
3082
3083 if (relStruct->relchecks != numchecks)
3084 {
3085 relStruct->relchecks = numchecks;
3086
3087 CatalogTupleUpdate(relrel, &reltup->t_self, reltup);
3088 }
3089 else
3090 {
3091 /* Skip the disk update, but force relcache inval anyway */
3093 }
3094
3095 heap_freetuple(reltup);
3097}
3098
3099/*
3100 * Check for references to generated columns
3101 */
3102static bool
3104{
3105 ParseState *pstate = context;
3106
3107 if (node == NULL)
3108 return false;
3109 else if (IsA(node, Var))
3110 {
3111 Var *var = (Var *) node;
3112 Oid relid;
3114
3115 relid = rt_fetch(var->varno, pstate->p_rtable)->relid;
3116 if (!OidIsValid(relid))
3117 return false; /* XXX shouldn't we raise an error? */
3118
3119 attnum = var->varattno;
3120
3121 if (attnum > 0 && get_attgenerated(relid, attnum))
3122 ereport(ERROR,
3123 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3124 errmsg("cannot use generated column \"%s\" in column generation expression",
3125 get_attname(relid, attnum, false)),
3126 errdetail("A generated column cannot reference another generated column."),
3127 parser_errposition(pstate, var->location)));
3128 /* A whole-row Var is necessarily self-referential, so forbid it */
3129 if (attnum == 0)
3130 ereport(ERROR,
3131 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3132 errmsg("cannot use whole-row variable in column generation expression"),
3133 errdetail("This would cause the generated column to depend on its own value."),
3134 parser_errposition(pstate, var->location)));
3135 /* System columns were already checked in the parser */
3136
3137 return false;
3138 }
3139 else
3141 context);
3142}
3143
3144static void
3146{
3147 check_nested_generated_walker(node, pstate);
3148}
3149
3150/*
3151 * Take a raw default and convert it to a cooked format ready for
3152 * storage.
3153 *
3154 * Parse state should be set up to recognize any vars that might appear
3155 * in the expression. (Even though we plan to reject vars, it's more
3156 * user-friendly to give the correct error message than "unknown var".)
3157 *
3158 * If atttypid is not InvalidOid, coerce the expression to the specified
3159 * type (and typmod atttypmod). attname is only needed in this case:
3160 * it is used in the error message, if any.
3161 */
3162Node *
3164 Node *raw_default,
3165 Oid atttypid,
3166 int32 atttypmod,
3167 const char *attname,
3168 char attgenerated)
3169{
3170 Node *expr;
3171
3172 Assert(raw_default != NULL);
3173
3174 /*
3175 * Transform raw parsetree to executable expression.
3176 */
3177 expr = transformExpr(pstate, raw_default, attgenerated ? EXPR_KIND_GENERATED_COLUMN : EXPR_KIND_COLUMN_DEFAULT);
3178
3179 if (attgenerated)
3180 {
3181 /* Disallow refs to other generated columns */
3182 check_nested_generated(pstate, expr);
3183
3184 /* Disallow mutable functions */
3186 ereport(ERROR,
3187 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3188 errmsg("generation expression is not immutable")));
3189 }
3190 else
3191 {
3192 /*
3193 * For a default expression, transformExpr() should have rejected
3194 * column references.
3195 */
3196 Assert(!contain_var_clause(expr));
3197 }
3198
3199 /*
3200 * Coerce the expression to the correct type and typmod, if given. This
3201 * should match the parser's processing of non-defaulted expressions ---
3202 * see transformAssignedExpr().
3203 */
3204 if (OidIsValid(atttypid))
3205 {
3206 Oid type_id = exprType(expr);
3207
3208 expr = coerce_to_target_type(pstate, expr, type_id,
3209 atttypid, atttypmod,
3212 -1);
3213 if (expr == NULL)
3214 ereport(ERROR,
3215 (errcode(ERRCODE_DATATYPE_MISMATCH),
3216 errmsg("column \"%s\" is of type %s"
3217 " but default expression is of type %s",
3218 attname,
3219 format_type_be(atttypid),
3220 format_type_be(type_id)),
3221 errhint("You will need to rewrite or cast the expression.")));
3222 }
3223
3224 /*
3225 * Finally, take care of collations in the finished expression.
3226 */
3227 assign_expr_collations(pstate, expr);
3228
3229 return expr;
3230}
3231
3232/*
3233 * Take a raw CHECK constraint expression and convert it to a cooked format
3234 * ready for storage.
3235 *
3236 * Parse state must be set up to recognize any vars that might appear
3237 * in the expression.
3238 */
3239static Node *
3241 Node *raw_constraint,
3242 char *relname)
3243{
3244 Node *expr;
3245
3246 /*
3247 * Transform raw parsetree to executable expression.
3248 */
3249 expr = transformExpr(pstate, raw_constraint, EXPR_KIND_CHECK_CONSTRAINT);
3250
3251 /*
3252 * Make sure it yields a boolean result.
3253 */
3254 expr = coerce_to_boolean(pstate, expr, "CHECK");
3255
3256 /*
3257 * Take care of collations.
3258 */
3259 assign_expr_collations(pstate, expr);
3260
3261 /*
3262 * Make sure no outside relations are referred to (this is probably dead
3263 * code now that add_missing_from is history).
3264 */
3265 if (list_length(pstate->p_rtable) != 1)
3266 ereport(ERROR,
3267 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
3268 errmsg("only table \"%s\" can be referenced in check constraint",
3269 relname)));
3270
3271 return expr;
3272}
3273
3274/*
3275 * CopyStatistics --- copy entries in pg_statistic from one rel to another
3276 */
3277void
3278CopyStatistics(Oid fromrelid, Oid torelid)
3279{
3280 HeapTuple tup;
3281 SysScanDesc scan;
3282 ScanKeyData key[1];
3283 Relation statrel;
3284 CatalogIndexState indstate = NULL;
3285
3286 statrel = table_open(StatisticRelationId, RowExclusiveLock);
3287
3288 /* Now search for stat records */
3289 ScanKeyInit(&key[0],
3290 Anum_pg_statistic_starelid,
3291 BTEqualStrategyNumber, F_OIDEQ,
3292 ObjectIdGetDatum(fromrelid));
3293
3294 scan = systable_beginscan(statrel, StatisticRelidAttnumInhIndexId,
3295 true, NULL, 1, key);
3296
3297 while (HeapTupleIsValid((tup = systable_getnext(scan))))
3298 {
3299 Form_pg_statistic statform;
3300
3301 /* make a modifiable copy */
3302 tup = heap_copytuple(tup);
3303 statform = (Form_pg_statistic) GETSTRUCT(tup);
3304
3305 /* update the copy of the tuple and insert it */
3306 statform->starelid = torelid;
3307
3308 /* fetch index information when we know we need it */
3309 if (indstate == NULL)
3310 indstate = CatalogOpenIndexes(statrel);
3311
3312 CatalogTupleInsertWithInfo(statrel, tup, indstate);
3313
3314 heap_freetuple(tup);
3315 }
3316
3317 systable_endscan(scan);
3318
3319 if (indstate != NULL)
3320 CatalogCloseIndexes(indstate);
3321 table_close(statrel, RowExclusiveLock);
3322}
3323
3324/*
3325 * RemoveStatistics --- remove entries in pg_statistic for a rel or column
3326 *
3327 * If attnum is zero, remove all entries for rel; else remove only the one(s)
3328 * for that column.
3329 */
3330void
3332{
3333 Relation pgstatistic;
3334 SysScanDesc scan;
3335 ScanKeyData key[2];
3336 int nkeys;
3337 HeapTuple tuple;
3338
3339 pgstatistic = table_open(StatisticRelationId, RowExclusiveLock);
3340
3341 ScanKeyInit(&key[0],
3342 Anum_pg_statistic_starelid,
3343 BTEqualStrategyNumber, F_OIDEQ,
3344 ObjectIdGetDatum(relid));
3345
3346 if (attnum == 0)
3347 nkeys = 1;
3348 else
3349 {
3350 ScanKeyInit(&key[1],
3351 Anum_pg_statistic_staattnum,
3352 BTEqualStrategyNumber, F_INT2EQ,
3354 nkeys = 2;
3355 }
3356
3357 scan = systable_beginscan(pgstatistic, StatisticRelidAttnumInhIndexId, true,
3358 NULL, nkeys, key);
3359
3360 /* we must loop even when attnum != 0, in case of inherited stats */
3361 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
3362 CatalogTupleDelete(pgstatistic, &tuple->t_self);
3363
3364 systable_endscan(scan);
3365
3366 table_close(pgstatistic, RowExclusiveLock);
3367}
3368
3369
3370/*
3371 * RelationTruncateIndexes - truncate all indexes associated
3372 * with the heap relation to zero tuples.
3373 *
3374 * The routine will truncate and then reconstruct the indexes on
3375 * the specified relation. Caller must hold exclusive lock on rel.
3376 */
3377static void
3379{
3380 ListCell *indlist;
3381
3382 /* Ask the relcache to produce a list of the indexes of the rel */
3383 foreach(indlist, RelationGetIndexList(heapRelation))
3384 {
3385 Oid indexId = lfirst_oid(indlist);
3386 Relation currentIndex;
3387 IndexInfo *indexInfo;
3388
3389 /* Open the index relation; use exclusive lock, just to be sure */
3390 currentIndex = index_open(indexId, AccessExclusiveLock);
3391
3392 /*
3393 * Fetch info needed for index_build. Since we know there are no
3394 * tuples that actually need indexing, we can use a dummy IndexInfo.
3395 * This is slightly cheaper to build, but the real point is to avoid
3396 * possibly running user-defined code in index expressions or
3397 * predicates. We might be getting invoked during ON COMMIT
3398 * processing, and we don't want to run any such code then.
3399 */
3400 indexInfo = BuildDummyIndexInfo(currentIndex);
3401
3402 /*
3403 * Now truncate the actual file (and discard buffers).
3404 */
3405 RelationTruncate(currentIndex, 0);
3406
3407 /* Initialize the index and rebuild */
3408 /* Note: we do not need to re-establish pkey setting */
3409 index_build(heapRelation, currentIndex, indexInfo, true, false);
3410
3411 /* We're done with this index */
3412 index_close(currentIndex, NoLock);
3413 }
3414}
3415
3416/*
3417 * heap_truncate
3418 *
3419 * This routine deletes all data within all the specified relations.
3420 *
3421 * This is not transaction-safe! There is another, transaction-safe
3422 * implementation in commands/tablecmds.c. We now use this only for
3423 * ON COMMIT truncation of temporary tables, where it doesn't matter.
3424 */
3425void
3427{
3428 List *relations = NIL;
3429 ListCell *cell;
3430
3431 /* Open relations for processing, and grab exclusive access on each */
3432 foreach(cell, relids)
3433 {
3434 Oid rid = lfirst_oid(cell);
3435 Relation rel;
3436
3437 rel = table_open(rid, AccessExclusiveLock);
3438 relations = lappend(relations, rel);
3439 }
3440
3441 /* Don't allow truncate on tables that are referenced by foreign keys */
3442 heap_truncate_check_FKs(relations, true);
3443
3444 /* OK to do it */
3445 foreach(cell, relations)
3446 {
3447 Relation rel = lfirst(cell);
3448
3449 /* Truncate the relation */
3451
3452 /* Close the relation, but keep exclusive lock on it until commit */
3453 table_close(rel, NoLock);
3454 }
3455}
3456
3457/*
3458 * heap_truncate_one_rel
3459 *
3460 * This routine deletes all data within the specified relation.
3461 *
3462 * This is not transaction-safe, because the truncation is done immediately
3463 * and cannot be rolled back later. Caller is responsible for having
3464 * checked permissions etc, and must have obtained AccessExclusiveLock.
3465 */
3466void
3468{
3469 Oid toastrelid;
3470
3471 /*
3472 * Truncate the relation. Partitioned tables have no storage, so there is
3473 * nothing to do for them here.
3474 */
3475 if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
3476 return;
3477
3478 /* Truncate the underlying relation */
3480
3481 /* If the relation has indexes, truncate the indexes too */
3483
3484 /* If there is a toast table, truncate that too */
3485 toastrelid = rel->rd_rel->reltoastrelid;
3486 if (OidIsValid(toastrelid))
3487 {
3488 Relation toastrel = table_open(toastrelid, AccessExclusiveLock);
3489
3491 RelationTruncateIndexes(toastrel);
3492 /* keep the lock... */
3493 table_close(toastrel, NoLock);
3494 }
3495}
3496
3497/*
3498 * heap_truncate_check_FKs
3499 * Check for foreign keys referencing a list of relations that
3500 * are to be truncated, and raise error if there are any
3501 *
3502 * We disallow such FKs (except self-referential ones) since the whole point
3503 * of TRUNCATE is to not scan the individual rows to be thrown away.
3504 *
3505 * This is split out so it can be shared by both implementations of truncate.
3506 * Caller should already hold a suitable lock on the relations.
3507 *
3508 * tempTables is only used to select an appropriate error message.
3509 */
3510void
3511heap_truncate_check_FKs(List *relations, bool tempTables)
3512{
3513 List *oids = NIL;
3514 List *dependents;
3515 ListCell *cell;
3516
3517 /*
3518 * Build a list of OIDs of the interesting relations.
3519 *
3520 * If a relation has no triggers, then it can neither have FKs nor be
3521 * referenced by a FK from another table, so we can ignore it. For
3522 * partitioned tables, FKs have no triggers, so we must include them
3523 * anyway.
3524 */
3525 foreach(cell, relations)
3526 {
3527 Relation rel = lfirst(cell);
3528
3529 if (rel->rd_rel->relhastriggers ||
3530 rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
3531 oids = lappend_oid(oids, RelationGetRelid(rel));
3532 }
3533
3534 /*
3535 * Fast path: if no relation has triggers, none has FKs either.
3536 */
3537 if (oids == NIL)
3538 return;
3539
3540 /*
3541 * Otherwise, must scan pg_constraint. We make one pass with all the
3542 * relations considered; if this finds nothing, then all is well.
3543 */
3544 dependents = heap_truncate_find_FKs(oids);
3545 if (dependents == NIL)
3546 return;
3547
3548 /*
3549 * Otherwise we repeat the scan once per relation to identify a particular
3550 * pair of relations to complain about. This is pretty slow, but
3551 * performance shouldn't matter much in a failure path. The reason for
3552 * doing things this way is to ensure that the message produced is not
3553 * dependent on chance row locations within pg_constraint.
3554 */
3555 foreach(cell, oids)
3556 {
3557 Oid relid = lfirst_oid(cell);
3558 ListCell *cell2;
3559
3560 dependents = heap_truncate_find_FKs(list_make1_oid(relid));
3561
3562 foreach(cell2, dependents)
3563 {
3564 Oid relid2 = lfirst_oid(cell2);
3565
3566 if (!list_member_oid(oids, relid2))
3567 {
3568 char *relname = get_rel_name(relid);
3569 char *relname2 = get_rel_name(relid2);
3570
3571 if (tempTables)
3572 ereport(ERROR,
3573 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3574 errmsg("unsupported ON COMMIT and foreign key combination"),
3575 errdetail("Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting.",
3576 relname2, relname)));
3577 else
3578 ereport(ERROR,
3579 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3580 errmsg("cannot truncate a table referenced in a foreign key constraint"),
3581 errdetail("Table \"%s\" references \"%s\".",
3582 relname2, relname),
3583 errhint("Truncate table \"%s\" at the same time, "
3584 "or use TRUNCATE ... CASCADE.",
3585 relname2)));
3586 }
3587 }
3588 }
3589}
3590
3591/*
3592 * heap_truncate_find_FKs
3593 * Find relations having foreign keys referencing any of the given rels
3594 *
3595 * Input and result are both lists of relation OIDs. The result contains
3596 * no duplicates, does *not* include any rels that were already in the input
3597 * list, and is sorted in OID order. (The last property is enforced mainly
3598 * to guarantee consistent behavior in the regression tests; we don't want
3599 * behavior to change depending on chance locations of rows in pg_constraint.)
3600 *
3601 * Note: caller should already have appropriate lock on all rels mentioned
3602 * in relationIds. Since adding or dropping an FK requires exclusive lock
3603 * on both rels, this ensures that the answer will be stable.
3604 */
3605List *
3607{
3608 List *result = NIL;
3609 List *oids;
3610 List *parent_cons;
3611 ListCell *cell;
3613 Relation fkeyRel;
3614 SysScanDesc fkeyScan;
3615 HeapTuple tuple;
3616 bool restart;
3617
3618 oids = list_copy(relationIds);
3619
3620 /*
3621 * Must scan pg_constraint. Right now, it is a seqscan because there is
3622 * no available index on confrelid.
3623 */
3624 fkeyRel = table_open(ConstraintRelationId, AccessShareLock);
3625
3626restart:
3627 restart = false;
3628 parent_cons = NIL;
3629
3630 fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false,
3631 NULL, 0, NULL);
3632
3633 while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan)))
3634 {
3636
3637 /* Not a foreign key */
3638 if (con->contype != CONSTRAINT_FOREIGN)
3639 continue;
3640
3641 /* Not referencing one of our list of tables */
3642 if (!list_member_oid(oids, con->confrelid))
3643 continue;
3644
3645 /*
3646 * If this constraint has a parent constraint which we have not seen
3647 * yet, keep track of it for the second loop, below. Tracking parent
3648 * constraints allows us to climb up to the top-level constraint and
3649 * look for all possible relations referencing the partitioned table.
3650 */
3651 if (OidIsValid(con->conparentid) &&
3652 !list_member_oid(parent_cons, con->conparentid))
3653 parent_cons = lappend_oid(parent_cons, con->conparentid);
3654
3655 /*
3656 * Add referencer to result, unless present in input list. (Don't
3657 * worry about dupes: we'll fix that below).
3658 */
3659 if (!list_member_oid(relationIds, con->conrelid))
3660 result = lappend_oid(result, con->conrelid);
3661 }
3662
3663 systable_endscan(fkeyScan);
3664
3665 /*
3666 * Process each parent constraint we found to add the list of referenced
3667 * relations by them to the oids list. If we do add any new such
3668 * relations, redo the first loop above. Also, if we see that the parent
3669 * constraint in turn has a parent, add that so that we process all
3670 * relations in a single additional pass.
3671 */
3672 foreach(cell, parent_cons)
3673 {
3674 Oid parent = lfirst_oid(cell);
3675
3677 Anum_pg_constraint_oid,
3678 BTEqualStrategyNumber, F_OIDEQ,
3679 ObjectIdGetDatum(parent));
3680
3681 fkeyScan = systable_beginscan(fkeyRel, ConstraintOidIndexId,
3682 true, NULL, 1, &key);
3683
3684 tuple = systable_getnext(fkeyScan);
3685 if (HeapTupleIsValid(tuple))
3686 {
3688
3689 /*
3690 * pg_constraint rows always appear for partitioned hierarchies
3691 * this way: on the each side of the constraint, one row appears
3692 * for each partition that points to the top-most table on the
3693 * other side.
3694 *
3695 * Because of this arrangement, we can correctly catch all
3696 * relevant relations by adding to 'parent_cons' all rows with
3697 * valid conparentid, and to the 'oids' list all rows with a zero
3698 * conparentid. If any oids are added to 'oids', redo the first
3699 * loop above by setting 'restart'.
3700 */
3701 if (OidIsValid(con->conparentid))
3702 parent_cons = list_append_unique_oid(parent_cons,
3703 con->conparentid);
3704 else if (!list_member_oid(oids, con->confrelid))
3705 {
3706 oids = lappend_oid(oids, con->confrelid);
3707 restart = true;
3708 }
3709 }
3710
3711 systable_endscan(fkeyScan);
3712 }
3713
3714 list_free(parent_cons);
3715 if (restart)
3716 goto restart;
3717
3718 table_close(fkeyRel, AccessShareLock);
3719 list_free(oids);
3720
3721 /* Now sort and de-duplicate the result list */
3722 list_sort(result, list_oid_cmp);
3723 list_deduplicate_oid(result);
3724
3725 return result;
3726}
3727
3728/*
3729 * StorePartitionKey
3730 * Store information about the partition key rel into the catalog
3731 */
3732void
3734 char strategy,
3735 int16 partnatts,
3736 AttrNumber *partattrs,
3737 List *partexprs,
3738 Oid *partopclass,
3739 Oid *partcollation)
3740{
3741 int i;
3742 int2vector *partattrs_vec;
3743 oidvector *partopclass_vec;
3744 oidvector *partcollation_vec;
3745 Datum partexprDatum;
3746 Relation pg_partitioned_table;
3747 HeapTuple tuple;
3748 Datum values[Natts_pg_partitioned_table];
3749 bool nulls[Natts_pg_partitioned_table] = {0};
3750 ObjectAddress myself;
3751 ObjectAddress referenced;
3752 ObjectAddresses *addrs;
3753
3754 Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
3755
3756 /* Copy the partition attribute numbers, opclass OIDs into arrays */
3757 partattrs_vec = buildint2vector(partattrs, partnatts);
3758 partopclass_vec = buildoidvector(partopclass, partnatts);
3759 partcollation_vec = buildoidvector(partcollation, partnatts);
3760
3761 /* Convert the expressions (if any) to a text datum */
3762 if (partexprs)
3763 {
3764 char *exprString;
3765
3766 exprString = nodeToString(partexprs);
3767 partexprDatum = CStringGetTextDatum(exprString);
3768 pfree(exprString);
3769 }
3770 else
3771 partexprDatum = (Datum) 0;
3772
3773 pg_partitioned_table = table_open(PartitionedRelationId, RowExclusiveLock);
3774
3775 /* Only this can ever be NULL */
3776 if (!partexprDatum)
3777 nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
3778
3779 values[Anum_pg_partitioned_table_partrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
3780 values[Anum_pg_partitioned_table_partstrat - 1] = CharGetDatum(strategy);
3781 values[Anum_pg_partitioned_table_partnatts - 1] = Int16GetDatum(partnatts);
3782 values[Anum_pg_partitioned_table_partdefid - 1] = ObjectIdGetDatum(InvalidOid);
3783 values[Anum_pg_partitioned_table_partattrs - 1] = PointerGetDatum(partattrs_vec);
3784 values[Anum_pg_partitioned_table_partclass - 1] = PointerGetDatum(partopclass_vec);
3785 values[Anum_pg_partitioned_table_partcollation - 1] = PointerGetDatum(partcollation_vec);
3786 values[Anum_pg_partitioned_table_partexprs - 1] = partexprDatum;
3787
3788 tuple = heap_form_tuple(RelationGetDescr(pg_partitioned_table), values, nulls);
3789
3790 CatalogTupleInsert(pg_partitioned_table, tuple);
3791 table_close(pg_partitioned_table, RowExclusiveLock);
3792
3793 /* Mark this relation as dependent on a few things as follows */
3794 addrs = new_object_addresses();
3795 ObjectAddressSet(myself, RelationRelationId, RelationGetRelid(rel));
3796
3797 /* Operator class and collation per key column */
3798 for (i = 0; i < partnatts; i++)
3799 {
3800 ObjectAddressSet(referenced, OperatorClassRelationId, partopclass[i]);
3801 add_exact_object_address(&referenced, addrs);
3802
3803 /* The default collation is pinned, so don't bother recording it */
3804 if (OidIsValid(partcollation[i]) &&
3805 partcollation[i] != DEFAULT_COLLATION_OID)
3806 {
3807 ObjectAddressSet(referenced, CollationRelationId, partcollation[i]);
3808 add_exact_object_address(&referenced, addrs);
3809 }
3810 }
3811
3813 free_object_addresses(addrs);
3814
3815 /*
3816 * The partitioning columns are made internally dependent on the table,
3817 * because we cannot drop any of them without dropping the whole table.
3818 * (ATExecDropColumn independently enforces that, but it's not bulletproof
3819 * so we need the dependencies too.)
3820 */
3821 for (i = 0; i < partnatts; i++)
3822 {
3823 if (partattrs[i] == 0)
3824 continue; /* ignore expressions here */
3825
3826 ObjectAddressSubSet(referenced, RelationRelationId,
3827 RelationGetRelid(rel), partattrs[i]);
3828 recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
3829 }
3830
3831 /*
3832 * Also consider anything mentioned in partition expressions. External
3833 * references (e.g. functions) get NORMAL dependencies. Table columns
3834 * mentioned in the expressions are handled the same as plain partitioning
3835 * columns, i.e. they become internally dependent on the whole table.
3836 */
3837 if (partexprs)
3839 (Node *) partexprs,
3840 RelationGetRelid(rel),
3843 true /* reverse the self-deps */ );
3844
3845 /*
3846 * We must invalidate the relcache so that the next
3847 * CommandCounterIncrement() will cause the same to be rebuilt using the
3848 * information in just created catalog entry.
3849 */
3851}
3852
3853/*
3854 * RemovePartitionKeyByRelId
3855 * Remove pg_partitioned_table entry for a relation
3856 */
3857void
3859{
3860 Relation rel;
3861 HeapTuple tuple;
3862
3863 rel = table_open(PartitionedRelationId, RowExclusiveLock);
3864
3865 tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(relid));
3866 if (!HeapTupleIsValid(tuple))
3867 elog(ERROR, "cache lookup failed for partition key of relation %u",
3868 relid);
3869
3870 CatalogTupleDelete(rel, &tuple->t_self);
3871
3872 ReleaseSysCache(tuple);
3874}
3875
3876/*
3877 * StorePartitionBound
3878 * Update pg_class tuple of rel to store the partition bound and set
3879 * relispartition to true
3880 *
3881 * If this is the default partition, also update the default partition OID in
3882 * pg_partitioned_table.
3883 *
3884 * Also, invalidate the parent's relcache, so that the next rebuild will load
3885 * the new partition's info into its partition descriptor. If there is a
3886 * default partition, we must invalidate its relcache entry as well.
3887 */
3888void
3890{
3891 Relation classRel;
3892 HeapTuple tuple,
3893 newtuple;
3894 Datum new_val[Natts_pg_class];
3895 bool new_null[Natts_pg_class],
3896 new_repl[Natts_pg_class];
3897 Oid defaultPartOid;
3898
3899 /* Update pg_class tuple */
3900 classRel = table_open(RelationRelationId, RowExclusiveLock);
3901 tuple = SearchSysCacheCopy1(RELOID,
3903 if (!HeapTupleIsValid(tuple))
3904 elog(ERROR, "cache lookup failed for relation %u",
3905 RelationGetRelid(rel));
3906
3907#ifdef USE_ASSERT_CHECKING
3908 {
3909 Form_pg_class classForm;
3910 bool isnull;
3911
3912 classForm = (Form_pg_class) GETSTRUCT(tuple);
3913 Assert(!classForm->relispartition);
3914 (void) SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relpartbound,
3915 &isnull);
3916 Assert(isnull);
3917 }
3918#endif
3919
3920 /* Fill in relpartbound value */
3921 memset(new_val, 0, sizeof(new_val));
3922 memset(new_null, false, sizeof(new_null));
3923 memset(new_repl, false, sizeof(new_repl));
3924 new_val[Anum_pg_class_relpartbound - 1] = CStringGetTextDatum(nodeToString(bound));
3925 new_null[Anum_pg_class_relpartbound - 1] = false;
3926 new_repl[Anum_pg_class_relpartbound - 1] = true;
3927 newtuple = heap_modify_tuple(tuple, RelationGetDescr(classRel),
3928 new_val, new_null, new_repl);
3929 /* Also set the flag */
3930 ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true;
3931
3932 /*
3933 * We already checked for no inheritance children, but reset
3934 * relhassubclass in case it was left over.
3935 */
3936 if (rel->rd_rel->relkind == RELKIND_RELATION && rel->rd_rel->relhassubclass)
3937 ((Form_pg_class) GETSTRUCT(newtuple))->relhassubclass = false;
3938
3939 CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
3940 heap_freetuple(newtuple);
3941 table_close(classRel, RowExclusiveLock);
3942
3943 /*
3944 * If we're storing bounds for the default partition, update
3945 * pg_partitioned_table too.
3946 */
3947 if (bound->is_default)
3949 RelationGetRelid(rel));
3950
3951 /* Make these updates visible */
3953
3954 /*
3955 * The partition constraint for the default partition depends on the
3956 * partition bounds of every other partition, so we must invalidate the
3957 * relcache entry for that partition every time a partition is added or
3958 * removed.
3959 */
3960 defaultPartOid =
3962 if (OidIsValid(defaultPartOid))
3963 CacheInvalidateRelcacheByRelid(defaultPartOid);
3964
3966}
void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
Definition: aclchk.c:4291
Acl * get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid)
Definition: aclchk.c:4215
int16 AttrNumber
Definition: attnum.h:21
#define InvalidAttrNumber
Definition: attnum.h:23
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#define CStringGetTextDatum(s)
Definition: builtins.h:97
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define NameStr(name)
Definition: c.h:703
#define Min(x, y)
Definition: c.h:961
#define Assert(condition)
Definition: c.h:815
TransactionId MultiXactId
Definition: c.h:619
int16_t int16
Definition: c.h:483
int32_t int32
Definition: c.h:484
#define lengthof(array)
Definition: c.h:745
uint32 CommandId
Definition: c.h:623
uint32 TransactionId
Definition: c.h:609
#define OidIsValid(objectId)
Definition: c.h:732
bool IsToastNamespace(Oid namespaceId)
Definition: catalog.c:230
RelFileNumber GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence)
Definition: catalog.c:528
bool IsCatalogNamespace(Oid namespaceId)
Definition: catalog.c:212
bool contain_volatile_functions_after_planning(Expr *expr)
Definition: clauses.c:658
bool contain_mutable_functions_after_planning(Expr *expr)
Definition: clauses.c:489
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
Definition: dependency.c:2757
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool reverse_self)
Definition: dependency.c:1596
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2548
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2502
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2788
@ DEPENDENCY_INTERNAL
Definition: dependency.h:35
@ DEPENDENCY_NORMAL
Definition: dependency.h:33
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define NOTICE
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:149
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:223
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1425
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1441
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1739
const TupleTableSlotOps TTSOpsHeapTuple
Definition: execTuples.c:85
#define OidFunctionCall3(functionId, arg1, arg2, arg3)
Definition: fmgr.h:683
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:606
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:513
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
bool IsBinaryUpgrade
Definition: globals.c:120
Oid MyDatabaseTableSpace
Definition: globals.c:95
void RemoveAttributeById(Oid relid, AttrNumber attnum)
Definition: heap.c:1659
void RelationClearMissing(Relation rel)
Definition: heap.c:1940
void SetAttrMissing(Oid relid, char *attname, char *value)
Definition: heap.c:2008
static Oid StoreRelCheck(Relation rel, const char *ccname, Node *expr, bool is_enforced, bool is_validated, bool is_local, int16 inhcount, bool is_no_inherit, bool is_internal)
Definition: heap.c:2069
List * heap_truncate_find_FKs(List *relationIds)
Definition: heap.c:3606
void DeleteSystemAttributeTuples(Oid relid)
Definition: heap.c:1618
void StorePartitionKey(Relation rel, char strategy, int16 partnatts, AttrNumber *partattrs, List *partexprs, Oid *partopclass, Oid *partcollation)
Definition: heap.c:3733
static void StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal)
Definition: heap.c:2232
static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, char relkind)
Definition: heap.c:813
void DeleteRelationTuple(Oid relid)
Definition: heap.c:1552
static void RelationTruncateIndexes(Relation heapRelation)
Definition: heap.c:3378
RelFileNumber binary_upgrade_next_heap_pg_class_relfilenumber
Definition: heap.c:82
static void AddNewRelationTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Oid new_type_oid, Oid reloftype, Oid relowner, char relkind, TransactionId relfrozenxid, TransactionId relminmxid, Datum relacl, Datum reloptions)
Definition: heap.c:962
void DeleteAttributeTuples(Oid relid)
Definition: heap.c:1581
void RemoveStatistics(Oid relid, AttrNumber attnum)
Definition: heap.c:3331
static const FormData_pg_attribute a4
Definition: heap.c:182
RelFileNumber binary_upgrade_next_toast_pg_class_relfilenumber
Definition: heap.c:83
static ObjectAddress AddNewRelationType(const char *typeName, Oid typeNamespace, Oid new_rel_oid, char new_rel_kind, Oid ownerid, Oid new_row_type, Oid new_array_type)
Definition: heap.c:1020
static const FormData_pg_attribute a1
Definition: heap.c:143
Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, Oid reltypeid, Oid reloftypeid, Oid ownerid, Oid accessmtd, TupleDesc tupdesc, List *cooked_constraints, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, OnCommitAction oncommit, Datum reloptions, bool use_user_acl, bool allow_system_table_mods, bool is_internal, Oid relrewrite, ObjectAddress *typaddress)
Definition: heap.c:1098
void heap_truncate(List *relids)
Definition: heap.c:3426
static bool MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr, bool allow_merge, bool is_local, bool is_enforced, bool is_initially_valid, bool is_no_inherit)
Definition: heap.c:2634
static const FormData_pg_attribute *const SysAtt[]
Definition: heap.c:227
static Oid StoreRelNotNull(Relation rel, const char *nnname, AttrNumber attnum, bool is_validated, bool is_local, int inhcount, bool is_no_inherit)
Definition: heap.c:2176
void CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation, List *containing_rowtypes, int flags)
Definition: heap.c:543
const FormData_pg_attribute * SystemAttributeByName(const char *attname)
Definition: heap.c:247
void CopyStatistics(Oid fromrelid, Oid torelid)
Definition: heap.c:3278
void heap_truncate_check_FKs(List *relations, bool tempTables)
Definition: heap.c:3511
static const FormData_pg_attribute a6
Definition: heap.c:214
static bool check_nested_generated_walker(Node *node, void *context)
Definition: heap.c:3103
static void SetRelationNumChecks(Relation rel, int numchecks)
Definition: heap.c:3069
static const FormData_pg_attribute a3
Definition: heap.c:169
static void RelationRemoveInheritance(Oid relid)
Definition: heap.c:1519
static const FormData_pg_attribute a2
Definition: heap.c:156
void StorePartitionBound(Relation rel, Relation parent, PartitionBoundSpec *bound)
Definition: heap.c:3889
List * AddRelationNotNullConstraints(Relation rel, List *constraints, List *old_notnulls)
Definition: heap.c:2817
void heap_drop_with_catalog(Oid relid)
Definition: heap.c:1760
List * AddRelationNewConstraints(Relation rel, List *newColDefaults, List *newConstraints, bool allow_merge, bool is_local, bool is_internal, const char *queryString)
Definition: heap.c:2307
void InsertPgClassTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Datum relacl, Datum reloptions)
Definition: heap.c:889
void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, int flags)
Definition: heap.c:451
static void check_nested_generated(ParseState *pstate, Node *node)
Definition: heap.c:3145
Oid binary_upgrade_next_toast_pg_class_oid
Definition: heap.c:81
void InsertPgAttributeTuples(Relation pg_attribute_rel, TupleDesc tupdesc, Oid new_rel_oid, const FormExtraData_pg_attribute tupdesc_extra[], CatalogIndexState indstate)
Definition: heap.c:696
Node * cookDefault(ParseState *pstate, Node *raw_default, Oid atttypid, int32 atttypmod, const char *attname, char attgenerated)
Definition: heap.c:3163
void heap_truncate_one_rel(Relation rel)
Definition: heap.c:3467
void RemovePartitionKeyByRelId(Oid relid)
Definition: heap.c:3858
Oid binary_upgrade_next_heap_pg_class_oid
Definition: heap.c:80
const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)
Definition: heap.c:235
static const FormData_pg_attribute a5
Definition: heap.c:195
Relation heap_create(const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, RelFileNumber relfilenumber, Oid accessmtd, TupleDesc tupDesc, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, bool allow_system_table_mods, TransactionId *relfrozenxid, MultiXactId *relminmxid, bool create_storage)
Definition: heap.c:284
static Node * cookConstraint(ParseState *pstate, Node *raw_constraint, char *relname)
Definition: heap.c:3240
#define CHKATYPE_ANYRECORD
Definition: heap.h:24
#define CHKATYPE_ANYARRAY
Definition: heap.h:23
#define CHKATYPE_IS_PARTKEY
Definition: heap.h:25
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition: heaptuple.c:1210
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:778
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
#define MaxHeapAttributeNumber
Definition: htup_details.h:48
static Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:860
IndexInfo * BuildDummyIndexInfo(Relation index)
Definition: index.c:2487
void index_build(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, bool isreindex, bool parallel)
Definition: index.c:2973
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:177
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:133
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
void CatalogTuplesMultiInsertWithInfo(Relation heapRel, TupleTableSlot **slot, int ntuples, CatalogIndexState indstate)
Definition: indexing.c:273
void CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:256
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:61
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:233
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:43
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:365
#define MAX_CATALOG_MULTI_INSERT_BYTES
Definition: indexing.h:33
static struct @162 value
long val
Definition: informix.c:689
int2vector * buildint2vector(const int16 *int2s, int n)
Definition: int.c:114
static bool pg_add_s16_overflow(int16 a, int16 b, int16 *result)
Definition: int.h:67
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1556
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition: inval.c:1612
int j
Definition: isn.c:73
int i
Definition: isn.c:72
struct ItemPointerData ItemPointerData
List * lappend(List *list, void *datum)
Definition: list.c:339
void list_sort(List *list, list_sort_comparator cmp)
Definition: list.c:1674
List * list_delete_nth_cell(List *list, int n)
Definition: list.c:767
List * list_copy(const List *oldlist)
Definition: list.c:1573
List * lappend_int(List *list, int datum)
Definition: list.c:357
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:1380
void list_deduplicate_oid(List *list)
Definition: list.c:1495
int list_oid_cmp(const ListCell *p1, const ListCell *p2)
Definition: list.c:1703
List * list_delete_last(List *list)
Definition: list.c:957
void list_free(List *list)
Definition: list.c:1546
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:722
List * list_union(const List *list1, const List *list2)
Definition: list.c:1066
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:107
#define NoLock
Definition: lockdefs.h:34
#define AccessExclusiveLock
Definition: lockdefs.h:43
#define AccessShareLock
Definition: lockdefs.h:36
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid get_range_subtype(Oid rangeOid)
Definition: lsyscache.c:3434
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1955
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:859
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2786
char get_attgenerated(Oid relid, AttrNumber attnum)
Definition: lsyscache.c:889
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition: lsyscache.c:828
Oid get_range_collation(Oid rangeOid)
Definition: lsyscache.c:3460
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:3108
Oid get_typ_typrelid(Oid typid)
Definition: lsyscache.c:2758
char get_typtype(Oid typid)
Definition: lsyscache.c:2656
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2548
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3393
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1912
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc(Size size)
Definition: mcxt.c:1317
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:466
#define IsNormalProcessingMode()
Definition: miscadmin.h:468
#define InvalidMultiXactId
Definition: multixact.h:24
void namestrcpy(Name name, const char *str)
Definition: name.c:233
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define expression_tree_walker(n, w, c)
Definition: nodeFuncs.h:153
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
Definition: objectaccess.h:175
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id)
Definition: objectaddress.h:33
oidvector * buildoidvector(const Oid *oids, int n)
Definition: oid.c:87
char * nodeToString(const void *obj)
Definition: outfuncs.c:794
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
Definition: parse_coerce.c:78
void assign_expr_collations(ParseState *pstate, Node *expr)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:118
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:106
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:39
@ EXPR_KIND_COLUMN_DEFAULT
Definition: parse_node.h:70
@ EXPR_KIND_GENERATED_COLUMN
Definition: parse_node.h:83
@ EXPR_KIND_CHECK_CONSTRAINT
Definition: parse_node.h:68
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, int lockmode, Alias *alias, bool inh, bool inFromCl)
void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
@ CONSTR_DEFAULT
Definition: parsenodes.h:2771
@ CONSTR_NOTNULL
Definition: parsenodes.h:2770
@ CONSTR_CHECK
Definition: parsenodes.h:2774
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2349
@ OBJECT_TABLE
Definition: parsenodes.h:2353
#define rt_fetch(rangetable_index, rangetable)
Definition: parsetree.h:31
PartitionDesc RelationGetPartitionDesc(Relation rel, bool omit_detached)
Definition: partdesc.c:71
Oid get_default_oid_from_partdesc(PartitionDesc partdesc)
Definition: partdesc.c:501
void update_default_partition_oid(Oid parentId, Oid defaultPartId)
Definition: partition.c:340
Oid get_default_partition_oid(Oid parentId)
Definition: partition.c:315
Oid get_partition_parent(Oid relid, bool even_if_detached)
Definition: partition.c:53
Oid StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr, bool is_internal, bool add_column_mode)
Definition: pg_attrdef.c:46
FormData_pg_attribute
Definition: pg_attribute.h:184
NameData attname
Definition: pg_attribute.h:41
char attstorage
Definition: pg_attribute.h:108
bool attbyval
Definition: pg_attribute.h:94
char attalign
Definition: pg_attribute.h:100
int16 attnum
Definition: pg_attribute.h:74
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
bool attnotnull
Definition: pg_attribute.h:121
NameData relname
Definition: pg_class.h:38
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define NAMEDATALEN
Oid CreateConstraintEntry(const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, bool isEnforced, bool isValidated, Oid parentConstrId, Oid relId, const int16 *constraintKey, int constraintNKeys, int constraintNTotalKeys, Oid domainId, Oid indexRelId, Oid foreignRelId, const int16 *foreignKey, const Oid *pfEqOp, const Oid *ppEqOp, const Oid *ffEqOp, int foreignNKeys, char foreignUpdateType, char foreignDeleteType, const int16 *fkDeleteSetCols, int numFkDeleteSetCols, char foreignMatchType, const Oid *exclOp, Node *conExpr, const char *conBin, bool conIsLocal, int16 conInhCount, bool conNoInherit, bool conPeriod, bool is_internal)
Definition: pg_constraint.c:51
bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, const char *conname)
char * ChooseConstraintName(const char *name1, const char *name2, const char *label, Oid namespaceid, List *others)
bool AdjustNotNullInheritance(Oid relid, AttrNumber attnum, bool is_local, bool is_no_inherit)
FormData_pg_constraint * Form_pg_constraint
@ CONSTRAINT_RELATION
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:45
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:193
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define foreach_delete_current(lst, var_or_cell)
Definition: pg_list.h:391
#define list_make1_oid(x1)
Definition: pg_list.h:242
#define foreach_ptr(type, var, lst)
Definition: pg_list.h:469
static void * list_nth(const List *list, int n)
Definition: pg_list.h:299
#define linitial(l)
Definition: pg_list.h:178
#define foreach_node(type, var, lst)
Definition: pg_list.h:496
#define list_nth_node(type, list, n)
Definition: pg_list.h:327
#define lfirst_oid(lc)
Definition: pg_list.h:174
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:168
void recordDependencyOnTablespace(Oid classId, Oid objectId, Oid tablespace)
Definition: pg_shdepend.c:370
FormData_pg_statistic * Form_pg_statistic
Definition: pg_statistic.h:135
void RemoveSubscriptionRel(Oid subid, Oid relid)
ObjectAddress TypeCreate(Oid newTypeOid, const char *typeName, Oid typeNamespace, Oid relationOid, char relationKind, Oid ownerId, int16 internalSize, char typeType, char typeCategory, bool typePreferred, char typDelim, Oid inputProcedure, Oid outputProcedure, Oid receiveProcedure, Oid sendProcedure, Oid typmodinProcedure, Oid typmodoutProcedure, Oid analyzeProcedure, Oid subscriptProcedure, Oid elementType, bool isImplicitArray, Oid arrayType, Oid baseType, const char *defaultTypeValue, char *defaultTypeBin, bool passedByValue, char alignment, char storage, int32 typeMod, int32 typNDims, bool typeNotNull, Oid typeCollation)
Definition: pg_type.c:195
bool moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace)
Definition: pg_type.c:905
char * makeArrayTypeName(const char *typeName, Oid typeNamespace)
Definition: pg_type.c:840
void pgstat_create_relation(Relation rel)
void pgstat_drop_relation(Relation rel)
#define snprintf
Definition: port.h:239
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
static Datum Float4GetDatum(float4 X)
Definition: postgres.h:480
static Datum TransactionIdGetDatum(TransactionId X)
Definition: postgres.h:277
uintptr_t Datum
Definition: postgres.h:69
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:177
static Datum MultiXactIdGetDatum(MultiXactId X)
Definition: postgres.h:287
static Datum BoolGetDatum(bool X)
Definition: postgres.h:107
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
static Datum NameGetDatum(const NameData *X)
Definition: postgres.h:378
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:355
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:217
static Datum CharGetDatum(char X)
Definition: postgres.h:127
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
void CheckTableForSerializableConflictIn(Relation relation)
Definition: predicate.c:4409
OnCommitAction
Definition: primnodes.h:57
@ ONCOMMIT_NOOP
Definition: primnodes.h:58
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:753
@ COERCION_ASSIGNMENT
Definition: primnodes.h:732
void * stringToNode(const char *str)
Definition: read.c:90
#define RelationGetRelid(relation)
Definition: rel.h:506
#define RelationGetDescr(relation)
Definition: rel.h:532
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:512
#define RelationGetRelationName(relation)
Definition: rel.h:540
#define RelationGetNamespace(relation)
Definition: rel.h:547
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4756
void RelationForgetRelation(Oid rid)
Definition: relcache.c:2846
Relation RelationBuildLocalRelation(const char *relname, Oid relnamespace, TupleDesc tupDesc, Oid relid, Oid accessmtd, RelFileNumber relfilenumber, Oid reltablespace, bool shared_relation, bool mapped_relation, char relpersistence, char relkind)
Definition: relcache.c:3468
Oid RelFileNumber
Definition: relpath.h:25
#define InvalidRelFileNumber
Definition: relpath.h:26
#define RelFileNumberIsValid(relnumber)
Definition: relpath.h:27
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:205
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:47
void check_stack_depth(void)
Definition: stack_depth.c:95
SMgrRelation RelationCreateStorage(RelFileLocator rlocator, char relpersistence, bool register_delete)
Definition: storage.c:121
void RelationDropStorage(Relation rel)
Definition: storage.c:206
void RelationTruncate(Relation rel, BlockNumber nblocks)
Definition: storage.c:288
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define BTLessEqualStrategyNumber
Definition: stratnum.h:30
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:30
List * keys
Definition: parsenodes.h:2816
ConstrType contype
Definition: parsenodes.h:2802
bool is_no_inherit
Definition: parsenodes.h:2809
char * conname
Definition: parsenodes.h:2803
Oid conoid
Definition: heap.h:39
char * name
Definition: heap.h:40
AttrNumber attnum
Definition: heap.h:41
bool skip_validation
Definition: heap.h:44
bool is_enforced
Definition: heap.h:43
bool is_no_inherit
Definition: heap.h:47
int16 inhcount
Definition: heap.h:46
bool is_local
Definition: heap.h:45
ConstrType contype
Definition: heap.h:37
Node * expr
Definition: heap.h:42
ItemPointerData t_self
Definition: htup.h:65
Definition: pg_list.h:54
Definition: nodes.h:129
Datum value
Definition: postgres.h:80
bool isnull
Definition: postgres.h:82
const char * p_sourcetext
Definition: parse_node.h:209
List * p_rtable
Definition: parse_node.h:212
TupleDesc rd_att
Definition: rel.h:112
RelFileLocator rd_locator
Definition: rel.h:57
Form_pg_class rd_rel
Definition: rel.h:111
uint16 num_check
Definition: tupdesc.h:44
TupleConstr * constr
Definition: tupdesc.h:134
int32 tdtypmod
Definition: tupdesc.h:132
Oid tdtypeid
Definition: tupdesc.h:131
bool * tts_isnull
Definition: tuptable.h:127
Datum * tts_values
Definition: tuptable.h:125
Definition: primnodes.h:262
ParseLoc location
Definition: primnodes.h:310
AttrNumber varattno
Definition: primnodes.h:274
int varno
Definition: primnodes.h:269
Definition: c.h:672
Definition: c.h:683
Definition: regcomp.c:282
#define MinTransactionIdAttributeNumber
Definition: sysattr.h:22
#define MaxCommandIdAttributeNumber
Definition: sysattr.h:25
#define MaxTransactionIdAttributeNumber
Definition: sysattr.h:24
#define TableOidAttributeNumber
Definition: sysattr.h:26
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
#define MinCommandIdAttributeNumber
Definition: sysattr.h:23
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:600
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:232
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:480
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:91
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition: syscache.h:93
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:111
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
static void table_relation_set_new_filelocator(Relation rel, const RelFileLocator *newrlocator, char persistence, TransactionId *freezeXid, MultiXactId *minmulti)
Definition: tableam.h:1627
static void table_relation_nontransactional_truncate(Relation rel)
Definition: tableam.h:1645
void CheckTableNotInUse(Relation rel, const char *stmt)
Definition: tablecmds.c:4361
void remove_on_commit_action(Oid relid)
Definition: tablecmds.c:18257
void register_on_commit_action(Oid relid, OnCommitAction action)
Definition: tablecmds.c:18221
#define InvalidTransactionId
Definition: transam.h:31
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:478
TupleDesc CreateTupleDesc(int natts, Form_pg_attribute *attrs)
Definition: tupdesc.c:211
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:153
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:454
Oid AssignTypeArrayOid(void)
Definition: typecmds.c:2436
#define DEFAULT_TYPDELIM
Definition: typecmds.h:22
#define strVal(v)
Definition: value.h:82
bool contain_var_clause(Node *node)
Definition: var.c:406
List * pull_var_clause(Node *node, int flags)
Definition: var.c:653
void CommandCounterIncrement(void)
Definition: xact.c:1099