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