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