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