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