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