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