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