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