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