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