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