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