PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
tablecmds.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * tablecmds.c
4  * Commands for creating and altering table structures and settings
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/commands/tablecmds.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "access/genam.h"
18 #include "access/heapam.h"
19 #include "access/multixact.h"
20 #include "access/reloptions.h"
21 #include "access/relscan.h"
22 #include "access/sysattr.h"
23 #include "access/tupconvert.h"
24 #include "access/xact.h"
25 #include "access/xlog.h"
26 #include "catalog/catalog.h"
27 #include "catalog/dependency.h"
28 #include "catalog/heap.h"
29 #include "catalog/index.h"
30 #include "catalog/indexing.h"
31 #include "catalog/namespace.h"
32 #include "catalog/objectaccess.h"
33 #include "catalog/partition.h"
34 #include "catalog/pg_am.h"
35 #include "catalog/pg_collation.h"
36 #include "catalog/pg_constraint.h"
38 #include "catalog/pg_depend.h"
40 #include "catalog/pg_inherits.h"
41 #include "catalog/pg_inherits_fn.h"
42 #include "catalog/pg_namespace.h"
43 #include "catalog/pg_opclass.h"
44 #include "catalog/pg_tablespace.h"
45 #include "catalog/pg_trigger.h"
46 #include "catalog/pg_type.h"
47 #include "catalog/pg_type_fn.h"
48 #include "catalog/storage.h"
49 #include "catalog/storage_xlog.h"
50 #include "catalog/toasting.h"
51 #include "commands/cluster.h"
52 #include "commands/comment.h"
53 #include "commands/defrem.h"
54 #include "commands/event_trigger.h"
55 #include "commands/policy.h"
56 #include "commands/sequence.h"
57 #include "commands/tablecmds.h"
58 #include "commands/tablespace.h"
59 #include "commands/trigger.h"
60 #include "commands/typecmds.h"
61 #include "commands/user.h"
62 #include "executor/executor.h"
63 #include "foreign/foreign.h"
64 #include "miscadmin.h"
65 #include "nodes/makefuncs.h"
66 #include "nodes/nodeFuncs.h"
67 #include "nodes/parsenodes.h"
68 #include "optimizer/clauses.h"
69 #include "optimizer/planner.h"
70 #include "optimizer/predtest.h"
71 #include "optimizer/prep.h"
72 #include "optimizer/var.h"
73 #include "parser/parse_clause.h"
74 #include "parser/parse_coerce.h"
75 #include "parser/parse_collate.h"
76 #include "parser/parse_expr.h"
77 #include "parser/parse_oper.h"
78 #include "parser/parse_relation.h"
79 #include "parser/parse_type.h"
80 #include "parser/parse_utilcmd.h"
81 #include "parser/parser.h"
82 #include "pgstat.h"
83 #include "rewrite/rewriteDefine.h"
84 #include "rewrite/rewriteHandler.h"
85 #include "rewrite/rewriteManip.h"
86 #include "storage/bufmgr.h"
87 #include "storage/lmgr.h"
88 #include "storage/lock.h"
89 #include "storage/predicate.h"
90 #include "storage/smgr.h"
91 #include "utils/acl.h"
92 #include "utils/builtins.h"
93 #include "utils/fmgroids.h"
94 #include "utils/inval.h"
95 #include "utils/lsyscache.h"
96 #include "utils/memutils.h"
97 #include "utils/relcache.h"
98 #include "utils/ruleutils.h"
99 #include "utils/snapmgr.h"
100 #include "utils/syscache.h"
101 #include "utils/tqual.h"
102 #include "utils/typcache.h"
103 
104 
105 /*
106  * ON COMMIT action list
107  */
108 typedef struct OnCommitItem
109 {
110  Oid relid; /* relid of relation */
111  OnCommitAction oncommit; /* what to do at end of xact */
112 
113  /*
114  * If this entry was created during the current transaction,
115  * creating_subid is the ID of the creating subxact; if created in a prior
116  * transaction, creating_subid is zero. If deleted during the current
117  * transaction, deleting_subid is the ID of the deleting subxact; if no
118  * deletion request is pending, deleting_subid is zero.
119  */
122 } OnCommitItem;
123 
124 static List *on_commits = NIL;
125 
126 
127 /*
128  * State information for ALTER TABLE
129  *
130  * The pending-work queue for an ALTER TABLE is a List of AlteredTableInfo
131  * structs, one for each table modified by the operation (the named table
132  * plus any child tables that are affected). We save lists of subcommands
133  * to apply to this table (possibly modified by parse transformation steps);
134  * these lists will be executed in Phase 2. If a Phase 3 step is needed,
135  * necessary information is stored in the constraints and newvals lists.
136  *
137  * Phase 2 is divided into multiple passes; subcommands are executed in
138  * a pass determined by subcommand type.
139  */
140 
141 #define AT_PASS_UNSET -1 /* UNSET will cause ERROR */
142 #define AT_PASS_DROP 0 /* DROP (all flavors) */
143 #define AT_PASS_ALTER_TYPE 1 /* ALTER COLUMN TYPE */
144 #define AT_PASS_OLD_INDEX 2 /* re-add existing indexes */
145 #define AT_PASS_OLD_CONSTR 3 /* re-add existing constraints */
146 #define AT_PASS_COL_ATTRS 4 /* set other column attributes */
147 /* We could support a RENAME COLUMN pass here, but not currently used */
148 #define AT_PASS_ADD_COL 5 /* ADD COLUMN */
149 #define AT_PASS_ADD_INDEX 6 /* ADD indexes */
150 #define AT_PASS_ADD_CONSTR 7 /* ADD constraints, defaults */
151 #define AT_PASS_MISC 8 /* other stuff */
152 #define AT_NUM_PASSES 9
153 
154 typedef struct AlteredTableInfo
155 {
156  /* Information saved before any work commences: */
157  Oid relid; /* Relation to work on */
158  char relkind; /* Its relkind */
159  TupleDesc oldDesc; /* Pre-modification tuple descriptor */
160  /* Information saved by Phase 1 for Phase 2: */
161  List *subcmds[AT_NUM_PASSES]; /* Lists of AlterTableCmd */
162  /* Information saved by Phases 1/2 for Phase 3: */
163  List *constraints; /* List of NewConstraint */
164  List *newvals; /* List of NewColumnValue */
165  bool new_notnull; /* T if we added new NOT NULL constraints */
166  int rewrite; /* Reason for forced rewrite, if any */
167  Oid newTableSpace; /* new tablespace; 0 means no change */
168  bool chgPersistence; /* T if SET LOGGED/UNLOGGED is used */
169  char newrelpersistence; /* if above is true */
170  Expr *partition_constraint; /* for attach partition validation */
171  /* true, if validating default due to some other attach/detach */
173  /* Objects to rebuild after completing ALTER TYPE operations */
174  List *changedConstraintOids; /* OIDs of constraints to rebuild */
175  List *changedConstraintDefs; /* string definitions of same */
176  List *changedIndexOids; /* OIDs of indexes to rebuild */
177  List *changedIndexDefs; /* string definitions of same */
179 
180 /* Struct describing one new constraint to check in Phase 3 scan */
181 /* Note: new NOT NULL constraints are handled elsewhere */
182 typedef struct NewConstraint
183 {
184  char *name; /* Constraint name, or NULL if none */
185  ConstrType contype; /* CHECK or FOREIGN */
186  Oid refrelid; /* PK rel, if FOREIGN */
187  Oid refindid; /* OID of PK's index, if FOREIGN */
188  Oid conid; /* OID of pg_constraint entry, if FOREIGN */
189  Node *qual; /* Check expr or CONSTR_FOREIGN Constraint */
190  ExprState *qualstate; /* Execution state for CHECK expr */
191 } NewConstraint;
192 
193 /*
194  * Struct describing one new column value that needs to be computed during
195  * Phase 3 copy (this could be either a new column with a non-null default, or
196  * a column that we're changing the type of). Columns without such an entry
197  * are just copied from the old table during ATRewriteTable. Note that the
198  * expr is an expression over *old* table values.
199  */
200 typedef struct NewColumnValue
201 {
202  AttrNumber attnum; /* which column */
203  Expr *expr; /* expression to compute */
204  ExprState *exprstate; /* execution state */
206 
207 /*
208  * Error-reporting support for RemoveRelations
209  */
211 {
212  char kind;
214  const char *nonexistent_msg;
215  const char *skipping_msg;
216  const char *nota_msg;
217  const char *drophint_msg;
218 };
219 
220 static const struct dropmsgstrings dropmsgstringarray[] = {
223  gettext_noop("table \"%s\" does not exist"),
224  gettext_noop("table \"%s\" does not exist, skipping"),
225  gettext_noop("\"%s\" is not a table"),
226  gettext_noop("Use DROP TABLE to remove a table.")},
229  gettext_noop("sequence \"%s\" does not exist"),
230  gettext_noop("sequence \"%s\" does not exist, skipping"),
231  gettext_noop("\"%s\" is not a sequence"),
232  gettext_noop("Use DROP SEQUENCE to remove a sequence.")},
233  {RELKIND_VIEW,
235  gettext_noop("view \"%s\" does not exist"),
236  gettext_noop("view \"%s\" does not exist, skipping"),
237  gettext_noop("\"%s\" is not a view"),
238  gettext_noop("Use DROP VIEW to remove a view.")},
241  gettext_noop("materialized view \"%s\" does not exist"),
242  gettext_noop("materialized view \"%s\" does not exist, skipping"),
243  gettext_noop("\"%s\" is not a materialized view"),
244  gettext_noop("Use DROP MATERIALIZED VIEW to remove a materialized view.")},
245  {RELKIND_INDEX,
246  ERRCODE_UNDEFINED_OBJECT,
247  gettext_noop("index \"%s\" does not exist"),
248  gettext_noop("index \"%s\" does not exist, skipping"),
249  gettext_noop("\"%s\" is not an index"),
250  gettext_noop("Use DROP INDEX to remove an index.")},
252  ERRCODE_UNDEFINED_OBJECT,
253  gettext_noop("type \"%s\" does not exist"),
254  gettext_noop("type \"%s\" does not exist, skipping"),
255  gettext_noop("\"%s\" is not a type"),
256  gettext_noop("Use DROP TYPE to remove a type.")},
258  ERRCODE_UNDEFINED_OBJECT,
259  gettext_noop("foreign table \"%s\" does not exist"),
260  gettext_noop("foreign table \"%s\" does not exist, skipping"),
261  gettext_noop("\"%s\" is not a foreign table"),
262  gettext_noop("Use DROP FOREIGN TABLE to remove a foreign table.")},
265  gettext_noop("table \"%s\" does not exist"),
266  gettext_noop("table \"%s\" does not exist, skipping"),
267  gettext_noop("\"%s\" is not a table"),
268  gettext_noop("Use DROP TABLE to remove a table.")},
269  {'\0', 0, NULL, NULL, NULL, NULL}
270 };
271 
273 {
274  char relkind;
278 };
279 
280 /* Alter table target-type flags for ATSimplePermissions */
281 #define ATT_TABLE 0x0001
282 #define ATT_VIEW 0x0002
283 #define ATT_MATVIEW 0x0004
284 #define ATT_INDEX 0x0008
285 #define ATT_COMPOSITE_TYPE 0x0010
286 #define ATT_FOREIGN_TABLE 0x0020
287 
288 /*
289  * Partition tables are expected to be dropped when the parent partitioned
290  * table gets dropped. Hence for partitioning we use AUTO dependency.
291  * Otherwise, for regular inheritance use NORMAL dependency.
292  */
293 #define child_dependency_type(child_is_partition) \
294  ((child_is_partition) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL)
295 
296 static void truncate_check_rel(Relation rel);
297 static List *MergeAttributes(List *schema, List *supers, char relpersistence,
298  bool is_partition, List **supOids, List **supconstr,
299  int *supOidCount);
300 static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
301 static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
302 static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
303 static void StoreCatalogInheritance(Oid relationId, List *supers,
304  bool child_is_partition);
305 static void StoreCatalogInheritance1(Oid relationId, Oid parentOid,
306  int16 seqNumber, Relation inhRelation,
307  bool child_is_partition);
308 static int findAttrByName(const char *attributeName, List *schema);
309 static void AlterIndexNamespaces(Relation classRel, Relation rel,
310  Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved);
311 static void AlterSeqNamespaces(Relation classRel, Relation rel,
312  Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved,
313  LOCKMODE lockmode);
315  bool recurse, bool recursing, LOCKMODE lockmode);
316 static ObjectAddress ATExecValidateConstraint(Relation rel, char *constrName,
317  bool recurse, bool recursing, LOCKMODE lockmode);
318 static int transformColumnNameList(Oid relId, List *colList,
319  int16 *attnums, Oid *atttypids);
320 static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
321  List **attnamelist,
322  int16 *attnums, Oid *atttypids,
323  Oid *opclasses);
325  int numattrs, int16 *attnums,
326  Oid *opclasses);
327 static void checkFkeyPermissions(Relation rel, int16 *attnums, int natts);
328 static CoercionPathType findFkeyCast(Oid targetTypeId, Oid sourceTypeId,
329  Oid *funcid);
330 static void validateCheckConstraint(Relation rel, HeapTuple constrtup);
331 static void validateForeignKeyConstraint(char *conname,
332  Relation rel, Relation pkrel,
333  Oid pkindOid, Oid constraintOid);
334 static void createForeignKeyTriggers(Relation rel, Oid refRelOid,
335  Constraint *fkconstraint,
336  Oid constraintOid, Oid indexOid);
337 static void ATController(AlterTableStmt *parsetree,
338  Relation rel, List *cmds, bool recurse, LOCKMODE lockmode);
339 static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
340  bool recurse, bool recursing, LOCKMODE lockmode);
341 static void ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode);
342 static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
343  AlterTableCmd *cmd, LOCKMODE lockmode);
344 static void ATRewriteTables(AlterTableStmt *parsetree,
345  List **wqueue, LOCKMODE lockmode);
346 static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode);
347 static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel);
348 static void ATSimplePermissions(Relation rel, int allowed_targets);
349 static void ATWrongRelkindError(Relation rel, int allowed_targets);
350 static void ATSimpleRecursion(List **wqueue, Relation rel,
351  AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode);
352 static void ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
353  LOCKMODE lockmode);
354 static List *find_typed_table_dependencies(Oid typeOid, const char *typeName,
355  DropBehavior behavior);
356 static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
357  bool is_view, AlterTableCmd *cmd, LOCKMODE lockmode);
358 static ObjectAddress ATExecAddColumn(List **wqueue, AlteredTableInfo *tab,
359  Relation rel, ColumnDef *colDef, bool isOid,
360  bool recurse, bool recursing,
361  bool if_not_exists, LOCKMODE lockmode);
362 static bool check_for_column_name_collision(Relation rel, const char *colname,
363  bool if_not_exists);
364 static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid);
365 static void add_column_collation_dependency(Oid relid, int32 attnum, Oid collid);
366 static void ATPrepAddOids(List **wqueue, Relation rel, bool recurse,
367  AlterTableCmd *cmd, LOCKMODE lockmode);
368 static void ATPrepDropNotNull(Relation rel, bool recurse, bool recursing);
369 static ObjectAddress ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode);
370 static void ATPrepSetNotNull(Relation rel, bool recurse, bool recursing);
372  const char *colName, LOCKMODE lockmode);
373 static ObjectAddress ATExecColumnDefault(Relation rel, const char *colName,
374  Node *newDefault, LOCKMODE lockmode);
375 static ObjectAddress ATExecAddIdentity(Relation rel, const char *colName,
376  Node *def, LOCKMODE lockmode);
377 static ObjectAddress ATExecSetIdentity(Relation rel, const char *colName,
378  Node *def, LOCKMODE lockmode);
379 static ObjectAddress ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE lockmode);
380 static void ATPrepSetStatistics(Relation rel, const char *colName, int16 colNum,
381  Node *newValue, LOCKMODE lockmode);
382 static ObjectAddress ATExecSetStatistics(Relation rel, const char *colName, int16 colNum,
383  Node *newValue, LOCKMODE lockmode);
384 static ObjectAddress ATExecSetOptions(Relation rel, const char *colName,
385  Node *options, bool isReset, LOCKMODE lockmode);
386 static ObjectAddress ATExecSetStorage(Relation rel, const char *colName,
387  Node *newValue, LOCKMODE lockmode);
388 static void ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
389  AlterTableCmd *cmd, LOCKMODE lockmode);
390 static ObjectAddress ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
391  DropBehavior behavior,
392  bool recurse, bool recursing,
393  bool missing_ok, LOCKMODE lockmode);
395  IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode);
396 static ObjectAddress ATExecAddConstraint(List **wqueue,
397  AlteredTableInfo *tab, Relation rel,
398  Constraint *newConstraint, bool recurse, bool is_readd,
399  LOCKMODE lockmode);
401  IndexStmt *stmt, LOCKMODE lockmode);
402 static ObjectAddress ATAddCheckConstraint(List **wqueue,
403  AlteredTableInfo *tab, Relation rel,
404  Constraint *constr,
405  bool recurse, bool recursing, bool is_readd,
406  LOCKMODE lockmode);
408  Constraint *fkconstraint, LOCKMODE lockmode);
409 static void ATExecDropConstraint(Relation rel, const char *constrName,
410  DropBehavior behavior,
411  bool recurse, bool recursing,
412  bool missing_ok, LOCKMODE lockmode);
413 static void ATPrepAlterColumnType(List **wqueue,
414  AlteredTableInfo *tab, Relation rel,
415  bool recurse, bool recursing,
416  AlterTableCmd *cmd, LOCKMODE lockmode);
417 static bool ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno);
419  AlterTableCmd *cmd, LOCKMODE lockmode);
420 static ObjectAddress ATExecAlterColumnGenericOptions(Relation rel, const char *colName,
421  List *options, LOCKMODE lockmode);
422 static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab,
423  LOCKMODE lockmode);
424 static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId,
425  char *cmd, List **wqueue, LOCKMODE lockmode,
426  bool rewrite);
427 static void RebuildConstraintComment(AlteredTableInfo *tab, int pass,
428  Oid objid, Relation rel, char *conname);
429 static void TryReuseIndex(Oid oldId, IndexStmt *stmt);
430 static void TryReuseForeignKey(Oid oldId, Constraint *con);
431 static void change_owner_fix_column_acls(Oid relationOid,
432  Oid oldOwnerId, Oid newOwnerId);
433 static void change_owner_recurse_to_sequences(Oid relationOid,
434  Oid newOwnerId, LOCKMODE lockmode);
435 static ObjectAddress ATExecClusterOn(Relation rel, const char *indexName,
436  LOCKMODE lockmode);
437 static void ATExecDropCluster(Relation rel, LOCKMODE lockmode);
438 static bool ATPrepChangePersistence(Relation rel, bool toLogged);
439 static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
440  char *tablespacename, LOCKMODE lockmode);
441 static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode);
442 static void ATExecSetRelOptions(Relation rel, List *defList,
443  AlterTableType operation,
444  LOCKMODE lockmode);
445 static void ATExecEnableDisableTrigger(Relation rel, char *trigname,
446  char fires_when, bool skip_system, LOCKMODE lockmode);
447 static void ATExecEnableDisableRule(Relation rel, char *rulename,
448  char fires_when, LOCKMODE lockmode);
449 static void ATPrepAddInherit(Relation child_rel);
450 static ObjectAddress ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode);
451 static ObjectAddress ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode);
452 static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid,
453  DependencyType deptype);
454 static ObjectAddress ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode);
455 static void ATExecDropOf(Relation rel, LOCKMODE lockmode);
456 static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode);
457 static void ATExecGenericOptions(Relation rel, List *options);
458 static void ATExecEnableRowSecurity(Relation rel);
459 static void ATExecDisableRowSecurity(Relation rel);
460 static void ATExecForceNoForceRowSecurity(Relation rel, bool force_rls);
461 
462 static void copy_relation_data(SMgrRelation rel, SMgrRelation dst,
463  ForkNumber forkNum, char relpersistence);
464 static const char *storage_name(char c);
465 
466 static void RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid,
467  Oid oldRelOid, void *arg);
468 static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid,
469  Oid oldrelid, void *arg);
470 static bool is_partition_attr(Relation rel, AttrNumber attnum, bool *used_in_expr);
471 static PartitionSpec *transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy);
472 static void ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs,
473  List **partexprs, Oid *partopclass, Oid *partcollation);
474 static void CreateInheritance(Relation child_rel, Relation parent_rel);
475 static void RemoveInheritance(Relation child_rel, Relation parent_rel);
476 static ObjectAddress ATExecAttachPartition(List **wqueue, Relation rel,
477  PartitionCmd *cmd);
478 static void ValidatePartitionConstraints(List **wqueue, Relation scanrel,
479  List *scanrel_children,
480  List *partConstraint,
481  bool validate_default);
483 
484 
485 /* ----------------------------------------------------------------
486  * DefineRelation
487  * Creates a new relation.
488  *
489  * stmt carries parsetree information from an ordinary CREATE TABLE statement.
490  * The other arguments are used to extend the behavior for other cases:
491  * relkind: relkind to assign to the new relation
492  * ownerId: if not InvalidOid, use this as the new relation's owner.
493  * typaddress: if not null, it's set to the pg_type entry's address.
494  *
495  * Note that permissions checks are done against current user regardless of
496  * ownerId. A nonzero ownerId is used when someone is creating a relation
497  * "on behalf of" someone else, so we still want to see that the current user
498  * has permissions to do it.
499  *
500  * If successful, returns the address of the new relation.
501  * ----------------------------------------------------------------
502  */
504 DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
505  ObjectAddress *typaddress, const char *queryString)
506 {
507  char relname[NAMEDATALEN];
508  Oid namespaceId;
509  Oid relationId;
510  Oid tablespaceId;
511  Relation rel;
513  List *inheritOids;
514  List *old_constraints;
515  bool localHasOids;
516  int parentOidCount;
517  List *rawDefaults;
518  List *cookedDefaults;
519  Datum reloptions;
520  ListCell *listptr;
521  AttrNumber attnum;
522  static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
523  Oid ofTypeId;
524  ObjectAddress address;
525 
526  /*
527  * Truncate relname to appropriate length (probably a waste of time, as
528  * parser should have done this already).
529  */
530  StrNCpy(relname, stmt->relation->relname, NAMEDATALEN);
531 
532  /*
533  * Check consistency of arguments
534  */
535  if (stmt->oncommit != ONCOMMIT_NOOP
537  ereport(ERROR,
538  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
539  errmsg("ON COMMIT can only be used on temporary tables")));
540 
541  if (stmt->partspec != NULL)
542  {
543  if (relkind != RELKIND_RELATION)
544  elog(ERROR, "unexpected relkind: %d", (int) relkind);
545 
546  relkind = RELKIND_PARTITIONED_TABLE;
547  }
548 
549  /*
550  * Look up the namespace in which we are supposed to create the relation,
551  * check we have permission to create there, lock it against concurrent
552  * drop, and mark stmt->relation as RELPERSISTENCE_TEMP if a temporary
553  * namespace is selected.
554  */
555  namespaceId =
557 
558  /*
559  * Security check: disallow creating temp tables from security-restricted
560  * code. This is needed because calling code might not expect untrusted
561  * tables to appear in pg_temp at the front of its search path.
562  */
565  ereport(ERROR,
566  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
567  errmsg("cannot create temporary table within security-restricted operation")));
568 
569  /*
570  * Select tablespace to use. If not specified, use default tablespace
571  * (which may in turn default to database's default).
572  */
573  if (stmt->tablespacename)
574  {
575  tablespaceId = get_tablespace_oid(stmt->tablespacename, false);
576  }
577  else
578  {
579  tablespaceId = GetDefaultTablespace(stmt->relation->relpersistence);
580  /* note InvalidOid is OK in this case */
581  }
582 
583  /* Check permissions except when using database's default */
584  if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace)
585  {
586  AclResult aclresult;
587 
588  aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
589  ACL_CREATE);
590  if (aclresult != ACLCHECK_OK)
592  get_tablespace_name(tablespaceId));
593  }
594 
595  /* In all cases disallow placing user relations in pg_global */
596  if (tablespaceId == GLOBALTABLESPACE_OID)
597  ereport(ERROR,
598  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
599  errmsg("only shared relations can be placed in pg_global tablespace")));
600 
601  /* Identify user ID that will own the table */
602  if (!OidIsValid(ownerId))
603  ownerId = GetUserId();
604 
605  /*
606  * Parse and validate reloptions, if any.
607  */
608  reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps,
609  true, false);
610 
611  if (relkind == RELKIND_VIEW)
612  (void) view_reloptions(reloptions, true);
613  else
614  (void) heap_reloptions(relkind, reloptions, true);
615 
616  if (stmt->ofTypename)
617  {
618  AclResult aclresult;
619 
620  ofTypeId = typenameTypeId(NULL, stmt->ofTypename);
621 
622  aclresult = pg_type_aclcheck(ofTypeId, GetUserId(), ACL_USAGE);
623  if (aclresult != ACLCHECK_OK)
624  aclcheck_error_type(aclresult, ofTypeId);
625  }
626  else
627  ofTypeId = InvalidOid;
628 
629  /*
630  * Look up inheritance ancestors and generate relation schema, including
631  * inherited attributes. (Note that stmt->tableElts is destructively
632  * modified by MergeAttributes.)
633  */
634  stmt->tableElts =
636  stmt->relation->relpersistence,
637  stmt->partbound != NULL,
638  &inheritOids, &old_constraints, &parentOidCount);
639 
640  /*
641  * Create a tuple descriptor from the relation schema. Note that this
642  * deals with column names, types, and NOT NULL constraints, but not
643  * default values or CHECK constraints; we handle those below.
644  */
645  descriptor = BuildDescForRelation(stmt->tableElts);
646 
647  /*
648  * Notice that we allow OIDs here only for plain tables and partitioned
649  * tables, even though some other relkinds can support them. This is
650  * necessary because the default_with_oids GUC must apply only to plain
651  * tables and not any other relkind; doing otherwise would break existing
652  * pg_dump files. We could allow explicit "WITH OIDS" while not allowing
653  * default_with_oids to affect other relkinds, but it would complicate
654  * interpretOidsOption().
655  */
656  localHasOids = interpretOidsOption(stmt->options,
657  (relkind == RELKIND_RELATION ||
658  relkind == RELKIND_PARTITIONED_TABLE));
659  descriptor->tdhasoid = (localHasOids || parentOidCount > 0);
660 
661  /*
662  * If a partitioned table doesn't have the system OID column, then none of
663  * its partitions should have it.
664  */
665  if (stmt->partbound && parentOidCount == 0 && localHasOids)
666  ereport(ERROR,
667  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
668  errmsg("cannot create table with OIDs as partition of table without OIDs")));
669 
670  /*
671  * Find columns with default values and prepare for insertion of the
672  * defaults. Pre-cooked (that is, inherited) defaults go into a list of
673  * CookedConstraint structs that we'll pass to heap_create_with_catalog,
674  * while raw defaults go into a list of RawColumnDefault structs that will
675  * be processed by AddRelationNewConstraints. (We can't deal with raw
676  * expressions until we can do transformExpr.)
677  *
678  * We can set the atthasdef flags now in the tuple descriptor; this just
679  * saves StoreAttrDefault from having to do an immediate update of the
680  * pg_attribute rows.
681  */
682  rawDefaults = NIL;
683  cookedDefaults = NIL;
684  attnum = 0;
685 
686  foreach(listptr, stmt->tableElts)
687  {
688  ColumnDef *colDef = lfirst(listptr);
689  Form_pg_attribute attr;
690 
691  attnum++;
692  attr = TupleDescAttr(descriptor, attnum - 1);
693 
694  if (colDef->raw_default != NULL)
695  {
696  RawColumnDefault *rawEnt;
697 
698  Assert(colDef->cooked_default == NULL);
699 
700  rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
701  rawEnt->attnum = attnum;
702  rawEnt->raw_default = colDef->raw_default;
703  rawDefaults = lappend(rawDefaults, rawEnt);
704  attr->atthasdef = true;
705  }
706  else if (colDef->cooked_default != NULL)
707  {
708  CookedConstraint *cooked;
709 
710  cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
711  cooked->contype = CONSTR_DEFAULT;
712  cooked->conoid = InvalidOid; /* until created */
713  cooked->name = NULL;
714  cooked->attnum = attnum;
715  cooked->expr = colDef->cooked_default;
716  cooked->skip_validation = false;
717  cooked->is_local = true; /* not used for defaults */
718  cooked->inhcount = 0; /* ditto */
719  cooked->is_no_inherit = false;
720  cookedDefaults = lappend(cookedDefaults, cooked);
721  attr->atthasdef = true;
722  }
723 
724  if (colDef->identity)
725  attr->attidentity = colDef->identity;
726  }
727 
728  /*
729  * Create the relation. Inherited defaults and constraints are passed in
730  * for immediate handling --- since they don't need parsing, they can be
731  * stored immediately.
732  */
733  relationId = heap_create_with_catalog(relname,
734  namespaceId,
735  tablespaceId,
736  InvalidOid,
737  InvalidOid,
738  ofTypeId,
739  ownerId,
740  descriptor,
741  list_concat(cookedDefaults,
742  old_constraints),
743  relkind,
744  stmt->relation->relpersistence,
745  false,
746  false,
747  localHasOids,
748  parentOidCount,
749  stmt->oncommit,
750  reloptions,
751  true,
753  false,
754  typaddress);
755 
756  /* Store inheritance information for new rel. */
757  StoreCatalogInheritance(relationId, inheritOids, stmt->partbound != NULL);
758 
759  /*
760  * We must bump the command counter to make the newly-created relation
761  * tuple visible for opening.
762  */
764 
765  /*
766  * Open the new relation and acquire exclusive lock on it. This isn't
767  * really necessary for locking out other backends (since they can't see
768  * the new rel anyway until we commit), but it keeps the lock manager from
769  * complaining about deadlock risks.
770  */
771  rel = relation_open(relationId, AccessExclusiveLock);
772 
773  /* Process and store partition bound, if any. */
774  if (stmt->partbound)
775  {
776  PartitionBoundSpec *bound;
777  ParseState *pstate;
778  Oid parentId = linitial_oid(inheritOids),
779  defaultPartOid;
780  Relation parent,
781  defaultRel = NULL;
782 
783  /* Already have strong enough lock on the parent */
784  parent = heap_open(parentId, NoLock);
785 
786  /*
787  * We are going to try to validate the partition bound specification
788  * against the partition key of parentRel, so it better have one.
789  */
790  if (parent->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
791  ereport(ERROR,
792  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
793  errmsg("\"%s\" is not partitioned",
794  RelationGetRelationName(parent))));
795 
796  /*
797  * The partition constraint of the default partition depends on the
798  * partition bounds of every other partition. It is possible that
799  * another backend might be about to execute a query on the default
800  * partition table, and that the query relies on previously cached
801  * default partition constraints. We must therefore take a table lock
802  * strong enough to prevent all queries on the default partition from
803  * proceeding until we commit and send out a shared-cache-inval notice
804  * that will make them update their index lists.
805  *
806  * Order of locking: The relation being added won't be visible to
807  * other backends until it is committed, hence here in
808  * DefineRelation() the order of locking the default partition and the
809  * relation being added does not matter. But at all other places we
810  * need to lock the default relation before we lock the relation being
811  * added or removed i.e. we should take the lock in same order at all
812  * the places such that lock parent, lock default partition and then
813  * lock the partition so as to avoid a deadlock.
814  */
815  defaultPartOid =
817  if (OidIsValid(defaultPartOid))
818  defaultRel = heap_open(defaultPartOid, AccessExclusiveLock);
819 
820  /* Tranform the bound values */
821  pstate = make_parsestate(NULL);
822  pstate->p_sourcetext = queryString;
823 
824  bound = transformPartitionBound(pstate, parent, stmt->partbound);
825 
826  /*
827  * Check first that the new partition's bound is valid and does not
828  * overlap with any of existing partitions of the parent.
829  */
830  check_new_partition_bound(relname, parent, bound);
831 
832  /*
833  * If the default partition exists, its partition constraints will
834  * change after the addition of this new partition such that it won't
835  * allow any row that qualifies for this new partition. So, check that
836  * the existing data in the default partition satisfies the constraint
837  * as it will exist after adding this partition.
838  */
839  if (OidIsValid(defaultPartOid))
840  {
841  check_default_allows_bound(parent, defaultRel, bound);
842  /* Keep the lock until commit. */
843  heap_close(defaultRel, NoLock);
844  }
845 
846  /* Update the pg_class entry. */
847  StorePartitionBound(rel, parent, bound);
848 
849  /* Update the default partition oid */
850  if (bound->is_default)
851  update_default_partition_oid(RelationGetRelid(parent), relationId);
852 
853  heap_close(parent, NoLock);
854 
855  /*
856  * The code that follows may also update the pg_class tuple to update
857  * relnumchecks, so bump up the command counter to avoid the "already
858  * updated by self" error.
859  */
861  }
862 
863  /*
864  * Process the partitioning specification (if any) and store the partition
865  * key information into the catalog.
866  */
867  if (stmt->partspec)
868  {
869  char strategy;
870  int partnatts;
871  AttrNumber partattrs[PARTITION_MAX_KEYS];
872  Oid partopclass[PARTITION_MAX_KEYS];
873  Oid partcollation[PARTITION_MAX_KEYS];
874  List *partexprs = NIL;
875 
876  partnatts = list_length(stmt->partspec->partParams);
877 
878  /* Protect fixed-size arrays here and in executor */
879  if (partnatts > PARTITION_MAX_KEYS)
880  ereport(ERROR,
881  (errcode(ERRCODE_TOO_MANY_COLUMNS),
882  errmsg("cannot partition using more than %d columns",
884 
885  /*
886  * We need to transform the raw parsetrees corresponding to partition
887  * expressions into executable expression trees. Like column defaults
888  * and CHECK constraints, we could not have done the transformation
889  * earlier.
890  */
891  stmt->partspec = transformPartitionSpec(rel, stmt->partspec,
892  &strategy);
893 
895  partattrs, &partexprs, partopclass,
896  partcollation);
897 
898  StorePartitionKey(rel, strategy, partnatts, partattrs, partexprs,
899  partopclass, partcollation);
900  }
901 
902  /*
903  * Now add any newly specified column default values and CHECK constraints
904  * to the new relation. These are passed to us in the form of raw
905  * parsetrees; we need to transform them to executable expression trees
906  * before they can be added. The most convenient way to do that is to
907  * apply the parser's transformExpr routine, but transformExpr doesn't
908  * work unless we have a pre-existing relation. So, the transformation has
909  * to be postponed to this final step of CREATE TABLE.
910  */
911  if (rawDefaults || stmt->constraints)
912  AddRelationNewConstraints(rel, rawDefaults, stmt->constraints,
913  true, true, false);
914 
915  ObjectAddressSet(address, RelationRelationId, relationId);
916 
917  /*
918  * Clean up. We keep lock on new relation (although it shouldn't be
919  * visible to anyone else anyway, until commit).
920  */
921  relation_close(rel, NoLock);
922 
923  return address;
924 }
925 
926 /*
927  * Emit the right error or warning message for a "DROP" command issued on a
928  * non-existent relation
929  */
930 static void
931 DropErrorMsgNonExistent(RangeVar *rel, char rightkind, bool missing_ok)
932 {
933  const struct dropmsgstrings *rentry;
934 
935  if (rel->schemaname != NULL &&
937  {
938  if (!missing_ok)
939  {
940  ereport(ERROR,
941  (errcode(ERRCODE_UNDEFINED_SCHEMA),
942  errmsg("schema \"%s\" does not exist", rel->schemaname)));
943  }
944  else
945  {
946  ereport(NOTICE,
947  (errmsg("schema \"%s\" does not exist, skipping",
948  rel->schemaname)));
949  }
950  return;
951  }
952 
953  for (rentry = dropmsgstringarray; rentry->kind != '\0'; rentry++)
954  {
955  if (rentry->kind == rightkind)
956  {
957  if (!missing_ok)
958  {
959  ereport(ERROR,
960  (errcode(rentry->nonexistent_code),
961  errmsg(rentry->nonexistent_msg, rel->relname)));
962  }
963  else
964  {
965  ereport(NOTICE, (errmsg(rentry->skipping_msg, rel->relname)));
966  break;
967  }
968  }
969  }
970 
971  Assert(rentry->kind != '\0'); /* Should be impossible */
972 }
973 
974 /*
975  * Emit the right error message for a "DROP" command issued on a
976  * relation of the wrong type
977  */
978 static void
979 DropErrorMsgWrongType(const char *relname, char wrongkind, char rightkind)
980 {
981  const struct dropmsgstrings *rentry;
982  const struct dropmsgstrings *wentry;
983 
984  for (rentry = dropmsgstringarray; rentry->kind != '\0'; rentry++)
985  if (rentry->kind == rightkind)
986  break;
987  Assert(rentry->kind != '\0');
988 
989  for (wentry = dropmsgstringarray; wentry->kind != '\0'; wentry++)
990  if (wentry->kind == wrongkind)
991  break;
992  /* wrongkind could be something we don't have in our table... */
993 
994  ereport(ERROR,
995  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
996  errmsg(rentry->nota_msg, relname),
997  (wentry->kind != '\0') ? errhint("%s", _(wentry->drophint_msg)) : 0));
998 }
999 
1000 /*
1001  * RemoveRelations
1002  * Implements DROP TABLE, DROP INDEX, DROP SEQUENCE, DROP VIEW,
1003  * DROP MATERIALIZED VIEW, DROP FOREIGN TABLE
1004  */
1005 void
1007 {
1008  ObjectAddresses *objects;
1009  char relkind;
1010  ListCell *cell;
1011  int flags = 0;
1012  LOCKMODE lockmode = AccessExclusiveLock;
1013 
1014  /* DROP CONCURRENTLY uses a weaker lock, and has some restrictions */
1015  if (drop->concurrent)
1016  {
1018  lockmode = ShareUpdateExclusiveLock;
1019  Assert(drop->removeType == OBJECT_INDEX);
1020  if (list_length(drop->objects) != 1)
1021  ereport(ERROR,
1022  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1023  errmsg("DROP INDEX CONCURRENTLY does not support dropping multiple objects")));
1024  if (drop->behavior == DROP_CASCADE)
1025  ereport(ERROR,
1026  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1027  errmsg("DROP INDEX CONCURRENTLY does not support CASCADE")));
1028  }
1029 
1030  /*
1031  * First we identify all the relations, then we delete them in a single
1032  * performMultipleDeletions() call. This is to avoid unwanted DROP
1033  * RESTRICT errors if one of the relations depends on another.
1034  */
1035 
1036  /* Determine required relkind */
1037  switch (drop->removeType)
1038  {
1039  case OBJECT_TABLE:
1040  relkind = RELKIND_RELATION;
1041  break;
1042 
1043  case OBJECT_INDEX:
1044  relkind = RELKIND_INDEX;
1045  break;
1046 
1047  case OBJECT_SEQUENCE:
1048  relkind = RELKIND_SEQUENCE;
1049  break;
1050 
1051  case OBJECT_VIEW:
1052  relkind = RELKIND_VIEW;
1053  break;
1054 
1055  case OBJECT_MATVIEW:
1056  relkind = RELKIND_MATVIEW;
1057  break;
1058 
1059  case OBJECT_FOREIGN_TABLE:
1060  relkind = RELKIND_FOREIGN_TABLE;
1061  break;
1062 
1063  default:
1064  elog(ERROR, "unrecognized drop object type: %d",
1065  (int) drop->removeType);
1066  relkind = 0; /* keep compiler quiet */
1067  break;
1068  }
1069 
1070  /* Lock and validate each relation; build a list of object addresses */
1071  objects = new_object_addresses();
1072 
1073  foreach(cell, drop->objects)
1074  {
1075  RangeVar *rel = makeRangeVarFromNameList((List *) lfirst(cell));
1076  Oid relOid;
1077  ObjectAddress obj;
1078  struct DropRelationCallbackState state;
1079 
1080  /*
1081  * These next few steps are a great deal like relation_openrv, but we
1082  * don't bother building a relcache entry since we don't need it.
1083  *
1084  * Check for shared-cache-inval messages before trying to access the
1085  * relation. This is needed to cover the case where the name
1086  * identifies a rel that has been dropped and recreated since the
1087  * start of our transaction: if we don't flush the old syscache entry,
1088  * then we'll latch onto that entry and suffer an error later.
1089  */
1091 
1092  /* Look up the appropriate relation using namespace search. */
1093  state.relkind = relkind;
1094  state.heapOid = InvalidOid;
1095  state.partParentOid = InvalidOid;
1096  state.concurrent = drop->concurrent;
1097  relOid = RangeVarGetRelidExtended(rel, lockmode, true,
1098  false,
1100  (void *) &state);
1101 
1102  /* Not there? */
1103  if (!OidIsValid(relOid))
1104  {
1105  DropErrorMsgNonExistent(rel, relkind, drop->missing_ok);
1106  continue;
1107  }
1108 
1109  /* OK, we're ready to delete this one */
1111  obj.objectId = relOid;
1112  obj.objectSubId = 0;
1113 
1114  add_exact_object_address(&obj, objects);
1115  }
1116 
1117  performMultipleDeletions(objects, drop->behavior, flags);
1118 
1119  free_object_addresses(objects);
1120 }
1121 
1122 /*
1123  * Before acquiring a table lock, check whether we have sufficient rights.
1124  * In the case of DROP INDEX, also try to lock the table before the index.
1125  * Also, if the table to be dropped is a partition, we try to lock the parent
1126  * first.
1127  */
1128 static void
1129 RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid,
1130  void *arg)
1131 {
1132  HeapTuple tuple;
1134  char relkind;
1135  char expected_relkind;
1136  bool is_partition;
1137  Form_pg_class classform;
1138  LOCKMODE heap_lockmode;
1139 
1140  state = (struct DropRelationCallbackState *) arg;
1141  relkind = state->relkind;
1142  heap_lockmode = state->concurrent ?
1144 
1145  /*
1146  * If we previously locked some other index's heap, and the name we're
1147  * looking up no longer refers to that relation, release the now-useless
1148  * lock.
1149  */
1150  if (relOid != oldRelOid && OidIsValid(state->heapOid))
1151  {
1152  UnlockRelationOid(state->heapOid, heap_lockmode);
1153  state->heapOid = InvalidOid;
1154  }
1155 
1156  /*
1157  * Similarly, if we previously locked some other partition's heap, and the
1158  * name we're looking up no longer refers to that relation, release the
1159  * now-useless lock.
1160  */
1161  if (relOid != oldRelOid && OidIsValid(state->partParentOid))
1162  {
1164  state->partParentOid = InvalidOid;
1165  }
1166 
1167  /* Didn't find a relation, so no need for locking or permission checks. */
1168  if (!OidIsValid(relOid))
1169  return;
1170 
1171  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
1172  if (!HeapTupleIsValid(tuple))
1173  return; /* concurrently dropped, so nothing to do */
1174  classform = (Form_pg_class) GETSTRUCT(tuple);
1175  is_partition = classform->relispartition;
1176 
1177  /*
1178  * Both RELKIND_RELATION and RELKIND_PARTITIONED_TABLE are OBJECT_TABLE,
1179  * but RemoveRelations() can only pass one relkind for a given relation.
1180  * It chooses RELKIND_RELATION for both regular and partitioned tables.
1181  * That means we must be careful before giving the wrong type error when
1182  * the relation is RELKIND_PARTITIONED_TABLE.
1183  */
1184  if (classform->relkind == RELKIND_PARTITIONED_TABLE)
1185  expected_relkind = RELKIND_RELATION;
1186  else
1187  expected_relkind = classform->relkind;
1188 
1189  if (relkind != expected_relkind)
1190  DropErrorMsgWrongType(rel->relname, classform->relkind, relkind);
1191 
1192  /* Allow DROP to either table owner or schema owner */
1193  if (!pg_class_ownercheck(relOid, GetUserId()) &&
1194  !pg_namespace_ownercheck(classform->relnamespace, GetUserId()))
1196  rel->relname);
1197 
1198  if (!allowSystemTableMods && IsSystemClass(relOid, classform))
1199  ereport(ERROR,
1200  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1201  errmsg("permission denied: \"%s\" is a system catalog",
1202  rel->relname)));
1203 
1204  ReleaseSysCache(tuple);
1205 
1206  /*
1207  * In DROP INDEX, attempt to acquire lock on the parent table before
1208  * locking the index. index_drop() will need this anyway, and since
1209  * regular queries lock tables before their indexes, we risk deadlock if
1210  * we do it the other way around. No error if we don't find a pg_index
1211  * entry, though --- the relation may have been dropped.
1212  */
1213  if (relkind == RELKIND_INDEX && relOid != oldRelOid)
1214  {
1215  state->heapOid = IndexGetRelation(relOid, true);
1216  if (OidIsValid(state->heapOid))
1217  LockRelationOid(state->heapOid, heap_lockmode);
1218  }
1219 
1220  /*
1221  * Similarly, if the relation is a partition, we must acquire lock on its
1222  * parent before locking the partition. That's because queries lock the
1223  * parent before its partitions, so we risk deadlock it we do it the other
1224  * way around.
1225  */
1226  if (is_partition && relOid != oldRelOid)
1227  {
1228  state->partParentOid = get_partition_parent(relOid);
1229  if (OidIsValid(state->partParentOid))
1231  }
1232 }
1233 
1234 /*
1235  * ExecuteTruncate
1236  * Executes a TRUNCATE command.
1237  *
1238  * This is a multi-relation truncate. We first open and grab exclusive
1239  * lock on all relations involved, checking permissions and otherwise
1240  * verifying that the relation is OK for truncation. In CASCADE mode,
1241  * relations having FK references to the targeted relations are automatically
1242  * added to the group; in RESTRICT mode, we check that all FK references are
1243  * internal to the group that's being truncated. Finally all the relations
1244  * are truncated and reindexed.
1245  */
1246 void
1248 {
1249  List *rels = NIL;
1250  List *relids = NIL;
1251  List *seq_relids = NIL;
1252  EState *estate;
1253  ResultRelInfo *resultRelInfos;
1254  ResultRelInfo *resultRelInfo;
1255  SubTransactionId mySubid;
1256  ListCell *cell;
1257 
1258  /*
1259  * Open, exclusive-lock, and check all the explicitly-specified relations
1260  */
1261  foreach(cell, stmt->relations)
1262  {
1263  RangeVar *rv = lfirst(cell);
1264  Relation rel;
1265  bool recurse = rv->inh;
1266  Oid myrelid;
1267 
1268  rel = heap_openrv(rv, AccessExclusiveLock);
1269  myrelid = RelationGetRelid(rel);
1270  /* don't throw error for "TRUNCATE foo, foo" */
1271  if (list_member_oid(relids, myrelid))
1272  {
1274  continue;
1275  }
1276  truncate_check_rel(rel);
1277  rels = lappend(rels, rel);
1278  relids = lappend_oid(relids, myrelid);
1279 
1280  if (recurse)
1281  {
1282  ListCell *child;
1283  List *children;
1284 
1285  children = find_all_inheritors(myrelid, AccessExclusiveLock, NULL);
1286 
1287  foreach(child, children)
1288  {
1289  Oid childrelid = lfirst_oid(child);
1290 
1291  if (list_member_oid(relids, childrelid))
1292  continue;
1293 
1294  /* find_all_inheritors already got lock */
1295  rel = heap_open(childrelid, NoLock);
1296  truncate_check_rel(rel);
1297  rels = lappend(rels, rel);
1298  relids = lappend_oid(relids, childrelid);
1299  }
1300  }
1301  else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1302  ereport(ERROR,
1303  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1304  errmsg("cannot truncate only a partitioned table"),
1305  errhint("Do not specify the ONLY keyword, or use truncate only on the partitions directly.")));
1306  }
1307 
1308  /*
1309  * In CASCADE mode, suck in all referencing relations as well. This
1310  * requires multiple iterations to find indirectly-dependent relations. At
1311  * each phase, we need to exclusive-lock new rels before looking for their
1312  * dependencies, else we might miss something. Also, we check each rel as
1313  * soon as we open it, to avoid a faux pas such as holding lock for a long
1314  * time on a rel we have no permissions for.
1315  */
1316  if (stmt->behavior == DROP_CASCADE)
1317  {
1318  for (;;)
1319  {
1320  List *newrelids;
1321 
1322  newrelids = heap_truncate_find_FKs(relids);
1323  if (newrelids == NIL)
1324  break; /* nothing else to add */
1325 
1326  foreach(cell, newrelids)
1327  {
1328  Oid relid = lfirst_oid(cell);
1329  Relation rel;
1330 
1331  rel = heap_open(relid, AccessExclusiveLock);
1332  ereport(NOTICE,
1333  (errmsg("truncate cascades to table \"%s\"",
1334  RelationGetRelationName(rel))));
1335  truncate_check_rel(rel);
1336  rels = lappend(rels, rel);
1337  relids = lappend_oid(relids, relid);
1338  }
1339  }
1340  }
1341 
1342  /*
1343  * Check foreign key references. In CASCADE mode, this should be
1344  * unnecessary since we just pulled in all the references; but as a
1345  * cross-check, do it anyway if in an Assert-enabled build.
1346  */
1347 #ifdef USE_ASSERT_CHECKING
1348  heap_truncate_check_FKs(rels, false);
1349 #else
1350  if (stmt->behavior == DROP_RESTRICT)
1351  heap_truncate_check_FKs(rels, false);
1352 #endif
1353 
1354  /*
1355  * If we are asked to restart sequences, find all the sequences, lock them
1356  * (we need AccessExclusiveLock for ResetSequence), and check permissions.
1357  * We want to do this early since it's pointless to do all the truncation
1358  * work only to fail on sequence permissions.
1359  */
1360  if (stmt->restart_seqs)
1361  {
1362  foreach(cell, rels)
1363  {
1364  Relation rel = (Relation) lfirst(cell);
1365  List *seqlist = getOwnedSequences(RelationGetRelid(rel), 0);
1366  ListCell *seqcell;
1367 
1368  foreach(seqcell, seqlist)
1369  {
1370  Oid seq_relid = lfirst_oid(seqcell);
1371  Relation seq_rel;
1372 
1373  seq_rel = relation_open(seq_relid, AccessExclusiveLock);
1374 
1375  /* This check must match AlterSequence! */
1376  if (!pg_class_ownercheck(seq_relid, GetUserId()))
1378  RelationGetRelationName(seq_rel));
1379 
1380  seq_relids = lappend_oid(seq_relids, seq_relid);
1381 
1382  relation_close(seq_rel, NoLock);
1383  }
1384  }
1385  }
1386 
1387  /* Prepare to catch AFTER triggers. */
1389 
1390  /*
1391  * To fire triggers, we'll need an EState as well as a ResultRelInfo for
1392  * each relation. We don't need to call ExecOpenIndices, though.
1393  */
1394  estate = CreateExecutorState();
1395  resultRelInfos = (ResultRelInfo *)
1396  palloc(list_length(rels) * sizeof(ResultRelInfo));
1397  resultRelInfo = resultRelInfos;
1398  foreach(cell, rels)
1399  {
1400  Relation rel = (Relation) lfirst(cell);
1401 
1402  InitResultRelInfo(resultRelInfo,
1403  rel,
1404  0, /* dummy rangetable index */
1405  NULL,
1406  0);
1407  resultRelInfo++;
1408  }
1409  estate->es_result_relations = resultRelInfos;
1410  estate->es_num_result_relations = list_length(rels);
1411 
1412  /*
1413  * Process all BEFORE STATEMENT TRUNCATE triggers before we begin
1414  * truncating (this is because one of them might throw an error). Also, if
1415  * we were to allow them to prevent statement execution, that would need
1416  * to be handled here.
1417  */
1418  resultRelInfo = resultRelInfos;
1419  foreach(cell, rels)
1420  {
1421  estate->es_result_relation_info = resultRelInfo;
1422  ExecBSTruncateTriggers(estate, resultRelInfo);
1423  resultRelInfo++;
1424  }
1425 
1426  /*
1427  * OK, truncate each table.
1428  */
1429  mySubid = GetCurrentSubTransactionId();
1430 
1431  foreach(cell, rels)
1432  {
1433  Relation rel = (Relation) lfirst(cell);
1434 
1435  /* Skip partitioned tables as there is nothing to do */
1436  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1437  continue;
1438 
1439  /*
1440  * Normally, we need a transaction-safe truncation here. However, if
1441  * the table was either created in the current (sub)transaction or has
1442  * a new relfilenode in the current (sub)transaction, then we can just
1443  * truncate it in-place, because a rollback would cause the whole
1444  * table or the current physical file to be thrown away anyway.
1445  */
1446  if (rel->rd_createSubid == mySubid ||
1447  rel->rd_newRelfilenodeSubid == mySubid)
1448  {
1449  /* Immediate, non-rollbackable truncation is OK */
1450  heap_truncate_one_rel(rel);
1451  }
1452  else
1453  {
1454  Oid heap_relid;
1455  Oid toast_relid;
1456  MultiXactId minmulti;
1457 
1458  /*
1459  * This effectively deletes all rows in the table, and may be done
1460  * in a serializable transaction. In that case we must record a
1461  * rw-conflict in to this transaction from each transaction
1462  * holding a predicate lock on the table.
1463  */
1465 
1466  minmulti = GetOldestMultiXactId();
1467 
1468  /*
1469  * Need the full transaction-safe pushups.
1470  *
1471  * Create a new empty storage file for the relation, and assign it
1472  * as the relfilenode value. The old storage file is scheduled for
1473  * deletion at commit.
1474  */
1475  RelationSetNewRelfilenode(rel, rel->rd_rel->relpersistence,
1476  RecentXmin, minmulti);
1477  if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
1478  heap_create_init_fork(rel);
1479 
1480  heap_relid = RelationGetRelid(rel);
1481  toast_relid = rel->rd_rel->reltoastrelid;
1482 
1483  /*
1484  * The same for the toast table, if any.
1485  */
1486  if (OidIsValid(toast_relid))
1487  {
1488  rel = relation_open(toast_relid, AccessExclusiveLock);
1489  RelationSetNewRelfilenode(rel, rel->rd_rel->relpersistence,
1490  RecentXmin, minmulti);
1491  if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
1492  heap_create_init_fork(rel);
1493  heap_close(rel, NoLock);
1494  }
1495 
1496  /*
1497  * Reconstruct the indexes to match, and we're done.
1498  */
1500  }
1501 
1502  pgstat_count_truncate(rel);
1503  }
1504 
1505  /*
1506  * Restart owned sequences if we were asked to.
1507  */
1508  foreach(cell, seq_relids)
1509  {
1510  Oid seq_relid = lfirst_oid(cell);
1511 
1512  ResetSequence(seq_relid);
1513  }
1514 
1515  /*
1516  * Process all AFTER STATEMENT TRUNCATE triggers.
1517  */
1518  resultRelInfo = resultRelInfos;
1519  foreach(cell, rels)
1520  {
1521  estate->es_result_relation_info = resultRelInfo;
1522  ExecASTruncateTriggers(estate, resultRelInfo);
1523  resultRelInfo++;
1524  }
1525 
1526  /* Handle queued AFTER triggers */
1527  AfterTriggerEndQuery(estate);
1528 
1529  /* We can clean up the EState now */
1530  FreeExecutorState(estate);
1531 
1532  /* And close the rels (can't do this while EState still holds refs) */
1533  foreach(cell, rels)
1534  {
1535  Relation rel = (Relation) lfirst(cell);
1536 
1537  heap_close(rel, NoLock);
1538  }
1539 }
1540 
1541 /*
1542  * Check that a given rel is safe to truncate. Subroutine for ExecuteTruncate
1543  */
1544 static void
1546 {
1547  AclResult aclresult;
1548 
1549  /*
1550  * Only allow truncate on regular tables and partitioned tables (although,
1551  * the latter are only being included here for the following checks; no
1552  * physical truncation will occur in their case.)
1553  */
1554  if (rel->rd_rel->relkind != RELKIND_RELATION &&
1555  rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1556  ereport(ERROR,
1557  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1558  errmsg("\"%s\" is not a table",
1559  RelationGetRelationName(rel))));
1560 
1561  /* Permissions checks */
1562  aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
1563  ACL_TRUNCATE);
1564  if (aclresult != ACLCHECK_OK)
1565  aclcheck_error(aclresult, ACL_KIND_CLASS,
1567 
1569  ereport(ERROR,
1570  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1571  errmsg("permission denied: \"%s\" is a system catalog",
1572  RelationGetRelationName(rel))));
1573 
1574  /*
1575  * Don't allow truncate on temp tables of other backends ... their local
1576  * buffer manager is not going to cope.
1577  */
1578  if (RELATION_IS_OTHER_TEMP(rel))
1579  ereport(ERROR,
1580  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1581  errmsg("cannot truncate temporary tables of other sessions")));
1582 
1583  /*
1584  * Also check for active uses of the relation in the current transaction,
1585  * including open scans and pending AFTER trigger events.
1586  */
1587  CheckTableNotInUse(rel, "TRUNCATE");
1588 }
1589 
1590 /*
1591  * storage_name
1592  * returns the name corresponding to a typstorage/attstorage enum value
1593  */
1594 static const char *
1596 {
1597  switch (c)
1598  {
1599  case 'p':
1600  return "PLAIN";
1601  case 'm':
1602  return "MAIN";
1603  case 'x':
1604  return "EXTENDED";
1605  case 'e':
1606  return "EXTERNAL";
1607  default:
1608  return "???";
1609  }
1610 }
1611 
1612 /*----------
1613  * MergeAttributes
1614  * Returns new schema given initial schema and superclasses.
1615  *
1616  * Input arguments:
1617  * 'schema' is the column/attribute definition for the table. (It's a list
1618  * of ColumnDef's.) It is destructively changed.
1619  * 'supers' is a list of names (as RangeVar nodes) of parent relations.
1620  * 'relpersistence' is a persistence type of the table.
1621  * 'is_partition' tells if the table is a partition
1622  *
1623  * Output arguments:
1624  * 'supOids' receives a list of the OIDs of the parent relations.
1625  * 'supconstr' receives a list of constraints belonging to the parents,
1626  * updated as necessary to be valid for the child.
1627  * 'supOidCount' is set to the number of parents that have OID columns.
1628  *
1629  * Return value:
1630  * Completed schema list.
1631  *
1632  * Notes:
1633  * The order in which the attributes are inherited is very important.
1634  * Intuitively, the inherited attributes should come first. If a table
1635  * inherits from multiple parents, the order of those attributes are
1636  * according to the order of the parents specified in CREATE TABLE.
1637  *
1638  * Here's an example:
1639  *
1640  * create table person (name text, age int4, location point);
1641  * create table emp (salary int4, manager text) inherits(person);
1642  * create table student (gpa float8) inherits (person);
1643  * create table stud_emp (percent int4) inherits (emp, student);
1644  *
1645  * The order of the attributes of stud_emp is:
1646  *
1647  * person {1:name, 2:age, 3:location}
1648  * / \
1649  * {6:gpa} student emp {4:salary, 5:manager}
1650  * \ /
1651  * stud_emp {7:percent}
1652  *
1653  * If the same attribute name appears multiple times, then it appears
1654  * in the result table in the proper location for its first appearance.
1655  *
1656  * Constraints (including NOT NULL constraints) for the child table
1657  * are the union of all relevant constraints, from both the child schema
1658  * and parent tables.
1659  *
1660  * The default value for a child column is defined as:
1661  * (1) If the child schema specifies a default, that value is used.
1662  * (2) If neither the child nor any parent specifies a default, then
1663  * the column will not have a default.
1664  * (3) If conflicting defaults are inherited from different parents
1665  * (and not overridden by the child), an error is raised.
1666  * (4) Otherwise the inherited default is used.
1667  * Rule (3) is new in Postgres 7.1; in earlier releases you got a
1668  * rather arbitrary choice of which parent default to use.
1669  *----------
1670  */
1671 static List *
1672 MergeAttributes(List *schema, List *supers, char relpersistence,
1673  bool is_partition, List **supOids, List **supconstr,
1674  int *supOidCount)
1675 {
1676  ListCell *entry;
1677  List *inhSchema = NIL;
1678  List *parentOids = NIL;
1679  List *constraints = NIL;
1680  int parentsWithOids = 0;
1681  bool have_bogus_defaults = false;
1682  int child_attno;
1683  static Node bogus_marker = {0}; /* marks conflicting defaults */
1684  List *saved_schema = NIL;
1685 
1686  /*
1687  * Check for and reject tables with too many columns. We perform this
1688  * check relatively early for two reasons: (a) we don't run the risk of
1689  * overflowing an AttrNumber in subsequent code (b) an O(n^2) algorithm is
1690  * okay if we're processing <= 1600 columns, but could take minutes to
1691  * execute if the user attempts to create a table with hundreds of
1692  * thousands of columns.
1693  *
1694  * Note that we also need to check that we do not exceed this figure after
1695  * including columns from inherited relations.
1696  */
1697  if (list_length(schema) > MaxHeapAttributeNumber)
1698  ereport(ERROR,
1699  (errcode(ERRCODE_TOO_MANY_COLUMNS),
1700  errmsg("tables can have at most %d columns",
1702 
1703  /*
1704  * In case of a partition, there are no new column definitions, only dummy
1705  * ColumnDefs created for column constraints. We merge them with the
1706  * constraints inherited from the parent.
1707  */
1708  if (is_partition)
1709  {
1710  saved_schema = schema;
1711  schema = NIL;
1712  }
1713 
1714  /*
1715  * Check for duplicate names in the explicit list of attributes.
1716  *
1717  * Although we might consider merging such entries in the same way that we
1718  * handle name conflicts for inherited attributes, it seems to make more
1719  * sense to assume such conflicts are errors.
1720  */
1721  foreach(entry, schema)
1722  {
1723  ColumnDef *coldef = lfirst(entry);
1724  ListCell *rest = lnext(entry);
1725  ListCell *prev = entry;
1726 
1727  if (coldef->typeName == NULL)
1728 
1729  /*
1730  * Typed table column option that does not belong to a column from
1731  * the type. This works because the columns from the type come
1732  * first in the list.
1733  */
1734  ereport(ERROR,
1735  (errcode(ERRCODE_UNDEFINED_COLUMN),
1736  errmsg("column \"%s\" does not exist",
1737  coldef->colname)));
1738 
1739  while (rest != NULL)
1740  {
1741  ColumnDef *restdef = lfirst(rest);
1742  ListCell *next = lnext(rest); /* need to save it in case we
1743  * delete it */
1744 
1745  if (strcmp(coldef->colname, restdef->colname) == 0)
1746  {
1747  if (coldef->is_from_type)
1748  {
1749  /*
1750  * merge the column options into the column from the type
1751  */
1752  coldef->is_not_null = restdef->is_not_null;
1753  coldef->raw_default = restdef->raw_default;
1754  coldef->cooked_default = restdef->cooked_default;
1755  coldef->constraints = restdef->constraints;
1756  coldef->is_from_type = false;
1757  list_delete_cell(schema, rest, prev);
1758  }
1759  else
1760  ereport(ERROR,
1761  (errcode(ERRCODE_DUPLICATE_COLUMN),
1762  errmsg("column \"%s\" specified more than once",
1763  coldef->colname)));
1764  }
1765  prev = rest;
1766  rest = next;
1767  }
1768  }
1769 
1770  /*
1771  * Scan the parents left-to-right, and merge their attributes to form a
1772  * list of inherited attributes (inhSchema). Also check to see if we need
1773  * to inherit an OID column.
1774  */
1775  child_attno = 0;
1776  foreach(entry, supers)
1777  {
1778  RangeVar *parent = (RangeVar *) lfirst(entry);
1779  Relation relation;
1781  TupleConstr *constr;
1782  AttrNumber *newattno;
1783  AttrNumber parent_attno;
1784 
1785  /*
1786  * A self-exclusive lock is needed here. If two backends attempt to
1787  * add children to the same parent simultaneously, and that parent has
1788  * no pre-existing children, then both will attempt to update the
1789  * parent's relhassubclass field, leading to a "tuple concurrently
1790  * updated" error. Also, this interlocks against a concurrent ANALYZE
1791  * on the parent table, which might otherwise be attempting to clear
1792  * the parent's relhassubclass field, if its previous children were
1793  * recently dropped.
1794  *
1795  * If the child table is a partition, then we instead grab an
1796  * exclusive lock on the parent because its partition descriptor will
1797  * be changed by addition of the new partition.
1798  */
1799  if (!is_partition)
1800  relation = heap_openrv(parent, ShareUpdateExclusiveLock);
1801  else
1802  relation = heap_openrv(parent, AccessExclusiveLock);
1803 
1804  /*
1805  * We do not allow partitioned tables and partitions to participate in
1806  * regular inheritance.
1807  */
1808  if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE &&
1809  !is_partition)
1810  ereport(ERROR,
1811  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1812  errmsg("cannot inherit from partitioned table \"%s\"",
1813  parent->relname)));
1814  if (relation->rd_rel->relispartition && !is_partition)
1815  ereport(ERROR,
1816  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1817  errmsg("cannot inherit from partition \"%s\"",
1818  parent->relname)));
1819 
1820  if (relation->rd_rel->relkind != RELKIND_RELATION &&
1821  relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
1822  relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1823  ereport(ERROR,
1824  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1825  errmsg("inherited relation \"%s\" is not a table or foreign table",
1826  parent->relname)));
1827  /* Permanent rels cannot inherit from temporary ones */
1828  if (relpersistence != RELPERSISTENCE_TEMP &&
1829  relation->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
1830  ereport(ERROR,
1831  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1832  errmsg(!is_partition
1833  ? "cannot inherit from temporary relation \"%s\""
1834  : "cannot create a permanent relation as partition of temporary relation \"%s\"",
1835  parent->relname)));
1836 
1837  /* If existing rel is temp, it must belong to this session */
1838  if (relation->rd_rel->relpersistence == RELPERSISTENCE_TEMP &&
1839  !relation->rd_islocaltemp)
1840  ereport(ERROR,
1841  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1842  errmsg(!is_partition
1843  ? "cannot inherit from temporary relation of another session"
1844  : "cannot create as partition of temporary relation of another session")));
1845 
1846  /*
1847  * We should have an UNDER permission flag for this, but for now,
1848  * demand that creator of a child table own the parent.
1849  */
1850  if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
1852  RelationGetRelationName(relation));
1853 
1854  /*
1855  * Reject duplications in the list of parents.
1856  */
1857  if (list_member_oid(parentOids, RelationGetRelid(relation)))
1858  ereport(ERROR,
1859  (errcode(ERRCODE_DUPLICATE_TABLE),
1860  errmsg("relation \"%s\" would be inherited from more than once",
1861  parent->relname)));
1862 
1863  parentOids = lappend_oid(parentOids, RelationGetRelid(relation));
1864 
1865  if (relation->rd_rel->relhasoids)
1866  parentsWithOids++;
1867 
1868  tupleDesc = RelationGetDescr(relation);
1869  constr = tupleDesc->constr;
1870 
1871  /*
1872  * newattno[] will contain the child-table attribute numbers for the
1873  * attributes of this parent table. (They are not the same for
1874  * parents after the first one, nor if we have dropped columns.)
1875  */
1876  newattno = (AttrNumber *)
1877  palloc0(tupleDesc->natts * sizeof(AttrNumber));
1878 
1879  for (parent_attno = 1; parent_attno <= tupleDesc->natts;
1880  parent_attno++)
1881  {
1882  Form_pg_attribute attribute = TupleDescAttr(tupleDesc,
1883  parent_attno - 1);
1884  char *attributeName = NameStr(attribute->attname);
1885  int exist_attno;
1886  ColumnDef *def;
1887 
1888  /*
1889  * Ignore dropped columns in the parent.
1890  */
1891  if (attribute->attisdropped)
1892  continue; /* leave newattno entry as zero */
1893 
1894  /*
1895  * Does it conflict with some previously inherited column?
1896  */
1897  exist_attno = findAttrByName(attributeName, inhSchema);
1898  if (exist_attno > 0)
1899  {
1900  Oid defTypeId;
1901  int32 deftypmod;
1902  Oid defCollId;
1903 
1904  /*
1905  * Yes, try to merge the two column definitions. They must
1906  * have the same type, typmod, and collation.
1907  */
1908  ereport(NOTICE,
1909  (errmsg("merging multiple inherited definitions of column \"%s\"",
1910  attributeName)));
1911  def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
1912  typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
1913  if (defTypeId != attribute->atttypid ||
1914  deftypmod != attribute->atttypmod)
1915  ereport(ERROR,
1916  (errcode(ERRCODE_DATATYPE_MISMATCH),
1917  errmsg("inherited column \"%s\" has a type conflict",
1918  attributeName),
1919  errdetail("%s versus %s",
1920  format_type_with_typemod(defTypeId,
1921  deftypmod),
1922  format_type_with_typemod(attribute->atttypid,
1923  attribute->atttypmod))));
1924  defCollId = GetColumnDefCollation(NULL, def, defTypeId);
1925  if (defCollId != attribute->attcollation)
1926  ereport(ERROR,
1927  (errcode(ERRCODE_COLLATION_MISMATCH),
1928  errmsg("inherited column \"%s\" has a collation conflict",
1929  attributeName),
1930  errdetail("\"%s\" versus \"%s\"",
1931  get_collation_name(defCollId),
1932  get_collation_name(attribute->attcollation))));
1933 
1934  /* Copy storage parameter */
1935  if (def->storage == 0)
1936  def->storage = attribute->attstorage;
1937  else if (def->storage != attribute->attstorage)
1938  ereport(ERROR,
1939  (errcode(ERRCODE_DATATYPE_MISMATCH),
1940  errmsg("inherited column \"%s\" has a storage parameter conflict",
1941  attributeName),
1942  errdetail("%s versus %s",
1943  storage_name(def->storage),
1944  storage_name(attribute->attstorage))));
1945 
1946  def->inhcount++;
1947  /* Merge of NOT NULL constraints = OR 'em together */
1948  def->is_not_null |= attribute->attnotnull;
1949  /* Default and other constraints are handled below */
1950  newattno[parent_attno - 1] = exist_attno;
1951  }
1952  else
1953  {
1954  /*
1955  * No, create a new inherited column
1956  */
1957  def = makeNode(ColumnDef);
1958  def->colname = pstrdup(attributeName);
1959  def->typeName = makeTypeNameFromOid(attribute->atttypid,
1960  attribute->atttypmod);
1961  def->inhcount = 1;
1962  def->is_local = false;
1963  def->is_not_null = attribute->attnotnull;
1964  def->is_from_type = false;
1965  def->is_from_parent = true;
1966  def->storage = attribute->attstorage;
1967  def->raw_default = NULL;
1968  def->cooked_default = NULL;
1969  def->collClause = NULL;
1970  def->collOid = attribute->attcollation;
1971  def->constraints = NIL;
1972  def->location = -1;
1973  inhSchema = lappend(inhSchema, def);
1974  newattno[parent_attno - 1] = ++child_attno;
1975  }
1976 
1977  /*
1978  * Copy default if any
1979  */
1980  if (attribute->atthasdef)
1981  {
1982  Node *this_default = NULL;
1983  AttrDefault *attrdef;
1984  int i;
1985 
1986  /* Find default in constraint structure */
1987  Assert(constr != NULL);
1988  attrdef = constr->defval;
1989  for (i = 0; i < constr->num_defval; i++)
1990  {
1991  if (attrdef[i].adnum == parent_attno)
1992  {
1993  this_default = stringToNode(attrdef[i].adbin);
1994  break;
1995  }
1996  }
1997  Assert(this_default != NULL);
1998 
1999  /*
2000  * If default expr could contain any vars, we'd need to fix
2001  * 'em, but it can't; so default is ready to apply to child.
2002  *
2003  * If we already had a default from some prior parent, check
2004  * to see if they are the same. If so, no problem; if not,
2005  * mark the column as having a bogus default. Below, we will
2006  * complain if the bogus default isn't overridden by the child
2007  * schema.
2008  */
2009  Assert(def->raw_default == NULL);
2010  if (def->cooked_default == NULL)
2011  def->cooked_default = this_default;
2012  else if (!equal(def->cooked_default, this_default))
2013  {
2014  def->cooked_default = &bogus_marker;
2015  have_bogus_defaults = true;
2016  }
2017  }
2018  }
2019 
2020  /*
2021  * Now copy the CHECK constraints of this parent, adjusting attnos
2022  * using the completed newattno[] map. Identically named constraints
2023  * are merged if possible, else we throw error.
2024  */
2025  if (constr && constr->num_check > 0)
2026  {
2027  ConstrCheck *check = constr->check;
2028  int i;
2029 
2030  for (i = 0; i < constr->num_check; i++)
2031  {
2032  char *name = check[i].ccname;
2033  Node *expr;
2034  bool found_whole_row;
2035 
2036  /* ignore if the constraint is non-inheritable */
2037  if (check[i].ccnoinherit)
2038  continue;
2039 
2040  /* Adjust Vars to match new table's column numbering */
2041  expr = map_variable_attnos(stringToNode(check[i].ccbin),
2042  1, 0,
2043  newattno, tupleDesc->natts,
2044  InvalidOid, &found_whole_row);
2045 
2046  /*
2047  * For the moment we have to reject whole-row variables. We
2048  * could convert them, if we knew the new table's rowtype OID,
2049  * but that hasn't been assigned yet.
2050  */
2051  if (found_whole_row)
2052  ereport(ERROR,
2053  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2054  errmsg("cannot convert whole-row table reference"),
2055  errdetail("Constraint \"%s\" contains a whole-row reference to table \"%s\".",
2056  name,
2057  RelationGetRelationName(relation))));
2058 
2059  /* check for duplicate */
2060  if (!MergeCheckConstraint(constraints, name, expr))
2061  {
2062  /* nope, this is a new one */
2063  CookedConstraint *cooked;
2064 
2065  cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
2066  cooked->contype = CONSTR_CHECK;
2067  cooked->conoid = InvalidOid; /* until created */
2068  cooked->name = pstrdup(name);
2069  cooked->attnum = 0; /* not used for constraints */
2070  cooked->expr = expr;
2071  cooked->skip_validation = false;
2072  cooked->is_local = false;
2073  cooked->inhcount = 1;
2074  cooked->is_no_inherit = false;
2075  constraints = lappend(constraints, cooked);
2076  }
2077  }
2078  }
2079 
2080  pfree(newattno);
2081 
2082  /*
2083  * Close the parent rel, but keep our lock on it until xact commit.
2084  * That will prevent someone else from deleting or ALTERing the parent
2085  * before the child is committed.
2086  */
2087  heap_close(relation, NoLock);
2088  }
2089 
2090  /*
2091  * If we had no inherited attributes, the result schema is just the
2092  * explicitly declared columns. Otherwise, we need to merge the declared
2093  * columns into the inherited schema list. Although, we never have any
2094  * explicitly declared columns if the table is a partition.
2095  */
2096  if (inhSchema != NIL)
2097  {
2098  int schema_attno = 0;
2099 
2100  foreach(entry, schema)
2101  {
2102  ColumnDef *newdef = lfirst(entry);
2103  char *attributeName = newdef->colname;
2104  int exist_attno;
2105 
2106  schema_attno++;
2107 
2108  /*
2109  * Does it conflict with some previously inherited column?
2110  */
2111  exist_attno = findAttrByName(attributeName, inhSchema);
2112  if (exist_attno > 0)
2113  {
2114  ColumnDef *def;
2115  Oid defTypeId,
2116  newTypeId;
2117  int32 deftypmod,
2118  newtypmod;
2119  Oid defcollid,
2120  newcollid;
2121 
2122  /*
2123  * Partitions have only one parent and have no column
2124  * definitions of their own, so conflict should never occur.
2125  */
2126  Assert(!is_partition);
2127 
2128  /*
2129  * Yes, try to merge the two column definitions. They must
2130  * have the same type, typmod, and collation.
2131  */
2132  if (exist_attno == schema_attno)
2133  ereport(NOTICE,
2134  (errmsg("merging column \"%s\" with inherited definition",
2135  attributeName)));
2136  else
2137  ereport(NOTICE,
2138  (errmsg("moving and merging column \"%s\" with inherited definition", attributeName),
2139  errdetail("User-specified column moved to the position of the inherited column.")));
2140  def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
2141  typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
2142  typenameTypeIdAndMod(NULL, newdef->typeName, &newTypeId, &newtypmod);
2143  if (defTypeId != newTypeId || deftypmod != newtypmod)
2144  ereport(ERROR,
2145  (errcode(ERRCODE_DATATYPE_MISMATCH),
2146  errmsg("column \"%s\" has a type conflict",
2147  attributeName),
2148  errdetail("%s versus %s",
2149  format_type_with_typemod(defTypeId,
2150  deftypmod),
2151  format_type_with_typemod(newTypeId,
2152  newtypmod))));
2153  defcollid = GetColumnDefCollation(NULL, def, defTypeId);
2154  newcollid = GetColumnDefCollation(NULL, newdef, newTypeId);
2155  if (defcollid != newcollid)
2156  ereport(ERROR,
2157  (errcode(ERRCODE_COLLATION_MISMATCH),
2158  errmsg("column \"%s\" has a collation conflict",
2159  attributeName),
2160  errdetail("\"%s\" versus \"%s\"",
2161  get_collation_name(defcollid),
2162  get_collation_name(newcollid))));
2163 
2164  /*
2165  * Identity is never inherited. The new column can have an
2166  * identity definition, so we always just take that one.
2167  */
2168  def->identity = newdef->identity;
2169 
2170  /* Copy storage parameter */
2171  if (def->storage == 0)
2172  def->storage = newdef->storage;
2173  else if (newdef->storage != 0 && def->storage != newdef->storage)
2174  ereport(ERROR,
2175  (errcode(ERRCODE_DATATYPE_MISMATCH),
2176  errmsg("column \"%s\" has a storage parameter conflict",
2177  attributeName),
2178  errdetail("%s versus %s",
2179  storage_name(def->storage),
2180  storage_name(newdef->storage))));
2181 
2182  /* Mark the column as locally defined */
2183  def->is_local = true;
2184  /* Merge of NOT NULL constraints = OR 'em together */
2185  def->is_not_null |= newdef->is_not_null;
2186  /* If new def has a default, override previous default */
2187  if (newdef->raw_default != NULL)
2188  {
2189  def->raw_default = newdef->raw_default;
2190  def->cooked_default = newdef->cooked_default;
2191  }
2192  }
2193  else
2194  {
2195  /*
2196  * No, attach new column to result schema
2197  */
2198  inhSchema = lappend(inhSchema, newdef);
2199  }
2200  }
2201 
2202  schema = inhSchema;
2203 
2204  /*
2205  * Check that we haven't exceeded the legal # of columns after merging
2206  * in inherited columns.
2207  */
2208  if (list_length(schema) > MaxHeapAttributeNumber)
2209  ereport(ERROR,
2210  (errcode(ERRCODE_TOO_MANY_COLUMNS),
2211  errmsg("tables can have at most %d columns",
2213  }
2214 
2215  /*
2216  * Now that we have the column definition list for a partition, we can
2217  * check whether the columns referenced in the column constraint specs
2218  * actually exist. Also, we merge the constraints into the corresponding
2219  * column definitions.
2220  */
2221  if (is_partition && list_length(saved_schema) > 0)
2222  {
2223  schema = list_concat(schema, saved_schema);
2224 
2225  foreach(entry, schema)
2226  {
2227  ColumnDef *coldef = lfirst(entry);
2228  ListCell *rest = lnext(entry);
2229  ListCell *prev = entry;
2230 
2231  /*
2232  * Partition column option that does not belong to a column from
2233  * the parent. This works because the columns from the parent
2234  * come first in the list (see above).
2235  */
2236  if (coldef->typeName == NULL)
2237  ereport(ERROR,
2238  (errcode(ERRCODE_UNDEFINED_COLUMN),
2239  errmsg("column \"%s\" does not exist",
2240  coldef->colname)));
2241  while (rest != NULL)
2242  {
2243  ColumnDef *restdef = lfirst(rest);
2244  ListCell *next = lnext(rest); /* need to save it in case we
2245  * delete it */
2246 
2247  if (strcmp(coldef->colname, restdef->colname) == 0)
2248  {
2249  /*
2250  * merge the column options into the column from the
2251  * parent
2252  */
2253  if (coldef->is_from_parent)
2254  {
2255  coldef->is_not_null = restdef->is_not_null;
2256  coldef->raw_default = restdef->raw_default;
2257  coldef->cooked_default = restdef->cooked_default;
2258  coldef->constraints = restdef->constraints;
2259  coldef->is_from_parent = false;
2260  list_delete_cell(schema, rest, prev);
2261  }
2262  else
2263  ereport(ERROR,
2264  (errcode(ERRCODE_DUPLICATE_COLUMN),
2265  errmsg("column \"%s\" specified more than once",
2266  coldef->colname)));
2267  }
2268  prev = rest;
2269  rest = next;
2270  }
2271  }
2272  }
2273 
2274  /*
2275  * If we found any conflicting parent default values, check to make sure
2276  * they were overridden by the child.
2277  */
2278  if (have_bogus_defaults)
2279  {
2280  foreach(entry, schema)
2281  {
2282  ColumnDef *def = lfirst(entry);
2283 
2284  if (def->cooked_default == &bogus_marker)
2285  ereport(ERROR,
2286  (errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
2287  errmsg("column \"%s\" inherits conflicting default values",
2288  def->colname),
2289  errhint("To resolve the conflict, specify a default explicitly.")));
2290  }
2291  }
2292 
2293  *supOids = parentOids;
2294  *supconstr = constraints;
2295  *supOidCount = parentsWithOids;
2296  return schema;
2297 }
2298 
2299 
2300 /*
2301  * MergeCheckConstraint
2302  * Try to merge an inherited CHECK constraint with previous ones
2303  *
2304  * If we inherit identically-named constraints from multiple parents, we must
2305  * merge them, or throw an error if they don't have identical definitions.
2306  *
2307  * constraints is a list of CookedConstraint structs for previous constraints.
2308  *
2309  * Returns TRUE if merged (constraint is a duplicate), or FALSE if it's
2310  * got a so-far-unique name, or throws error if conflict.
2311  */
2312 static bool
2313 MergeCheckConstraint(List *constraints, char *name, Node *expr)
2314 {
2315  ListCell *lc;
2316 
2317  foreach(lc, constraints)
2318  {
2319  CookedConstraint *ccon = (CookedConstraint *) lfirst(lc);
2320 
2321  Assert(ccon->contype == CONSTR_CHECK);
2322 
2323  /* Non-matching names never conflict */
2324  if (strcmp(ccon->name, name) != 0)
2325  continue;
2326 
2327  if (equal(expr, ccon->expr))
2328  {
2329  /* OK to merge */
2330  ccon->inhcount++;
2331  return true;
2332  }
2333 
2334  ereport(ERROR,
2336  errmsg("check constraint name \"%s\" appears multiple times but with different expressions",
2337  name)));
2338  }
2339 
2340  return false;
2341 }
2342 
2343 
2344 /*
2345  * StoreCatalogInheritance
2346  * Updates the system catalogs with proper inheritance information.
2347  *
2348  * supers is a list of the OIDs of the new relation's direct ancestors.
2349  */
2350 static void
2351 StoreCatalogInheritance(Oid relationId, List *supers,
2352  bool child_is_partition)
2353 {
2354  Relation relation;
2355  int16 seqNumber;
2356  ListCell *entry;
2357 
2358  /*
2359  * sanity checks
2360  */
2361  AssertArg(OidIsValid(relationId));
2362 
2363  if (supers == NIL)
2364  return;
2365 
2366  /*
2367  * Store INHERITS information in pg_inherits using direct ancestors only.
2368  * Also enter dependencies on the direct ancestors, and make sure they are
2369  * marked with relhassubclass = true.
2370  *
2371  * (Once upon a time, both direct and indirect ancestors were found here
2372  * and then entered into pg_ipl. Since that catalog doesn't exist
2373  * anymore, there's no need to look for indirect ancestors.)
2374  */
2376 
2377  seqNumber = 1;
2378  foreach(entry, supers)
2379  {
2380  Oid parentOid = lfirst_oid(entry);
2381 
2382  StoreCatalogInheritance1(relationId, parentOid, seqNumber, relation,
2383  child_is_partition);
2384  seqNumber++;
2385  }
2386 
2387  heap_close(relation, RowExclusiveLock);
2388 }
2389 
2390 /*
2391  * Make catalog entries showing relationId as being an inheritance child
2392  * of parentOid. inhRelation is the already-opened pg_inherits catalog.
2393  */
2394 static void
2395 StoreCatalogInheritance1(Oid relationId, Oid parentOid,
2396  int16 seqNumber, Relation inhRelation,
2397  bool child_is_partition)
2398 {
2399  TupleDesc desc = RelationGetDescr(inhRelation);
2401  bool nulls[Natts_pg_inherits];
2402  ObjectAddress childobject,
2403  parentobject;
2404  HeapTuple tuple;
2405 
2406  /*
2407  * Make the pg_inherits entry
2408  */
2409  values[Anum_pg_inherits_inhrelid - 1] = ObjectIdGetDatum(relationId);
2410  values[Anum_pg_inherits_inhparent - 1] = ObjectIdGetDatum(parentOid);
2411  values[Anum_pg_inherits_inhseqno - 1] = Int16GetDatum(seqNumber);
2412 
2413  memset(nulls, 0, sizeof(nulls));
2414 
2415  tuple = heap_form_tuple(desc, values, nulls);
2416 
2417  CatalogTupleInsert(inhRelation, tuple);
2418 
2419  heap_freetuple(tuple);
2420 
2421  /*
2422  * Store a dependency too
2423  */
2424  parentobject.classId = RelationRelationId;
2425  parentobject.objectId = parentOid;
2426  parentobject.objectSubId = 0;
2427  childobject.classId = RelationRelationId;
2428  childobject.objectId = relationId;
2429  childobject.objectSubId = 0;
2430 
2431  recordDependencyOn(&childobject, &parentobject,
2432  child_dependency_type(child_is_partition));
2433 
2434  /*
2435  * Post creation hook of this inheritance. Since object_access_hook
2436  * doesn't take multiple object identifiers, we relay oid of parent
2437  * relation using auxiliary_id argument.
2438  */
2440  relationId, 0,
2441  parentOid, false);
2442 
2443  /*
2444  * Mark the parent as having subclasses.
2445  */
2446  SetRelationHasSubclass(parentOid, true);
2447 }
2448 
2449 /*
2450  * Look for an existing schema entry with the given name.
2451  *
2452  * Returns the index (starting with 1) if attribute already exists in schema,
2453  * 0 if it doesn't.
2454  */
2455 static int
2456 findAttrByName(const char *attributeName, List *schema)
2457 {
2458  ListCell *s;
2459  int i = 1;
2460 
2461  foreach(s, schema)
2462  {
2463  ColumnDef *def = lfirst(s);
2464 
2465  if (strcmp(attributeName, def->colname) == 0)
2466  return i;
2467 
2468  i++;
2469  }
2470  return 0;
2471 }
2472 
2473 
2474 /*
2475  * SetRelationHasSubclass
2476  * Set the value of the relation's relhassubclass field in pg_class.
2477  *
2478  * NOTE: caller must be holding an appropriate lock on the relation.
2479  * ShareUpdateExclusiveLock is sufficient.
2480  *
2481  * NOTE: an important side-effect of this operation is that an SI invalidation
2482  * message is sent out to all backends --- including me --- causing plans
2483  * referencing the relation to be rebuilt with the new list of children.
2484  * This must happen even if we find that no change is needed in the pg_class
2485  * row.
2486  */
2487 void
2488 SetRelationHasSubclass(Oid relationId, bool relhassubclass)
2489 {
2490  Relation relationRelation;
2491  HeapTuple tuple;
2492  Form_pg_class classtuple;
2493 
2494  /*
2495  * Fetch a modifiable copy of the tuple, modify it, update pg_class.
2496  */
2497  relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
2498  tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId));
2499  if (!HeapTupleIsValid(tuple))
2500  elog(ERROR, "cache lookup failed for relation %u", relationId);
2501  classtuple = (Form_pg_class) GETSTRUCT(tuple);
2502 
2503  if (classtuple->relhassubclass != relhassubclass)
2504  {
2505  classtuple->relhassubclass = relhassubclass;
2506  CatalogTupleUpdate(relationRelation, &tuple->t_self, tuple);
2507  }
2508  else
2509  {
2510  /* no need to change tuple, but force relcache rebuild anyway */
2512  }
2513 
2514  heap_freetuple(tuple);
2515  heap_close(relationRelation, RowExclusiveLock);
2516 }
2517 
2518 /*
2519  * renameatt_check - basic sanity checks before attribute rename
2520  */
2521 static void
2522 renameatt_check(Oid myrelid, Form_pg_class classform, bool recursing)
2523 {
2524  char relkind = classform->relkind;
2525 
2526  if (classform->reloftype && !recursing)
2527  ereport(ERROR,
2528  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2529  errmsg("cannot rename column of typed table")));
2530 
2531  /*
2532  * Renaming the columns of sequences or toast tables doesn't actually
2533  * break anything from the system's point of view, since internal
2534  * references are by attnum. But it doesn't seem right to allow users to
2535  * change names that are hardcoded into the system, hence the following
2536  * restriction.
2537  */
2538  if (relkind != RELKIND_RELATION &&
2539  relkind != RELKIND_VIEW &&
2540  relkind != RELKIND_MATVIEW &&
2541  relkind != RELKIND_COMPOSITE_TYPE &&
2542  relkind != RELKIND_INDEX &&
2543  relkind != RELKIND_FOREIGN_TABLE &&
2544  relkind != RELKIND_PARTITIONED_TABLE)
2545  ereport(ERROR,
2546  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2547  errmsg("\"%s\" is not a table, view, materialized view, composite type, index, or foreign table",
2548  NameStr(classform->relname))));
2549 
2550  /*
2551  * permissions checking. only the owner of a class can change its schema.
2552  */
2553  if (!pg_class_ownercheck(myrelid, GetUserId()))
2555  NameStr(classform->relname));
2556  if (!allowSystemTableMods && IsSystemClass(myrelid, classform))
2557  ereport(ERROR,
2558  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2559  errmsg("permission denied: \"%s\" is a system catalog",
2560  NameStr(classform->relname))));
2561 }
2562 
2563 /*
2564  * renameatt_internal - workhorse for renameatt
2565  *
2566  * Return value is the attribute number in the 'myrelid' relation.
2567  */
2568 static AttrNumber
2570  const char *oldattname,
2571  const char *newattname,
2572  bool recurse,
2573  bool recursing,
2574  int expected_parents,
2575  DropBehavior behavior)
2576 {
2577  Relation targetrelation;
2578  Relation attrelation;
2579  HeapTuple atttup;
2580  Form_pg_attribute attform;
2581  AttrNumber attnum;
2582 
2583  /*
2584  * Grab an exclusive lock on the target table, which we will NOT release
2585  * until end of transaction.
2586  */
2587  targetrelation = relation_open(myrelid, AccessExclusiveLock);
2588  renameatt_check(myrelid, RelationGetForm(targetrelation), recursing);
2589 
2590  /*
2591  * if the 'recurse' flag is set then we are supposed to rename this
2592  * attribute in all classes that inherit from 'relname' (as well as in
2593  * 'relname').
2594  *
2595  * any permissions or problems with duplicate attributes will cause the
2596  * whole transaction to abort, which is what we want -- all or nothing.
2597  */
2598  if (recurse)
2599  {
2600  List *child_oids,
2601  *child_numparents;
2602  ListCell *lo,
2603  *li;
2604 
2605  /*
2606  * we need the number of parents for each child so that the recursive
2607  * calls to renameatt() can determine whether there are any parents
2608  * outside the inheritance hierarchy being processed.
2609  */
2610  child_oids = find_all_inheritors(myrelid, AccessExclusiveLock,
2611  &child_numparents);
2612 
2613  /*
2614  * find_all_inheritors does the recursive search of the inheritance
2615  * hierarchy, so all we have to do is process all of the relids in the
2616  * list that it returns.
2617  */
2618  forboth(lo, child_oids, li, child_numparents)
2619  {
2620  Oid childrelid = lfirst_oid(lo);
2621  int numparents = lfirst_int(li);
2622 
2623  if (childrelid == myrelid)
2624  continue;
2625  /* note we need not recurse again */
2626  renameatt_internal(childrelid, oldattname, newattname, false, true, numparents, behavior);
2627  }
2628  }
2629  else
2630  {
2631  /*
2632  * If we are told not to recurse, there had better not be any child
2633  * tables; else the rename would put them out of step.
2634  *
2635  * expected_parents will only be 0 if we are not already recursing.
2636  */
2637  if (expected_parents == 0 &&
2638  find_inheritance_children(myrelid, NoLock) != NIL)
2639  ereport(ERROR,
2640  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2641  errmsg("inherited column \"%s\" must be renamed in child tables too",
2642  oldattname)));
2643  }
2644 
2645  /* rename attributes in typed tables of composite type */
2646  if (targetrelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
2647  {
2648  List *child_oids;
2649  ListCell *lo;
2650 
2651  child_oids = find_typed_table_dependencies(targetrelation->rd_rel->reltype,
2652  RelationGetRelationName(targetrelation),
2653  behavior);
2654 
2655  foreach(lo, child_oids)
2656  renameatt_internal(lfirst_oid(lo), oldattname, newattname, true, true, 0, behavior);
2657  }
2658 
2660 
2661  atttup = SearchSysCacheCopyAttName(myrelid, oldattname);
2662  if (!HeapTupleIsValid(atttup))
2663  ereport(ERROR,
2664  (errcode(ERRCODE_UNDEFINED_COLUMN),
2665  errmsg("column \"%s\" does not exist",
2666  oldattname)));
2667  attform = (Form_pg_attribute) GETSTRUCT(atttup);
2668 
2669  attnum = attform->attnum;
2670  if (attnum <= 0)
2671  ereport(ERROR,
2672  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2673  errmsg("cannot rename system column \"%s\"",
2674  oldattname)));
2675 
2676  /*
2677  * if the attribute is inherited, forbid the renaming. if this is a
2678  * top-level call to renameatt(), then expected_parents will be 0, so the
2679  * effect of this code will be to prohibit the renaming if the attribute
2680  * is inherited at all. if this is a recursive call to renameatt(),
2681  * expected_parents will be the number of parents the current relation has
2682  * within the inheritance hierarchy being processed, so we'll prohibit the
2683  * renaming only if there are additional parents from elsewhere.
2684  */
2685  if (attform->attinhcount > expected_parents)
2686  ereport(ERROR,
2687  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2688  errmsg("cannot rename inherited column \"%s\"",
2689  oldattname)));
2690 
2691  /* new name should not already exist */
2692  (void) check_for_column_name_collision(targetrelation, newattname, false);
2693 
2694  /* apply the update */
2695  namestrcpy(&(attform->attname), newattname);
2696 
2697  CatalogTupleUpdate(attrelation, &atttup->t_self, atttup);
2698 
2700 
2701  heap_freetuple(atttup);
2702 
2703  heap_close(attrelation, RowExclusiveLock);
2704 
2705  relation_close(targetrelation, NoLock); /* close rel but keep lock */
2706 
2707  return attnum;
2708 }
2709 
2710 /*
2711  * Perform permissions and integrity checks before acquiring a relation lock.
2712  */
2713 static void
2715  void *arg)
2716 {
2717  HeapTuple tuple;
2718  Form_pg_class form;
2719 
2720  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
2721  if (!HeapTupleIsValid(tuple))
2722  return; /* concurrently dropped */
2723  form = (Form_pg_class) GETSTRUCT(tuple);
2724  renameatt_check(relid, form, false);
2725  ReleaseSysCache(tuple);
2726 }
2727 
2728 /*
2729  * renameatt - changes the name of an attribute in a relation
2730  *
2731  * The returned ObjectAddress is that of the renamed column.
2732  */
2735 {
2736  Oid relid;
2737  AttrNumber attnum;
2738  ObjectAddress address;
2739 
2740  /* lock level taken here should match renameatt_internal */
2742  stmt->missing_ok, false,
2744  NULL);
2745 
2746  if (!OidIsValid(relid))
2747  {
2748  ereport(NOTICE,
2749  (errmsg("relation \"%s\" does not exist, skipping",
2750  stmt->relation->relname)));
2751  return InvalidObjectAddress;
2752  }
2753 
2754  attnum =
2755  renameatt_internal(relid,
2756  stmt->subname, /* old att name */
2757  stmt->newname, /* new att name */
2758  stmt->relation->inh, /* recursive? */
2759  false, /* recursing? */
2760  0, /* expected inhcount */
2761  stmt->behavior);
2762 
2763  ObjectAddressSubSet(address, RelationRelationId, relid, attnum);
2764 
2765  return address;
2766 }
2767 
2768 /*
2769  * same logic as renameatt_internal
2770  */
2771 static ObjectAddress
2773  Oid mytypid,
2774  const char *oldconname,
2775  const char *newconname,
2776  bool recurse,
2777  bool recursing,
2778  int expected_parents)
2779 {
2780  Relation targetrelation = NULL;
2781  Oid constraintOid;
2782  HeapTuple tuple;
2783  Form_pg_constraint con;
2784  ObjectAddress address;
2785 
2786  AssertArg(!myrelid || !mytypid);
2787 
2788  if (mytypid)
2789  {
2790  constraintOid = get_domain_constraint_oid(mytypid, oldconname, false);
2791  }
2792  else
2793  {
2794  targetrelation = relation_open(myrelid, AccessExclusiveLock);
2795 
2796  /*
2797  * don't tell it whether we're recursing; we allow changing typed
2798  * tables here
2799  */
2800  renameatt_check(myrelid, RelationGetForm(targetrelation), false);
2801 
2802  constraintOid = get_relation_constraint_oid(myrelid, oldconname, false);
2803  }
2804 
2805  tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(constraintOid));
2806  if (!HeapTupleIsValid(tuple))
2807  elog(ERROR, "cache lookup failed for constraint %u",
2808  constraintOid);
2809  con = (Form_pg_constraint) GETSTRUCT(tuple);
2810 
2811  if (myrelid && con->contype == CONSTRAINT_CHECK && !con->connoinherit)
2812  {
2813  if (recurse)
2814  {
2815  List *child_oids,
2816  *child_numparents;
2817  ListCell *lo,
2818  *li;
2819 
2820  child_oids = find_all_inheritors(myrelid, AccessExclusiveLock,
2821  &child_numparents);
2822 
2823  forboth(lo, child_oids, li, child_numparents)
2824  {
2825  Oid childrelid = lfirst_oid(lo);
2826  int numparents = lfirst_int(li);
2827 
2828  if (childrelid == myrelid)
2829  continue;
2830 
2831  rename_constraint_internal(childrelid, InvalidOid, oldconname, newconname, false, true, numparents);
2832  }
2833  }
2834  else
2835  {
2836  if (expected_parents == 0 &&
2837  find_inheritance_children(myrelid, NoLock) != NIL)
2838  ereport(ERROR,
2839  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2840  errmsg("inherited constraint \"%s\" must be renamed in child tables too",
2841  oldconname)));
2842  }
2843 
2844  if (con->coninhcount > expected_parents)
2845  ereport(ERROR,
2846  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2847  errmsg("cannot rename inherited constraint \"%s\"",
2848  oldconname)));
2849  }
2850 
2851  if (con->conindid
2852  && (con->contype == CONSTRAINT_PRIMARY
2853  || con->contype == CONSTRAINT_UNIQUE
2854  || con->contype == CONSTRAINT_EXCLUSION))
2855  /* rename the index; this renames the constraint as well */
2856  RenameRelationInternal(con->conindid, newconname, false);
2857  else
2858  RenameConstraintById(constraintOid, newconname);
2859 
2860  ObjectAddressSet(address, ConstraintRelationId, constraintOid);
2861 
2862  ReleaseSysCache(tuple);
2863 
2864  if (targetrelation)
2865  relation_close(targetrelation, NoLock); /* close rel but keep lock */
2866 
2867  return address;
2868 }
2869 
2872 {
2873  Oid relid = InvalidOid;
2874  Oid typid = InvalidOid;
2875 
2876  if (stmt->renameType == OBJECT_DOMCONSTRAINT)
2877  {
2878  Relation rel;
2879  HeapTuple tup;
2880 
2883  tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2884  if (!HeapTupleIsValid(tup))
2885  elog(ERROR, "cache lookup failed for type %u", typid);
2886  checkDomainOwner(tup);
2887  ReleaseSysCache(tup);
2888  heap_close(rel, NoLock);
2889  }
2890  else
2891  {
2892  /* lock level taken here should match rename_constraint_internal */
2894  stmt->missing_ok, false,
2896  NULL);
2897  if (!OidIsValid(relid))
2898  {
2899  ereport(NOTICE,
2900  (errmsg("relation \"%s\" does not exist, skipping",
2901  stmt->relation->relname)));
2902  return InvalidObjectAddress;
2903  }
2904  }
2905 
2906  return
2907  rename_constraint_internal(relid, typid,
2908  stmt->subname,
2909  stmt->newname,
2910  (stmt->relation &&
2911  stmt->relation->inh), /* recursive? */
2912  false, /* recursing? */
2913  0 /* expected inhcount */ );
2914 
2915 }
2916 
2917 /*
2918  * Execute ALTER TABLE/INDEX/SEQUENCE/VIEW/MATERIALIZED VIEW/FOREIGN TABLE
2919  * RENAME
2920  */
2923 {
2924  Oid relid;
2925  ObjectAddress address;
2926 
2927  /*
2928  * Grab an exclusive lock on the target table, index, sequence, view,
2929  * materialized view, or foreign table, which we will NOT release until
2930  * end of transaction.
2931  *
2932  * Lock level used here should match RenameRelationInternal, to avoid lock
2933  * escalation.
2934  */
2936  stmt->missing_ok, false,
2938  (void *) stmt);
2939 
2940  if (!OidIsValid(relid))
2941  {
2942  ereport(NOTICE,
2943  (errmsg("relation \"%s\" does not exist, skipping",
2944  stmt->relation->relname)));
2945  return InvalidObjectAddress;
2946  }
2947 
2948  /* Do the work */
2949  RenameRelationInternal(relid, stmt->newname, false);
2950 
2951  ObjectAddressSet(address, RelationRelationId, relid);
2952 
2953  return address;
2954 }
2955 
2956 /*
2957  * RenameRelationInternal - change the name of a relation
2958  *
2959  * XXX - When renaming sequences, we don't bother to modify the
2960  * sequence name that is stored within the sequence itself
2961  * (this would cause problems with MVCC). In the future,
2962  * the sequence name should probably be removed from the
2963  * sequence, AFAIK there's no need for it to be there.
2964  */
2965 void
2966 RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal)
2967 {
2968  Relation targetrelation;
2969  Relation relrelation; /* for RELATION relation */
2970  HeapTuple reltup;
2971  Form_pg_class relform;
2972  Oid namespaceId;
2973 
2974  /*
2975  * Grab an exclusive lock on the target table, index, sequence, view,
2976  * materialized view, or foreign table, which we will NOT release until
2977  * end of transaction.
2978  */
2979  targetrelation = relation_open(myrelid, AccessExclusiveLock);
2980  namespaceId = RelationGetNamespace(targetrelation);
2981 
2982  /*
2983  * Find relation's pg_class tuple, and make sure newrelname isn't in use.
2984  */
2986 
2987  reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(myrelid));
2988  if (!HeapTupleIsValid(reltup)) /* shouldn't happen */
2989  elog(ERROR, "cache lookup failed for relation %u", myrelid);
2990  relform = (Form_pg_class) GETSTRUCT(reltup);
2991 
2992  if (get_relname_relid(newrelname, namespaceId) != InvalidOid)
2993  ereport(ERROR,
2994  (errcode(ERRCODE_DUPLICATE_TABLE),
2995  errmsg("relation \"%s\" already exists",
2996  newrelname)));
2997 
2998  /*
2999  * Update pg_class tuple with new relname. (Scribbling on reltup is OK
3000  * because it's a copy...)
3001  */
3002  namestrcpy(&(relform->relname), newrelname);
3003 
3004  CatalogTupleUpdate(relrelation, &reltup->t_self, reltup);
3005 
3007  InvalidOid, is_internal);
3008 
3009  heap_freetuple(reltup);
3010  heap_close(relrelation, RowExclusiveLock);
3011 
3012  /*
3013  * Also rename the associated type, if any.
3014  */
3015  if (OidIsValid(targetrelation->rd_rel->reltype))
3016  RenameTypeInternal(targetrelation->rd_rel->reltype,
3017  newrelname, namespaceId);
3018 
3019  /*
3020  * Also rename the associated constraint, if any.
3021  */
3022  if (targetrelation->rd_rel->relkind == RELKIND_INDEX)
3023  {
3024  Oid constraintId = get_index_constraint(myrelid);
3025 
3026  if (OidIsValid(constraintId))
3027  RenameConstraintById(constraintId, newrelname);
3028  }
3029 
3030  /*
3031  * Close rel, but keep exclusive lock!
3032  */
3033  relation_close(targetrelation, NoLock);
3034 }
3035 
3036 /*
3037  * Disallow ALTER TABLE (and similar commands) when the current backend has
3038  * any open reference to the target table besides the one just acquired by
3039  * the calling command; this implies there's an open cursor or active plan.
3040  * We need this check because our lock doesn't protect us against stomping
3041  * on our own foot, only other people's feet!
3042  *
3043  * For ALTER TABLE, the only case known to cause serious trouble is ALTER
3044  * COLUMN TYPE, and some changes are obviously pretty benign, so this could
3045  * possibly be relaxed to only error out for certain types of alterations.
3046  * But the use-case for allowing any of these things is not obvious, so we
3047  * won't work hard at it for now.
3048  *
3049  * We also reject these commands if there are any pending AFTER trigger events
3050  * for the rel. This is certainly necessary for the rewriting variants of
3051  * ALTER TABLE, because they don't preserve tuple TIDs and so the pending
3052  * events would try to fetch the wrong tuples. It might be overly cautious
3053  * in other cases, but again it seems better to err on the side of paranoia.
3054  *
3055  * REINDEX calls this with "rel" referencing the index to be rebuilt; here
3056  * we are worried about active indexscans on the index. The trigger-event
3057  * check can be skipped, since we are doing no damage to the parent table.
3058  *
3059  * The statement name (eg, "ALTER TABLE") is passed for use in error messages.
3060  */
3061 void
3062 CheckTableNotInUse(Relation rel, const char *stmt)
3063 {
3064  int expected_refcnt;
3065 
3066  expected_refcnt = rel->rd_isnailed ? 2 : 1;
3067  if (rel->rd_refcnt != expected_refcnt)
3068  ereport(ERROR,
3069  (errcode(ERRCODE_OBJECT_IN_USE),
3070  /* translator: first %s is a SQL command, eg ALTER TABLE */
3071  errmsg("cannot %s \"%s\" because "
3072  "it is being used by active queries in this session",
3073  stmt, RelationGetRelationName(rel))));
3074 
3075  if (rel->rd_rel->relkind != RELKIND_INDEX &&
3077  ereport(ERROR,
3078  (errcode(ERRCODE_OBJECT_IN_USE),
3079  /* translator: first %s is a SQL command, eg ALTER TABLE */
3080  errmsg("cannot %s \"%s\" because "
3081  "it has pending trigger events",
3082  stmt, RelationGetRelationName(rel))));
3083 }
3084 
3085 /*
3086  * AlterTableLookupRelation
3087  * Look up, and lock, the OID for the relation named by an alter table
3088  * statement.
3089  */
3090 Oid
3092 {
3093  return RangeVarGetRelidExtended(stmt->relation, lockmode, stmt->missing_ok, false,
3095  (void *) stmt);
3096 }
3097 
3098 /*
3099  * AlterTable
3100  * Execute ALTER TABLE, which can be a list of subcommands
3101  *
3102  * ALTER TABLE is performed in three phases:
3103  * 1. Examine subcommands and perform pre-transformation checking.
3104  * 2. Update system catalogs.
3105  * 3. Scan table(s) to check new constraints, and optionally recopy
3106  * the data into new table(s).
3107  * Phase 3 is not performed unless one or more of the subcommands requires
3108  * it. The intention of this design is to allow multiple independent
3109  * updates of the table schema to be performed with only one pass over the
3110  * data.
3111  *
3112  * ATPrepCmd performs phase 1. A "work queue" entry is created for
3113  * each table to be affected (there may be multiple affected tables if the
3114  * commands traverse a table inheritance hierarchy). Also we do preliminary
3115  * validation of the subcommands, including parse transformation of those
3116  * expressions that need to be evaluated with respect to the old table
3117  * schema.
3118  *
3119  * ATRewriteCatalogs performs phase 2 for each affected table. (Note that
3120  * phases 2 and 3 normally do no explicit recursion, since phase 1 already
3121  * did it --- although some subcommands have to recurse in phase 2 instead.)
3122  * Certain subcommands need to be performed before others to avoid
3123  * unnecessary conflicts; for example, DROP COLUMN should come before
3124  * ADD COLUMN. Therefore phase 1 divides the subcommands into multiple
3125  * lists, one for each logical "pass" of phase 2.
3126  *
3127  * ATRewriteTables performs phase 3 for those tables that need it.
3128  *
3129  * Thanks to the magic of MVCC, an error anywhere along the way rolls back
3130  * the whole operation; we don't have to do anything special to clean up.
3131  *
3132  * The caller must lock the relation, with an appropriate lock level
3133  * for the subcommands requested, using AlterTableGetLockLevel(stmt->cmds)
3134  * or higher. We pass the lock level down
3135  * so that we can apply it recursively to inherited tables. Note that the
3136  * lock level we want as we recurse might well be higher than required for
3137  * that specific subcommand. So we pass down the overall lock requirement,
3138  * rather than reassess it at lower levels.
3139  */
3140 void
3141 AlterTable(Oid relid, LOCKMODE lockmode, AlterTableStmt *stmt)
3142 {
3143  Relation rel;
3144 
3145  /* Caller is required to provide an adequate lock. */
3146  rel = relation_open(relid, NoLock);
3147 
3148  CheckTableNotInUse(rel, "ALTER TABLE");
3149 
3150  ATController(stmt, rel, stmt->cmds, stmt->relation->inh, lockmode);
3151 }
3152 
3153 /*
3154  * AlterTableInternal
3155  *
3156  * ALTER TABLE with target specified by OID
3157  *
3158  * We do not reject if the relation is already open, because it's quite
3159  * likely that one or more layers of caller have it open. That means it
3160  * is unsafe to use this entry point for alterations that could break
3161  * existing query plans. On the assumption it's not used for such, we
3162  * don't have to reject pending AFTER triggers, either.
3163  */
3164 void
3165 AlterTableInternal(Oid relid, List *cmds, bool recurse)
3166 {
3167  Relation rel;
3168  LOCKMODE lockmode = AlterTableGetLockLevel(cmds);
3169 
3170  rel = relation_open(relid, lockmode);
3171 
3173 
3174  ATController(NULL, rel, cmds, recurse, lockmode);
3175 }
3176 
3177 /*
3178  * AlterTableGetLockLevel
3179  *
3180  * Sets the overall lock level required for the supplied list of subcommands.
3181  * Policy for doing this set according to needs of AlterTable(), see
3182  * comments there for overall explanation.
3183  *
3184  * Function is called before and after parsing, so it must give same
3185  * answer each time it is called. Some subcommands are transformed
3186  * into other subcommand types, so the transform must never be made to a
3187  * lower lock level than previously assigned. All transforms are noted below.
3188  *
3189  * Since this is called before we lock the table we cannot use table metadata
3190  * to influence the type of lock we acquire.
3191  *
3192  * There should be no lockmodes hardcoded into the subcommand functions. All
3193  * lockmode decisions for ALTER TABLE are made here only. The one exception is
3194  * ALTER TABLE RENAME which is treated as a different statement type T_RenameStmt
3195  * and does not travel through this section of code and cannot be combined with
3196  * any of the subcommands given here.
3197  *
3198  * Note that Hot Standby only knows about AccessExclusiveLocks on the master
3199  * so any changes that might affect SELECTs running on standbys need to use
3200  * AccessExclusiveLocks even if you think a lesser lock would do, unless you
3201  * have a solution for that also.
3202  *
3203  * Also note that pg_dump uses only an AccessShareLock, meaning that anything
3204  * that takes a lock less than AccessExclusiveLock can change object definitions
3205  * while pg_dump is running. Be careful to check that the appropriate data is
3206  * derived by pg_dump using an MVCC snapshot, rather than syscache lookups,
3207  * otherwise we might end up with an inconsistent dump that can't restore.
3208  */
3209 LOCKMODE
3211 {
3212  /*
3213  * This only works if we read catalog tables using MVCC snapshots.
3214  */
3215  ListCell *lcmd;
3217 
3218  foreach(lcmd, cmds)
3219  {
3220  AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
3221  LOCKMODE cmd_lockmode = AccessExclusiveLock; /* default for compiler */
3222 
3223  switch (cmd->subtype)
3224  {
3225  /*
3226  * These subcommands rewrite the heap, so require full locks.
3227  */
3228  case AT_AddColumn: /* may rewrite heap, in some cases and visible
3229  * to SELECT */
3230  case AT_SetTableSpace: /* must rewrite heap */
3231  case AT_AlterColumnType: /* must rewrite heap */
3232  case AT_AddOids: /* must rewrite heap */
3233  cmd_lockmode = AccessExclusiveLock;
3234  break;
3235 
3236  /*
3237  * These subcommands may require addition of toast tables. If
3238  * we add a toast table to a table currently being scanned, we
3239  * might miss data added to the new toast table by concurrent
3240  * insert transactions.
3241  */
3242  case AT_SetStorage: /* may add toast tables, see
3243  * ATRewriteCatalogs() */
3244  cmd_lockmode = AccessExclusiveLock;
3245  break;
3246 
3247  /*
3248  * Removing constraints can affect SELECTs that have been
3249  * optimised assuming the constraint holds true.
3250  */
3251  case AT_DropConstraint: /* as DROP INDEX */
3252  case AT_DropNotNull: /* may change some SQL plans */
3253  cmd_lockmode = AccessExclusiveLock;
3254  break;
3255 
3256  /*
3257  * Subcommands that may be visible to concurrent SELECTs
3258  */
3259  case AT_DropColumn: /* change visible to SELECT */
3260  case AT_AddColumnToView: /* CREATE VIEW */
3261  case AT_DropOids: /* calls AT_DropColumn */
3262  case AT_EnableAlwaysRule: /* may change SELECT rules */
3263  case AT_EnableReplicaRule: /* may change SELECT rules */
3264  case AT_EnableRule: /* may change SELECT rules */
3265  case AT_DisableRule: /* may change SELECT rules */
3266  cmd_lockmode = AccessExclusiveLock;
3267  break;
3268 
3269  /*
3270  * Changing owner may remove implicit SELECT privileges
3271  */
3272  case AT_ChangeOwner: /* change visible to SELECT */
3273  cmd_lockmode = AccessExclusiveLock;
3274  break;
3275 
3276  /*
3277  * Changing foreign table options may affect optimization.
3278  */
3279  case AT_GenericOptions:
3281  cmd_lockmode = AccessExclusiveLock;
3282  break;
3283 
3284  /*
3285  * These subcommands affect write operations only.
3286  */
3287  case AT_EnableTrig:
3288  case AT_EnableAlwaysTrig:
3289  case AT_EnableReplicaTrig:
3290  case AT_EnableTrigAll:
3291  case AT_EnableTrigUser:
3292  case AT_DisableTrig:
3293  case AT_DisableTrigAll:
3294  case AT_DisableTrigUser:
3295  cmd_lockmode = ShareRowExclusiveLock;
3296  break;
3297 
3298  /*
3299  * These subcommands affect write operations only. XXX
3300  * Theoretically, these could be ShareRowExclusiveLock.
3301  */
3302  case AT_ColumnDefault:
3303  case AT_AlterConstraint:
3304  case AT_AddIndex: /* from ADD CONSTRAINT */
3305  case AT_AddIndexConstraint:
3306  case AT_ReplicaIdentity:
3307  case AT_SetNotNull:
3308  case AT_EnableRowSecurity:
3309  case AT_DisableRowSecurity:
3310  case AT_ForceRowSecurity:
3311  case AT_NoForceRowSecurity:
3312  case AT_AddIdentity:
3313  case AT_DropIdentity:
3314  case AT_SetIdentity:
3315  cmd_lockmode = AccessExclusiveLock;
3316  break;
3317 
3318  case AT_AddConstraint:
3319  case AT_ProcessedConstraint: /* becomes AT_AddConstraint */
3320  case AT_AddConstraintRecurse: /* becomes AT_AddConstraint */
3321  case AT_ReAddConstraint: /* becomes AT_AddConstraint */
3322  if (IsA(cmd->def, Constraint))
3323  {
3324  Constraint *con = (Constraint *) cmd->def;
3325 
3326  switch (con->contype)
3327  {
3328  case CONSTR_EXCLUSION:
3329  case CONSTR_PRIMARY:
3330  case CONSTR_UNIQUE:
3331 
3332  /*
3333  * Cases essentially the same as CREATE INDEX. We
3334  * could reduce the lock strength to ShareLock if
3335  * we can work out how to allow concurrent catalog
3336  * updates. XXX Might be set down to
3337  * ShareRowExclusiveLock but requires further
3338  * analysis.
3339  */
3340  cmd_lockmode = AccessExclusiveLock;
3341  break;
3342  case CONSTR_FOREIGN:
3343 
3344  /*
3345  * We add triggers to both tables when we add a
3346  * Foreign Key, so the lock level must be at least
3347  * as strong as CREATE TRIGGER.
3348  */
3349  cmd_lockmode = ShareRowExclusiveLock;
3350  break;
3351 
3352  default:
3353  cmd_lockmode = AccessExclusiveLock;
3354  }
3355  }
3356  break;
3357 
3358  /*
3359  * These subcommands affect inheritance behaviour. Queries
3360  * started before us will continue to see the old inheritance
3361  * behaviour, while queries started after we commit will see
3362  * new behaviour. No need to prevent reads or writes to the
3363  * subtable while we hook it up though. Changing the TupDesc
3364  * may be a problem, so keep highest lock.
3365  */
3366  case AT_AddInherit:
3367  case AT_DropInherit:
3368  cmd_lockmode = AccessExclusiveLock;
3369  break;
3370 
3371  /*
3372  * These subcommands affect implicit row type conversion. They
3373  * have affects similar to CREATE/DROP CAST on queries. don't
3374  * provide for invalidating parse trees as a result of such
3375  * changes, so we keep these at AccessExclusiveLock.
3376  */
3377  case AT_AddOf:
3378  case AT_DropOf:
3379  cmd_lockmode = AccessExclusiveLock;
3380  break;
3381 
3382  /*
3383  * Only used by CREATE OR REPLACE VIEW which must conflict
3384  * with an SELECTs currently using the view.
3385  */
3386  case AT_ReplaceRelOptions:
3387  cmd_lockmode = AccessExclusiveLock;
3388  break;
3389 
3390  /*
3391  * These subcommands affect general strategies for performance
3392  * and maintenance, though don't change the semantic results
3393  * from normal data reads and writes. Delaying an ALTER TABLE
3394  * behind currently active writes only delays the point where
3395  * the new strategy begins to take effect, so there is no
3396  * benefit in waiting. In this case the minimum restriction
3397  * applies: we don't currently allow concurrent catalog
3398  * updates.
3399  */
3400  case AT_SetStatistics: /* Uses MVCC in getTableAttrs() */
3401  case AT_ClusterOn: /* Uses MVCC in getIndexes() */
3402  case AT_DropCluster: /* Uses MVCC in getIndexes() */
3403  case AT_SetOptions: /* Uses MVCC in getTableAttrs() */
3404  case AT_ResetOptions: /* Uses MVCC in getTableAttrs() */
3405  cmd_lockmode = ShareUpdateExclusiveLock;
3406  break;
3407 
3408  case AT_SetLogged:
3409  case AT_SetUnLogged:
3410  cmd_lockmode = AccessExclusiveLock;
3411  break;
3412 
3413  case AT_ValidateConstraint: /* Uses MVCC in getConstraints() */
3414  cmd_lockmode = ShareUpdateExclusiveLock;
3415  break;
3416 
3417  /*
3418  * Rel options are more complex than first appears. Options
3419  * are set here for tables, views and indexes; for historical
3420  * reasons these can all be used with ALTER TABLE, so we can't
3421  * decide between them using the basic grammar.
3422  */
3423  case AT_SetRelOptions: /* Uses MVCC in getIndexes() and
3424  * getTables() */
3425  case AT_ResetRelOptions: /* Uses MVCC in getIndexes() and
3426  * getTables() */
3427  cmd_lockmode = AlterTableGetRelOptionsLockLevel((List *) cmd->def);
3428  break;
3429 
3430  case AT_AttachPartition:
3431  case AT_DetachPartition:
3432  cmd_lockmode = AccessExclusiveLock;
3433  break;
3434 
3435  default: /* oops */
3436  elog(ERROR, "unrecognized alter table type: %d",
3437  (int) cmd->subtype);
3438  break;
3439  }
3440 
3441  /*
3442  * Take the greatest lockmode from any subcommand
3443  */
3444  if (cmd_lockmode > lockmode)
3445  lockmode = cmd_lockmode;
3446  }
3447 
3448  return lockmode;
3449 }
3450 
3451 /*
3452  * ATController provides top level control over the phases.
3453  *
3454  * parsetree is passed in to allow it to be passed to event triggers
3455  * when requested.
3456  */
3457 static void
3459  Relation rel, List *cmds, bool recurse, LOCKMODE lockmode)
3460 {
3461  List *wqueue = NIL;
3462  ListCell *lcmd;
3463 
3464  /* Phase 1: preliminary examination of commands, create work queue */
3465  foreach(lcmd, cmds)
3466  {
3467  AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
3468 
3469  ATPrepCmd(&wqueue, rel, cmd, recurse, false, lockmode);
3470  }
3471 
3472  /* Close the relation, but keep lock until commit */
3473  relation_close(rel, NoLock);
3474 
3475  /* Phase 2: update system catalogs */
3476  ATRewriteCatalogs(&wqueue, lockmode);
3477 
3478  /* Phase 3: scan/rewrite tables as needed */
3479  ATRewriteTables(parsetree, &wqueue, lockmode);
3480 }
3481 
3482 /*
3483  * ATPrepCmd
3484  *
3485  * Traffic cop for ALTER TABLE Phase 1 operations, including simple
3486  * recursion and permission checks.
3487  *
3488  * Caller must have acquired appropriate lock type on relation already.
3489  * This lock should be held until commit.
3490  */
3491 static void
3492 ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
3493  bool recurse, bool recursing, LOCKMODE lockmode)
3494 {
3495  AlteredTableInfo *tab;
3496  int pass = AT_PASS_UNSET;
3497 
3498  /* Find or create work queue entry for this table */
3499  tab = ATGetQueueEntry(wqueue, rel);
3500 
3501  /*
3502  * Copy the original subcommand for each table. This avoids conflicts
3503  * when different child tables need to make different parse
3504  * transformations (for example, the same column may have different column
3505  * numbers in different children).
3506  */
3507  cmd = copyObject(cmd);
3508 
3509  /*
3510  * Do permissions checking, recursion to child tables if needed, and any
3511  * additional phase-1 processing needed.
3512  */
3513  switch (cmd->subtype)
3514  {
3515  case AT_AddColumn: /* ADD COLUMN */
3516  ATSimplePermissions(rel,
3518  ATPrepAddColumn(wqueue, rel, recurse, recursing, false, cmd,
3519  lockmode);
3520  /* Recursion occurs during execution phase */
3521  pass = AT_PASS_ADD_COL;
3522  break;
3523  case AT_AddColumnToView: /* add column via CREATE OR REPLACE VIEW */
3525  ATPrepAddColumn(wqueue, rel, recurse, recursing, true, cmd,
3526  lockmode);
3527  /* Recursion occurs during execution phase */
3528  pass = AT_PASS_ADD_COL;
3529  break;
3530  case AT_ColumnDefault: /* ALTER COLUMN DEFAULT */
3531 
3532  /*
3533  * We allow defaults on views so that INSERT into a view can have
3534  * default-ish behavior. This works because the rewriter
3535  * substitutes default values into INSERTs before it expands
3536  * rules.
3537  */
3539  ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
3540  /* No command-specific prep needed */
3541  pass = cmd->def ? AT_PASS_ADD_CONSTR : AT_PASS_DROP;
3542  break;
3543  case AT_AddIdentity:
3545  pass = AT_PASS_ADD_CONSTR;
3546  break;
3547  case AT_DropIdentity:
3549  pass = AT_PASS_DROP;
3550  break;
3551  case AT_SetIdentity:
3553  pass = AT_PASS_COL_ATTRS;
3554  break;
3555  case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */
3557  ATPrepDropNotNull(rel, recurse, recursing);
3558  ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
3559  /* No command-specific prep needed */
3560  pass = AT_PASS_DROP;
3561  break;
3562  case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */
3564  ATPrepSetNotNull(rel, recurse, recursing);
3565  ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
3566  /* No command-specific prep needed */
3567  pass = AT_PASS_ADD_CONSTR;
3568  break;
3569  case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */
3570  ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
3571  /* Performs own permission checks */
3572  ATPrepSetStatistics(rel, cmd->name, cmd->num, cmd->def, lockmode);
3573  pass = AT_PASS_MISC;
3574  break;
3575  case AT_SetOptions: /* ALTER COLUMN SET ( options ) */
3576  case AT_ResetOptions: /* ALTER COLUMN RESET ( options ) */
3578  /* This command never recurses */
3579  pass = AT_PASS_MISC;
3580  break;
3581  case AT_SetStorage: /* ALTER COLUMN SET STORAGE */
3583  ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
3584  /* No command-specific prep needed */
3585  pass = AT_PASS_MISC;
3586  break;
3587  case AT_DropColumn: /* DROP COLUMN */
3588  ATSimplePermissions(rel,
3590  ATPrepDropColumn(wqueue, rel, recurse, recursing, cmd, lockmode);
3591  /* Recursion occurs during execution phase */
3592  pass = AT_PASS_DROP;
3593  break;
3594  case AT_AddIndex: /* ADD INDEX */
3596  /* This command never recurses */
3597  /* No command-specific prep needed */
3598  pass = AT_PASS_ADD_INDEX;
3599  break;
3600  case AT_AddConstraint: /* ADD CONSTRAINT */
3602  /* Recursion occurs during execution phase */
3603  /* No command-specific prep needed except saving recurse flag */
3604  if (recurse)
3606  pass = AT_PASS_ADD_CONSTR;
3607  break;
3608  case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */
3610  /* This command never recurses */
3611  /* No command-specific prep needed */
3612  pass = AT_PASS_ADD_CONSTR;
3613  break;
3614  case AT_DropConstraint: /* DROP CONSTRAINT */
3616  /* Recursion occurs during execution phase */
3617  /* No command-specific prep needed except saving recurse flag */
3618  if (recurse)
3620  pass = AT_PASS_DROP;
3621  break;
3622  case AT_AlterColumnType: /* ALTER COLUMN TYPE */
3623  ATSimplePermissions(rel,
3625  /* Performs own recursion */
3626  ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd, lockmode);
3627  pass = AT_PASS_ALTER_TYPE;
3628  break;
3631  /* This command never recurses */
3632  /* No command-specific prep needed */
3633  pass = AT_PASS_MISC;
3634  break;
3635  case AT_ChangeOwner: /* ALTER OWNER */
3636  /* This command never recurses */
3637  /* No command-specific prep needed */
3638  pass = AT_PASS_MISC;
3639  break;
3640  case AT_ClusterOn: /* CLUSTER ON */
3641  case AT_DropCluster: /* SET WITHOUT CLUSTER */
3643  /* These commands never recurse */
3644  /* No command-specific prep needed */
3645  pass = AT_PASS_MISC;
3646  break;
3647  case AT_SetLogged: /* SET LOGGED */
3649  tab->chgPersistence = ATPrepChangePersistence(rel, true);
3650  /* force rewrite if necessary; see comment in ATRewriteTables */
3651  if (tab->chgPersistence)
3652  {
3655  }
3656  pass = AT_PASS_MISC;
3657  break;
3658  case AT_SetUnLogged: /* SET UNLOGGED */
3660  tab->chgPersistence = ATPrepChangePersistence(rel, false);
3661  /* force rewrite if necessary; see comment in ATRewriteTables */
3662  if (tab->chgPersistence)
3663  {
3666  }
3667  pass = AT_PASS_MISC;
3668  break;
3669  case AT_AddOids: /* SET WITH OIDS */
3671  if (!rel->rd_rel->relhasoids || recursing)
3672  ATPrepAddOids(wqueue, rel, recurse, cmd, lockmode);
3673  /* Recursion occurs during execution phase */
3674  pass = AT_PASS_ADD_COL;
3675  break;
3676  case AT_DropOids: /* SET WITHOUT OIDS */
3678  /* Performs own recursion */
3679  if (rel->rd_rel->relhasoids)
3680  {
3681  AlterTableCmd *dropCmd = makeNode(AlterTableCmd);
3682 
3683  dropCmd->subtype = AT_DropColumn;
3684  dropCmd->name = pstrdup("oid");
3685  dropCmd->behavior = cmd->behavior;
3686  ATPrepCmd(wqueue, rel, dropCmd, recurse, false, lockmode);
3687  }
3688  pass = AT_PASS_DROP;
3689  break;
3690  case AT_SetTableSpace: /* SET TABLESPACE */
3692  /* This command never recurses */
3693  ATPrepSetTableSpace(tab, rel, cmd->name, lockmode);
3694  pass = AT_PASS_MISC; /* doesn't actually matter */
3695  break;
3696  case AT_SetRelOptions: /* SET (...) */
3697  case AT_ResetRelOptions: /* RESET (...) */
3698  case AT_ReplaceRelOptions: /* reset them all, then set just these */
3700  /* This command never recurses */
3701  /* No command-specific prep needed */
3702  pass = AT_PASS_MISC;
3703  break;
3704  case AT_AddInherit: /* INHERIT */
3706  /* This command never recurses */
3707  ATPrepAddInherit(rel);
3708  pass = AT_PASS_MISC;
3709  break;
3710  case AT_DropInherit: /* NO INHERIT */
3712  /* This command never recurses */
3713  /* No command-specific prep needed */
3714  pass = AT_PASS_MISC;
3715  break;
3716  case AT_AlterConstraint: /* ALTER CONSTRAINT */
3718  pass = AT_PASS_MISC;
3719  break;
3720  case AT_ValidateConstraint: /* VALIDATE CONSTRAINT */
3722  /* Recursion occurs during execution phase */
3723  /* No command-specific prep needed except saving recurse flag */
3724  if (recurse)
3726  pass = AT_PASS_MISC;
3727  break;
3728  case AT_ReplicaIdentity: /* REPLICA IDENTITY ... */
3730  pass = AT_PASS_MISC;
3731  /* This command never recurses */
3732  /* No command-specific prep needed */
3733  break;
3734  case AT_EnableTrig: /* ENABLE TRIGGER variants */
3735  case AT_EnableAlwaysTrig:
3736  case AT_EnableReplicaTrig:
3737  case AT_EnableTrigAll:
3738  case AT_EnableTrigUser:
3739  case AT_DisableTrig: /* DISABLE TRIGGER variants */
3740  case AT_DisableTrigAll:
3741  case AT_DisableTrigUser:
3743  pass = AT_PASS_MISC;
3744  break;
3745  case AT_EnableRule: /* ENABLE/DISABLE RULE variants */
3746  case AT_EnableAlwaysRule:
3747  case AT_EnableReplicaRule:
3748  case AT_DisableRule:
3749  case AT_AddOf: /* OF */
3750  case AT_DropOf: /* NOT OF */
3751  case AT_EnableRowSecurity:
3752  case AT_DisableRowSecurity:
3753  case AT_ForceRowSecurity:
3754  case AT_NoForceRowSecurity:
3756  /* These commands never recurse */
3757  /* No command-specific prep needed */
3758  pass = AT_PASS_MISC;
3759  break;
3760  case AT_GenericOptions:
3762  /* No command-specific prep needed */
3763  pass = AT_PASS_MISC;
3764  break;
3765  case AT_AttachPartition:
3766  case AT_DetachPartition:
3768  /* No command-specific prep needed */
3769  pass = AT_PASS_MISC;
3770  break;
3771  default: /* oops */
3772  elog(ERROR, "unrecognized alter table type: %d",
3773  (int) cmd->subtype);
3774  pass = AT_PASS_UNSET; /* keep compiler quiet */
3775  break;
3776  }
3777  Assert(pass > AT_PASS_UNSET);
3778 
3779  /* Add the subcommand to the appropriate list for phase 2 */
3780  tab->subcmds[pass] = lappend(tab->subcmds[pass], cmd);
3781 }
3782 
3783 /*
3784  * ATRewriteCatalogs
3785  *
3786  * Traffic cop for ALTER TABLE Phase 2 operations. Subcommands are
3787  * dispatched in a "safe" execution order (designed to avoid unnecessary
3788  * conflicts).
3789  */
3790 static void
3791 ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode)
3792 {
3793  int pass;
3794  ListCell *ltab;
3795 
3796  /*
3797  * We process all the tables "in parallel", one pass at a time. This is
3798  * needed because we may have to propagate work from one table to another
3799  * (specifically, ALTER TYPE on a foreign key's PK has to dispatch the
3800  * re-adding of the foreign key constraint to the other table). Work can
3801  * only be propagated into later passes, however.
3802  */
3803  for (pass = 0; pass < AT_NUM_PASSES; pass++)
3804  {
3805  /* Go through each table that needs to be processed */
3806  foreach(ltab, *wqueue)
3807  {
3808  AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
3809  List *subcmds = tab->subcmds[pass];
3810  Relation rel;
3811  ListCell *lcmd;
3812 
3813  if (subcmds == NIL)
3814  continue;
3815 
3816  /*
3817  * Appropriate lock was obtained by phase 1, needn't get it again
3818  */
3819  rel = relation_open(tab->relid, NoLock);
3820 
3821  foreach(lcmd, subcmds)
3822  ATExecCmd(wqueue, tab, rel, (AlterTableCmd *) lfirst(lcmd), lockmode);
3823 
3824  /*
3825  * After the ALTER TYPE pass, do cleanup work (this is not done in
3826  * ATExecAlterColumnType since it should be done only once if
3827  * multiple columns of a table are altered).
3828  */
3829  if (pass == AT_PASS_ALTER_TYPE)
3830  ATPostAlterTypeCleanup(wqueue, tab, lockmode);
3831 
3832  relation_close(rel, NoLock);
3833  }
3834  }
3835 
3836  /* Check to see if a toast table must be added. */
3837  foreach(ltab, *wqueue)
3838  {
3839  AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
3840 
3841  /*
3842  * If the table is source table of ATTACH PARTITION command, we did
3843  * not modify anything about it that will change its toasting
3844  * requirement, so no need to check.
3845  */
3846  if (((tab->relkind == RELKIND_RELATION ||
3848  tab->partition_constraint == NULL) ||
3849  tab->relkind == RELKIND_MATVIEW)
3850  AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode);
3851  }
3852 }
3853 
3854 /*
3855  * ATExecCmd: dispatch a subcommand to appropriate execution routine
3856  */
3857 static void
3859  AlterTableCmd *cmd, LOCKMODE lockmode)
3860 {
3862 
3863  switch (cmd->subtype)
3864  {
3865  case AT_AddColumn: /* ADD COLUMN */
3866  case AT_AddColumnToView: /* add column via CREATE OR REPLACE VIEW */
3867  address = ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3868  false, false, false,
3869  false, lockmode);
3870  break;
3871  case AT_AddColumnRecurse:
3872  address = ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3873  false, true, false,
3874  cmd->missing_ok, lockmode);
3875  break;
3876  case AT_ColumnDefault: /* ALTER COLUMN DEFAULT */
3877  address = ATExecColumnDefault(rel, cmd->name, cmd->def, lockmode);
3878  break;
3879  case AT_AddIdentity:
3880  address = ATExecAddIdentity(rel, cmd->name, cmd->def, lockmode);
3881  break;
3882  case AT_SetIdentity:
3883  address = ATExecSetIdentity(rel, cmd->name, cmd->def, lockmode);
3884  break;
3885  case AT_DropIdentity:
3886  address = ATExecDropIdentity(rel, cmd->name, cmd->missing_ok, lockmode);
3887  break;
3888  case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */
3889  address = ATExecDropNotNull(rel, cmd->name, lockmode);
3890  break;
3891  case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */
3892  address = ATExecSetNotNull(tab, rel, cmd->name, lockmode);
3893  break;
3894  case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */
3895  address = ATExecSetStatistics(rel, cmd->name, cmd->num, cmd->def, lockmode);
3896  break;
3897  case AT_SetOptions: /* ALTER COLUMN SET ( options ) */
3898  address = ATExecSetOptions(rel, cmd->name, cmd->def, false, lockmode);
3899  break;
3900  case AT_ResetOptions: /* ALTER COLUMN RESET ( options ) */
3901  address = ATExecSetOptions(rel, cmd->name, cmd->def, true, lockmode);
3902  break;
3903  case AT_SetStorage: /* ALTER COLUMN SET STORAGE */
3904  address = ATExecSetStorage(rel, cmd->name, cmd->def, lockmode);
3905  break;
3906  case AT_DropColumn: /* DROP COLUMN */
3907  address = ATExecDropColumn(wqueue, rel, cmd->name,
3908  cmd->behavior, false, false,
3909  cmd->missing_ok, lockmode);
3910  break;
3911  case AT_DropColumnRecurse: /* DROP COLUMN with recursion */
3912  address = ATExecDropColumn(wqueue, rel, cmd->name,
3913  cmd->behavior, true, false,
3914  cmd->missing_ok, lockmode);
3915  break;
3916  case AT_AddIndex: /* ADD INDEX */
3917  address = ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, false,
3918  lockmode);
3919  break;
3920  case AT_ReAddIndex: /* ADD INDEX */
3921  address = ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true,
3922  lockmode);
3923  break;
3924  case AT_AddConstraint: /* ADD CONSTRAINT */
3925  address =
3926  ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
3927  false, false, lockmode);
3928  break;
3929  case AT_AddConstraintRecurse: /* ADD CONSTRAINT with recursion */
3930  address =
3931  ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
3932  true, false, lockmode);
3933  break;
3934  case AT_ReAddConstraint: /* Re-add pre-existing check constraint */
3935  address =
3936  ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
3937  true, true, lockmode);
3938  break;
3939  case AT_ReAddComment: /* Re-add existing comment */
3940  address = CommentObject((CommentStmt *) cmd->def);
3941  break;
3942  case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */
3943  address = ATExecAddIndexConstraint(tab, rel, (IndexStmt *) cmd->def,
3944  lockmode);
3945  break;
3946  case AT_AlterConstraint: /* ALTER CONSTRAINT */
3947  address = ATExecAlterConstraint(rel, cmd, false, false, lockmode);
3948  break;
3949  case AT_ValidateConstraint: /* VALIDATE CONSTRAINT */
3950  address = ATExecValidateConstraint(rel, cmd->name, false, false,
3951  lockmode);
3952  break;
3953  case AT_ValidateConstraintRecurse: /* VALIDATE CONSTRAINT with
3954  * recursion */
3955  address = ATExecValidateConstraint(rel, cmd->name, true, false,
3956  lockmode);
3957  break;
3958  case AT_DropConstraint: /* DROP CONSTRAINT */
3959  ATExecDropConstraint(rel, cmd->name, cmd->behavior,
3960  false, false,
3961  cmd->missing_ok, lockmode);
3962  break;
3963  case AT_DropConstraintRecurse: /* DROP CONSTRAINT with recursion */
3964  ATExecDropConstraint(rel, cmd->name, cmd->behavior,
3965  true, false,
3966  cmd->missing_ok, lockmode);
3967  break;
3968  case AT_AlterColumnType: /* ALTER COLUMN TYPE */
3969  address = ATExecAlterColumnType(tab, rel, cmd, lockmode);
3970  break;
3971  case AT_AlterColumnGenericOptions: /* ALTER COLUMN OPTIONS */
3972  address =
3974  (List *) cmd->def, lockmode);
3975  break;
3976  case AT_ChangeOwner: /* ALTER OWNER */
3978  get_rolespec_oid(cmd->newowner, false),
3979  false, lockmode);
3980  break;
3981  case AT_ClusterOn: /* CLUSTER ON */
3982  address = ATExecClusterOn(rel, cmd->name, lockmode);
3983  break;
3984  case AT_DropCluster: /* SET WITHOUT CLUSTER */
3985  ATExecDropCluster(rel, lockmode);
3986  break;
3987  case AT_SetLogged: /* SET LOGGED */
3988  case AT_SetUnLogged: /* SET UNLOGGED */
3989  break;
3990  case AT_AddOids: /* SET WITH OIDS */
3991  /* Use the ADD COLUMN code, unless prep decided to do nothing */
3992  if (cmd->def != NULL)
3993  address =
3994  ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3995  true, false, false,
3996  cmd->missing_ok, lockmode);
3997  break;
3998  case AT_AddOidsRecurse: /* SET WITH OIDS */
3999  /* Use the ADD COLUMN code, unless prep decided to do nothing */
4000  if (cmd->def != NULL)
4001  address =
4002  ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
4003  true, true, false,
4004  cmd->missing_ok, lockmode);
4005  break;
4006  case AT_DropOids: /* SET WITHOUT OIDS */
4007 
4008  /*
4009  * Nothing to do here; we'll have generated a DropColumn
4010  * subcommand to do the real work
4011  */
4012  break;
4013  case AT_SetTableSpace: /* SET TABLESPACE */
4014 
4015  /*
4016  * Nothing to do here; Phase 3 does the work
4017  */
4018  break;
4019  case AT_SetRelOptions: /* SET (...) */
4020  case AT_ResetRelOptions: /* RESET (...) */
4021  case AT_ReplaceRelOptions: /* replace entire option list */
4022  ATExecSetRelOptions(rel, (List *) cmd->def, cmd->subtype, lockmode);
4023  break;
4024  case AT_EnableTrig: /* ENABLE TRIGGER name */
4025  ATExecEnableDisableTrigger(rel, cmd->name,
4026  TRIGGER_FIRES_ON_ORIGIN, false, lockmode);
4027  break;
4028  case AT_EnableAlwaysTrig: /* ENABLE ALWAYS TRIGGER name */
4029  ATExecEnableDisableTrigger(rel, cmd->name,
4030  TRIGGER_FIRES_ALWAYS, false, lockmode);
4031  break;
4032  case AT_EnableReplicaTrig: /* ENABLE REPLICA TRIGGER name */
4033  ATExecEnableDisableTrigger(rel, cmd->name,
4034  TRIGGER_FIRES_ON_REPLICA, false, lockmode);
4035  break;
4036  case AT_DisableTrig: /* DISABLE TRIGGER name */
4037  ATExecEnableDisableTrigger(rel, cmd->name,
4038  TRIGGER_DISABLED, false, lockmode);
4039  break;
4040  case AT_EnableTrigAll: /* ENABLE TRIGGER ALL */
4041  ATExecEnableDisableTrigger(rel, NULL,
4042  TRIGGER_FIRES_ON_ORIGIN, false, lockmode);
4043  break;
4044  case AT_DisableTrigAll: /* DISABLE TRIGGER ALL */
4045  ATExecEnableDisableTrigger(rel, NULL,
4046  TRIGGER_DISABLED, false, lockmode);
4047  break;
4048  case AT_EnableTrigUser: /* ENABLE TRIGGER USER */
4049  ATExecEnableDisableTrigger(rel, NULL,
4050  TRIGGER_FIRES_ON_ORIGIN, true, lockmode);
4051  break;
4052  case AT_DisableTrigUser: /* DISABLE TRIGGER USER */
4053  ATExecEnableDisableTrigger(rel, NULL,
4054  TRIGGER_DISABLED, true, lockmode);
4055  break;
4056 
4057  case AT_EnableRule: /* ENABLE RULE name */
4058  ATExecEnableDisableRule(rel, cmd->name,
4059  RULE_FIRES_ON_ORIGIN, lockmode);
4060  break;
4061  case AT_EnableAlwaysRule: /* ENABLE ALWAYS RULE name */
4062  ATExecEnableDisableRule(rel, cmd->name,
4063  RULE_FIRES_ALWAYS, lockmode);
4064  break;
4065  case AT_EnableReplicaRule: /* ENABLE REPLICA RULE name */
4066  ATExecEnableDisableRule(rel, cmd->name,
4067  RULE_FIRES_ON_REPLICA, lockmode);
4068  break;
4069  case AT_DisableRule: /* DISABLE RULE name */
4070  ATExecEnableDisableRule(rel, cmd->name,
4071  RULE_DISABLED, lockmode);
4072  break;
4073 
4074  case AT_AddInherit:
4075  address = ATExecAddInherit(rel, (RangeVar *) cmd->def, lockmode);
4076  break;
4077  case AT_DropInherit:
4078  address = ATExecDropInherit(rel, (RangeVar *) cmd->def, lockmode);
4079  break;
4080  case AT_AddOf:
4081  address = ATExecAddOf(rel, (TypeName *) cmd->def, lockmode);
4082  break;
4083  case AT_DropOf:
4084  ATExecDropOf(rel, lockmode);
4085  break;
4086  case AT_ReplicaIdentity:
4087  ATExecReplicaIdentity(rel, (ReplicaIdentityStmt *) cmd->def, lockmode);
4088  break;
4089  case AT_EnableRowSecurity:
4091  break;
4092  case AT_DisableRowSecurity:
4094  break;
4095  case AT_ForceRowSecurity:
4096  ATExecForceNoForceRowSecurity(rel, true);
4097  break;
4098  case AT_NoForceRowSecurity:
4099  ATExecForceNoForceRowSecurity(rel, false);
4100  break;
4101  case AT_GenericOptions:
4102  ATExecGenericOptions(rel, (List *) cmd->def);
4103  break;
4104  case AT_AttachPartition:
4105  ATExecAttachPartition(wqueue, rel, (PartitionCmd *) cmd->def);
4106  break;
4107  case AT_DetachPartition:
4108  ATExecDetachPartition(rel, ((PartitionCmd *) cmd->def)->name);
4109  break;
4110  default: /* oops */
4111  elog(ERROR, "unrecognized alter table type: %d",
4112  (int) cmd->subtype);
4113  break;
4114  }
4115 
4116  /*
4117  * Report the subcommand to interested event triggers.
4118  */
4119  EventTriggerCollectAlterTableSubcmd((Node *) cmd, address);
4120 
4121  /*
4122  * Bump the command counter to ensure the next subcommand in the sequence
4123  * can see the changes so far
4124  */
4126 }
4127 
4128 /*
4129  * ATRewriteTables: ALTER TABLE phase 3
4130  */
4131 static void
4132 ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode)
4133 {
4134  ListCell *ltab;
4135 
4136  /* Go through each table that needs to be checked or rewritten */
4137  foreach(ltab, *wqueue)
4138  {
4139  AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
4140 
4141  /* Foreign tables have no storage, nor do partitioned tables. */
4142  if (tab->relkind == RELKIND_FOREIGN_TABLE ||
4144  continue;
4145 
4146  /*
4147  * If we change column data types or add/remove OIDs, the operation
4148  * has to be propagated to tables that use this table's rowtype as a
4149  * column type. tab->newvals will also be non-NULL in the case where
4150  * we're adding a column with a default. We choose to forbid that
4151  * case as well, since composite types might eventually support
4152  * defaults.
4153  *
4154  * (Eventually we'll probably need to check for composite type
4155  * dependencies even when we're just scanning the table without a
4156  * rewrite, but at the moment a composite type does not enforce any
4157  * constraints, so it's not necessary/appropriate to enforce them just
4158  * during ALTER.)
4159  */
4160  if (tab->newvals != NIL || tab->rewrite > 0)
4161  {
4162  Relation rel;
4163 
4164  rel = heap_open(tab->relid, NoLock);
4165  find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
4166  heap_close(rel, NoLock);
4167  }
4168 
4169  /*
4170  * We only need to rewrite the table if at least one column needs to
4171  * be recomputed, we are adding/removing the OID column, or we are
4172  * changing its persistence.
4173  *
4174  * There are two reasons for requiring a rewrite when changing
4175  * persistence: on one hand, we need to ensure that the buffers
4176  * belonging to each of the two relations are marked with or without
4177  * BM_PERMANENT properly. On the other hand, since rewriting creates
4178  * and assigns a new relfilenode, we automatically create or drop an
4179  * init fork for the relation as appropriate.
4180  */
4181  if (tab->rewrite > 0)
4182  {
4183  /* Build a temporary relation and copy data */
4184  Relation OldHeap;
4185  Oid OIDNewHeap;
4186  Oid NewTableSpace;
4187  char persistence;
4188 
4189  OldHeap = heap_open(tab->relid, NoLock);
4190 
4191  /*
4192  * We don't support rewriting of system catalogs; there are too
4193  * many corner cases and too little benefit. In particular this
4194  * is certainly not going to work for mapped catalogs.
4195  */
4196  if (IsSystemRelation(OldHeap))
4197  ereport(ERROR,
4198  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4199  errmsg("cannot rewrite system relation \"%s\"",
4200  RelationGetRelationName(OldHeap))));
4201 
4202  if (RelationIsUsedAsCatalogTable(OldHeap))
4203  ereport(ERROR,
4204  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4205  errmsg("cannot rewrite table \"%s\" used as a catalog table",
4206  RelationGetRelationName(OldHeap))));
4207 
4208  /*
4209  * Don't allow rewrite on temp tables of other backends ... their
4210  * local buffer manager is not going to cope.
4211  */
4212  if (RELATION_IS_OTHER_TEMP(OldHeap))
4213  ereport(ERROR,
4214  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4215  errmsg("cannot rewrite temporary tables of other sessions")));
4216 
4217  /*
4218  * Select destination tablespace (same as original unless user
4219  * requested a change)
4220  */
4221  if (tab->newTableSpace)
4222  NewTableSpace = tab->newTableSpace;
4223  else
4224  NewTableSpace = OldHeap->rd_rel->reltablespace;
4225 
4226  /*
4227  * Select persistence of transient table (same as original unless
4228  * user requested a change)
4229  */
4230  persistence = tab->chgPersistence ?
4231  tab->newrelpersistence : OldHeap->rd_rel->relpersistence;
4232 
4233  heap_close(OldHeap, NoLock);
4234 
4235  /*
4236  * Fire off an Event Trigger now, before actually rewriting the
4237  * table.
4238  *
4239  * We don't support Event Trigger for nested commands anywhere,
4240  * here included, and parsetree is given NULL when coming from
4241  * AlterTableInternal.
4242  *
4243  * And fire it only once.
4244  */
4245  if (parsetree)
4246  EventTriggerTableRewrite((Node *) parsetree,
4247  tab->relid,
4248  tab->rewrite);
4249 
4250  /*
4251  * Create transient table that will receive the modified data.
4252  *
4253  * Ensure it is marked correctly as logged or unlogged. We have
4254  * to do this here so that buffers for the new relfilenode will
4255  * have the right persistence set, and at the same time ensure
4256  * that the original filenode's buffers will get read in with the
4257  * correct setting (i.e. the original one). Otherwise a rollback
4258  * after the rewrite would possibly result with buffers for the
4259  * original filenode having the wrong persistence setting.
4260  *
4261  * NB: This relies on swap_relation_files() also swapping the
4262  * persistence. That wouldn't work for pg_class, but that can't be
4263  * unlogged anyway.
4264  */
4265  OIDNewHeap = make_new_heap(tab->relid, NewTableSpace, persistence,
4266  lockmode);
4267 
4268  /*
4269  * Copy the heap data into the new table with the desired
4270  * modifications, and test the current data within the table
4271  * against new constraints generated by ALTER TABLE commands.
4272  */
4273  ATRewriteTable(tab, OIDNewHeap, lockmode);
4274 
4275  /*
4276  * Swap the physical files of the old and new heaps, then rebuild
4277  * indexes and discard the old heap. We can use RecentXmin for
4278  * the table's new relfrozenxid because we rewrote all the tuples
4279  * in ATRewriteTable, so no older Xid remains in the table. Also,
4280  * we never try to swap toast tables by content, since we have no
4281  * interest in letting this code work on system catalogs.
4282  */
4283  finish_heap_swap(tab->relid, OIDNewHeap,
4284  false, false, true,
4285  !OidIsValid(tab->newTableSpace),
4286  RecentXmin,
4288  persistence);
4289  }
4290  else
4291  {
4292  /*
4293  * Test the current data within the table against new constraints
4294  * generated by ALTER TABLE commands, but don't rebuild data.
4295  */
4296  if (tab->constraints != NIL || tab->new_notnull ||
4297  tab->partition_constraint != NULL)
4298  ATRewriteTable(tab, InvalidOid, lockmode);
4299 
4300  /*
4301  * If we had SET TABLESPACE but no reason to reconstruct tuples,
4302  * just do a block-by-block copy.
4303  */
4304  if (tab->newTableSpace)
4305  ATExecSetTableSpace(tab->relid, tab->newTableSpace, lockmode);
4306  }
4307  }
4308 
4309  /*
4310  * Foreign key constraints are checked in a final pass, since (a) it's
4311  * generally best to examine each one separately, and (b) it's at least
4312  * theoretically possible that we have changed both relations of the
4313  * foreign key, and we'd better have finished both rewrites before we try
4314  * to read the tables.
4315  */
4316  foreach(ltab, *wqueue)
4317  {
4318  AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
4319  Relation rel = NULL;
4320  ListCell *lcon;
4321 
4322  foreach(lcon, tab->constraints)
4323  {
4324  NewConstraint *con = lfirst(lcon);
4325 
4326  if (con->contype == CONSTR_FOREIGN)
4327  {
4328  Constraint *fkconstraint = (Constraint *) con->qual;
4329  Relation refrel;
4330 
4331  if (rel == NULL)
4332  {
4333  /* Long since locked, no need for another */
4334  rel = heap_open(tab->relid, NoLock);
4335  }
4336 
4337  refrel = heap_open(con->refrelid, RowShareLock);
4338 
4339  validateForeignKeyConstraint(fkconstraint->conname, rel, refrel,
4340  con->refindid,
4341  con->conid);
4342 
4343  /*
4344  * No need to mark the constraint row as validated, we did
4345  * that when we inserted the row earlier.
4346  */
4347 
4348  heap_close(refrel, NoLock);
4349  }
4350  }
4351 
4352  if (rel)
4353  heap_close(rel, NoLock);
4354  }
4355 }
4356 
4357 /*
4358  * ATRewriteTable: scan or rewrite one table
4359  *
4360  * OIDNewHeap is InvalidOid if we don't need to rewrite
4361  */
4362 static void
4363 ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
4364 {
4365  Relation oldrel;
4366  Relation newrel;
4367  TupleDesc oldTupDesc;
4368  TupleDesc newTupDesc;
4369  bool needscan = false;
4370  List *notnull_attrs;
4371  int i;
4372  ListCell *l;
4373  EState *estate;
4374  CommandId mycid;
4375  BulkInsertState bistate;
4376  int hi_options;
4377  ExprState *partqualstate = NULL;
4378 
4379  /*
4380  * Open the relation(s). We have surely already locked the existing
4381  * table.
4382  */
4383  oldrel = heap_open(tab->relid, NoLock);
4384  oldTupDesc = tab->oldDesc;
4385  newTupDesc = RelationGetDescr(oldrel); /* includes all mods */
4386 
4387  if (OidIsValid(OIDNewHeap))
4388  newrel = heap_open(OIDNewHeap, lockmode);
4389  else
4390  newrel = NULL;
4391 
4392  /*
4393  * Prepare a BulkInsertState and options for heap_insert. Because we're
4394  * building a new heap, we can skip WAL-logging and fsync it to disk at
4395  * the end instead (unless WAL-logging is required for archiving or
4396  * streaming replication). The FSM is empty too, so don't bother using it.
4397  */
4398  if (newrel)
4399  {
4400  mycid = GetCurrentCommandId(true);
4401  bistate = GetBulkInsertState();
4402 
4403  hi_options = HEAP_INSERT_SKIP_FSM;
4404  if (!XLogIsNeeded())
4405  hi_options |= HEAP_INSERT_SKIP_WAL;
4406  }
4407  else
4408  {
4409  /* keep compiler quiet about using these uninitialized */
4410  mycid = 0;
4411  bistate = NULL;
4412  hi_options = 0;
4413  }
4414 
4415  /*
4416  * Generate the constraint and default execution states
4417  */
4418 
4419  estate = CreateExecutorState();
4420 
4421  /* Build the needed expression execution states */
4422  foreach(l, tab->constraints)
4423  {
4424  NewConstraint *con = lfirst(l);
4425 
4426  switch (con->contype)
4427  {
4428  case CONSTR_CHECK:
4429  needscan = true;
4430  con->qualstate = ExecPrepareExpr((Expr *) con->qual, estate);
4431  break;
4432  case CONSTR_FOREIGN:
4433  /* Nothing to do here */
4434  break;
4435  default:
4436  elog(ERROR, "unrecognized constraint type: %d",
4437  (int) con->contype);
4438  }
4439  }
4440 
4441  /* Build expression execution states for partition check quals */
4442  if (tab->partition_constraint)
4443  {
4444  needscan = true;
4445  partqualstate = ExecPrepareExpr(tab->partition_constraint, estate);
4446  }
4447 
4448  foreach(l, tab->newvals)
4449  {
4450  NewColumnValue *ex = lfirst(l);
4451 
4452  /* expr already planned */
4453  ex->exprstate = ExecInitExpr((Expr *) ex->expr, NULL);
4454  }
4455 
4456  notnull_attrs = NIL;
4457  if (newrel || tab->new_notnull)
4458  {
4459  /*
4460  * If we are rebuilding the tuples OR if we added any new NOT NULL
4461  * constraints, check all not-null constraints. This is a bit of
4462  * overkill but it minimizes risk of bugs, and heap_attisnull is a
4463  * pretty cheap test anyway.
4464  */
4465  for (i = 0; i < newTupDesc->natts; i++)
4466  {
4467  Form_pg_attribute attr = TupleDescAttr(newTupDesc, i);
4468 
4469  if (attr->attnotnull && !attr->attisdropped)
4470  notnull_attrs = lappend_int(notnull_attrs, i);
4471  }
4472  if (notnull_attrs)
4473  needscan = true;
4474  }
4475 
4476  if (newrel || needscan)
4477  {
4478  ExprContext *econtext;
4479  Datum *values;
4480  bool *isnull;
4481  TupleTableSlot *oldslot;
4482  TupleTableSlot *newslot;
4483  HeapScanDesc scan;
4484  HeapTuple tuple;
4485  MemoryContext oldCxt;
4486  List *dropped_attrs = NIL;
4487  ListCell *lc;
4488  Snapshot snapshot;
4489 
4490  if (newrel)
4491  ereport(DEBUG1,
4492  (errmsg("rewriting table \"%s\"",
4493  RelationGetRelationName(oldrel))));
4494  else
4495  ereport(DEBUG1,
4496  (errmsg("verifying table \"%s\"",
4497  RelationGetRelationName(oldrel))));
4498 
4499  if (newrel)
4500  {
4501  /*
4502  * All predicate locks on the tuples or pages are about to be made
4503  * invalid, because we move tuples around. Promote them to
4504  * relation locks.
4505  */
4507  }
4508 
4509  econtext = GetPerTupleExprContext(estate);
4510 
4511  /*
4512  * Make tuple slots for old and new tuples. Note that even when the
4513  * tuples are the same, the tupDescs might not be (consider ADD COLUMN
4514  * without a default).
4515  */
4516  oldslot = MakeSingleTupleTableSlot(oldTupDesc);
4517  newslot = MakeSingleTupleTableSlot(newTupDesc);
4518 
4519  /* Preallocate values/isnull arrays */
4520  i = Max(newTupDesc->natts, oldTupDesc->natts);
4521  values = (Datum *) palloc(i * sizeof(Datum));
4522  isnull = (bool *) palloc(i * sizeof(bool));
4523  memset(values, 0, i * sizeof(Datum));
4524  memset(isnull, true, i * sizeof(bool));
4525 
4526  /*
4527  * Any attributes that are dropped according to the new tuple
4528  * descriptor can be set to NULL. We precompute the list of dropped
4529  * attributes to avoid needing to do so in the per-tuple loop.
4530  */
4531  for (i = 0; i < newTupDesc->natts; i++)
4532  {
4533  if (TupleDescAttr(newTupDesc, i)->attisdropped)
4534  dropped_attrs = lappend_int(dropped_attrs, i);
4535  }
4536 
4537  /*
4538  * Scan through the rows, generating a new row if needed and then
4539  * checking all the constraints.
4540  */
4541  snapshot = RegisterSnapshot(GetLatestSnapshot());
4542  scan = heap_beginscan(oldrel, snapshot, 0, NULL);
4543 
4544  /*
4545  * Switch to per-tuple memory context and reset it for each tuple
4546  * produced, so we don't leak memory.
4547  */
4549 
4550  while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
4551  {
4552  if (tab->rewrite > 0)
4553  {
4554  Oid tupOid = InvalidOid;
4555 
4556  /* Extract data from old tuple */
4557  heap_deform_tuple(tuple, oldTupDesc, values, isnull);
4558  if (oldTupDesc->tdhasoid)
4559  tupOid = HeapTupleGetOid(tuple);
4560 
4561  /* Set dropped attributes to null in new tuple */
4562  foreach(lc, dropped_attrs)
4563  isnull[lfirst_int(lc)] = true;
4564 
4565  /*
4566  * Process supplied expressions to replace selected columns.
4567  * Expression inputs come from the old tuple.
4568  */
4569  ExecStoreTuple(tuple, oldslot, InvalidBuffer, false);
4570  econtext->ecxt_scantuple = oldslot;
4571 
4572  foreach(l, tab->newvals)
4573  {
4574  NewColumnValue *ex = lfirst(l);
4575 
4576  values[ex->attnum - 1] = ExecEvalExpr(ex->exprstate,
4577  econtext,
4578  &isnull[ex->attnum - 1]);
4579  }
4580 
4581  /*
4582  * Form the new tuple. Note that we don't explicitly pfree it,
4583  * since the per-tuple memory context will be reset shortly.
4584  */
4585  tuple = heap_form_tuple(newTupDesc, values, isnull);
4586 
4587  /* Preserve OID, if any */
4588  if (newTupDesc->tdhasoid)
4589  HeapTupleSetOid(tuple, tupOid);
4590 
4591  /*
4592  * Constraints might reference the tableoid column, so
4593  * initialize t_tableOid before evaluating them.
4594  */
4595  tuple->t_tableOid = RelationGetRelid(oldrel);
4596  }
4597 
4598  /* Now check any constraints on the possibly-changed tuple */
4599  ExecStoreTuple(tuple, newslot, InvalidBuffer, false);
4600  econtext->ecxt_scantuple = newslot;
4601 
4602  foreach(l, notnull_attrs)
4603  {
4604  int attn = lfirst_int(l);
4605 
4606  if (heap_attisnull(tuple, attn + 1))
4607  {
4608  Form_pg_attribute attr = TupleDescAttr(newTupDesc, attn);
4609 
4610  ereport(ERROR,
4611  (errcode(ERRCODE_NOT_NULL_VIOLATION),
4612  errmsg("column \"%s\" contains null values",
4613  NameStr(attr->attname)),
4614  errtablecol(oldrel, attn + 1)));
4615  }
4616  }
4617 
4618  foreach(l, tab->constraints)
4619  {
4620  NewConstraint *con = lfirst(l);
4621 
4622  switch (con->contype)
4623  {
4624  case CONSTR_CHECK:
4625  if (!ExecCheck(con->qualstate, econtext))
4626  ereport(ERROR,
4627  (errcode(ERRCODE_CHECK_VIOLATION),
4628  errmsg("check constraint \"%s\" is violated by some row",
4629  con->name),
4630  errtableconstraint(oldrel, con->name)));
4631  break;
4632  case CONSTR_FOREIGN:
4633  /* Nothing to do here */
4634  break;
4635  default:
4636  elog(ERROR, "unrecognized constraint type: %d",
4637  (int) con->contype);
4638  }
4639  }
4640 
4641  if (partqualstate && !ExecCheck(partqualstate, econtext))
4642  {
4643  if (tab->validate_default)
4644  ereport(ERROR,
4645  (errcode(ERRCODE_CHECK_VIOLATION),
4646  errmsg("updated partition constraint for default partition would be violated by some row")));
4647  else
4648  ereport(ERROR,
4649  (errcode(ERRCODE_CHECK_VIOLATION),
4650  errmsg("partition constraint is violated by some row")));
4651  }
4652 
4653  /* Write the tuple out to the new relation */
4654  if (newrel)
4655  heap_insert(newrel, tuple, mycid, hi_options, bistate);
4656 
4657  ResetExprContext(econtext);
4658 
4660  }
4661 
4662  MemoryContextSwitchTo(oldCxt);
4663  heap_endscan(scan);
4664  UnregisterSnapshot(snapshot);
4665 
4668  }
4669 
4670  FreeExecutorState(estate);
4671 
4672  heap_close(oldrel, NoLock);
4673  if (newrel)
4674  {
4675  FreeBulkInsertState(bistate);
4676 
4677  /* If we skipped writing WAL, then we need to sync the heap. */
4678  if (hi_options & HEAP_INSERT_SKIP_WAL)
4679  heap_sync(newrel);
4680 
4681  heap_close(newrel, NoLock);
4682  }
4683 }
4684 
4685 /*
4686  * ATGetQueueEntry: find or create an entry in the ALTER TABLE work queue
4687  */
4688 static AlteredTableInfo *
4690 {
4691  Oid relid = RelationGetRelid(rel);
4692  AlteredTableInfo *tab;
4693  ListCell *ltab;
4694 
4695  foreach(ltab, *wqueue)
4696  {
4697  tab = (AlteredTableInfo *) lfirst(ltab);
4698  if (tab->relid == relid)
4699  return tab;
4700  }
4701 
4702  /*
4703  * Not there, so add it. Note that we make a copy of the relation's
4704  * existing descriptor before anything interesting can happen to it.
4705  */
4706  tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo));
4707  tab->relid = relid;
4708  tab->relkind = rel->rd_rel->relkind;
4711  tab->chgPersistence = false;
4712 
4713  *wqueue = lappend(*wqueue, tab);
4714 
4715  return tab;
4716 }
4717 
4718 /*
4719  * ATSimplePermissions
4720  *
4721  * - Ensure that it is a relation (or possibly a view)
4722  * - Ensure this user is the owner
4723  * - Ensure that it is not a system table
4724  */
4725 static void
4726 ATSimplePermissions(Relation rel, int allowed_targets)
4727 {
4728  int actual_target;
4729 
4730  switch (rel->rd_rel->relkind)
4731  {
4732  case RELKIND_RELATION:
4734  actual_target = ATT_TABLE;
4735  break;
4736  case RELKIND_VIEW:
4737  actual_target = ATT_VIEW;
4738  break;
4739  case RELKIND_MATVIEW:
4740  actual_target = ATT_MATVIEW;
4741  break;
4742  case RELKIND_INDEX:
4743  actual_target = ATT_INDEX;
4744  break;
4746  actual_target = ATT_COMPOSITE_TYPE;
4747  break;
4748  case RELKIND_FOREIGN_TABLE:
4749  actual_target = ATT_FOREIGN_TABLE;
4750  break;
4751  default:
4752  actual_target = 0;
4753  break;
4754  }
4755 
4756  /* Wrong target type? */
4757  if ((actual_target & allowed_targets) == 0)
4758  ATWrongRelkindError(rel, allowed_targets);
4759 
4760  /* Permissions checks */
4764 
4766  ereport(ERROR,
4767  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4768  errmsg("permission denied: \"%s\" is a system catalog",
4769  RelationGetRelationName(rel))));
4770 }
4771 
4772 /*
4773  * ATWrongRelkindError
4774  *
4775  * Throw an error when a relation has been determined to be of the wrong
4776  * type.
4777  */
4778 static void
4779 ATWrongRelkindError(Relation rel, int allowed_targets)
4780 {
4781  char *msg;
4782 
4783  switch (allowed_targets)
4784  {
4785  case ATT_TABLE:
4786  msg = _("\"%s\" is not a table");
4787  break;
4788  case ATT_TABLE | ATT_VIEW:
4789  msg = _("\"%s\" is not a table or view");
4790  break;
4792  msg = _("\"%s\" is not a table, view, or foreign table");
4793  break;
4795  msg = _("\"%s\" is not a table, view, materialized view, or index");
4796  break;
4797  case ATT_TABLE | ATT_MATVIEW:
4798  msg = _("\"%s\" is not a table or materialized view");
4799  break;
4800  case ATT_TABLE | ATT_MATVIEW | ATT_INDEX:
4801  msg = _("\"%s\" is not a table, materialized view, or index");
4802  break;
4804  msg = _("\"%s\" is not a table, materialized view, or foreign table");
4805  break;
4807  msg = _("\"%s\" is not a table or foreign table");
4808  break;
4810  msg = _("\"%s\" is not a table, composite type, or foreign table");
4811  break;
4813  msg = _("\"%s\" is not a table, materialized view, index, or foreign table");
4814  break;
4815  case ATT_VIEW:
4816  msg = _("\"%s\" is not a view");
4817  break;
4818  case ATT_FOREIGN_TABLE:
4819  msg = _("\"%s\" is not a foreign table");
4820  break;
4821  default:
4822  /* shouldn't get here, add all necessary cases above */
4823  msg = _("\"%s\" is of the wrong type");
4824  break;
4825  }
4826 
4827  ereport(ERROR,
4828  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4829  errmsg(msg, RelationGetRelationName(rel))));
4830 }
4831 
4832 /*
4833  * ATSimpleRecursion
4834  *
4835  * Simple table recursion sufficient for most ALTER TABLE operations.
4836  * All direct and indirect children are processed in an unspecified order.
4837  * Note that if a child inherits from the original table via multiple
4838  * inheritance paths, it will be visited just once.
4839  */
4840 static void
4842  AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode)
4843 {
4844  /*
4845  * Propagate to children if desired. Only plain tables and foreign tables
4846  * have children, so no need to search for other relkinds.
4847  */
4848  if (recurse &&
4849  (rel->rd_rel->relkind == RELKIND_RELATION ||
4850  rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
4851  rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
4852  {
4853  Oid relid = RelationGetRelid(rel);
4854  ListCell *child;
4855  List *children;
4856 
4857  children = find_all_inheritors(relid, lockmode, NULL);
4858 
4859  /*
4860  * find_all_inheritors does the recursive search of the inheritance
4861  * hierarchy, so all we have to do is process all of the relids in the
4862  * list that it returns.
4863  */
4864  foreach(child, children)
4865  {
4866  Oid childrelid = lfirst_oid(child);
4867  Relation childrel;
4868 
4869  if (childrelid == relid)
4870  continue;
4871  /* find_all_inheritors already got lock */
4872  childrel = relation_open(childrelid, NoLock);
4873  CheckTableNotInUse(childrel, "ALTER TABLE");
4874  ATPrepCmd(wqueue, childrel, cmd, false, true, lockmode);
4875  relation_close(childrel, NoLock);
4876  }
4877  }
4878 }
4879 
4880 /*
4881  * ATTypedTableRecursion
4882  *
4883  * Propagate ALTER TYPE operations to the typed tables of that type.
4884  * Also check the RESTRICT/CASCADE behavior. Given CASCADE, also permit
4885  * recursion to inheritance children of the typed tables.
4886  */
4887 static void
4889  LOCKMODE lockmode)
4890 {
4891  ListCell *child;
4892  List *children;
4893 
4894  Assert(rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE);
4895 
4896  children = find_typed_table_dependencies(rel->rd_rel->reltype,
4898  cmd->behavior);
4899 
4900  foreach(child, children)
4901  {
4902  Oid childrelid = lfirst_oid(child);
4903  Relation childrel;
4904 
4905  childrel = relation_open(childrelid, lockmode);
4906  CheckTableNotInUse(childrel, "ALTER TABLE");
4907  ATPrepCmd(wqueue, childrel, cmd, true, true, lockmode);
4908  relation_close(childrel, NoLock);
4909  }
4910 }
4911 
4912 
4913 /*
4914  * find_composite_type_dependencies
4915  *
4916  * Check to see if the type "typeOid" is being used as a column in some table
4917  * (possibly nested several levels deep in composite types, arrays, etc!).
4918  * Eventually, we'd like to propagate the check or rewrite operation
4919  * into such tables, but for now, just error out if we find any.
4920  *
4921  * Caller should provide either the associated relation of a rowtype,
4922  * or a type name (not both) for use in the error message, if any.
4923  *
4924  * Note that "typeOid" is not necessarily a composite type; it could also be
4925  * another container type such as an array or range, or a domain over one of
4926  * these things. The name of this function is therefore somewhat historical,
4927  * but it's not worth changing.
4928  *
4929  * We assume that functions and views depending on the type are not reasons
4930  * to reject the ALTER. (How safe is this really?)
4931  */
4932 void
4934  const char *origTypeName)
4935 {
4936  Relation depRel;
4937  ScanKeyData key[2];
4938  SysScanDesc depScan;
4939  HeapTuple depTup;
4940 
4941  /* since this function recurses, it could be driven to stack overflow */
4943 
4944  /*
4945  * We scan pg_depend to find those things that depend on the given type.
4946  * (We assume we can ignore refobjsubid for a type.)
4947  */
4949 
4950  ScanKeyInit(&key[0],
4952  BTEqualStrategyNumber, F_OIDEQ,
4954  ScanKeyInit(&key[1],
4956  BTEqualStrategyNumber, F_OIDEQ,
4957  ObjectIdGetDatum(typeOid));
4958 
4959  depScan = systable_beginscan(depRel, DependReferenceIndexId, true,
4960  NULL, 2, key);
4961 
4962  while (HeapTupleIsValid(depTup = systable_getnext(depScan)))
4963  {
4964  Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
4965  Relation rel;
4966  Form_pg_attribute att;
4967 
4968  /* Check for directly dependent types */
4969  if (pg_depend->classid == TypeRelationId)
4970  {
4971  /*
4972  * This must be an array, domain, or range containing the given
4973  * type, so recursively check for uses of this type. Note that
4974  * any error message will mention the original type not the
4975  * container; this is intentional.
4976  */
4977  find_composite_type_dependencies(pg_depend->objid,
4978  origRelation, origTypeName);
4979  continue;
4980  }
4981 
4982  /* Else, ignore dependees that aren't user columns of relations */
4983  /* (we assume system columns are never of interesting types) */
4984  if (pg_depend->classid != RelationRelationId ||
4985  pg_depend->objsubid <= 0)
4986  continue;
4987 
4988  rel = relation_open(pg_depend->objid, AccessShareLock);
4989  att = TupleDescAttr(rel->rd_att, pg_depend->objsubid - 1);
4990 
4991  if (rel->rd_rel->relkind == RELKIND_RELATION ||
4992  rel->rd_rel->relkind == RELKIND_MATVIEW ||
4993  rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
4994  {
4995  if (origTypeName)
4996  ereport(ERROR,
4997  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4998  errmsg("cannot alter type \"%s\" because column \"%s.%s\" uses it",
4999  origTypeName,
5001  NameStr(att->attname))));
5002  else if (origRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
5003  ereport(ERROR,
5004  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5005  errmsg("cannot alter type \"%s\" because column \"%s.%s\" uses it",
5006  RelationGetRelationName(origRelation),
5008  NameStr(att->attname))));
5009  else if (origRelation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
5010  ereport(ERROR,
5011  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5012  errmsg("cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type",
5013  RelationGetRelationName(origRelation),
5015  NameStr(att->attname))));
5016  else
5017  ereport(ERROR,
5018  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5019  errmsg("cannot alter table \"%s\" because column \"%s.%s\" uses its row type",
5020  RelationGetRelationName(origRelation),
5022  NameStr(att->attname))));
5023  }
5024  else if (OidIsValid(rel->rd_rel->reltype))
5025  {
5026  /*
5027  * A view or composite type itself isn't a problem, but we must
5028  * recursively check for indirect dependencies via its rowtype.
5029  */
5031  origRelation, origTypeName);
5032  }
5033 
5035  }
5036 
5037  systable_endscan(depScan);
5038 
5040 }
5041 
5042 
5043 /*
5044  * find_typed_table_dependencies
5045  *
5046  * Check to see if a composite type is being used as the type of a
5047  * typed table. Abort if any are found and behavior is RESTRICT.
5048  * Else return the list of tables.
5049  */
5050 static List *
5051 find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior behavior)
5052 {
5053  Relation classRel;
5054  ScanKeyData key[1];
5055  HeapScanDesc scan;
5056  HeapTuple tuple;
5057  List *result = NIL;
5058 
5060 
5061  ScanKeyInit(&key[0],
5063  BTEqualStrategyNumber, F_OIDEQ,
5064  ObjectIdGetDatum(typeOid));
5065 
5066  scan = heap_beginscan_catalog(classRel, 1, key);
5067 
5068  while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
5069  {
5070  if (behavior == DROP_RESTRICT)
5071  ereport(ERROR,
5072  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
5073  errmsg("cannot alter type \"%s\" because it is the type of a typed table",
5074  typeName),
5075  errhint("Use ALTER ... CASCADE to alter the typed tables too.")));
5076  else
5077  result = lappend_oid(result, HeapTupleGetOid(tuple));
5078  }
5079 
5080  heap_endscan(scan);
5081  heap_close(classRel, AccessShareLock);
5082 
5083  return result;
5084 }
5085 
5086 
5087 /*
5088  * check_of_type
5089  *
5090  * Check whether a type is suitable for CREATE TABLE OF/ALTER TABLE OF. If it
5091  * isn't suitable, throw an error. Currently, we require that the type
5092  * originated with CREATE TYPE AS. We could support any row type, but doing so
5093  * would require handling a number of extra corner cases in the DDL commands.
5094  */
5095 void
5097 {
5098  Form_pg_type typ = (Form_pg_type) GETSTRUCT(typetuple);
5099  bool typeOk = false;
5100 
5101  if (typ->typtype == TYPTYPE_COMPOSITE)
5102  {
5103  Relation typeRelation;
5104 
5105  Assert(OidIsValid(typ->typrelid));
5106  typeRelation = relation_open(typ->typrelid, AccessShareLock);
5107  typeOk = (typeRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE);
5108 
5109  /*
5110  * Close the parent rel, but keep our AccessShareLock on it until xact
5111  * commit. That will prevent someone else from deleting or ALTERing
5112  * the type before the typed table creation/conversion commits.
5113  */
5114  relation_close(typeRelation, NoLock);
5115  }
5116  if (!typeOk)
5117  ereport(ERROR,
5118  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5119  errmsg("type %s is not a composite type",
5120  format_type_be(HeapTupleGetOid(typetuple)))));
5121 }
5122 
5123 
5124 /*
5125  * ALTER TABLE ADD COLUMN
5126  *
5127  * Adds an additional attribute to a relation making the assumption that
5128  * CHECK, NOT NULL, and FOREIGN KEY constraints will be removed from the
5129  * AT_AddColumn AlterTableCmd by parse_utilcmd.c and added as independent
5130  * AlterTableCmd's.
5131  *
5132  * ADD COLUMN cannot use the normal ALTER TABLE recursion mechanism, because we
5133  * have to decide at runtime whether to recurse or not depending on whether we
5134  * actually add a column or merely merge with an existing column. (We can't
5135  * check this in a static pre-pass because it won't handle multiple inheritance
5136  * situations correctly.)
5137  */
5138 static void
5139 ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
5140  bool is_view, AlterTableCmd *cmd, LOCKMODE lockmode)
5141 {
5142  if (rel->rd_rel->reloftype && !recursing)
5143  ereport(ERROR,
5144  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5145  errmsg("cannot add column to typed table")));
5146 
5147  if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
5148  ATTypedTableRecursion(wqueue, rel, cmd, lockmode);
5149 
5150  if (recurse && !is_view)
5152 }
5153 
5154 /*
5155  * Add a column to a table; this handles the AT_AddOids cases as well. The
5156  * return value is the address of the new column in the parent relation.
5157  */
5158 static ObjectAddress
5160  ColumnDef *colDef, bool isOid,
5161  bool recurse, bool recursing,
5162  bool if_not_exists, LOCKMODE lockmode)
5163 {
5164  Oid myrelid = RelationGetRelid(rel);
5165  Relation pgclass,
5166  attrdesc;
5167  HeapTuple reltup;
5168  FormData_pg_attribute attribute;
5169  int newattnum;
5170  char relkind;
5171  HeapTuple typeTuple;
5172  Oid typeOid;
5173  int32 typmod;
5174  Oid collOid;
5175  Form_pg_type tform;
5176  Expr *defval;
5177  List *children;
5178  ListCell *child;
5179  AclResult aclresult;
5180  ObjectAddress address;
5181 
5182  /* At top level, permission check was done in ATPrepCmd, else do it */
5183  if (recursing)
5185 
5186  if (rel->rd_rel->relispartition && !recursing)
5187  ereport(ERROR,
5188  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5189  errmsg("cannot add column to a partition")));
5190 
5192 
5193  /*
5194  * Are we adding the column to a recursion child? If so, check whether to
5195  * merge with an existing definition for the column. If we do merge, we
5196  * must not recurse. Children will already have the column, and recursing
5197  * into them would mess up attinhcount.
5198  */
5199  if (colDef->inhcount > 0)
5200  {
5201  HeapTuple tuple;
5202 
5203  /* Does child already have a column by this name? */
5204  tuple = SearchSysCacheCopyAttName(myrelid, colDef->colname);
5205  if (HeapTupleIsValid(tuple))
5206  {
5207  Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
5208  Oid ctypeId;
5209  int32 ctypmod;
5210  Oid ccollid;
5211 
5212  /* Child column must match on type, typmod, and collation */
5213  typenameTypeIdAndMod(NULL, colDef->typeName, &ctypeId, &ctypmod);
5214  if (ctypeId != childatt->atttypid ||
5215  ctypmod != childatt->atttypmod)
5216  ereport(ERROR,
5217  (errcode(ERRCODE_DATATYPE_MISMATCH),
5218  errmsg("child table \"%s\" has different type for column \"%s\"",
5219  RelationGetRelationName(rel), colDef->colname)));
5220  ccollid = GetColumnDefCollation(NULL, colDef, ctypeId);
5221  if (ccollid != childatt->attcollation)
5222  ereport(ERROR,
5223  (errcode(ERRCODE_COLLATION_MISMATCH),
5224  errmsg("child table \"%s\" has different collation for column \"%s\"",
5225  RelationGetRelationName(rel), colDef->colname),
5226  errdetail("\"%s\" versus \"%s\"",
5227  get_collation_name(ccollid),
5228  get_collation_name(childatt->attcollation))));
5229 
5230  /* If it's OID, child column must actually be OID */
5231  if (isOid && childatt->attnum != ObjectIdAttributeNumber)
5232  ereport(ERROR,
5233  (errcode(ERRCODE_DATATYPE_MISMATCH),
5234  errmsg("child table \"%s\" has a conflicting \"%s\" column",
5235  RelationGetRelationName(rel), colDef->colname)));
5236 
5237  /* Bump the existing child att's inhcount */
5238  childatt->attinhcount++;
5239  CatalogTupleUpdate(attrdesc, &tuple->t_self, tuple);
5240 
5241  heap_freetuple(tuple);
5242 
5243  /* Inform the user about the merge */
5244  ereport(NOTICE,
5245  (errmsg("merging definition of column \"%s\" for child \"%s\"",
5246  colDef->colname, RelationGetRelationName(rel))));
5247 
5248  heap_close(attrdesc, RowExclusiveLock);
5249  return InvalidObjectAddress;
5250  }
5251  }
5252 
5254 
5255  reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(myrelid));
5256  if (!HeapTupleIsValid(reltup))
5257  elog(ERROR, "cache lookup failed for relation %u", myrelid);
5258  relkind = ((Form_pg_class) GETSTRUCT(reltup))->relkind;
5259 
5260  /*
5261  * Cannot add identity column if table has children, because identity does
5262  * not inherit. (Adding column and identity separately will work.)
5263  */
5264  if (colDef->identity &&
5265  recurse &&
5266  find_inheritance_children(myrelid, NoLock) != NIL)
5267  ereport(ERROR,
5268  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5269  errmsg("cannot recursively add identity column to table that has child tables")));
5270 
5271  /* skip if the name already exists and if_not_exists is true */
5272  if (!check_for_column_name_collision(rel, colDef->colname, if_not_exists))
5273  {
5274  heap_close(attrdesc, RowExclusiveLock);
5275  heap_freetuple(reltup);
5276  heap_close(pgclass, RowExclusiveLock);
5277  return InvalidObjectAddress;
5278  }
5279 
5280  /* Determine the new attribute's number */
5281  if (isOid)
5282  newattnum = ObjectIdAttributeNumber;
5283  else
5284  {
5285  newattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts + 1;
5286  if (newattnum > MaxHeapAttributeNumber)
5287  ereport(ERROR,
5288  (errcode(ERRCODE_TOO_MANY_COLUMNS),
5289  errmsg("tables can have at most %d columns",
5291  }
5292 
5293  typeTuple = typenameType(NULL, colDef->typeName, &typmod);
5294  tform = (Form_pg_type) GETSTRUCT(typeTuple);
5295  typeOid = HeapTupleGetOid(typeTuple);
5296 
5297  aclresult = pg_type_aclcheck(typeOid, GetUserId(), ACL_USAGE);
5298  if (aclresult != ACLCHECK_OK)
5299  aclcheck_error_type(aclresult, typeOid);
5300 
5301  collOid = GetColumnDefCollation(NULL, colDef, typeOid);
5302 
5303  /* make sure datatype is legal for a column */
5304  CheckAttributeType(colDef->colname, typeOid, collOid,
5305  list_make1_oid(rel->rd_rel->reltype),
5306  false);
5307 
5308  /* construct new attribute's pg_attribute entry */
5309  attribute.attrelid = myrelid;
5310  namestrcpy(&(attribute.attname), colDef->colname);
5311  attribute.atttypid = typeOid;
5312  attribute.attstattarget = (newattnum > 0) ? -1 : 0;
5313  attribute.attlen = tform->typlen;
5314  attribute.attcacheoff = -1;
5315  attribute.atttypmod = typmod;
5316  attribute.attnum = newattnum;
5317  attribute.attbyval = tform->typbyval;
5318  attribute.attndims = list_length(colDef->typeName->arrayBounds);
5319  attribute.attstorage = tform->typstorage;
5320  attribute.attalign = tform->typalign;
5321  attribute.attnotnull = colDef->is_not_null;
5322  attribute.atthasdef = false;
5323  attribute.attidentity = colDef->identity;
5324  attribute.attisdropped = false;
5325  attribute.attislocal = colDef->is_local;
5326  attribute.attinhcount = colDef->inhcount;
5327  attribute.attcollation = collOid;
5328  /* attribute.attacl is handled by InsertPgAttributeTuple */
5329 
5330  ReleaseSysCache(typeTuple);
5331 
5332  InsertPgAttributeTuple(attrdesc, &attribute, NULL);
5333 
5334  heap_close(attrdesc, RowExclusiveLock);
5335 
5336  /*
5337  * Update pg_class tuple as appropriate
5338  */
5339  if (isOid)
5340  ((Form_pg_class) GETSTRUCT(reltup))->relhasoids = true;
5341  else
5342  ((Form_pg_class) GETSTRUCT(reltup))->relnatts = newattnum;
5343 
5344  CatalogTupleUpdate(pgclass, &reltup->t_self, reltup);
5345 
5346  heap_freetuple(reltup);
5347 
5348  /* Post creation hook for new attribute */
5349  InvokeObjectPostCreateHook(RelationRelationId, myrelid, newattnum);
5350 
5351  heap_close(pgclass, RowExclusiveLock);
5352 
5353  /* Make the attribute's catalog entry visible */