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