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