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  /* clear the missing value if any */
1617  if (attStruct->atthasmissing)
1618  {
1619  Datum valuesAtt[Natts_pg_attribute];
1620  bool nullsAtt[Natts_pg_attribute];
1621  bool replacesAtt[Natts_pg_attribute];
1622 
1623  /* update the tuple - set atthasmissing and attmissingval */
1624  MemSet(valuesAtt, 0, sizeof(valuesAtt));
1625  MemSet(nullsAtt, false, sizeof(nullsAtt));
1626  MemSet(replacesAtt, false, sizeof(replacesAtt));
1627 
1628  valuesAtt[Anum_pg_attribute_atthasmissing - 1] =
1629  BoolGetDatum(false);
1630  replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true;
1631  valuesAtt[Anum_pg_attribute_attmissingval - 1] = (Datum) 0;
1632  nullsAtt[Anum_pg_attribute_attmissingval - 1] = true;
1633  replacesAtt[Anum_pg_attribute_attmissingval - 1] = true;
1634 
1635  tuple = heap_modify_tuple(tuple, RelationGetDescr(attr_rel),
1636  valuesAtt, nullsAtt, replacesAtt);
1637  }
1638 
1639  CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
1640  }
1641 
1642  /*
1643  * Because updating the pg_attribute row will trigger a relcache flush for
1644  * the target relation, we need not do anything else to notify other
1645  * backends of the change.
1646  */
1647 
1648  heap_close(attr_rel, RowExclusiveLock);
1649 
1650  if (attnum > 0)
1651  RemoveStatistics(relid, attnum);
1652 
1653  relation_close(rel, NoLock);
1654 }
1655 
1656 /*
1657  * RemoveAttrDefault
1658  *
1659  * If the specified relation/attribute has a default, remove it.
1660  * (If no default, raise error if complain is true, else return quietly.)
1661  */
1662 void
1664  DropBehavior behavior, bool complain, bool internal)
1665 {
1666  Relation attrdef_rel;
1667  ScanKeyData scankeys[2];
1668  SysScanDesc scan;
1669  HeapTuple tuple;
1670  bool found = false;
1671 
1672  attrdef_rel = heap_open(AttrDefaultRelationId, RowExclusiveLock);
1673 
1674  ScanKeyInit(&scankeys[0],
1675  Anum_pg_attrdef_adrelid,
1676  BTEqualStrategyNumber, F_OIDEQ,
1677  ObjectIdGetDatum(relid));
1678  ScanKeyInit(&scankeys[1],
1679  Anum_pg_attrdef_adnum,
1680  BTEqualStrategyNumber, F_INT2EQ,
1681  Int16GetDatum(attnum));
1682 
1683  scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true,
1684  NULL, 2, scankeys);
1685 
1686  /* There should be at most one matching tuple, but we loop anyway */
1687  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1688  {
1690 
1691  object.classId = AttrDefaultRelationId;
1692  object.objectId = HeapTupleGetOid(tuple);
1693  object.objectSubId = 0;
1694 
1695  performDeletion(&object, behavior,
1696  internal ? PERFORM_DELETION_INTERNAL : 0);
1697 
1698  found = true;
1699  }
1700 
1701  systable_endscan(scan);
1702  heap_close(attrdef_rel, RowExclusiveLock);
1703 
1704  if (complain && !found)
1705  elog(ERROR, "could not find attrdef tuple for relation %u attnum %d",
1706  relid, attnum);
1707 }
1708 
1709 /*
1710  * RemoveAttrDefaultById
1711  *
1712  * Remove a pg_attrdef entry specified by OID. This is the guts of
1713  * attribute-default removal. Note it should be called via performDeletion,
1714  * not directly.
1715  */
1716 void
1718 {
1719  Relation attrdef_rel;
1720  Relation attr_rel;
1721  Relation myrel;
1722  ScanKeyData scankeys[1];
1723  SysScanDesc scan;
1724  HeapTuple tuple;
1725  Oid myrelid;
1726  AttrNumber myattnum;
1727 
1728  /* Grab an appropriate lock on the pg_attrdef relation */
1729  attrdef_rel = heap_open(AttrDefaultRelationId, RowExclusiveLock);
1730 
1731  /* Find the pg_attrdef tuple */
1732  ScanKeyInit(&scankeys[0],
1734  BTEqualStrategyNumber, F_OIDEQ,
1735  ObjectIdGetDatum(attrdefId));
1736 
1737  scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndexId, true,
1738  NULL, 1, scankeys);
1739 
1740  tuple = systable_getnext(scan);
1741  if (!HeapTupleIsValid(tuple))
1742  elog(ERROR, "could not find tuple for attrdef %u", attrdefId);
1743 
1744  myrelid = ((Form_pg_attrdef) GETSTRUCT(tuple))->adrelid;
1745  myattnum = ((Form_pg_attrdef) GETSTRUCT(tuple))->adnum;
1746 
1747  /* Get an exclusive lock on the relation owning the attribute */
1748  myrel = relation_open(myrelid, AccessExclusiveLock);
1749 
1750  /* Now we can delete the pg_attrdef row */
1751  CatalogTupleDelete(attrdef_rel, &tuple->t_self);
1752 
1753  systable_endscan(scan);
1754  heap_close(attrdef_rel, RowExclusiveLock);
1755 
1756  /* Fix the pg_attribute row */
1757  attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
1758 
1759  tuple = SearchSysCacheCopy2(ATTNUM,
1760  ObjectIdGetDatum(myrelid),
1761  Int16GetDatum(myattnum));
1762  if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
1763  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1764  myattnum, myrelid);
1765 
1766  ((Form_pg_attribute) GETSTRUCT(tuple))->atthasdef = false;
1767 
1768  CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
1769 
1770  /*
1771  * Our update of the pg_attribute row will force a relcache rebuild, so
1772  * there's nothing else to do here.
1773  */
1774  heap_close(attr_rel, RowExclusiveLock);
1775 
1776  /* Keep lock on attribute's rel until end of xact */
1777  relation_close(myrel, NoLock);
1778 }
1779 
1780 /*
1781  * heap_drop_with_catalog - removes specified relation from catalogs
1782  *
1783  * Note that this routine is not responsible for dropping objects that are
1784  * linked to the pg_class entry via dependencies (for example, indexes and
1785  * constraints). Those are deleted by the dependency-tracing logic in
1786  * dependency.c before control gets here. In general, therefore, this routine
1787  * should never be called directly; go through performDeletion() instead.
1788  */
1789 void
1791 {
1792  Relation rel;
1793  HeapTuple tuple;
1794  Oid parentOid = InvalidOid,
1795  defaultPartOid = InvalidOid;
1796 
1797  /*
1798  * To drop a partition safely, we must grab exclusive lock on its parent,
1799  * because another backend might be about to execute a query on the parent
1800  * table. If it relies on previously cached partition descriptor, then it
1801  * could attempt to access the just-dropped relation as its partition. We
1802  * must therefore take a table lock strong enough to prevent all queries
1803  * on the table from proceeding until we commit and send out a
1804  * shared-cache-inval notice that will make them update their partition
1805  * descriptors.
1806  */
1807  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1808  if (!HeapTupleIsValid(tuple))
1809  elog(ERROR, "cache lookup failed for relation %u", relid);
1810  if (((Form_pg_class) GETSTRUCT(tuple))->relispartition)
1811  {
1812  parentOid = get_partition_parent(relid);
1814 
1815  /*
1816  * If this is not the default partition, dropping it will change the
1817  * default partition's partition constraint, so we must lock it.
1818  */
1819  defaultPartOid = get_default_partition_oid(parentOid);
1820  if (OidIsValid(defaultPartOid) && relid != defaultPartOid)
1821  LockRelationOid(defaultPartOid, AccessExclusiveLock);
1822  }
1823 
1824  ReleaseSysCache(tuple);
1825 
1826  /*
1827  * Open and lock the relation.
1828  */
1829  rel = relation_open(relid, AccessExclusiveLock);
1830 
1831  /*
1832  * There can no longer be anyone *else* touching the relation, but we
1833  * might still have open queries or cursors, or pending trigger events, in
1834  * our own session.
1835  */
1836  CheckTableNotInUse(rel, "DROP TABLE");
1837 
1838  /*
1839  * This effectively deletes all rows in the table, and may be done in a
1840  * serializable transaction. In that case we must record a rw-conflict in
1841  * to this transaction from each transaction holding a predicate lock on
1842  * the table.
1843  */
1845 
1846  /*
1847  * Delete pg_foreign_table tuple first.
1848  */
1849  if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1850  {
1851  Relation rel;
1852  HeapTuple tuple;
1853 
1854  rel = heap_open(ForeignTableRelationId, RowExclusiveLock);
1855 
1857  if (!HeapTupleIsValid(tuple))
1858  elog(ERROR, "cache lookup failed for foreign table %u", relid);
1859 
1860  CatalogTupleDelete(rel, &tuple->t_self);
1861 
1862  ReleaseSysCache(tuple);
1864  }
1865 
1866  /*
1867  * If a partitioned table, delete the pg_partitioned_table tuple.
1868  */
1869  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1871 
1872  /*
1873  * If the relation being dropped is the default partition itself,
1874  * invalidate its entry in pg_partitioned_table.
1875  */
1876  if (relid == defaultPartOid)
1878 
1879  /*
1880  * Schedule unlinking of the relation's physical files at commit.
1881  */
1882  if (rel->rd_rel->relkind != RELKIND_VIEW &&
1883  rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
1884  rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
1885  rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1886  {
1887  RelationDropStorage(rel);
1888  }
1889 
1890  /*
1891  * Close relcache entry, but *keep* AccessExclusiveLock on the relation
1892  * until transaction commit. This ensures no one else will try to do
1893  * something with the doomed relation.
1894  */
1895  relation_close(rel, NoLock);
1896 
1897  /*
1898  * Remove any associated relation synchronization states.
1899  */
1901 
1902  /*
1903  * Forget any ON COMMIT action for the rel
1904  */
1905  remove_on_commit_action(relid);
1906 
1907  /*
1908  * Flush the relation from the relcache. We want to do this before
1909  * starting to remove catalog entries, just to be certain that no relcache
1910  * entry rebuild will happen partway through. (That should not really
1911  * matter, since we don't do CommandCounterIncrement here, but let's be
1912  * safe.)
1913  */
1914  RelationForgetRelation(relid);
1915 
1916  /*
1917  * remove inheritance information
1918  */
1920 
1921  /*
1922  * delete statistics
1923  */
1924  RemoveStatistics(relid, 0);
1925 
1926  /*
1927  * delete attribute tuples
1928  */
1929  DeleteAttributeTuples(relid);
1930 
1931  /*
1932  * delete relation tuple
1933  */
1934  DeleteRelationTuple(relid);
1935 
1936  if (OidIsValid(parentOid))
1937  {
1938  /*
1939  * If this is not the default partition, the partition constraint of
1940  * the default partition has changed to include the portion of the key
1941  * space previously covered by the dropped partition.
1942  */
1943  if (OidIsValid(defaultPartOid) && relid != defaultPartOid)
1944  CacheInvalidateRelcacheByRelid(defaultPartOid);
1945 
1946  /*
1947  * Invalidate the parent's relcache so that the partition is no longer
1948  * included in its partition descriptor.
1949  */
1950  CacheInvalidateRelcacheByRelid(parentOid);
1951  /* keep the lock */
1952  }
1953 }
1954 
1955 
1956 /*
1957  * RelationClearMissing
1958  *
1959  * Set atthasmissing and attmissingval to false/null for all attributes
1960  * where they are currently set. This can be safely and usefully done if
1961  * the table is rewritten (e.g. by VACUUM FULL or CLUSTER) where we know there
1962  * are no rows left with less than a full complement of attributes.
1963  *
1964  * The caller must have an AccessExclusive lock on the relation.
1965  */
1966 void
1968 {
1969  Relation attr_rel;
1970  Oid relid = RelationGetRelid(rel);
1971  int natts = RelationGetNumberOfAttributes(rel);
1972  int attnum;
1973  Datum repl_val[Natts_pg_attribute];
1974  bool repl_null[Natts_pg_attribute];
1975  bool repl_repl[Natts_pg_attribute];
1976  Form_pg_attribute attrtuple;
1977  HeapTuple tuple,
1978  newtuple;
1979 
1980  memset(repl_val, 0, sizeof(repl_val));
1981  memset(repl_null, false, sizeof(repl_null));
1982  memset(repl_repl, false, sizeof(repl_repl));
1983 
1984  repl_val[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(false);
1985  repl_null[Anum_pg_attribute_attmissingval - 1] = true;
1986 
1987  repl_repl[Anum_pg_attribute_atthasmissing - 1] = true;
1988  repl_repl[Anum_pg_attribute_attmissingval - 1] = true;
1989 
1990 
1991  /* Get a lock on pg_attribute */
1992  attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
1993 
1994  /* process each non-system attribute, including any dropped columns */
1995  for (attnum = 1; attnum <= natts; attnum++)
1996  {
1997  tuple = SearchSysCache2(ATTNUM,
1998  ObjectIdGetDatum(relid),
1999  Int16GetDatum(attnum));
2000  if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
2001  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
2002  attnum, relid);
2003 
2004  attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
2005 
2006  /* ignore any where atthasmissing is not true */
2007  if (attrtuple->atthasmissing)
2008  {
2009  newtuple = heap_modify_tuple(tuple, RelationGetDescr(attr_rel),
2010  repl_val, repl_null, repl_repl);
2011 
2012  CatalogTupleUpdate(attr_rel, &newtuple->t_self, newtuple);
2013 
2014  heap_freetuple(newtuple);
2015  }
2016 
2017  ReleaseSysCache(tuple);
2018  }
2019 
2020  /*
2021  * Our update of the pg_attribute rows will force a relcache rebuild, so
2022  * there's nothing else to do here.
2023  */
2024  heap_close(attr_rel, RowExclusiveLock);
2025 }
2026 
2027 /*
2028  * SetAttrMissing
2029  *
2030  * Set the missing value of a single attribute. This should only be used by
2031  * binary upgrade. Takes an AccessExclusive lock on the relation owning the
2032  * attribute.
2033  */
2034 void
2035 SetAttrMissing(Oid relid, char *attname, char *value)
2036 {
2037  Datum valuesAtt[Natts_pg_attribute];
2038  bool nullsAtt[Natts_pg_attribute];
2039  bool replacesAtt[Natts_pg_attribute];
2040  Datum missingval;
2041  Form_pg_attribute attStruct;
2042  Relation attrrel,
2043  tablerel;
2044  HeapTuple atttup,
2045  newtup;
2046 
2047  /* lock the table the attribute belongs to */
2048  tablerel = heap_open(relid, AccessExclusiveLock);
2049 
2050  /* Lock the attribute row and get the data */
2051  attrrel = heap_open(AttributeRelationId, RowExclusiveLock);
2052  atttup = SearchSysCacheAttName(relid, attname);
2053  if (!HeapTupleIsValid(atttup))
2054  elog(ERROR, "cache lookup failed for attribute %s of relation %u",
2055  attname, relid);
2056  attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
2057 
2058  /* get an array value from the value string */
2059  missingval = OidFunctionCall3(F_ARRAY_IN,
2060  CStringGetDatum(value),
2061  ObjectIdGetDatum(attStruct->atttypid),
2062  Int32GetDatum(attStruct->atttypmod));
2063 
2064  /* update the tuple - set atthasmissing and attmissingval */
2065  MemSet(valuesAtt, 0, sizeof(valuesAtt));
2066  MemSet(nullsAtt, false, sizeof(nullsAtt));
2067  MemSet(replacesAtt, false, sizeof(replacesAtt));
2068 
2069  valuesAtt[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(true);
2070  replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true;
2071  valuesAtt[Anum_pg_attribute_attmissingval - 1] = missingval;
2072  replacesAtt[Anum_pg_attribute_attmissingval - 1] = true;
2073 
2074  newtup = heap_modify_tuple(atttup, RelationGetDescr(attrrel),
2075  valuesAtt, nullsAtt, replacesAtt);
2076  CatalogTupleUpdate(attrrel, &newtup->t_self, newtup);
2077 
2078  /* clean up */
2079  ReleaseSysCache(atttup);
2080  heap_close(attrrel, RowExclusiveLock);
2081  heap_close(tablerel, AccessExclusiveLock);
2082 }
2083 
2084 /*
2085  * Store a default expression for column attnum of relation rel.
2086  *
2087  * Returns the OID of the new pg_attrdef tuple.
2088  *
2089  * add_column_mode must be true if we are storing the default for a new
2090  * attribute, and false if it's for an already existing attribute. The reason
2091  * for this is that the missing value must never be updated after it is set,
2092  * which can only be when a column is added to the table. Otherwise we would
2093  * in effect be changing existing tuples.
2094  */
2095 Oid
2097  Node *expr, bool is_internal, bool add_column_mode)
2098 {
2099  char *adbin;
2100  char *adsrc;
2101  Relation adrel;
2102  HeapTuple tuple;
2103  Datum values[4];
2104  static bool nulls[4] = {false, false, false, false};
2105  Relation attrrel;
2106  HeapTuple atttup;
2107  Form_pg_attribute attStruct;
2108  Oid attrdefOid;
2109  ObjectAddress colobject,
2110  defobject;
2111 
2112  /*
2113  * Flatten expression to string form for storage.
2114  */
2115  adbin = nodeToString(expr);
2116 
2117  /*
2118  * Also deparse it to form the mostly-obsolete adsrc field.
2119  */
2120  adsrc = deparse_expression(expr,
2122  RelationGetRelid(rel)),
2123  false, false);
2124 
2125  /*
2126  * Make the pg_attrdef entry.
2127  */
2128  values[Anum_pg_attrdef_adrelid - 1] = RelationGetRelid(rel);
2129  values[Anum_pg_attrdef_adnum - 1] = attnum;
2130  values[Anum_pg_attrdef_adbin - 1] = CStringGetTextDatum(adbin);
2131  values[Anum_pg_attrdef_adsrc - 1] = CStringGetTextDatum(adsrc);
2132 
2133  adrel = heap_open(AttrDefaultRelationId, RowExclusiveLock);
2134 
2135  tuple = heap_form_tuple(adrel->rd_att, values, nulls);
2136  attrdefOid = CatalogTupleInsert(adrel, tuple);
2137 
2138  defobject.classId = AttrDefaultRelationId;
2139  defobject.objectId = attrdefOid;
2140  defobject.objectSubId = 0;
2141 
2142  heap_close(adrel, RowExclusiveLock);
2143 
2144  /* now can free some of the stuff allocated above */
2145  pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
2146  pfree(DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
2147  heap_freetuple(tuple);
2148  pfree(adbin);
2149  pfree(adsrc);
2150 
2151  /*
2152  * Update the pg_attribute entry for the column to show that a default
2153  * exists.
2154  */
2155  attrrel = heap_open(AttributeRelationId, RowExclusiveLock);
2156  atttup = SearchSysCacheCopy2(ATTNUM,
2158  Int16GetDatum(attnum));
2159  if (!HeapTupleIsValid(atttup))
2160  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
2161  attnum, RelationGetRelid(rel));
2162  attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
2163  if (!attStruct->atthasdef)
2164  {
2165  Form_pg_attribute defAttStruct;
2166 
2167  ExprState *exprState;
2168  Expr *expr2 = (Expr *) expr;
2169  EState *estate = NULL;
2170  ExprContext *econtext;
2171  Datum valuesAtt[Natts_pg_attribute];
2172  bool nullsAtt[Natts_pg_attribute];
2173  bool replacesAtt[Natts_pg_attribute];
2174  Datum missingval = (Datum) 0;
2175  bool missingIsNull = true;
2176 
2177  MemSet(valuesAtt, 0, sizeof(valuesAtt));
2178  MemSet(nullsAtt, false, sizeof(nullsAtt));
2179  MemSet(replacesAtt, false, sizeof(replacesAtt));
2180  valuesAtt[Anum_pg_attribute_atthasdef - 1] = true;
2181  replacesAtt[Anum_pg_attribute_atthasdef - 1] = true;
2182 
2183  if (add_column_mode)
2184  {
2185  expr2 = expression_planner(expr2);
2186  estate = CreateExecutorState();
2187  exprState = ExecPrepareExpr(expr2, estate);
2188  econtext = GetPerTupleExprContext(estate);
2189 
2190  missingval = ExecEvalExpr(exprState, econtext,
2191  &missingIsNull);
2192 
2193  FreeExecutorState(estate);
2194 
2195  defAttStruct = TupleDescAttr(rel->rd_att, attnum - 1);
2196 
2197  if (missingIsNull)
2198  {
2199  /* if the default evaluates to NULL, just store a NULL array */
2200  missingval = (Datum) 0;
2201  }
2202  else
2203  {
2204  /* otherwise make a one-element array of the value */
2205  missingval = PointerGetDatum(
2206  construct_array(&missingval,
2207  1,
2208  defAttStruct->atttypid,
2209  defAttStruct->attlen,
2210  defAttStruct->attbyval,
2211  defAttStruct->attalign));
2212  }
2213 
2214  valuesAtt[Anum_pg_attribute_atthasmissing - 1] = !missingIsNull;
2215  replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true;
2216  valuesAtt[Anum_pg_attribute_attmissingval - 1] = missingval;
2217  replacesAtt[Anum_pg_attribute_attmissingval - 1] = true;
2218  nullsAtt[Anum_pg_attribute_attmissingval - 1] = missingIsNull;
2219  }
2220  atttup = heap_modify_tuple(atttup, RelationGetDescr(attrrel),
2221  valuesAtt, nullsAtt, replacesAtt);
2222 
2223  CatalogTupleUpdate(attrrel, &atttup->t_self, atttup);
2224 
2225  if (!missingIsNull)
2226  pfree(DatumGetPointer(missingval));
2227 
2228  }
2229  heap_close(attrrel, RowExclusiveLock);
2230  heap_freetuple(atttup);
2231 
2232  /*
2233  * Make a dependency so that the pg_attrdef entry goes away if the column
2234  * (or whole table) is deleted.
2235  */
2236  colobject.classId = RelationRelationId;
2237  colobject.objectId = RelationGetRelid(rel);
2238  colobject.objectSubId = attnum;
2239 
2240  recordDependencyOn(&defobject, &colobject, DEPENDENCY_AUTO);
2241 
2242  /*
2243  * Record dependencies on objects used in the expression, too.
2244  */
2245  recordDependencyOnExpr(&defobject, expr, NIL, DEPENDENCY_NORMAL);
2246 
2247  /*
2248  * Post creation hook for attribute defaults.
2249  *
2250  * XXX. ALTER TABLE ALTER COLUMN SET/DROP DEFAULT is implemented with a
2251  * couple of deletion/creation of the attribute's default entry, so the
2252  * callee should check existence of an older version of this entry if it
2253  * needs to distinguish.
2254  */
2255  InvokeObjectPostCreateHookArg(AttrDefaultRelationId,
2256  RelationGetRelid(rel), attnum, is_internal);
2257 
2258  return attrdefOid;
2259 }
2260 
2261 /*
2262  * Store a check-constraint expression for the given relation.
2263  *
2264  * Caller is responsible for updating the count of constraints
2265  * in the pg_class entry for the relation.
2266  *
2267  * The OID of the new constraint is returned.
2268  */
2269 static Oid
2270 StoreRelCheck(Relation rel, const char *ccname, Node *expr,
2271  bool is_validated, bool is_local, int inhcount,
2272  bool is_no_inherit, bool is_internal)
2273 {
2274  char *ccbin;
2275  char *ccsrc;
2276  List *varList;
2277  int keycount;
2278  int16 *attNos;
2279  Oid constrOid;
2280 
2281  /*
2282  * Flatten expression to string form for storage.
2283  */
2284  ccbin = nodeToString(expr);
2285 
2286  /*
2287  * Also deparse it to form the mostly-obsolete consrc field.
2288  */
2289  ccsrc = deparse_expression(expr,
2291  RelationGetRelid(rel)),
2292  false, false);
2293 
2294  /*
2295  * Find columns of rel that are used in expr
2296  *
2297  * NB: pull_var_clause is okay here only because we don't allow subselects
2298  * in check constraints; it would fail to examine the contents of
2299  * subselects.
2300  */
2301  varList = pull_var_clause(expr, 0);
2302  keycount = list_length(varList);
2303 
2304  if (keycount > 0)
2305  {
2306  ListCell *vl;
2307  int i = 0;
2308 
2309  attNos = (int16 *) palloc(keycount * sizeof(int16));
2310  foreach(vl, varList)
2311  {
2312  Var *var = (Var *) lfirst(vl);
2313  int j;
2314 
2315  for (j = 0; j < i; j++)
2316  if (attNos[j] == var->varattno)
2317  break;
2318  if (j == i)
2319  attNos[i++] = var->varattno;
2320  }
2321  keycount = i;
2322  }
2323  else
2324  attNos = NULL;
2325 
2326  /*
2327  * Partitioned tables do not contain any rows themselves, so a NO INHERIT
2328  * constraint makes no sense.
2329  */
2330  if (is_no_inherit &&
2331  rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2332  ereport(ERROR,
2333  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2334  errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
2335  RelationGetRelationName(rel))));
2336 
2337  /*
2338  * Create the Check Constraint
2339  */
2340  constrOid =
2341  CreateConstraintEntry(ccname, /* Constraint Name */
2342  RelationGetNamespace(rel), /* namespace */
2343  CONSTRAINT_CHECK, /* Constraint Type */
2344  false, /* Is Deferrable */
2345  false, /* Is Deferred */
2346  is_validated,
2347  InvalidOid, /* no parent constraint */
2348  RelationGetRelid(rel), /* relation */
2349  attNos, /* attrs in the constraint */
2350  keycount, /* # key attrs in the constraint */
2351  keycount, /* # total attrs in the constraint */
2352  InvalidOid, /* not a domain constraint */
2353  InvalidOid, /* no associated index */
2354  InvalidOid, /* Foreign key fields */
2355  NULL,
2356  NULL,
2357  NULL,
2358  NULL,
2359  0,
2360  ' ',
2361  ' ',
2362  ' ',
2363  NULL, /* not an exclusion constraint */
2364  expr, /* Tree form of check constraint */
2365  ccbin, /* Binary form of check constraint */
2366  ccsrc, /* Source form of check constraint */
2367  is_local, /* conislocal */
2368  inhcount, /* coninhcount */
2369  is_no_inherit, /* connoinherit */
2370  is_internal); /* internally constructed? */
2371 
2372  pfree(ccbin);
2373  pfree(ccsrc);
2374 
2375  return constrOid;
2376 }
2377 
2378 /*
2379  * Store defaults and constraints (passed as a list of CookedConstraint).
2380  *
2381  * Each CookedConstraint struct is modified to store the new catalog tuple OID.
2382  *
2383  * NOTE: only pre-cooked expressions will be passed this way, which is to
2384  * say expressions inherited from an existing relation. Newly parsed
2385  * expressions can be added later, by direct calls to StoreAttrDefault
2386  * and StoreRelCheck (see AddRelationNewConstraints()).
2387  */
2388 static void
2389 StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal)
2390 {
2391  int numchecks = 0;
2392  ListCell *lc;
2393 
2394  if (cooked_constraints == NIL)
2395  return; /* nothing to do */
2396 
2397  /*
2398  * Deparsing of constraint expressions will fail unless the just-created
2399  * pg_attribute tuples for this relation are made visible. So, bump the
2400  * command counter. CAUTION: this will cause a relcache entry rebuild.
2401  */
2403 
2404  foreach(lc, cooked_constraints)
2405  {
2406  CookedConstraint *con = (CookedConstraint *) lfirst(lc);
2407 
2408  switch (con->contype)
2409  {
2410  case CONSTR_DEFAULT:
2411  con->conoid = StoreAttrDefault(rel, con->attnum, con->expr,
2412  is_internal, false);
2413  break;
2414  case CONSTR_CHECK:
2415  con->conoid =
2416  StoreRelCheck(rel, con->name, con->expr,
2417  !con->skip_validation, con->is_local,
2418  con->inhcount, con->is_no_inherit,
2419  is_internal);
2420  numchecks++;
2421  break;
2422  default:
2423  elog(ERROR, "unrecognized constraint type: %d",
2424  (int) con->contype);
2425  }
2426  }
2427 
2428  if (numchecks > 0)
2429  SetRelationNumChecks(rel, numchecks);
2430 }
2431 
2432 /*
2433  * AddRelationNewConstraints
2434  *
2435  * Add new column default expressions and/or constraint check expressions
2436  * to an existing relation. This is defined to do both for efficiency in
2437  * DefineRelation, but of course you can do just one or the other by passing
2438  * empty lists.
2439  *
2440  * rel: relation to be modified
2441  * newColDefaults: list of RawColumnDefault structures
2442  * newConstraints: list of Constraint nodes
2443  * allow_merge: true if check constraints may be merged with existing ones
2444  * is_local: true if definition is local, false if it's inherited
2445  * is_internal: true if result of some internal process, not a user request
2446  *
2447  * All entries in newColDefaults will be processed. Entries in newConstraints
2448  * will be processed only if they are CONSTR_CHECK type.
2449  *
2450  * Returns a list of CookedConstraint nodes that shows the cooked form of
2451  * the default and constraint expressions added to the relation.
2452  *
2453  * NB: caller should have opened rel with AccessExclusiveLock, and should
2454  * hold that lock till end of transaction. Also, we assume the caller has
2455  * done a CommandCounterIncrement if necessary to make the relation's catalog
2456  * tuples visible.
2457  */
2458 List *
2460  List *newColDefaults,
2461  List *newConstraints,
2462  bool allow_merge,
2463  bool is_local,
2464  bool is_internal)
2465 {
2466  List *cookedConstraints = NIL;
2468  TupleConstr *oldconstr;
2469  int numoldchecks;
2470  ParseState *pstate;
2471  RangeTblEntry *rte;
2472  int numchecks;
2473  List *checknames;
2474  ListCell *cell;
2475  Node *expr;
2476  CookedConstraint *cooked;
2477 
2478  /*
2479  * Get info about existing constraints.
2480  */
2481  tupleDesc = RelationGetDescr(rel);
2482  oldconstr = tupleDesc->constr;
2483  if (oldconstr)
2484  numoldchecks = oldconstr->num_check;
2485  else
2486  numoldchecks = 0;
2487 
2488  /*
2489  * Create a dummy ParseState and insert the target relation as its sole
2490  * rangetable entry. We need a ParseState for transformExpr.
2491  */
2492  pstate = make_parsestate(NULL);
2493  rte = addRangeTableEntryForRelation(pstate,
2494  rel,
2495  NULL,
2496  false,
2497  true);
2498  addRTEtoQuery(pstate, rte, true, true, true);
2499 
2500  /*
2501  * Process column default expressions.
2502  */
2503  foreach(cell, newColDefaults)
2504  {
2505  RawColumnDefault *colDef = (RawColumnDefault *) lfirst(cell);
2506  Form_pg_attribute atp = TupleDescAttr(rel->rd_att, colDef->attnum - 1);
2507  Oid defOid;
2508 
2509  expr = cookDefault(pstate, colDef->raw_default,
2510  atp->atttypid, atp->atttypmod,
2511  NameStr(atp->attname));
2512 
2513  /*
2514  * If the expression is just a NULL constant, we do not bother to make
2515  * an explicit pg_attrdef entry, since the default behavior is
2516  * equivalent.
2517  *
2518  * Note a nonobvious property of this test: if the column is of a
2519  * domain type, what we'll get is not a bare null Const but a
2520  * CoerceToDomain expr, so we will not discard the default. This is
2521  * critical because the column default needs to be retained to
2522  * override any default that the domain might have.
2523  */
2524  if (expr == NULL ||
2525  (IsA(expr, Const) &&((Const *) expr)->constisnull))
2526  continue;
2527 
2528  /* If the DEFAULT is volatile we cannot use a missing value */
2529  if (colDef->missingMode && contain_volatile_functions((Node *) expr))
2530  colDef->missingMode = false;
2531 
2532  defOid = StoreAttrDefault(rel, colDef->attnum, expr, is_internal,
2533  colDef->missingMode);
2534 
2535  cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2536  cooked->contype = CONSTR_DEFAULT;
2537  cooked->conoid = defOid;
2538  cooked->name = NULL;
2539  cooked->attnum = colDef->attnum;
2540  cooked->expr = expr;
2541  cooked->skip_validation = false;
2542  cooked->is_local = is_local;
2543  cooked->inhcount = is_local ? 0 : 1;
2544  cooked->is_no_inherit = false;
2545  cookedConstraints = lappend(cookedConstraints, cooked);
2546  }
2547 
2548  /*
2549  * Process constraint expressions.
2550  */
2551  numchecks = numoldchecks;
2552  checknames = NIL;
2553  foreach(cell, newConstraints)
2554  {
2555  Constraint *cdef = (Constraint *) lfirst(cell);
2556  char *ccname;
2557  Oid constrOid;
2558 
2559  if (cdef->contype != CONSTR_CHECK)
2560  continue;
2561 
2562  if (cdef->raw_expr != NULL)
2563  {
2564  Assert(cdef->cooked_expr == NULL);
2565 
2566  /*
2567  * Transform raw parsetree to executable expression, and verify
2568  * it's valid as a CHECK constraint.
2569  */
2570  expr = cookConstraint(pstate, cdef->raw_expr,
2572  }
2573  else
2574  {
2575  Assert(cdef->cooked_expr != NULL);
2576 
2577  /*
2578  * Here, we assume the parser will only pass us valid CHECK
2579  * expressions, so we do no particular checking.
2580  */
2581  expr = stringToNode(cdef->cooked_expr);
2582  }
2583 
2584  /*
2585  * Check name uniqueness, or generate a name if none was given.
2586  */
2587  if (cdef->conname != NULL)
2588  {
2589  ListCell *cell2;
2590 
2591  ccname = cdef->conname;
2592  /* Check against other new constraints */
2593  /* Needed because we don't do CommandCounterIncrement in loop */
2594  foreach(cell2, checknames)
2595  {
2596  if (strcmp((char *) lfirst(cell2), ccname) == 0)
2597  ereport(ERROR,
2599  errmsg("check constraint \"%s\" already exists",
2600  ccname)));
2601  }
2602 
2603  /* save name for future checks */
2604  checknames = lappend(checknames, ccname);
2605 
2606  /*
2607  * Check against pre-existing constraints. If we are allowed to
2608  * merge with an existing constraint, there's no more to do here.
2609  * (We omit the duplicate constraint from the result, which is
2610  * what ATAddCheckConstraint wants.)
2611  */
2612  if (MergeWithExistingConstraint(rel, ccname, expr,
2613  allow_merge, is_local,
2614  cdef->initially_valid,
2615  cdef->is_no_inherit))
2616  continue;
2617  }
2618  else
2619  {
2620  /*
2621  * When generating a name, we want to create "tab_col_check" for a
2622  * column constraint and "tab_check" for a table constraint. We
2623  * no longer have any info about the syntactic positioning of the
2624  * constraint phrase, so we approximate this by seeing whether the
2625  * expression references more than one column. (If the user
2626  * played by the rules, the result is the same...)
2627  *
2628  * Note: pull_var_clause() doesn't descend into sublinks, but we
2629  * eliminated those above; and anyway this only needs to be an
2630  * approximate answer.
2631  */
2632  List *vars;
2633  char *colname;
2634 
2635  vars = pull_var_clause(expr, 0);
2636 
2637  /* eliminate duplicates */
2638  vars = list_union(NIL, vars);
2639 
2640  if (list_length(vars) == 1)
2641  colname = get_attname(RelationGetRelid(rel),
2642  ((Var *) linitial(vars))->varattno,
2643  true);
2644  else
2645  colname = NULL;
2646 
2648  colname,
2649  "check",
2650  RelationGetNamespace(rel),
2651  checknames);
2652 
2653  /* save name for future checks */
2654  checknames = lappend(checknames, ccname);
2655  }
2656 
2657  /*
2658  * OK, store it.
2659  */
2660  constrOid =
2661  StoreRelCheck(rel, ccname, expr, cdef->initially_valid, is_local,
2662  is_local ? 0 : 1, cdef->is_no_inherit, is_internal);
2663 
2664  numchecks++;
2665 
2666  cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2667  cooked->contype = CONSTR_CHECK;
2668  cooked->conoid = constrOid;
2669  cooked->name = ccname;
2670  cooked->attnum = 0;
2671  cooked->expr = expr;
2672  cooked->skip_validation = cdef->skip_validation;
2673  cooked->is_local = is_local;
2674  cooked->inhcount = is_local ? 0 : 1;
2675  cooked->is_no_inherit = cdef->is_no_inherit;
2676  cookedConstraints = lappend(cookedConstraints, cooked);
2677  }
2678 
2679  /*
2680  * Update the count of constraints in the relation's pg_class tuple. We do
2681  * this even if there was no change, in order to ensure that an SI update
2682  * message is sent out for the pg_class tuple, which will force other
2683  * backends to rebuild their relcache entries for the rel. (This is
2684  * critical if we added defaults but not constraints.)
2685  */
2686  SetRelationNumChecks(rel, numchecks);
2687 
2688  return cookedConstraints;
2689 }
2690 
2691 /*
2692  * Check for a pre-existing check constraint that conflicts with a proposed
2693  * new one, and either adjust its conislocal/coninhcount settings or throw
2694  * error as needed.
2695  *
2696  * Returns true if merged (constraint is a duplicate), or false if it's
2697  * got a so-far-unique name, or throws error if conflict.
2698  *
2699  * XXX See MergeConstraintsIntoExisting too if you change this code.
2700  */
2701 static bool
2702 MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr,
2703  bool allow_merge, bool is_local,
2704  bool is_initially_valid,
2705  bool is_no_inherit)
2706 {
2707  bool found;
2708  Relation conDesc;
2709  SysScanDesc conscan;
2710  ScanKeyData skey[2];
2711  HeapTuple tup;
2712 
2713  /* Search for a pg_constraint entry with same name and relation */
2714  conDesc = heap_open(ConstraintRelationId, RowExclusiveLock);
2715 
2716  found = false;
2717 
2718  ScanKeyInit(&skey[0],
2719  Anum_pg_constraint_conname,
2720  BTEqualStrategyNumber, F_NAMEEQ,
2721  CStringGetDatum(ccname));
2722 
2723  ScanKeyInit(&skey[1],
2724  Anum_pg_constraint_connamespace,
2725  BTEqualStrategyNumber, F_OIDEQ,
2727 
2728  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
2729  NULL, 2, skey);
2730 
2731  while (HeapTupleIsValid(tup = systable_getnext(conscan)))
2732  {
2734 
2735  if (con->conrelid == RelationGetRelid(rel))
2736  {
2737  /* Found it. Conflicts if not identical check constraint */
2738  if (con->contype == CONSTRAINT_CHECK)
2739  {
2740  Datum val;
2741  bool isnull;
2742 
2743  val = fastgetattr(tup,
2744  Anum_pg_constraint_conbin,
2745  conDesc->rd_att, &isnull);
2746  if (isnull)
2747  elog(ERROR, "null conbin for rel %s",
2749  if (equal(expr, stringToNode(TextDatumGetCString(val))))
2750  found = true;
2751  }
2752 
2753  /*
2754  * If the existing constraint is purely inherited (no local
2755  * definition) then interpret addition of a local constraint as a
2756  * legal merge. This allows ALTER ADD CONSTRAINT on parent and
2757  * child tables to be given in either order with same end state.
2758  * However if the relation is a partition, all inherited
2759  * constraints are always non-local, including those that were
2760  * merged.
2761  */
2762  if (is_local && !con->conislocal && !rel->rd_rel->relispartition)
2763  allow_merge = true;
2764 
2765  if (!found || !allow_merge)
2766  ereport(ERROR,
2768  errmsg("constraint \"%s\" for relation \"%s\" already exists",
2769  ccname, RelationGetRelationName(rel))));
2770 
2771  /* If the child constraint is "no inherit" then cannot merge */
2772  if (con->connoinherit)
2773  ereport(ERROR,
2774  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2775  errmsg("constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"",
2776  ccname, RelationGetRelationName(rel))));
2777 
2778  /*
2779  * Must not change an existing inherited constraint to "no
2780  * inherit" status. That's because inherited constraints should
2781  * be able to propagate to lower-level children.
2782  */
2783  if (con->coninhcount > 0 && is_no_inherit)
2784  ereport(ERROR,
2785  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2786  errmsg("constraint \"%s\" conflicts with inherited constraint on relation \"%s\"",
2787  ccname, RelationGetRelationName(rel))));
2788 
2789  /*
2790  * If the child constraint is "not valid" then cannot merge with a
2791  * valid parent constraint
2792  */
2793  if (is_initially_valid && !con->convalidated)
2794  ereport(ERROR,
2795  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2796  errmsg("constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"",
2797  ccname, RelationGetRelationName(rel))));
2798 
2799  /* OK to update the tuple */
2800  ereport(NOTICE,
2801  (errmsg("merging constraint \"%s\" with inherited definition",
2802  ccname)));
2803 
2804  tup = heap_copytuple(tup);
2805  con = (Form_pg_constraint) GETSTRUCT(tup);
2806 
2807  /*
2808  * In case of partitions, an inherited constraint must be
2809  * inherited only once since it cannot have multiple parents and
2810  * it is never considered local.
2811  */
2812  if (rel->rd_rel->relispartition)
2813  {
2814  con->coninhcount = 1;
2815  con->conislocal = false;
2816  }
2817  else
2818  {
2819  if (is_local)
2820  con->conislocal = true;
2821  else
2822  con->coninhcount++;
2823  }
2824 
2825  if (is_no_inherit)
2826  {
2827  Assert(is_local);
2828  con->connoinherit = true;
2829  }
2830  CatalogTupleUpdate(conDesc, &tup->t_self, tup);
2831  break;
2832  }
2833  }
2834 
2835  systable_endscan(conscan);
2836  heap_close(conDesc, RowExclusiveLock);
2837 
2838  return found;
2839 }
2840 
2841 /*
2842  * Update the count of constraints in the relation's pg_class tuple.
2843  *
2844  * Caller had better hold exclusive lock on the relation.
2845  *
2846  * An important side effect is that a SI update message will be sent out for
2847  * the pg_class tuple, which will force other backends to rebuild their
2848  * relcache entries for the rel. Also, this backend will rebuild its
2849  * own relcache entry at the next CommandCounterIncrement.
2850  */
2851 static void
2852 SetRelationNumChecks(Relation rel, int numchecks)
2853 {
2854  Relation relrel;
2855  HeapTuple reltup;
2856  Form_pg_class relStruct;
2857 
2858  relrel = heap_open(RelationRelationId, RowExclusiveLock);
2859  reltup = SearchSysCacheCopy1(RELOID,
2861  if (!HeapTupleIsValid(reltup))
2862  elog(ERROR, "cache lookup failed for relation %u",
2863  RelationGetRelid(rel));
2864  relStruct = (Form_pg_class) GETSTRUCT(reltup);
2865 
2866  if (relStruct->relchecks != numchecks)
2867  {
2868  relStruct->relchecks = numchecks;
2869 
2870  CatalogTupleUpdate(relrel, &reltup->t_self, reltup);
2871  }
2872  else
2873  {
2874  /* Skip the disk update, but force relcache inval anyway */
2876  }
2877 
2878  heap_freetuple(reltup);
2879  heap_close(relrel, RowExclusiveLock);
2880 }
2881 
2882 /*
2883  * Take a raw default and convert it to a cooked format ready for
2884  * storage.
2885  *
2886  * Parse state should be set up to recognize any vars that might appear
2887  * in the expression. (Even though we plan to reject vars, it's more
2888  * user-friendly to give the correct error message than "unknown var".)
2889  *
2890  * If atttypid is not InvalidOid, coerce the expression to the specified
2891  * type (and typmod atttypmod). attname is only needed in this case:
2892  * it is used in the error message, if any.
2893  */
2894 Node *
2896  Node *raw_default,
2897  Oid atttypid,
2898  int32 atttypmod,
2899  const char *attname)
2900 {
2901  Node *expr;
2902 
2903  Assert(raw_default != NULL);
2904 
2905  /*
2906  * Transform raw parsetree to executable expression.
2907  */
2908  expr = transformExpr(pstate, raw_default, EXPR_KIND_COLUMN_DEFAULT);
2909 
2910  /*
2911  * Make sure default expr does not refer to any vars (we need this check
2912  * since the pstate includes the target table).
2913  */
2914  if (contain_var_clause(expr))
2915  ereport(ERROR,
2916  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2917  errmsg("cannot use column references in default expression")));
2918 
2919  /*
2920  * transformExpr() should have already rejected subqueries, aggregates,
2921  * window functions, and SRFs, based on the EXPR_KIND_ for a default
2922  * expression.
2923  */
2924 
2925  /*
2926  * Coerce the expression to the correct type and typmod, if given. This
2927  * should match the parser's processing of non-defaulted expressions ---
2928  * see transformAssignedExpr().
2929  */
2930  if (OidIsValid(atttypid))
2931  {
2932  Oid type_id = exprType(expr);
2933 
2934  expr = coerce_to_target_type(pstate, expr, type_id,
2935  atttypid, atttypmod,
2938  -1);
2939  if (expr == NULL)
2940  ereport(ERROR,
2941  (errcode(ERRCODE_DATATYPE_MISMATCH),
2942  errmsg("column \"%s\" is of type %s"
2943  " but default expression is of type %s",
2944  attname,
2945  format_type_be(atttypid),
2946  format_type_be(type_id)),
2947  errhint("You will need to rewrite or cast the expression.")));
2948  }
2949 
2950  /*
2951  * Finally, take care of collations in the finished expression.
2952  */
2953  assign_expr_collations(pstate, expr);
2954 
2955  return expr;
2956 }
2957 
2958 /*
2959  * Take a raw CHECK constraint expression and convert it to a cooked format
2960  * ready for storage.
2961  *
2962  * Parse state must be set up to recognize any vars that might appear
2963  * in the expression.
2964  */
2965 static Node *
2967  Node *raw_constraint,
2968  char *relname)
2969 {
2970  Node *expr;
2971 
2972  /*
2973  * Transform raw parsetree to executable expression.
2974  */
2975  expr = transformExpr(pstate, raw_constraint, EXPR_KIND_CHECK_CONSTRAINT);
2976 
2977  /*
2978  * Make sure it yields a boolean result.
2979  */
2980  expr = coerce_to_boolean(pstate, expr, "CHECK");
2981 
2982  /*
2983  * Take care of collations.
2984  */
2985  assign_expr_collations(pstate, expr);
2986 
2987  /*
2988  * Make sure no outside relations are referred to (this is probably dead
2989  * code now that add_missing_from is history).
2990  */
2991  if (list_length(pstate->p_rtable) != 1)
2992  ereport(ERROR,
2993  (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2994  errmsg("only table \"%s\" can be referenced in check constraint",
2995  relname)));
2996 
2997  return expr;
2998 }
2999 
3000 
3001 /*
3002  * RemoveStatistics --- remove entries in pg_statistic for a rel or column
3003  *
3004  * If attnum is zero, remove all entries for rel; else remove only the one(s)
3005  * for that column.
3006  */
3007 void
3009 {
3010  Relation pgstatistic;
3011  SysScanDesc scan;
3012  ScanKeyData key[2];
3013  int nkeys;
3014  HeapTuple tuple;
3015 
3016  pgstatistic = heap_open(StatisticRelationId, RowExclusiveLock);
3017 
3018  ScanKeyInit(&key[0],
3019  Anum_pg_statistic_starelid,
3020  BTEqualStrategyNumber, F_OIDEQ,
3021  ObjectIdGetDatum(relid));
3022 
3023  if (attnum == 0)
3024  nkeys = 1;
3025  else
3026  {
3027  ScanKeyInit(&key[1],
3028  Anum_pg_statistic_staattnum,
3029  BTEqualStrategyNumber, F_INT2EQ,
3030  Int16GetDatum(attnum));
3031  nkeys = 2;
3032  }
3033 
3034  scan = systable_beginscan(pgstatistic, StatisticRelidAttnumInhIndexId, true,
3035  NULL, nkeys, key);
3036 
3037  /* we must loop even when attnum != 0, in case of inherited stats */
3038  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
3039  CatalogTupleDelete(pgstatistic, &tuple->t_self);
3040 
3041  systable_endscan(scan);
3042 
3043  heap_close(pgstatistic, RowExclusiveLock);
3044 }
3045 
3046 
3047 /*
3048  * RelationTruncateIndexes - truncate all indexes associated
3049  * with the heap relation to zero tuples.
3050  *
3051  * The routine will truncate and then reconstruct the indexes on
3052  * the specified relation. Caller must hold exclusive lock on rel.
3053  */
3054 static void
3056 {
3057  ListCell *indlist;
3058 
3059  /* Ask the relcache to produce a list of the indexes of the rel */
3060  foreach(indlist, RelationGetIndexList(heapRelation))
3061  {
3062  Oid indexId = lfirst_oid(indlist);
3063  Relation currentIndex;
3064  IndexInfo *indexInfo;
3065 
3066  /* Open the index relation; use exclusive lock, just to be sure */
3067  currentIndex = index_open(indexId, AccessExclusiveLock);
3068 
3069  /* Fetch info needed for index_build */
3070  indexInfo = BuildIndexInfo(currentIndex);
3071 
3072  /*
3073  * Now truncate the actual file (and discard buffers).
3074  */
3075  RelationTruncate(currentIndex, 0);
3076 
3077  /* Initialize the index and rebuild */
3078  /* Note: we do not need to re-establish pkey setting */
3079  index_build(heapRelation, currentIndex, indexInfo, false, true, false);
3080 
3081  /* We're done with this index */
3082  index_close(currentIndex, NoLock);
3083  }
3084 }
3085 
3086 /*
3087  * heap_truncate
3088  *
3089  * This routine deletes all data within all the specified relations.
3090  *
3091  * This is not transaction-safe! There is another, transaction-safe
3092  * implementation in commands/tablecmds.c. We now use this only for
3093  * ON COMMIT truncation of temporary tables, where it doesn't matter.
3094  */
3095 void
3097 {
3098  List *relations = NIL;
3099  ListCell *cell;
3100 
3101  /* Open relations for processing, and grab exclusive access on each */
3102  foreach(cell, relids)
3103  {
3104  Oid rid = lfirst_oid(cell);
3105  Relation rel;
3106 
3107  rel = heap_open(rid, AccessExclusiveLock);
3108  relations = lappend(relations, rel);
3109  }
3110 
3111  /* Don't allow truncate on tables that are referenced by foreign keys */
3112  heap_truncate_check_FKs(relations, true);
3113 
3114  /* OK to do it */
3115  foreach(cell, relations)
3116  {
3117  Relation rel = lfirst(cell);
3118 
3119  /* Truncate the relation */
3120  heap_truncate_one_rel(rel);
3121 
3122  /* Close the relation, but keep exclusive lock on it until commit */
3123  heap_close(rel, NoLock);
3124  }
3125 }
3126 
3127 /*
3128  * heap_truncate_one_rel
3129  *
3130  * This routine deletes all data within the specified relation.
3131  *
3132  * This is not transaction-safe, because the truncation is done immediately
3133  * and cannot be rolled back later. Caller is responsible for having
3134  * checked permissions etc, and must have obtained AccessExclusiveLock.
3135  */
3136 void
3138 {
3139  Oid toastrelid;
3140 
3141  /* Truncate the actual file (and discard buffers) */
3142  RelationTruncate(rel, 0);
3143 
3144  /* If the relation has indexes, truncate the indexes too */
3146 
3147  /* If there is a toast table, truncate that too */
3148  toastrelid = rel->rd_rel->reltoastrelid;
3149  if (OidIsValid(toastrelid))
3150  {
3151  Relation toastrel = heap_open(toastrelid, AccessExclusiveLock);
3152 
3153  RelationTruncate(toastrel, 0);
3154  RelationTruncateIndexes(toastrel);
3155  /* keep the lock... */
3156  heap_close(toastrel, NoLock);
3157  }
3158 }
3159 
3160 /*
3161  * heap_truncate_check_FKs
3162  * Check for foreign keys referencing a list of relations that
3163  * are to be truncated, and raise error if there are any
3164  *
3165  * We disallow such FKs (except self-referential ones) since the whole point
3166  * of TRUNCATE is to not scan the individual rows to be thrown away.
3167  *
3168  * This is split out so it can be shared by both implementations of truncate.
3169  * Caller should already hold a suitable lock on the relations.
3170  *
3171  * tempTables is only used to select an appropriate error message.
3172  */
3173 void
3174 heap_truncate_check_FKs(List *relations, bool tempTables)
3175 {
3176  List *oids = NIL;
3177  List *dependents;
3178  ListCell *cell;
3179 
3180  /*
3181  * Build a list of OIDs of the interesting relations.
3182  *
3183  * If a relation has no triggers, then it can neither have FKs nor be
3184  * referenced by a FK from another table, so we can ignore it.
3185  */
3186  foreach(cell, relations)
3187  {
3188  Relation rel = lfirst(cell);
3189 
3190  if (rel->rd_rel->relhastriggers)
3191  oids = lappend_oid(oids, RelationGetRelid(rel));
3192  }
3193 
3194  /*
3195  * Fast path: if no relation has triggers, none has FKs either.
3196  */
3197  if (oids == NIL)
3198  return;
3199 
3200  /*
3201  * Otherwise, must scan pg_constraint. We make one pass with all the
3202  * relations considered; if this finds nothing, then all is well.
3203  */
3204  dependents = heap_truncate_find_FKs(oids);
3205  if (dependents == NIL)
3206  return;
3207 
3208  /*
3209  * Otherwise we repeat the scan once per relation to identify a particular
3210  * pair of relations to complain about. This is pretty slow, but
3211  * performance shouldn't matter much in a failure path. The reason for
3212  * doing things this way is to ensure that the message produced is not
3213  * dependent on chance row locations within pg_constraint.
3214  */
3215  foreach(cell, oids)
3216  {
3217  Oid relid = lfirst_oid(cell);
3218  ListCell *cell2;
3219 
3220  dependents = heap_truncate_find_FKs(list_make1_oid(relid));
3221 
3222  foreach(cell2, dependents)
3223  {
3224  Oid relid2 = lfirst_oid(cell2);
3225 
3226  if (!list_member_oid(oids, relid2))
3227  {
3228  char *relname = get_rel_name(relid);
3229  char *relname2 = get_rel_name(relid2);
3230 
3231  if (tempTables)
3232  ereport(ERROR,
3233  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3234  errmsg("unsupported ON COMMIT and foreign key combination"),
3235  errdetail("Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting.",
3236  relname2, relname)));
3237  else
3238  ereport(ERROR,
3239  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3240  errmsg("cannot truncate a table referenced in a foreign key constraint"),
3241  errdetail("Table \"%s\" references \"%s\".",
3242  relname2, relname),
3243  errhint("Truncate table \"%s\" at the same time, "
3244  "or use TRUNCATE ... CASCADE.",
3245  relname2)));
3246  }
3247  }
3248  }
3249 }
3250 
3251 /*
3252  * heap_truncate_find_FKs
3253  * Find relations having foreign keys referencing any of the given rels
3254  *
3255  * Input and result are both lists of relation OIDs. The result contains
3256  * no duplicates, does *not* include any rels that were already in the input
3257  * list, and is sorted in OID order. (The last property is enforced mainly
3258  * to guarantee consistent behavior in the regression tests; we don't want
3259  * behavior to change depending on chance locations of rows in pg_constraint.)
3260  *
3261  * Note: caller should already have appropriate lock on all rels mentioned
3262  * in relationIds. Since adding or dropping an FK requires exclusive lock
3263  * on both rels, this ensures that the answer will be stable.
3264  */
3265 List *
3267 {
3268  List *result = NIL;
3269  Relation fkeyRel;
3270  SysScanDesc fkeyScan;
3271  HeapTuple tuple;
3272 
3273  /*
3274  * Must scan pg_constraint. Right now, it is a seqscan because there is
3275  * no available index on confrelid.
3276  */
3277  fkeyRel = heap_open(ConstraintRelationId, AccessShareLock);
3278 
3279  fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false,
3280  NULL, 0, NULL);
3281 
3282  while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan)))
3283  {
3285 
3286  /* Not a foreign key */
3287  if (con->contype != CONSTRAINT_FOREIGN)
3288  continue;
3289 
3290  /* Not referencing one of our list of tables */
3291  if (!list_member_oid(relationIds, con->confrelid))
3292  continue;
3293 
3294  /* Add referencer unless already in input or result list */
3295  if (!list_member_oid(relationIds, con->conrelid))
3296  result = insert_ordered_unique_oid(result, con->conrelid);
3297  }
3298 
3299  systable_endscan(fkeyScan);
3300  heap_close(fkeyRel, AccessShareLock);
3301 
3302  return result;
3303 }
3304 
3305 /*
3306  * insert_ordered_unique_oid
3307  * Insert a new Oid into a sorted list of Oids, preserving ordering,
3308  * and eliminating duplicates
3309  *
3310  * Building the ordered list this way is O(N^2), but with a pretty small
3311  * constant, so for the number of entries we expect it will probably be
3312  * faster than trying to apply qsort(). It seems unlikely someone would be
3313  * trying to truncate a table with thousands of dependent tables ...
3314  */
3315 static List *
3317 {
3318  ListCell *prev;
3319 
3320  /* Does the datum belong at the front? */
3321  if (list == NIL || datum < linitial_oid(list))
3322  return lcons_oid(datum, list);
3323  /* Does it match the first entry? */
3324  if (datum == linitial_oid(list))
3325  return list; /* duplicate, so don't insert */
3326  /* No, so find the entry it belongs after */
3327  prev = list_head(list);
3328  for (;;)
3329  {
3330  ListCell *curr = lnext(prev);
3331 
3332  if (curr == NULL || datum < lfirst_oid(curr))
3333  break; /* it belongs after 'prev', before 'curr' */
3334 
3335  if (datum == lfirst_oid(curr))
3336  return list; /* duplicate, so don't insert */
3337 
3338  prev = curr;
3339  }
3340  /* Insert datum into list after 'prev' */
3341  lappend_cell_oid(list, prev, datum);
3342  return list;
3343 }
3344 
3345 /*
3346  * StorePartitionKey
3347  * Store information about the partition key rel into the catalog
3348  */
3349 void
3351  char strategy,
3352  int16 partnatts,
3353  AttrNumber *partattrs,
3354  List *partexprs,
3355  Oid *partopclass,
3356  Oid *partcollation)
3357 {
3358  int i;
3359  int2vector *partattrs_vec;
3360  oidvector *partopclass_vec;
3361  oidvector *partcollation_vec;
3362  Datum partexprDatum;
3363  Relation pg_partitioned_table;
3364  HeapTuple tuple;
3365  Datum values[Natts_pg_partitioned_table];
3366  bool nulls[Natts_pg_partitioned_table];
3367  ObjectAddress myself;
3368  ObjectAddress referenced;
3369 
3370  Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
3371 
3372  /* Copy the partition attribute numbers, opclass OIDs into arrays */
3373  partattrs_vec = buildint2vector(partattrs, partnatts);
3374  partopclass_vec = buildoidvector(partopclass, partnatts);
3375  partcollation_vec = buildoidvector(partcollation, partnatts);
3376 
3377  /* Convert the expressions (if any) to a text datum */
3378  if (partexprs)
3379  {
3380  char *exprString;
3381 
3382  exprString = nodeToString(partexprs);
3383  partexprDatum = CStringGetTextDatum(exprString);
3384  pfree(exprString);
3385  }
3386  else
3387  partexprDatum = (Datum) 0;
3388 
3389  pg_partitioned_table = heap_open(PartitionedRelationId, RowExclusiveLock);
3390 
3391  MemSet(nulls, false, sizeof(nulls));
3392 
3393  /* Only this can ever be NULL */
3394  if (!partexprDatum)
3395  nulls[Anum_pg_partitioned_table_partexprs - 1] = true;
3396 
3397  values[Anum_pg_partitioned_table_partrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
3398  values[Anum_pg_partitioned_table_partstrat - 1] = CharGetDatum(strategy);
3399  values[Anum_pg_partitioned_table_partnatts - 1] = Int16GetDatum(partnatts);
3400  values[Anum_pg_partitioned_table_partdefid - 1] = ObjectIdGetDatum(InvalidOid);
3401  values[Anum_pg_partitioned_table_partattrs - 1] = PointerGetDatum(partattrs_vec);
3402  values[Anum_pg_partitioned_table_partclass - 1] = PointerGetDatum(partopclass_vec);
3403  values[Anum_pg_partitioned_table_partcollation - 1] = PointerGetDatum(partcollation_vec);
3404  values[Anum_pg_partitioned_table_partexprs - 1] = partexprDatum;
3405 
3406  tuple = heap_form_tuple(RelationGetDescr(pg_partitioned_table), values, nulls);
3407 
3408  CatalogTupleInsert(pg_partitioned_table, tuple);
3409  heap_close(pg_partitioned_table, RowExclusiveLock);
3410 
3411  /* Mark this relation as dependent on a few things as follows */
3412  myself.classId = RelationRelationId;
3413  myself.objectId = RelationGetRelid(rel);;
3414  myself.objectSubId = 0;
3415 
3416  /* Operator class and collation per key column */
3417  for (i = 0; i < partnatts; i++)
3418  {
3419  referenced.classId = OperatorClassRelationId;
3420  referenced.objectId = partopclass[i];
3421  referenced.objectSubId = 0;
3422 
3423  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3424 
3425  /* The default collation is pinned, so don't bother recording it */
3426  if (OidIsValid(partcollation[i]) &&
3427  partcollation[i] != DEFAULT_COLLATION_OID)
3428  {
3429  referenced.classId = CollationRelationId;
3430  referenced.objectId = partcollation[i];
3431  referenced.objectSubId = 0;
3432  }
3433 
3434  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3435  }
3436 
3437  /*
3438  * Anything mentioned in the expressions. We must ignore the column
3439  * references, which will depend on the table itself; there is no separate
3440  * partition key object.
3441  */
3442  if (partexprs)
3444  (Node *) partexprs,
3445  RelationGetRelid(rel),
3447  DEPENDENCY_AUTO, true);
3448 
3449  /*
3450  * We must invalidate the relcache so that the next
3451  * CommandCounterIncrement() will cause the same to be rebuilt using the
3452  * information in just created catalog entry.
3453  */
3455 }
3456 
3457 /*
3458  * RemovePartitionKeyByRelId
3459  * Remove pg_partitioned_table entry for a relation
3460  */
3461 void
3463 {
3464  Relation rel;
3465  HeapTuple tuple;
3466 
3467  rel = heap_open(PartitionedRelationId, RowExclusiveLock);
3468 
3469  tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(relid));
3470  if (!HeapTupleIsValid(tuple))
3471  elog(ERROR, "cache lookup failed for partition key of relation %u",
3472  relid);
3473 
3474  CatalogTupleDelete(rel, &tuple->t_self);
3475 
3476  ReleaseSysCache(tuple);
3478 }
3479 
3480 /*
3481  * StorePartitionBound
3482  * Update pg_class tuple of rel to store the partition bound and set
3483  * relispartition to true
3484  *
3485  * If this is the default partition, also update the default partition OID in
3486  * pg_partitioned_table.
3487  *
3488  * Also, invalidate the parent's relcache, so that the next rebuild will load
3489  * the new partition's info into its partition descriptor. If there is a
3490  * default partition, we must invalidate its relcache entry as well.
3491  */
3492 void
3494 {
3495  Relation classRel;
3496  HeapTuple tuple,
3497  newtuple;
3498  Datum new_val[Natts_pg_class];
3499  bool new_null[Natts_pg_class],
3500  new_repl[Natts_pg_class];
3501  Oid defaultPartOid;
3502 
3503  /* Update pg_class tuple */
3504  classRel = heap_open(RelationRelationId, RowExclusiveLock);
3505  tuple = SearchSysCacheCopy1(RELOID,
3507  if (!HeapTupleIsValid(tuple))
3508  elog(ERROR, "cache lookup failed for relation %u",
3509  RelationGetRelid(rel));
3510 
3511 #ifdef USE_ASSERT_CHECKING
3512  {
3513  Form_pg_class classForm;
3514  bool isnull;
3515 
3516  classForm = (Form_pg_class) GETSTRUCT(tuple);
3517  Assert(!classForm->relispartition);
3518  (void) SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relpartbound,
3519  &isnull);
3520  Assert(isnull);
3521  }
3522 #endif
3523 
3524  /* Fill in relpartbound value */
3525  memset(new_val, 0, sizeof(new_val));
3526  memset(new_null, false, sizeof(new_null));
3527  memset(new_repl, false, sizeof(new_repl));
3528  new_val[Anum_pg_class_relpartbound - 1] = CStringGetTextDatum(nodeToString(bound));
3529  new_null[Anum_pg_class_relpartbound - 1] = false;
3530  new_repl[Anum_pg_class_relpartbound - 1] = true;
3531  newtuple = heap_modify_tuple(tuple, RelationGetDescr(classRel),
3532  new_val, new_null, new_repl);
3533  /* Also set the flag */
3534  ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true;
3535  CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
3536  heap_freetuple(newtuple);
3537  heap_close(classRel, RowExclusiveLock);
3538 
3539  /*
3540  * If we're storing bounds for the default partition, update
3541  * pg_partitioned_table too.
3542  */
3543  if (bound->is_default)
3545  RelationGetRelid(rel));
3546 
3547  /* Make these updates visible */
3549 
3550  /*
3551  * The partition constraint for the default partition depends on the
3552  * partition bounds of every other partition, so we must invalidate the
3553  * relcache entry for that partition every time a partition is added or
3554  * removed.
3555  */
3556  defaultPartOid = get_default_oid_from_partdesc(RelationGetPartitionDesc(parent));
3557  if (OidIsValid(defaultPartOid))
3558  CacheInvalidateRelcacheByRelid(defaultPartOid);
3559 
3560  CacheInvalidateRelcache(parent);
3561 }
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:13175
#define IsA(nodeptr, _type_)
Definition: nodes.h:567
#define NameGetDatum(X)
Definition: postgres.h:580
char * makeArrayTypeName(const char *typeName, Oid typeNamespace)
Definition: pg_type.c:766
static void SetRelationNumChecks(Relation rel, int numchecks)
Definition: heap.c:2852
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:3094
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:668
bool is_no_inherit
Definition: heap.h:39
#define fastgetattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:731
bool tdhasoid
Definition: tupdesc.h:85
#define MultiXactIdGetDatum(X)
Definition: postgres.h:513
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:3350
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:541
#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:2966
int2vector * buildint2vector(const int16 *int2s, int n)
Definition: int.c:110
void heap_truncate_one_rel(Relation rel)
Definition: heap.c:3137
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:436
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:516
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:13206
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:3174
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:168
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:2595
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
void SetAttrMissing(Oid relid, char *attname, char *value)
Definition: heap.c:2035
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:163
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:109
OnCommitAction
Definition: primnodes.h:47
char relkind
Definition: pg_class.h:51
signed int int32
Definition: c.h:313
Oid MyDatabaseTableSpace
Definition: globals.c:86
#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:710
Node * cookDefault(ParseState *pstate, Node *raw_default, Oid atttypid, int32 atttypmod, const char *attname)
Definition: heap.c:2895
#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:488
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:492
#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:1889
#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:280
Oid reltablespace
Definition: pg_class.h:42
bool IsUnderPostmaster
Definition: globals.c:108
#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:563
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:1300
#define InvalidTransactionId
Definition: transam.h:31
static void StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal)
Definition: heap.c:2389
#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:1967
ConstrType contype
Definition: heap.h:31
void CheckTableNotInUse(Relation rel, const char *stmt)
Definition: tablecmds.c:3222
Oid relrewrite
Definition: pg_class.h:70
#define OidFunctionCall3(functionId, arg1, arg2, arg3)
Definition: fmgr.h:632
Oid atttypid
Definition: pg_attribute.h:49
#define lnext(lc)
Definition: pg_list.h:105
void RemoveAttrDefaultById(Oid attrdefId)
Definition: heap.c:1717
#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:2096
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:506
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:367
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:2702
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
Oid reloftype
Definition: pg_class.h:35
#define InvalidMultiXactId
Definition: multixact.h:23
static struct @131 value
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
Definition: objectaccess.h:147
TupleDesc rd_att
Definition: rel.h:85
#define BoolGetDatum(X)
Definition: postgres.h:387
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:3493
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:3316
#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:3096
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
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Definition: syscache.c:1248
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4260
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:401
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:534
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1241
void RemoveStatistics(Oid relid, AttrNumber attnum)
Definition: heap.c:3008
static Datum values[MAXATTR]
Definition: bootstrap.c:164
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:372
FormData_pg_class * Form_pg_class
Definition: pg_class.h:93
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:173
#define AccessExclusiveLock
Definition: lockdefs.h:45
#define Int32GetDatum(X)
Definition: postgres.h:464
void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_attribute, CatalogIndexState indstate)
Definition: heap.c:604
void RemovePartitionKeyByRelId(Oid relid)
Definition: heap.c:3462
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:4339
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:1663
#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:707
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:1790
#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:2459
#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:2270
List * heap_truncate_find_FKs(List *relationIds)
Definition: heap.c:3266
Acl * get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid)
Definition: aclchk.c:5451
#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:3055
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)