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