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