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