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