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