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