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