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