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);
406  IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode);
407 static ObjectAddress ATExecAddConstraint(List **wqueue,
408  AlteredTableInfo *tab, Relation rel,
409  Constraint *newConstraint, bool recurse, bool is_readd,
410  LOCKMODE lockmode);
411 static char *ChooseForeignKeyConstraintNameAddition(List *colnames);
413  IndexStmt *stmt, LOCKMODE lockmode);
414 static ObjectAddress ATAddCheckConstraint(List **wqueue,
415  AlteredTableInfo *tab, Relation rel,
416  Constraint *constr,
417  bool recurse, bool recursing, bool is_readd,
418  LOCKMODE lockmode);
420  Relation rel, Constraint *fkconstraint, Oid parentConstr,
421  bool recurse, bool recursing,
422  LOCKMODE lockmode);
423 static ObjectAddress addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint,
424  Relation rel, Relation pkrel, Oid indexOid, Oid parentConstr,
425  int numfks, int16 *pkattnum, int16 *fkattnum,
426  Oid *pfeqoperators, Oid *ppeqoperators, Oid *ffeqoperators,
427  bool old_check_ok);
428 static void addFkRecurseReferencing(List **wqueue, Constraint *fkconstraint,
429  Relation rel, Relation pkrel, Oid indexOid, Oid parentConstr,
430  int numfks, int16 *pkattnum, int16 *fkattnum,
431  Oid *pfeqoperators, Oid *ppeqoperators, Oid *ffeqoperators,
432  bool old_check_ok, LOCKMODE lockmode);
433 static void CloneForeignKeyConstraints(List **wqueue, Relation parentRel,
434  Relation partitionRel);
435 static void CloneFkReferenced(Relation parentRel, Relation partitionRel);
436 static void CloneFkReferencing(List **wqueue, Relation parentRel,
437  Relation partRel);
438 static void createForeignKeyCheckTriggers(Oid myRelOid, Oid refRelOid,
439  Constraint *fkconstraint, Oid constraintOid,
440  Oid indexOid);
441 static void createForeignKeyActionTriggers(Relation rel, Oid refRelOid,
442  Constraint *fkconstraint, Oid constraintOid,
443  Oid indexOid);
445  Oid partRelid,
446  Oid parentConstrOid, int numfks,
447  AttrNumber *mapped_conkey, AttrNumber *confkey,
448  Oid *conpfeqop);
449 static void ATExecDropConstraint(Relation rel, const char *constrName,
450  DropBehavior behavior,
451  bool recurse, bool recursing,
452  bool missing_ok, LOCKMODE lockmode);
453 static void ATPrepAlterColumnType(List **wqueue,
454  AlteredTableInfo *tab, Relation rel,
455  bool recurse, bool recursing,
456  AlterTableCmd *cmd, LOCKMODE lockmode);
457 static bool ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno);
459  AlterTableCmd *cmd, LOCKMODE lockmode);
460 static void RememberConstraintForRebuilding(Oid conoid, AlteredTableInfo *tab);
461 static void RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab);
462 static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab,
463  LOCKMODE lockmode);
464 static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId,
465  char *cmd, List **wqueue, LOCKMODE lockmode,
466  bool rewrite);
467 static void RebuildConstraintComment(AlteredTableInfo *tab, int pass,
468  Oid objid, Relation rel, List *domname,
469  const char *conname);
470 static void TryReuseIndex(Oid oldId, IndexStmt *stmt);
471 static void TryReuseForeignKey(Oid oldId, Constraint *con);
472 static ObjectAddress ATExecAlterColumnGenericOptions(Relation rel, const char *colName,
473  List *options, LOCKMODE lockmode);
474 static void change_owner_fix_column_acls(Oid relationOid,
475  Oid oldOwnerId, Oid newOwnerId);
476 static void change_owner_recurse_to_sequences(Oid relationOid,
477  Oid newOwnerId, LOCKMODE lockmode);
478 static ObjectAddress ATExecClusterOn(Relation rel, const char *indexName,
479  LOCKMODE lockmode);
480 static void ATExecDropCluster(Relation rel, LOCKMODE lockmode);
481 static bool ATPrepChangePersistence(Relation rel, bool toLogged);
482 static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
483  const char *tablespacename, LOCKMODE lockmode);
484 static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode);
485 static void ATExecSetTableSpaceNoStorage(Relation rel, Oid newTableSpace);
486 static void ATExecSetRelOptions(Relation rel, List *defList,
487  AlterTableType operation,
488  LOCKMODE lockmode);
489 static void ATExecEnableDisableTrigger(Relation rel, const char *trigname,
490  char fires_when, bool skip_system, LOCKMODE lockmode);
491 static void ATExecEnableDisableRule(Relation rel, const char *rulename,
492  char fires_when, LOCKMODE lockmode);
493 static void ATPrepAddInherit(Relation child_rel);
494 static ObjectAddress ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode);
495 static ObjectAddress ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode);
496 static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid,
497  DependencyType deptype);
498 static ObjectAddress ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode);
499 static void ATExecDropOf(Relation rel, LOCKMODE lockmode);
500 static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode);
501 static void ATExecGenericOptions(Relation rel, List *options);
502 static void ATExecEnableRowSecurity(Relation rel);
503 static void ATExecDisableRowSecurity(Relation rel);
504 static void ATExecForceNoForceRowSecurity(Relation rel, bool force_rls);
505 
506 static void index_copy_data(Relation rel, RelFileNode newrnode);
507 static const char *storage_name(char c);
508 
509 static void RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid,
510  Oid oldRelOid, void *arg);
511 static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid,
512  Oid oldrelid, void *arg);
513 static PartitionSpec *transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy);
514 static void ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNumber *partattrs,
515  List **partexprs, Oid *partopclass, Oid *partcollation, char strategy);
516 static void CreateInheritance(Relation child_rel, Relation parent_rel);
517 static void RemoveInheritance(Relation child_rel, Relation parent_rel);
518 static ObjectAddress ATExecAttachPartition(List **wqueue, Relation rel,
519  PartitionCmd *cmd);
520 static void AttachPartitionEnsureIndexes(Relation rel, Relation attachrel);
521 static void QueuePartitionConstraintValidation(List **wqueue, Relation scanrel,
522  List *partConstraint,
523  bool validate_default);
524 static void CloneRowTriggersToPartition(Relation parent, Relation partition);
527  RangeVar *name);
528 static void validatePartitionedIndex(Relation partedIdx, Relation partedTbl);
529 static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx,
530  Relation partitionTbl);
531 static List *GetParentedForeignKeyRefs(Relation partition);
532 static void ATDetachCheckNoForeignKeyRefs(Relation partition);
533 
534 
535 /* ----------------------------------------------------------------
536  * DefineRelation
537  * Creates a new relation.
538  *
539  * stmt carries parsetree information from an ordinary CREATE TABLE statement.
540  * The other arguments are used to extend the behavior for other cases:
541  * relkind: relkind to assign to the new relation
542  * ownerId: if not InvalidOid, use this as the new relation's owner.
543  * typaddress: if not null, it's set to the pg_type entry's address.
544  * queryString: for error reporting
545  *
546  * Note that permissions checks are done against current user regardless of
547  * ownerId. A nonzero ownerId is used when someone is creating a relation
548  * "on behalf of" someone else, so we still want to see that the current user
549  * has permissions to do it.
550  *
551  * If successful, returns the address of the new relation.
552  * ----------------------------------------------------------------
553  */
555 DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
556  ObjectAddress *typaddress, const char *queryString)
557 {
558  char relname[NAMEDATALEN];
559  Oid namespaceId;
560  Oid relationId;
561  Oid tablespaceId;
562  Relation rel;
564  List *inheritOids;
565  List *old_constraints;
566  List *rawDefaults;
567  List *cookedDefaults;
568  Datum reloptions;
569  ListCell *listptr;
571  bool partitioned;
572  static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
573  Oid ofTypeId;
574  ObjectAddress address;
575  LOCKMODE parentLockmode;
576  const char *accessMethod = NULL;
577  Oid accessMethodId = InvalidOid;
578 
579  /*
580  * Truncate relname to appropriate length (probably a waste of time, as
581  * parser should have done this already).
582  */
583  StrNCpy(relname, stmt->relation->relname, NAMEDATALEN);
584 
585  /*
586  * Check consistency of arguments
587  */
588  if (stmt->oncommit != ONCOMMIT_NOOP
589  && stmt->relation->relpersistence != RELPERSISTENCE_TEMP)
590  ereport(ERROR,
591  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
592  errmsg("ON COMMIT can only be used on temporary tables")));
593 
594  if (stmt->partspec != NULL)
595  {
596  if (relkind != RELKIND_RELATION)
597  elog(ERROR, "unexpected relkind: %d", (int) relkind);
598 
599  relkind = RELKIND_PARTITIONED_TABLE;
600  partitioned = true;
601  }
602  else
603  partitioned = false;
604 
605  /*
606  * Look up the namespace in which we are supposed to create the relation,
607  * check we have permission to create there, lock it against concurrent
608  * drop, and mark stmt->relation as RELPERSISTENCE_TEMP if a temporary
609  * namespace is selected.
610  */
611  namespaceId =
613 
614  /*
615  * Security check: disallow creating temp tables from security-restricted
616  * code. This is needed because calling code might not expect untrusted
617  * tables to appear in pg_temp at the front of its search path.
618  */
619  if (stmt->relation->relpersistence == RELPERSISTENCE_TEMP
621  ereport(ERROR,
622  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
623  errmsg("cannot create temporary table within security-restricted operation")));
624 
625  /*
626  * Determine the lockmode to use when scanning parents. A self-exclusive
627  * lock is needed here.
628  *
629  * For regular inheritance, if two backends attempt to add children to the
630  * same parent simultaneously, and that parent has no pre-existing
631  * children, then both will attempt to update the parent's relhassubclass
632  * field, leading to a "tuple concurrently updated" error. Also, this
633  * interlocks against a concurrent ANALYZE on the parent table, which
634  * might otherwise be attempting to clear the parent's relhassubclass
635  * field, if its previous children were recently dropped.
636  *
637  * If the child table is a partition, then we instead grab an exclusive
638  * lock on the parent because its partition descriptor will be changed by
639  * addition of the new partition.
640  */
641  parentLockmode = (stmt->partbound != NULL ? AccessExclusiveLock :
643 
644  /* Determine the list of OIDs of the parents. */
645  inheritOids = NIL;
646  foreach(listptr, stmt->inhRelations)
647  {
648  RangeVar *rv = (RangeVar *) lfirst(listptr);
649  Oid parentOid;
650 
651  parentOid = RangeVarGetRelid(rv, parentLockmode, false);
652 
653  /*
654  * Reject duplications in the list of parents.
655  */
656  if (list_member_oid(inheritOids, parentOid))
657  ereport(ERROR,
658  (errcode(ERRCODE_DUPLICATE_TABLE),
659  errmsg("relation \"%s\" would be inherited from more than once",
660  get_rel_name(parentOid))));
661 
662  inheritOids = lappend_oid(inheritOids, parentOid);
663  }
664 
665  /*
666  * Select tablespace to use: an explicitly indicated one, or (in the case
667  * of a partitioned table) the parent's, if it has one.
668  */
669  if (stmt->tablespacename)
670  {
671  tablespaceId = get_tablespace_oid(stmt->tablespacename, false);
672 
673  if (partitioned && tablespaceId == MyDatabaseTableSpace)
674  ereport(ERROR,
675  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
676  errmsg("cannot specify default tablespace for partitioned relations")));
677  }
678  else if (stmt->partbound)
679  {
680  /*
681  * For partitions, when no other tablespace is specified, we default
682  * the tablespace to the parent partitioned table's.
683  */
684  Assert(list_length(inheritOids) == 1);
685  tablespaceId = get_rel_tablespace(linitial_oid(inheritOids));
686  }
687  else
688  tablespaceId = InvalidOid;
689 
690  /* still nothing? use the default */
691  if (!OidIsValid(tablespaceId))
692  tablespaceId = GetDefaultTablespace(stmt->relation->relpersistence,
693  partitioned);
694 
695  /* Check permissions except when using database's default */
696  if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace)
697  {
698  AclResult aclresult;
699 
700  aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
701  ACL_CREATE);
702  if (aclresult != ACLCHECK_OK)
704  get_tablespace_name(tablespaceId));
705  }
706 
707  /* In all cases disallow placing user relations in pg_global */
708  if (tablespaceId == GLOBALTABLESPACE_OID)
709  ereport(ERROR,
710  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
711  errmsg("only shared relations can be placed in pg_global tablespace")));
712 
713  /* Identify user ID that will own the table */
714  if (!OidIsValid(ownerId))
715  ownerId = GetUserId();
716 
717  /*
718  * Parse and validate reloptions, if any.
719  */
720  reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps,
721  true, false);
722 
723  if (relkind == RELKIND_VIEW)
724  (void) view_reloptions(reloptions, true);
725  else
726  (void) heap_reloptions(relkind, reloptions, true);
727 
728  if (stmt->ofTypename)
729  {
730  AclResult aclresult;
731 
732  ofTypeId = typenameTypeId(NULL, stmt->ofTypename);
733 
734  aclresult = pg_type_aclcheck(ofTypeId, GetUserId(), ACL_USAGE);
735  if (aclresult != ACLCHECK_OK)
736  aclcheck_error_type(aclresult, ofTypeId);
737  }
738  else
739  ofTypeId = InvalidOid;
740 
741  /*
742  * Look up inheritance ancestors and generate relation schema, including
743  * inherited attributes. (Note that stmt->tableElts is destructively
744  * modified by MergeAttributes.)
745  */
746  stmt->tableElts =
747  MergeAttributes(stmt->tableElts, inheritOids,
748  stmt->relation->relpersistence,
749  stmt->partbound != NULL,
750  &old_constraints);
751 
752  /*
753  * Create a tuple descriptor from the relation schema. Note that this
754  * deals with column names, types, and NOT NULL constraints, but not
755  * default values or CHECK constraints; we handle those below.
756  */
757  descriptor = BuildDescForRelation(stmt->tableElts);
758 
759  /*
760  * Find columns with default values and prepare for insertion of the
761  * defaults. Pre-cooked (that is, inherited) defaults go into a list of
762  * CookedConstraint structs that we'll pass to heap_create_with_catalog,
763  * while raw defaults go into a list of RawColumnDefault structs that will
764  * be processed by AddRelationNewConstraints. (We can't deal with raw
765  * expressions until we can do transformExpr.)
766  *
767  * We can set the atthasdef flags now in the tuple descriptor; this just
768  * saves StoreAttrDefault from having to do an immediate update of the
769  * pg_attribute rows.
770  */
771  rawDefaults = NIL;
772  cookedDefaults = NIL;
773  attnum = 0;
774 
775  foreach(listptr, stmt->tableElts)
776  {
777  ColumnDef *colDef = lfirst(listptr);
778  Form_pg_attribute attr;
779 
780  attnum++;
781  attr = TupleDescAttr(descriptor, attnum - 1);
782 
783  if (colDef->raw_default != NULL)
784  {
785  RawColumnDefault *rawEnt;
786 
787  Assert(colDef->cooked_default == NULL);
788 
789  rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
790  rawEnt->attnum = attnum;
791  rawEnt->raw_default = colDef->raw_default;
792  rawEnt->missingMode = false;
793  rawEnt->generated = colDef->generated;
794  rawDefaults = lappend(rawDefaults, rawEnt);
795  attr->atthasdef = true;
796  }
797  else if (colDef->cooked_default != NULL)
798  {
799  CookedConstraint *cooked;
800 
801  cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
802  cooked->contype = CONSTR_DEFAULT;
803  cooked->conoid = InvalidOid; /* until created */
804  cooked->name = NULL;
805  cooked->attnum = attnum;
806  cooked->expr = colDef->cooked_default;
807  cooked->skip_validation = false;
808  cooked->is_local = true; /* not used for defaults */
809  cooked->inhcount = 0; /* ditto */
810  cooked->is_no_inherit = false;
811  cookedDefaults = lappend(cookedDefaults, cooked);
812  attr->atthasdef = true;
813  }
814 
815  if (colDef->identity)
816  attr->attidentity = colDef->identity;
817 
818  if (colDef->generated)
819  attr->attgenerated = colDef->generated;
820  }
821 
822  /*
823  * If the statement hasn't specified an access method, but we're defining
824  * a type of relation that needs one, use the default.
825  */
826  if (stmt->accessMethod != NULL)
827  {
828  accessMethod = stmt->accessMethod;
829 
830  if (partitioned)
831  ereport(ERROR,
832  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
833  errmsg("specifying a table access method is not supported on a partitioned table")));
834 
835  }
836  else if (relkind == RELKIND_RELATION ||
837  relkind == RELKIND_TOASTVALUE ||
838  relkind == RELKIND_MATVIEW)
839  accessMethod = default_table_access_method;
840 
841  /* look up the access method, verify it is for a table */
842  if (accessMethod != NULL)
843  accessMethodId = get_table_am_oid(accessMethod, false);
844 
845  /*
846  * Create the relation. Inherited defaults and constraints are passed in
847  * for immediate handling --- since they don't need parsing, they can be
848  * stored immediately.
849  */
850  relationId = heap_create_with_catalog(relname,
851  namespaceId,
852  tablespaceId,
853  InvalidOid,
854  InvalidOid,
855  ofTypeId,
856  ownerId,
857  accessMethodId,
858  descriptor,
859  list_concat(cookedDefaults,
860  old_constraints),
861  relkind,
862  stmt->relation->relpersistence,
863  false,
864  false,
865  stmt->oncommit,
866  reloptions,
867  true,
869  false,
870  InvalidOid,
871  typaddress);
872 
873  /*
874  * We must bump the command counter to make the newly-created relation
875  * tuple visible for opening.
876  */
878 
879  /*
880  * Open the new relation and acquire exclusive lock on it. This isn't
881  * really necessary for locking out other backends (since they can't see
882  * the new rel anyway until we commit), but it keeps the lock manager from
883  * complaining about deadlock risks.
884  */
885  rel = relation_open(relationId, AccessExclusiveLock);
886 
887  /*
888  * Now add any newly specified column default and generation expressions
889  * to the new relation. These are passed to us in the form of raw
890  * parsetrees; we need to transform them to executable expression trees
891  * before they can be added. The most convenient way to do that is to
892  * apply the parser's transformExpr routine, but transformExpr doesn't
893  * work unless we have a pre-existing relation. So, the transformation has
894  * to be postponed to this final step of CREATE TABLE.
895  *
896  * This needs to be before processing the partitioning clauses because
897  * those could refer to generated columns.
898  */
899  if (rawDefaults)
900  AddRelationNewConstraints(rel, rawDefaults, NIL,
901  true, true, false, queryString);
902 
903  /*
904  * Make column generation expressions visible for use by partitioning.
905  */
907 
908  /* Process and store partition bound, if any. */
909  if (stmt->partbound)
910  {
911  PartitionBoundSpec *bound;
912  ParseState *pstate;
913  Oid parentId = linitial_oid(inheritOids),
914  defaultPartOid;
915  Relation parent,
916  defaultRel = NULL;
917  RangeTblEntry *rte;
918 
919  /* Already have strong enough lock on the parent */
920  parent = table_open(parentId, NoLock);
921 
922  /*
923  * We are going to try to validate the partition bound specification
924  * against the partition key of parentRel, so it better have one.
925  */
926  if (parent->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
927  ereport(ERROR,
928  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
929  errmsg("\"%s\" is not partitioned",
930  RelationGetRelationName(parent))));
931 
932  /*
933  * The partition constraint of the default partition depends on the
934  * partition bounds of every other partition. It is possible that
935  * another backend might be about to execute a query on the default
936  * partition table, and that the query relies on previously cached
937  * default partition constraints. We must therefore take a table lock
938  * strong enough to prevent all queries on the default partition from
939  * proceeding until we commit and send out a shared-cache-inval notice
940  * that will make them update their index lists.
941  *
942  * Order of locking: The relation being added won't be visible to
943  * other backends until it is committed, hence here in
944  * DefineRelation() the order of locking the default partition and the
945  * relation being added does not matter. But at all other places we
946  * need to lock the default relation before we lock the relation being
947  * added or removed i.e. we should take the lock in same order at all
948  * the places such that lock parent, lock default partition and then
949  * lock the partition so as to avoid a deadlock.
950  */
951  defaultPartOid =
953  if (OidIsValid(defaultPartOid))
954  defaultRel = table_open(defaultPartOid, AccessExclusiveLock);
955 
956  /* Transform the bound values */
957  pstate = make_parsestate(NULL);
958  pstate->p_sourcetext = queryString;
959 
960  /*
961  * Add an RTE containing this relation, so that transformExpr called
962  * on partition bound expressions is able to report errors using a
963  * proper context.
964  */
966  NULL, false, false);
967  addRTEtoQuery(pstate, rte, false, true, true);
968  bound = transformPartitionBound(pstate, parent, stmt->partbound);
969 
970  /*
971  * Check first that the new partition's bound is valid and does not
972  * overlap with any of existing partitions of the parent.
973  */
974  check_new_partition_bound(relname, parent, bound);
975 
976  /*
977  * If the default partition exists, its partition constraints will
978  * change after the addition of this new partition such that it won't
979  * allow any row that qualifies for this new partition. So, check that
980  * the existing data in the default partition satisfies the constraint
981  * as it will exist after adding this partition.
982  */
983  if (OidIsValid(defaultPartOid))
984  {
985  check_default_partition_contents(parent, defaultRel, bound);
986  /* Keep the lock until commit. */
987  table_close(defaultRel, NoLock);
988  }
989 
990  /* Update the pg_class entry. */
991  StorePartitionBound(rel, parent, bound);
992 
993  table_close(parent, NoLock);
994  }
995 
996  /* Store inheritance information for new rel. */
997  StoreCatalogInheritance(relationId, inheritOids, stmt->partbound != NULL);
998 
999  /*
1000  * Process the partitioning specification (if any) and store the partition
1001  * key information into the catalog.
1002  */
1003  if (partitioned)
1004  {
1005  ParseState *pstate;
1006  char strategy;
1007  int partnatts;
1008  AttrNumber partattrs[PARTITION_MAX_KEYS];
1009  Oid partopclass[PARTITION_MAX_KEYS];
1010  Oid partcollation[PARTITION_MAX_KEYS];
1011  List *partexprs = NIL;
1012 
1013  pstate = make_parsestate(NULL);
1014  pstate->p_sourcetext = queryString;
1015 
1016  partnatts = list_length(stmt->partspec->partParams);
1017 
1018  /* Protect fixed-size arrays here and in executor */
1019  if (partnatts > PARTITION_MAX_KEYS)
1020  ereport(ERROR,
1021  (errcode(ERRCODE_TOO_MANY_COLUMNS),
1022  errmsg("cannot partition using more than %d columns",
1023  PARTITION_MAX_KEYS)));
1024 
1025  /*
1026  * We need to transform the raw parsetrees corresponding to partition
1027  * expressions into executable expression trees. Like column defaults
1028  * and CHECK constraints, we could not have done the transformation
1029  * earlier.
1030  */
1031  stmt->partspec = transformPartitionSpec(rel, stmt->partspec,
1032  &strategy);
1033 
1034  ComputePartitionAttrs(pstate, rel, stmt->partspec->partParams,
1035  partattrs, &partexprs, partopclass,
1036  partcollation, strategy);
1037 
1038  StorePartitionKey(rel, strategy, partnatts, partattrs, partexprs,
1039  partopclass, partcollation);
1040 
1041  /* make it all visible */
1043  }
1044 
1045  /*
1046  * If we're creating a partition, create now all the indexes, triggers,
1047  * FKs defined in the parent.
1048  *
1049  * We can't do it earlier, because DefineIndex wants to know the partition
1050  * key which we just stored.
1051  */
1052  if (stmt->partbound)
1053  {
1054  Oid parentId = linitial_oid(inheritOids);
1055  Relation parent;
1056  List *idxlist;
1057  ListCell *cell;
1058 
1059  /* Already have strong enough lock on the parent */
1060  parent = table_open(parentId, NoLock);
1061  idxlist = RelationGetIndexList(parent);
1062 
1063  /*
1064  * For each index in the parent table, create one in the partition
1065  */
1066  foreach(cell, idxlist)
1067  {
1068  Relation idxRel = index_open(lfirst_oid(cell), AccessShareLock);
1069  AttrNumber *attmap;
1070  IndexStmt *idxstmt;
1071  Oid constraintOid;
1072 
1073  if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1074  {
1075  if (idxRel->rd_index->indisunique)
1076  ereport(ERROR,
1077  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1078  errmsg("cannot create foreign partition of partitioned table \"%s\"",
1079  RelationGetRelationName(parent)),
1080  errdetail("Table \"%s\" contains indexes that are unique.",
1081  RelationGetRelationName(parent))));
1082  else
1083  {
1084  index_close(idxRel, AccessShareLock);
1085  continue;
1086  }
1087  }
1088 
1090  RelationGetDescr(parent),
1091  gettext_noop("could not convert row type"));
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  break;
4279  case AT_DropColumnRecurse: /* DROP COLUMN with recursion */
4280  address = ATExecDropColumn(wqueue, rel, cmd->name,
4281  cmd->behavior, true, false,
4282  cmd->missing_ok, lockmode);
4283  break;
4284  case AT_AddIndex: /* ADD INDEX */
4285  address = ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, false,
4286  lockmode);
4287  break;
4288  case AT_ReAddIndex: /* ADD INDEX */
4289  address = ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true,
4290  lockmode);
4291  break;
4292  case AT_AddConstraint: /* ADD CONSTRAINT */
4293  address =
4294  ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
4295  false, false, lockmode);
4296  break;
4297  case AT_AddConstraintRecurse: /* ADD CONSTRAINT with recursion */
4298  address =
4299  ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
4300  true, false, lockmode);
4301  break;
4302  case AT_ReAddConstraint: /* Re-add pre-existing check constraint */
4303  address =
4304  ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
4305  true, true, lockmode);
4306  break;
4307  case AT_ReAddDomainConstraint: /* Re-add pre-existing domain check
4308  * constraint */
4309  address =
4310  AlterDomainAddConstraint(((AlterDomainStmt *) cmd->def)->typeName,
4311  ((AlterDomainStmt *) cmd->def)->def,
4312  NULL);
4313  break;
4314  case AT_ReAddComment: /* Re-add existing comment */
4315  address = CommentObject((CommentStmt *) cmd->def);
4316  break;
4317  case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */
4318  address = ATExecAddIndexConstraint(tab, rel, (IndexStmt *) cmd->def,
4319  lockmode);
4320  break;
4321  case AT_AlterConstraint: /* ALTER CONSTRAINT */
4322  address = ATExecAlterConstraint(rel, cmd, false, false, lockmode);
4323  break;
4324  case AT_ValidateConstraint: /* VALIDATE CONSTRAINT */
4325  address = ATExecValidateConstraint(rel, cmd->name, false, false,
4326  lockmode);
4327  break;
4328  case AT_ValidateConstraintRecurse: /* VALIDATE CONSTRAINT with
4329  * recursion */
4330  address = ATExecValidateConstraint(rel, cmd->name, true, false,
4331  lockmode);
4332  break;
4333  case AT_DropConstraint: /* DROP CONSTRAINT */
4334  ATExecDropConstraint(rel, cmd->name, cmd->behavior,
4335  false, false,
4336  cmd->missing_ok, lockmode);
4337  break;
4338  case AT_DropConstraintRecurse: /* DROP CONSTRAINT with recursion */
4339  ATExecDropConstraint(rel, cmd->name, cmd->behavior,
4340  true, false,
4341  cmd->missing_ok, lockmode);
4342  break;
4343  case AT_AlterColumnType: /* ALTER COLUMN TYPE */
4344  address = ATExecAlterColumnType(tab, rel, cmd, lockmode);
4345  break;
4346  case AT_AlterColumnGenericOptions: /* ALTER COLUMN OPTIONS */
4347  address =
4349  (List *) cmd->def, lockmode);
4350  break;
4351  case AT_ChangeOwner: /* ALTER OWNER */
4353  get_rolespec_oid(cmd->newowner, false),
4354  false, lockmode);
4355  break;
4356  case AT_ClusterOn: /* CLUSTER ON */
4357  address = ATExecClusterOn(rel, cmd->name, lockmode);
4358  break;
4359  case AT_DropCluster: /* SET WITHOUT CLUSTER */
4360  ATExecDropCluster(rel, lockmode);
4361  break;
4362  case AT_SetLogged: /* SET LOGGED */
4363  case AT_SetUnLogged: /* SET UNLOGGED */
4364  break;
4365  case AT_DropOids: /* SET WITHOUT OIDS */
4366  /* nothing to do here, oid columns don't exist anymore */
4367  break;
4368  case AT_SetTableSpace: /* SET TABLESPACE */
4369 
4370  /*
4371  * Only do this for partitioned tables and indexes, for which this
4372  * is just a catalog change. Other relation types which have
4373  * storage are handled by Phase 3.
4374  */
4375  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ||
4376  rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
4378 
4379  break;
4380  case AT_SetRelOptions: /* SET (...) */
4381  case AT_ResetRelOptions: /* RESET (...) */
4382  case AT_ReplaceRelOptions: /* replace entire option list */
4383  ATExecSetRelOptions(rel, (List *) cmd->def, cmd->subtype, lockmode);
4384  break;
4385  case AT_EnableTrig: /* ENABLE TRIGGER name */
4386  ATExecEnableDisableTrigger(rel, cmd->name,
4387  TRIGGER_FIRES_ON_ORIGIN, false, lockmode);
4388  break;
4389  case AT_EnableAlwaysTrig: /* ENABLE ALWAYS TRIGGER name */
4390  ATExecEnableDisableTrigger(rel, cmd->name,
4391  TRIGGER_FIRES_ALWAYS, false, lockmode);
4392  break;
4393  case AT_EnableReplicaTrig: /* ENABLE REPLICA TRIGGER name */
4394  ATExecEnableDisableTrigger(rel, cmd->name,
4395  TRIGGER_FIRES_ON_REPLICA, false, lockmode);
4396  break;
4397  case AT_DisableTrig: /* DISABLE TRIGGER name */
4398  ATExecEnableDisableTrigger(rel, cmd->name,
4399  TRIGGER_DISABLED, false, lockmode);
4400  break;
4401  case AT_EnableTrigAll: /* ENABLE TRIGGER ALL */
4402  ATExecEnableDisableTrigger(rel, NULL,
4403  TRIGGER_FIRES_ON_ORIGIN, false, lockmode);
4404  break;
4405  case AT_DisableTrigAll: /* DISABLE TRIGGER ALL */
4406  ATExecEnableDisableTrigger(rel, NULL,
4407  TRIGGER_DISABLED, false, lockmode);
4408  break;
4409  case AT_EnableTrigUser: /* ENABLE TRIGGER USER */
4410  ATExecEnableDisableTrigger(rel, NULL,
4411  TRIGGER_FIRES_ON_ORIGIN, true, lockmode);
4412  break;
4413  case AT_DisableTrigUser: /* DISABLE TRIGGER USER */
4414  ATExecEnableDisableTrigger(rel, NULL,
4415  TRIGGER_DISABLED, true, lockmode);
4416  break;
4417 
4418  case AT_EnableRule: /* ENABLE RULE name */
4419  ATExecEnableDisableRule(rel, cmd->name,
4420  RULE_FIRES_ON_ORIGIN, lockmode);
4421  break;
4422  case AT_EnableAlwaysRule: /* ENABLE ALWAYS RULE name */
4423  ATExecEnableDisableRule(rel, cmd->name,
4424  RULE_FIRES_ALWAYS, lockmode);
4425  break;
4426  case AT_EnableReplicaRule: /* ENABLE REPLICA RULE name */
4427  ATExecEnableDisableRule(rel, cmd->name,
4428  RULE_FIRES_ON_REPLICA, lockmode);
4429  break;
4430  case AT_DisableRule: /* DISABLE RULE name */
4431  ATExecEnableDisableRule(rel, cmd->name,
4432  RULE_DISABLED, lockmode);
4433  break;
4434 
4435  case AT_AddInherit:
4436  address = ATExecAddInherit(rel, (RangeVar *) cmd->def, lockmode);
4437  break;
4438  case AT_DropInherit:
4439  address = ATExecDropInherit(rel, (RangeVar *) cmd->def, lockmode);
4440  break;
4441  case AT_AddOf:
4442  address = ATExecAddOf(rel, (TypeName *) cmd->def, lockmode);
4443  break;
4444  case AT_DropOf:
4445  ATExecDropOf(rel, lockmode);
4446  break;
4447  case AT_ReplicaIdentity:
4448  ATExecReplicaIdentity(rel, (ReplicaIdentityStmt *) cmd->def, lockmode);
4449  break;
4450  case AT_EnableRowSecurity:
4452  break;
4453  case AT_DisableRowSecurity:
4455  break;
4456  case AT_ForceRowSecurity:
4457  ATExecForceNoForceRowSecurity(rel, true);
4458  break;
4459  case AT_NoForceRowSecurity:
4460  ATExecForceNoForceRowSecurity(rel, false);
4461  break;
4462  case AT_GenericOptions:
4463  ATExecGenericOptions(rel, (List *) cmd->def);
4464  break;
4465  case AT_AttachPartition:
4466  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
4467  ATExecAttachPartition(wqueue, rel, (PartitionCmd *) cmd->def);
4468  else
4469  ATExecAttachPartitionIdx(wqueue, rel,
4470  ((PartitionCmd *) cmd->def)->name);
4471  break;
4472  case AT_DetachPartition:
4473  /* ATPrepCmd ensures it must be a table */
4474  Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
4475  ATExecDetachPartition(rel, ((PartitionCmd *) cmd->def)->name);
4476  break;
4477  default: /* oops */
4478  elog(ERROR, "unrecognized alter table type: %d",
4479  (int) cmd->subtype);
4480  break;
4481  }
4482 
4483  /*
4484  * Report the subcommand to interested event triggers.
4485  */
4486  EventTriggerCollectAlterTableSubcmd((Node *) cmd, address);
4487 
4488  /*
4489  * Bump the command counter to ensure the next subcommand in the sequence
4490  * can see the changes so far
4491  */
4493 }
4494 
4495 /*
4496  * ATRewriteTables: ALTER TABLE phase 3
4497  */
4498 static void
4499 ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode)
4500 {
4501  ListCell *ltab;
4502 
4503  /* Go through each table that needs to be checked or rewritten */
4504  foreach(ltab, *wqueue)
4505  {
4506  AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
4507 
4508  /* Relations without storage may be ignored here */
4509  if (!RELKIND_HAS_STORAGE(tab->relkind))
4510  continue;
4511 
4512  /*
4513  * If we change column data types or add/remove OIDs, the operation
4514  * has to be propagated to tables that use this table's rowtype as a
4515  * column type. tab->newvals will also be non-NULL in the case where
4516  * we're adding a column with a default. We choose to forbid that
4517  * case as well, since composite types might eventually support
4518  * defaults.
4519  *
4520  * (Eventually we'll probably need to check for composite type
4521  * dependencies even when we're just scanning the table without a
4522  * rewrite, but at the moment a composite type does not enforce any
4523  * constraints, so it's not necessary/appropriate to enforce them just
4524  * during ALTER.)
4525  */
4526  if (tab->newvals != NIL || tab->rewrite > 0)
4527  {
4528  Relation rel;
4529 
4530  rel = table_open(tab->relid, NoLock);
4531  find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
4532  table_close(rel, NoLock);
4533  }
4534 
4535  /*
4536  * We only need to rewrite the table if at least one column needs to
4537  * be recomputed, we are adding/removing the OID column, or we are
4538  * changing its persistence.
4539  *
4540  * There are two reasons for requiring a rewrite when changing
4541  * persistence: on one hand, we need to ensure that the buffers
4542  * belonging to each of the two relations are marked with or without
4543  * BM_PERMANENT properly. On the other hand, since rewriting creates
4544  * and assigns a new relfilenode, we automatically create or drop an
4545  * init fork for the relation as appropriate.
4546  */
4547  if (tab->rewrite > 0)
4548  {
4549  /* Build a temporary relation and copy data */
4550  Relation OldHeap;
4551  Oid OIDNewHeap;
4552  Oid NewTableSpace;
4553  char persistence;
4554 
4555  OldHeap = table_open(tab->relid, NoLock);
4556 
4557  /*
4558  * We don't support rewriting of system catalogs; there are too
4559  * many corner cases and too little benefit. In particular this
4560  * is certainly not going to work for mapped catalogs.
4561  */
4562  if (IsSystemRelation(OldHeap))
4563  ereport(ERROR,
4564  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4565  errmsg("cannot rewrite system relation \"%s\"",
4566  RelationGetRelationName(OldHeap))));
4567 
4568  if (RelationIsUsedAsCatalogTable(OldHeap))
4569  ereport(ERROR,
4570  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4571  errmsg("cannot rewrite table \"%s\" used as a catalog table",
4572  RelationGetRelationName(OldHeap))));
4573 
4574  /*
4575  * Don't allow rewrite on temp tables of other backends ... their
4576  * local buffer manager is not going to cope.
4577  */
4578  if (RELATION_IS_OTHER_TEMP(OldHeap))
4579  ereport(ERROR,
4580  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4581  errmsg("cannot rewrite temporary tables of other sessions")));
4582 
4583  /*
4584  * Select destination tablespace (same as original unless user
4585  * requested a change)
4586  */
4587  if (tab->newTableSpace)
4588  NewTableSpace = tab->newTableSpace;
4589  else
4590  NewTableSpace = OldHeap->rd_rel->reltablespace;
4591 
4592  /*
4593  * Select persistence of transient table (same as original unless
4594  * user requested a change)
4595  */
4596  persistence = tab->chgPersistence ?
4597  tab->newrelpersistence : OldHeap->rd_rel->relpersistence;
4598 
4599  table_close(OldHeap, NoLock);
4600 
4601  /*
4602  * Fire off an Event Trigger now, before actually rewriting the
4603  * table.
4604  *
4605  * We don't support Event Trigger for nested commands anywhere,
4606  * here included, and parsetree is given NULL when coming from
4607  * AlterTableInternal.
4608  *
4609  * And fire it only once.
4610  */
4611  if (parsetree)
4612  EventTriggerTableRewrite((Node *) parsetree,
4613  tab->relid,
4614  tab->rewrite);
4615 
4616  /*
4617  * Create transient table that will receive the modified data.
4618  *
4619  * Ensure it is marked correctly as logged or unlogged. We have
4620  * to do this here so that buffers for the new relfilenode will
4621  * have the right persistence set, and at the same time ensure
4622  * that the original filenode's buffers will get read in with the
4623  * correct setting (i.e. the original one). Otherwise a rollback
4624  * after the rewrite would possibly result with buffers for the
4625  * original filenode having the wrong persistence setting.
4626  *
4627  * NB: This relies on swap_relation_files() also swapping the
4628  * persistence. That wouldn't work for pg_class, but that can't be
4629  * unlogged anyway.
4630  */
4631  OIDNewHeap = make_new_heap(tab->relid, NewTableSpace, persistence,
4632  lockmode);
4633 
4634  /*
4635  * Copy the heap data into the new table with the desired
4636  * modifications, and test the current data within the table
4637  * against new constraints generated by ALTER TABLE commands.
4638  */
4639  ATRewriteTable(tab, OIDNewHeap, lockmode);
4640 
4641  /*
4642  * Swap the physical files of the old and new heaps, then rebuild
4643  * indexes and discard the old heap. We can use RecentXmin for
4644  * the table's new relfrozenxid because we rewrote all the tuples
4645  * in ATRewriteTable, so no older Xid remains in the table. Also,
4646  * we never try to swap toast tables by content, since we have no
4647  * interest in letting this code work on system catalogs.
4648  */
4649  finish_heap_swap(tab->relid, OIDNewHeap,
4650  false, false, true,
4651  !OidIsValid(tab->newTableSpace),
4652  RecentXmin,
4654  persistence);
4655  }
4656  else
4657  {
4658  /*
4659  * If required, test the current data within the table against new
4660  * constraints generated by ALTER TABLE commands, but don't
4661  * rebuild data.
4662  */
4663  if (tab->constraints != NIL || tab->verify_new_notnull ||
4664  tab->partition_constraint != NULL)
4665  ATRewriteTable(tab, InvalidOid, lockmode);
4666 
4667  /*
4668  * If we had SET TABLESPACE but no reason to reconstruct tuples,
4669  * just do a block-by-block copy.
4670  */
4671  if (tab->newTableSpace)
4672  ATExecSetTableSpace(tab->relid, tab->newTableSpace, lockmode);
4673  }
4674  }
4675 
4676  /*
4677  * Foreign key constraints are checked in a final pass, since (a) it's
4678  * generally best to examine each one separately, and (b) it's at least
4679  * theoretically possible that we have changed both relations of the
4680  * foreign key, and we'd better have finished both rewrites before we try
4681  * to read the tables.
4682  */
4683  foreach(ltab, *wqueue)
4684  {
4685  AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
4686  Relation rel = NULL;
4687  ListCell *lcon;
4688 
4689  /* Relations without storage may be ignored here too */
4690  if (!RELKIND_HAS_STORAGE(tab->relkind))
4691  continue;
4692 
4693  foreach(lcon, tab->constraints)
4694  {
4695  NewConstraint *con = lfirst(lcon);
4696 
4697  if (con->contype == CONSTR_FOREIGN)
4698  {
4699  Constraint *fkconstraint = (Constraint *) con->qual;
4700  Relation refrel;
4701 
4702  if (rel == NULL)
4703  {
4704  /* Long since locked, no need for another */
4705  rel = table_open(tab->relid, NoLock);
4706  }
4707 
4708  refrel = table_open(con->refrelid, RowShareLock);
4709 
4710  validateForeignKeyConstraint(fkconstraint->conname, rel, refrel,
4711  con->refindid,
4712  con->conid);
4713 
4714  /*
4715  * No need to mark the constraint row as validated, we did
4716  * that when we inserted the row earlier.
4717  */
4718 
4719  table_close(refrel, NoLock);
4720  }
4721  }
4722 
4723  if (rel)
4724  table_close(rel, NoLock);
4725  }
4726 }
4727 
4728 /*
4729  * ATRewriteTable: scan or rewrite one table
4730  *
4731  * OIDNewHeap is InvalidOid if we don't need to rewrite
4732  */
4733 static void
4734 ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
4735 {
4736  Relation oldrel;
4737  Relation newrel;
4738  TupleDesc oldTupDesc;
4739  TupleDesc newTupDesc;
4740  bool needscan = false;
4741  List *notnull_attrs;
4742  int i;
4743  ListCell *l;
4744  EState *estate;
4745  CommandId mycid;
4746  BulkInsertState bistate;
4747  int ti_options;
4748  ExprState *partqualstate = NULL;
4749 
4750  /*
4751  * Open the relation(s). We have surely already locked the existing
4752  * table.
4753  */
4754  oldrel = table_open(tab->relid, NoLock);
4755  oldTupDesc = tab->oldDesc;
4756  newTupDesc = RelationGetDescr(oldrel); /* includes all mods */
4757 
4758  if (OidIsValid(OIDNewHeap))
4759  newrel = table_open(OIDNewHeap, lockmode);
4760  else
4761  newrel = NULL;
4762 
4763  /*
4764  * Prepare a BulkInsertState and options for table_tuple_insert. Because
4765  * we're building a new heap, we can skip WAL-logging and fsync it to disk
4766  * at the end instead (unless WAL-logging is required for archiving or
4767  * streaming replication). The FSM is empty too, so don't bother using it.
4768  */
4769  if (newrel)
4770  {
4771  mycid = GetCurrentCommandId(true);
4772  bistate = GetBulkInsertState();
4773 
4774  ti_options = TABLE_INSERT_SKIP_FSM;
4775  if (!XLogIsNeeded())
4776  ti_options |= TABLE_INSERT_SKIP_WAL;
4777  }
4778  else
4779  {
4780  /* keep compiler quiet about using these uninitialized */
4781  mycid = 0;
4782  bistate = NULL;
4783  ti_options = 0;
4784  }
4785 
4786  /*
4787  * Generate the constraint and default execution states
4788  */
4789 
4790  estate = CreateExecutorState();
4791 
4792  /* Build the needed expression execution states */
4793  foreach(l, tab->constraints)
4794  {
4795  NewConstraint *con = lfirst(l);
4796 
4797  switch (con->contype)
4798  {
4799  case CONSTR_CHECK:
4800  needscan = true;
4801  con->qualstate = ExecPrepareExpr((Expr *) con->qual, estate);
4802  break;
4803  case CONSTR_FOREIGN:
4804  /* Nothing to do here */
4805  break;
4806  default:
4807  elog(ERROR, "unrecognized constraint type: %d",
4808  (int) con->contype);
4809  }
4810  }
4811 
4812  /* Build expression execution states for partition check quals */
4813  if (tab->partition_constraint)
4814  {
4815  needscan = true;
4816  partqualstate = ExecPrepareExpr(tab->partition_constraint, estate);
4817  }
4818 
4819  foreach(l, tab->newvals)
4820  {
4821  NewColumnValue *ex = lfirst(l);
4822 
4823  /* expr already planned */
4824  ex->exprstate = ExecInitExpr((Expr *) ex->expr, NULL);
4825  }
4826 
4827  notnull_attrs = NIL;
4828  if (newrel || tab->verify_new_notnull)
4829  {
4830  /*
4831  * If we are rebuilding the tuples OR if we added any new but not
4832  * verified NOT NULL constraints, check all not-null constraints. This
4833  * is a bit of overkill but it minimizes risk of bugs, and
4834  * heap_attisnull is a pretty cheap test anyway.
4835  */
4836  for (i = 0; i < newTupDesc->natts; i++)
4837  {
4838  Form_pg_attribute attr = TupleDescAttr(newTupDesc, i);
4839 
4840  if (attr->attnotnull && !attr->attisdropped)
4841  notnull_attrs = lappend_int(notnull_attrs, i);
4842  }
4843  if (notnull_attrs)
4844  needscan = true;
4845  }
4846 
4847  if (newrel || needscan)
4848  {
4849  ExprContext *econtext;
4850  TupleTableSlot *oldslot;
4851  TupleTableSlot *newslot;
4852  TableScanDesc scan;
4853  MemoryContext oldCxt;
4854  List *dropped_attrs = NIL;
4855  ListCell *lc;
4856  Snapshot snapshot;
4857 
4858  if (newrel)
4859  ereport(DEBUG1,
4860  (errmsg("rewriting table \"%s\"",
4861  RelationGetRelationName(oldrel))));
4862  else
4863  ereport(DEBUG1,
4864  (errmsg("verifying table \"%s\"",
4865  RelationGetRelationName(oldrel))));
4866 
4867  if (newrel)
4868  {
4869  /*
4870  * All predicate locks on the tuples or pages are about to be made
4871  * invalid, because we move tuples around. Promote them to
4872  * relation locks.
4873  */
4875  }
4876 
4877  econtext = GetPerTupleExprContext(estate);
4878 
4879  /*
4880  * Create necessary tuple slots. When rewriting, two slots are needed,
4881  * otherwise one suffices. In the case where one slot suffices, we
4882  * need to use the new tuple descriptor, otherwise some constraints
4883  * can't be evaluated. Note that even when the tuple layout is the
4884  * same and no rewrite is required, the tupDescs might not be
4885  * (consider ADD COLUMN without a default).
4886  */
4887  if (tab->rewrite)
4888  {
4889  Assert(newrel != NULL);
4890  oldslot = MakeSingleTupleTableSlot(oldTupDesc,
4891  table_slot_callbacks(oldrel));
4892  newslot = MakeSingleTupleTableSlot(newTupDesc,
4893  table_slot_callbacks(newrel));
4894  }
4895  else
4896  {
4897  oldslot = MakeSingleTupleTableSlot(newTupDesc,
4898  table_slot_callbacks(oldrel));
4899  newslot = NULL;
4900  }
4901 
4902  /*
4903  * Any attributes that are dropped according to the new tuple
4904  * descriptor can be set to NULL. We precompute the list of dropped
4905  * attributes to avoid needing to do so in the per-tuple loop.
4906  */
4907  for (i = 0; i < newTupDesc->natts; i++)
4908  {
4909  if (TupleDescAttr(newTupDesc, i)->attisdropped)
4910  dropped_attrs = lappend_int(dropped_attrs, i);
4911  }
4912 
4913  /*
4914  * Scan through the rows, generating a new row if needed and then
4915  * checking all the constraints.
4916  */
4917  snapshot = RegisterSnapshot(GetLatestSnapshot());
4918  scan = table_beginscan(oldrel, snapshot, 0, NULL);
4919 
4920  /*
4921  * Switch to per-tuple memory context and reset it for each tuple
4922  * produced, so we don't leak memory.
4923  */
4925 
4926  while (table_scan_getnextslot(scan, ForwardScanDirection, oldslot))
4927  {
4928  TupleTableSlot *insertslot;
4929 
4930  if (tab->rewrite > 0)
4931  {
4932  /* Extract data from old tuple */
4933  slot_getallattrs(oldslot);
4934  ExecClearTuple(newslot);
4935 
4936  /* copy attributes */
4937  memcpy(newslot->tts_values, oldslot->tts_values,
4938  sizeof(Datum) * oldslot->tts_nvalid);
4939  memcpy(newslot->tts_isnull, oldslot->tts_isnull,
4940  sizeof(bool) * oldslot->tts_nvalid);
4941 
4942  /* Set dropped attributes to null in new tuple */
4943  foreach(lc, dropped_attrs)
4944  newslot->tts_isnull[lfirst_int(lc)] = true;
4945 
4946  /*
4947  * Process supplied expressions to replace selected columns.
4948  * Expression inputs come from the old tuple.
4949  */
4950  econtext->ecxt_scantuple = oldslot;
4951 
4952  foreach(l, tab->newvals)
4953  {
4954  NewColumnValue *ex = lfirst(l);
4955 
4956  newslot->tts_values[ex->attnum - 1]
4957  = ExecEvalExpr(ex->exprstate,
4958  econtext,
4959  &newslot->tts_isnull[ex->attnum - 1]);
4960  }
4961 
4962  ExecStoreVirtualTuple(newslot);
4963 
4964  /*
4965  * Constraints might reference the tableoid column, so
4966  * initialize t_tableOid before evaluating them.
4967  */
4968  newslot->tts_tableOid = RelationGetRelid(oldrel);
4969  insertslot = newslot;
4970  }
4971  else
4972  {
4973  /*
4974  * If there's no rewrite, old and new table are guaranteed to
4975  * have the same AM, so we can just use the old slot to verify
4976  * new constraints etc.
4977  */
4978  insertslot = oldslot;
4979  }
4980 
4981  /* Now check any constraints on the possibly-changed tuple */
4982  econtext->ecxt_scantuple = insertslot;
4983 
4984  foreach(l, notnull_attrs)
4985  {
4986  int attn = lfirst_int(l);
4987 
4988  if (slot_attisnull(insertslot, attn + 1))
4989  {
4990  Form_pg_attribute attr = TupleDescAttr(newTupDesc, attn);
4991 
4992  ereport(ERROR,
4993  (errcode(ERRCODE_NOT_NULL_VIOLATION),
4994  errmsg("column \"%s\" contains null values",
4995  NameStr(attr->attname)),
4996  errtablecol(oldrel, attn + 1)));
4997  }
4998  }
4999 
5000  foreach(l, tab->constraints)
5001  {
5002  NewConstraint *con = lfirst(l);
5003 
5004  switch (con->contype)
5005  {
5006  case CONSTR_CHECK:
5007  if (!ExecCheck(con->qualstate, econtext))
5008  ereport(ERROR,
5009  (errcode(ERRCODE_CHECK_VIOLATION),
5010  errmsg("check constraint \"%s\" is violated by some row",
5011  con->name),
5012  errtableconstraint(oldrel, con->name)));
5013  break;
5014  case CONSTR_FOREIGN:
5015  /* Nothing to do here */
5016  break;
5017  default:
5018  elog(ERROR, "unrecognized constraint type: %d",
5019  (int) con->contype);
5020  }
5021  }
5022 
5023  if (partqualstate && !ExecCheck(partqualstate, econtext))
5024  {
5025  if (tab->validate_default)
5026  ereport(ERROR,
5027  (errcode(ERRCODE_CHECK_VIOLATION),
5028  errmsg("updated partition constraint for default partition would be violated by some row")));
5029  else
5030  ereport(ERROR,
5031  (errcode(ERRCODE_CHECK_VIOLATION),
5032  errmsg("partition constraint is violated by some row")));
5033  }
5034 
5035  /* Write the tuple out to the new relation */
5036  if (newrel)
5037  table_tuple_insert(newrel, insertslot, mycid,
5038  ti_options, bistate);
5039 
5040  ResetExprContext(econtext);
5041 
5043  }
5044 
5045  MemoryContextSwitchTo(oldCxt);
5046  table_endscan(scan);
5047  UnregisterSnapshot(snapshot);
5048 
5050  if (newslot)
5052  }
5053 
5054  FreeExecutorState(estate);
5055 
5056  table_close(oldrel, NoLock);
5057  if (newrel)
5058  {
5059  FreeBulkInsertState(bistate);
5060 
5061  table_finish_bulk_insert(newrel, ti_options);
5062 
5063  table_close(newrel, NoLock);
5064  }
5065 }
5066 
5067 /*
5068  * ATGetQueueEntry: find or create an entry in the ALTER TABLE work queue
5069  */
5070 static AlteredTableInfo *
5072 {
5073  Oid relid = RelationGetRelid(rel);
5074  AlteredTableInfo *tab;
5075  ListCell *ltab;
5076 
5077  foreach(ltab, *wqueue)
5078  {
5079  tab = (AlteredTableInfo *) lfirst(ltab);
5080  if (tab->relid == relid)
5081  return tab;
5082  }
5083 
5084  /*
5085  * Not there, so add it. Note that we make a copy of the relation's
5086  * existing descriptor before anything interesting can happen to it.
5087  */
5088  tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo));
5089  tab->relid = relid;
5090  tab->relkind = rel->rd_rel->relkind;
5092  tab->newrelpersistence = RELPERSISTENCE_PERMANENT;
5093  tab->chgPersistence = false;
5094 
5095  *wqueue = lappend(*wqueue, tab);
5096 
5097  return tab;
5098 }
5099 
5100 /*
5101  * ATSimplePermissions
5102  *
5103  * - Ensure that it is a relation (or possibly a view)
5104  * - Ensure this user is the owner
5105  * - Ensure that it is not a system table
5106  */
5107 static void
5108 ATSimplePermissions(Relation rel, int allowed_targets)
5109 {
5110  int actual_target;
5111 
5112  switch (rel->rd_rel->relkind)
5113  {
5114  case RELKIND_RELATION:
5115  case RELKIND_PARTITIONED_TABLE:
5116  actual_target = ATT_TABLE;
5117  break;
5118  case RELKIND_VIEW:
5119  actual_target = ATT_VIEW;
5120  break;
5121  case RELKIND_MATVIEW:
5122  actual_target = ATT_MATVIEW;
5123  break;
5124  case RELKIND_INDEX:
5125  actual_target = ATT_INDEX;
5126  break;
5127  case RELKIND_PARTITIONED_INDEX:
5128  actual_target = ATT_PARTITIONED_INDEX;
5129  break;
5130  case RELKIND_COMPOSITE_TYPE:
5131  actual_target = ATT_COMPOSITE_TYPE;
5132  break;
5133  case RELKIND_FOREIGN_TABLE:
5134  actual_target = ATT_FOREIGN_TABLE;
5135  break;
5136  default:
5137  actual_target = 0;
5138  break;
5139  }
5140 
5141  /* Wrong target type? */
5142  if ((actual_target & allowed_targets) == 0)
5143  ATWrongRelkindError(rel, allowed_targets);
5144 
5145  /* Permissions checks */
5149 
5151  ereport(ERROR,
5152  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5153  errmsg("permission denied: \"%s\" is a system catalog",
5154  RelationGetRelationName(rel))));
5155 }
5156 
5157 /*
5158  * ATWrongRelkindError
5159  *
5160  * Throw an error when a relation has been determined to be of the wrong
5161  * type.
5162  */
5163 static void
5164 ATWrongRelkindError(Relation rel, int allowed_targets)
5165 {
5166  char *msg;
5167 
5168  switch (allowed_targets)
5169  {
5170  case ATT_TABLE:
5171  msg = _("\"%s\" is not a table");
5172  break;
5173  case ATT_TABLE | ATT_VIEW:
5174  msg = _("\"%s\" is not a table or view");
5175  break;
5177  msg = _("\"%s\" is not a table, view, or foreign table");
5178  break;
5180  msg = _("\"%s\" is not a table, view, materialized view, or index");
5181  break;
5182  case ATT_TABLE | ATT_MATVIEW:
5183  msg = _("\"%s\" is not a table or materialized view");
5184  break;
5185  case ATT_TABLE | ATT_MATVIEW | ATT_INDEX:
5186  msg = _("\"%s\" is not a table, materialized view, or index");
5187  break;
5189  msg = _("\"%s\" is not a table, materialized view, or foreign table");
5190  break;
5192  msg = _("\"%s\" is not a table or foreign table");
5193  break;
5195  msg = _("\"%s\" is not a table, composite type, or foreign table");
5196  break;
5198  msg = _("\"%s\" is not a table, materialized view, index, or foreign table");
5199  break;
5200  case ATT_VIEW:
5201  msg = _("\"%s\" is not a view");
5202  break;
5203  case ATT_FOREIGN_TABLE:
5204  msg = _("\"%s\" is not a foreign table");
5205  break;
5206  default:
5207  /* shouldn't get here, add all necessary cases above */
5208  msg = _("\"%s\" is of the wrong type");
5209  break;
5210  }
5211 
5212  ereport(ERROR,
5213  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5214  errmsg(msg, RelationGetRelationName(rel))));
5215 }
5216 
5217 /*
5218  * ATSimpleRecursion
5219  *
5220  * Simple table recursion sufficient for most ALTER TABLE operations.
5221  * All direct and indirect children are processed in an unspecified order.
5222  * Note that if a child inherits from the original table via multiple
5223  * inheritance paths, it will be visited just once.
5224  */
5225 static void
5227  AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode)
5228 {
5229  /*
5230  * Propagate to children if desired. Only plain tables, foreign tables
5231  * and partitioned tables have children, so no need to search for other
5232  * relkinds.
5233  */
5234  if (recurse &&
5235  (rel->rd_rel->relkind == RELKIND_RELATION ||
5236  rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
5237  rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
5238  {
5239  Oid relid = RelationGetRelid(rel);
5240  ListCell *child;
5241  List *children;
5242 
5243  children = find_all_inheritors(relid, lockmode, NULL);
5244 
5245  /*
5246  * find_all_inheritors does the recursive search of the inheritance
5247  * hierarchy, so all we have to do is process all of the relids in the
5248  * list that it returns.
5249  */
5250  foreach(child, children)
5251  {
5252  Oid childrelid = lfirst_oid(child);
5253  Relation childrel;
5254 
5255  if (childrelid == relid)
5256  continue;
5257  /* find_all_inheritors already got lock */
5258  childrel = relation_open(childrelid, NoLock);
5259  CheckTableNotInUse(childrel, "ALTER TABLE");
5260  ATPrepCmd(wqueue, childrel, cmd, false, true, lockmode);
5261  relation_close(childrel, NoLock);
5262  }
5263  }
5264 }
5265 
5266 /*
5267  * Obtain list of partitions of the given table, locking them all at the given
5268  * lockmode and ensuring that they all pass CheckTableNotInUse.
5269  *
5270  * This function is a no-op if the given relation is not a partitioned table;
5271  * in particular, nothing is done if it's a legacy inheritance parent.
5272  */
5273 static void
5275 {
5276  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
5277  {
5278  List *inh;
5279  ListCell *cell;
5280 
5281  inh = find_all_inheritors(RelationGetRelid(rel), lockmode, NULL);
5282  /* first element is the parent rel; must ignore it */
5283  for_each_cell(cell, inh, list_second_cell(inh))
5284  {
5285  Relation childrel;
5286 
5287  /* find_all_inheritors already got lock */
5288  childrel = table_open(lfirst_oid(cell), NoLock);
5289  CheckTableNotInUse(childrel, "ALTER TABLE");
5290  table_close(childrel, NoLock);
5291  }
5292  list_free(inh);
5293  }
5294 }
5295 
5296 /*
5297  * ATTypedTableRecursion
5298  *
5299  * Propagate ALTER TYPE operations to the typed tables of that type.
5300  * Also check the RESTRICT/CASCADE behavior. Given CASCADE, also permit
5301  * recursion to inheritance children of the typed tables.
5302  */
5303 static void
5305  LOCKMODE lockmode)
5306 {
5307  ListCell *child;
5308  List *children;
5309 
5310  Assert(rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE);
5311 
5312  children = find_typed_table_dependencies(rel->rd_rel->reltype,
5314  cmd->behavior);
5315 
5316  foreach(child, children)
5317  {
5318  Oid childrelid = lfirst_oid(child);
5319  Relation childrel;
5320 
5321  childrel = relation_open(childrelid, lockmode);
5322  CheckTableNotInUse(childrel, "ALTER TABLE");
5323  ATPrepCmd(wqueue, childrel, cmd, true, true, lockmode);
5324  relation_close(childrel, NoLock);
5325  }
5326 }
5327 
5328 
5329 /*
5330  * find_composite_type_dependencies
5331  *
5332  * Check to see if the type "typeOid" is being used as a column in some table
5333  * (possibly nested several levels deep in composite types, arrays, etc!).
5334  * Eventually, we'd like to propagate the check or rewrite operation
5335  * into such tables, but for now, just error out if we find any.
5336  *
5337  * Caller should provide either the associated relation of a rowtype,
5338  * or a type name (not both) for use in the error message, if any.
5339  *
5340  * Note that "typeOid" is not necessarily a composite type; it could also be
5341  * another container type such as an array or range, or a domain over one of
5342  * these things. The name of this function is therefore somewhat historical,
5343  * but it's not worth changing.
5344  *
5345  * We assume that functions and views depending on the type are not reasons
5346  * to reject the ALTER. (How safe is this really?)
5347  */
5348 void
5350  const char *origTypeName)
5351 {
5352  Relation depRel;
5353  ScanKeyData key[2];
5354  SysScanDesc depScan;
5355  HeapTuple depTup;
5356 
5357  /* since this function recurses, it could be driven to stack overflow */
5359 
5360  /*
5361  * We scan pg_depend to find those things that depend on the given type.
5362  * (We assume we can ignore refobjsubid for a type.)
5363  */
5364  depRel = table_open(DependRelationId, AccessShareLock);
5365 
5366  ScanKeyInit(&key[0],
5367  Anum_pg_depend_refclassid,
5368  BTEqualStrategyNumber, F_OIDEQ,
5369  ObjectIdGetDatum(TypeRelationId));
5370  ScanKeyInit(&key[1],
5371  Anum_pg_depend_refobjid,
5372  BTEqualStrategyNumber, F_OIDEQ,
5373  ObjectIdGetDatum(typeOid));
5374 
5375  depScan = systable_beginscan(depRel, DependReferenceIndexId, true,
5376  NULL, 2, key);
5377 
5378  while (HeapTupleIsValid(depTup = systable_getnext(depScan)))
5379  {
5380  Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
5381  Relation rel;
5382  Form_pg_attribute att;
5383 
5384  /* Check for directly dependent types */
5385  if (pg_depend->classid == TypeRelationId)
5386  {
5387  /*
5388  * This must be an array, domain, or range containing the given
5389  * type, so recursively check for uses of this type. Note that
5390  * any error message will mention the original type not the
5391  * container; this is intentional.
5392  */
5393  find_composite_type_dependencies(pg_depend->objid,
5394  origRelation, origTypeName);
5395  continue;
5396  }
5397 
5398  /* Else, ignore dependees that aren't user columns of relations */
5399  /* (we assume system columns are never of interesting types) */
5400  if (pg_depend->classid != RelationRelationId ||
5401  pg_depend->objsubid <= 0)
5402  continue;
5403 
5404  rel = relation_open(pg_depend->objid, AccessShareLock);
5405  att = TupleDescAttr(rel->rd_att, pg_depend->objsubid - 1);
5406 
5407  if (rel->rd_rel->relkind == RELKIND_RELATION ||
5408  rel->rd_rel->relkind == RELKIND_MATVIEW ||
5409  rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
5410  {
5411  if (origTypeName)
5412  ereport(ERROR,
5413  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5414  errmsg("cannot alter type \"%s\" because column \"%s.%s\" uses it",
5415  origTypeName,
5417  NameStr(att->attname))));
5418  else if (origRelation->rd_rel->relkind == RELKIND_COMPOSITE_