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