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