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