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