]> granicus.if.org Git - postgresql/blob - src/backend/commands/tablecmds.c
437a6915b3312289b44ed38415b33067cd423d95
[postgresql] / src / backend / commands / tablecmds.c
1 /*-------------------------------------------------------------------------
2  *
3  * tablecmds.c
4  *        Commands for creating and altering table structures and settings
5  *
6  * Portions Copyright (c) 1996-2011, 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/reloptions.h"
20 #include "access/relscan.h"
21 #include "access/sysattr.h"
22 #include "access/xact.h"
23 #include "catalog/catalog.h"
24 #include "catalog/dependency.h"
25 #include "catalog/heap.h"
26 #include "catalog/index.h"
27 #include "catalog/indexing.h"
28 #include "catalog/namespace.h"
29 #include "catalog/objectaccess.h"
30 #include "catalog/pg_collation.h"
31 #include "catalog/pg_constraint.h"
32 #include "catalog/pg_depend.h"
33 #include "catalog/pg_foreign_table.h"
34 #include "catalog/pg_inherits.h"
35 #include "catalog/pg_inherits_fn.h"
36 #include "catalog/pg_namespace.h"
37 #include "catalog/pg_opclass.h"
38 #include "catalog/pg_tablespace.h"
39 #include "catalog/pg_trigger.h"
40 #include "catalog/pg_type.h"
41 #include "catalog/pg_type_fn.h"
42 #include "catalog/storage.h"
43 #include "catalog/toasting.h"
44 #include "commands/cluster.h"
45 #include "commands/comment.h"
46 #include "commands/defrem.h"
47 #include "commands/sequence.h"
48 #include "commands/tablecmds.h"
49 #include "commands/tablespace.h"
50 #include "commands/trigger.h"
51 #include "commands/typecmds.h"
52 #include "executor/executor.h"
53 #include "foreign/foreign.h"
54 #include "miscadmin.h"
55 #include "nodes/makefuncs.h"
56 #include "nodes/nodeFuncs.h"
57 #include "nodes/parsenodes.h"
58 #include "optimizer/clauses.h"
59 #include "parser/parse_clause.h"
60 #include "parser/parse_coerce.h"
61 #include "parser/parse_collate.h"
62 #include "parser/parse_expr.h"
63 #include "parser/parse_oper.h"
64 #include "parser/parse_relation.h"
65 #include "parser/parse_type.h"
66 #include "parser/parse_utilcmd.h"
67 #include "parser/parser.h"
68 #include "rewrite/rewriteDefine.h"
69 #include "rewrite/rewriteHandler.h"
70 #include "storage/bufmgr.h"
71 #include "storage/lmgr.h"
72 #include "storage/lock.h"
73 #include "storage/smgr.h"
74 #include "utils/acl.h"
75 #include "utils/builtins.h"
76 #include "utils/fmgroids.h"
77 #include "utils/inval.h"
78 #include "utils/lsyscache.h"
79 #include "utils/memutils.h"
80 #include "utils/relcache.h"
81 #include "utils/snapmgr.h"
82 #include "utils/syscache.h"
83 #include "utils/tqual.h"
84 #include "utils/typcache.h"
85
86
87 /*
88  * ON COMMIT action list
89  */
90 typedef struct OnCommitItem
91 {
92         Oid                     relid;                  /* relid of relation */
93         OnCommitAction oncommit;        /* what to do at end of xact */
94
95         /*
96          * If this entry was created during the current transaction,
97          * creating_subid is the ID of the creating subxact; if created in a prior
98          * transaction, creating_subid is zero.  If deleted during the current
99          * transaction, deleting_subid is the ID of the deleting subxact; if no
100          * deletion request is pending, deleting_subid is zero.
101          */
102         SubTransactionId creating_subid;
103         SubTransactionId deleting_subid;
104 } OnCommitItem;
105
106 static List *on_commits = NIL;
107
108
109 /*
110  * State information for ALTER TABLE
111  *
112  * The pending-work queue for an ALTER TABLE is a List of AlteredTableInfo
113  * structs, one for each table modified by the operation (the named table
114  * plus any child tables that are affected).  We save lists of subcommands
115  * to apply to this table (possibly modified by parse transformation steps);
116  * these lists will be executed in Phase 2.  If a Phase 3 step is needed,
117  * necessary information is stored in the constraints and newvals lists.
118  *
119  * Phase 2 is divided into multiple passes; subcommands are executed in
120  * a pass determined by subcommand type.
121  */
122
123 #define AT_PASS_DROP                    0               /* DROP (all flavors) */
124 #define AT_PASS_ALTER_TYPE              1               /* ALTER COLUMN TYPE */
125 #define AT_PASS_OLD_INDEX               2               /* re-add existing indexes */
126 #define AT_PASS_OLD_CONSTR              3               /* re-add existing constraints */
127 #define AT_PASS_COL_ATTRS               4               /* set other column attributes */
128 /* We could support a RENAME COLUMN pass here, but not currently used */
129 #define AT_PASS_ADD_COL                 5               /* ADD COLUMN */
130 #define AT_PASS_ADD_INDEX               6               /* ADD indexes */
131 #define AT_PASS_ADD_CONSTR              7               /* ADD constraints, defaults */
132 #define AT_PASS_MISC                    8               /* other stuff */
133 #define AT_NUM_PASSES                   9
134
135 typedef struct AlteredTableInfo
136 {
137         /* Information saved before any work commences: */
138         Oid                     relid;                  /* Relation to work on */
139         char            relkind;                /* Its relkind */
140         TupleDesc       oldDesc;                /* Pre-modification tuple descriptor */
141         /* Information saved by Phase 1 for Phase 2: */
142         List       *subcmds[AT_NUM_PASSES]; /* Lists of AlterTableCmd */
143         /* Information saved by Phases 1/2 for Phase 3: */
144         List       *constraints;        /* List of NewConstraint */
145         List       *newvals;            /* List of NewColumnValue */
146         bool            new_notnull;    /* T if we added new NOT NULL constraints */
147         bool            rewrite;                /* T if a rewrite is forced */
148         Oid                     newTableSpace;  /* new tablespace; 0 means no change */
149         /* Objects to rebuild after completing ALTER TYPE operations */
150         List       *changedConstraintOids;      /* OIDs of constraints to rebuild */
151         List       *changedConstraintDefs;      /* string definitions of same */
152         List       *changedIndexOids;           /* OIDs of indexes to rebuild */
153         List       *changedIndexDefs;           /* string definitions of same */
154 } AlteredTableInfo;
155
156 /* Struct describing one new constraint to check in Phase 3 scan */
157 /* Note: new NOT NULL constraints are handled elsewhere */
158 typedef struct NewConstraint
159 {
160         char       *name;                       /* Constraint name, or NULL if none */
161         ConstrType      contype;                /* CHECK or FOREIGN */
162         Oid                     refrelid;               /* PK rel, if FOREIGN */
163         Oid                     refindid;               /* OID of PK's index, if FOREIGN */
164         Oid                     conid;                  /* OID of pg_constraint entry, if FOREIGN */
165         Node       *qual;                       /* Check expr or CONSTR_FOREIGN Constraint */
166         List       *qualstate;          /* Execution state for CHECK */
167 } NewConstraint;
168
169 /*
170  * Struct describing one new column value that needs to be computed during
171  * Phase 3 copy (this could be either a new column with a non-null default, or
172  * a column that we're changing the type of).  Columns without such an entry
173  * are just copied from the old table during ATRewriteTable.  Note that the
174  * expr is an expression over *old* table values.
175  */
176 typedef struct NewColumnValue
177 {
178         AttrNumber      attnum;                 /* which column */
179         Expr       *expr;                       /* expression to compute */
180         ExprState  *exprstate;          /* execution state */
181 } NewColumnValue;
182
183 /*
184  * Error-reporting support for RemoveRelations
185  */
186 struct dropmsgstrings
187 {
188         char            kind;
189         int                     nonexistent_code;
190         const char *nonexistent_msg;
191         const char *skipping_msg;
192         const char *nota_msg;
193         const char *drophint_msg;
194 };
195
196 static const struct dropmsgstrings dropmsgstringarray[] = {
197         {RELKIND_RELATION,
198                 ERRCODE_UNDEFINED_TABLE,
199                 gettext_noop("table \"%s\" does not exist"),
200                 gettext_noop("table \"%s\" does not exist, skipping"),
201                 gettext_noop("\"%s\" is not a table"),
202         gettext_noop("Use DROP TABLE to remove a table.")},
203         {RELKIND_SEQUENCE,
204                 ERRCODE_UNDEFINED_TABLE,
205                 gettext_noop("sequence \"%s\" does not exist"),
206                 gettext_noop("sequence \"%s\" does not exist, skipping"),
207                 gettext_noop("\"%s\" is not a sequence"),
208         gettext_noop("Use DROP SEQUENCE to remove a sequence.")},
209         {RELKIND_VIEW,
210                 ERRCODE_UNDEFINED_TABLE,
211                 gettext_noop("view \"%s\" does not exist"),
212                 gettext_noop("view \"%s\" does not exist, skipping"),
213                 gettext_noop("\"%s\" is not a view"),
214         gettext_noop("Use DROP VIEW to remove a view.")},
215         {RELKIND_INDEX,
216                 ERRCODE_UNDEFINED_OBJECT,
217                 gettext_noop("index \"%s\" does not exist"),
218                 gettext_noop("index \"%s\" does not exist, skipping"),
219                 gettext_noop("\"%s\" is not an index"),
220         gettext_noop("Use DROP INDEX to remove an index.")},
221         {RELKIND_COMPOSITE_TYPE,
222                 ERRCODE_UNDEFINED_OBJECT,
223                 gettext_noop("type \"%s\" does not exist"),
224                 gettext_noop("type \"%s\" does not exist, skipping"),
225                 gettext_noop("\"%s\" is not a type"),
226         gettext_noop("Use DROP TYPE to remove a type.")},
227         {RELKIND_FOREIGN_TABLE,
228                 ERRCODE_UNDEFINED_OBJECT,
229                 gettext_noop("foreign table \"%s\" does not exist"),
230                 gettext_noop("foreign table \"%s\" does not exist, skipping"),
231                 gettext_noop("\"%s\" is not a foreign table"),
232         gettext_noop("Use DROP FOREIGN TABLE to remove a foreign table.")},
233         {'\0', 0, NULL, NULL, NULL, NULL}
234 };
235
236 /* Alter table target-type flags for ATSimplePermissions */
237 #define         ATT_TABLE                               0x0001
238 #define         ATT_VIEW                                0x0002
239 #define         ATT_INDEX                               0x0004
240 #define         ATT_COMPOSITE_TYPE              0x0008
241 #define         ATT_FOREIGN_TABLE               0x0010
242
243 static void truncate_check_rel(Relation rel);
244 static List *MergeAttributes(List *schema, List *supers, char relpersistence,
245                                 List **supOids, List **supconstr, int *supOidCount);
246 static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
247 static bool change_varattnos_walker(Node *node, const AttrNumber *newattno);
248 static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
249 static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
250 static void StoreCatalogInheritance(Oid relationId, List *supers);
251 static void StoreCatalogInheritance1(Oid relationId, Oid parentOid,
252                                                  int16 seqNumber, Relation inhRelation);
253 static int      findAttrByName(const char *attributeName, List *schema);
254 static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
255 static void AlterIndexNamespaces(Relation classRel, Relation rel,
256                                          Oid oldNspOid, Oid newNspOid);
257 static void AlterSeqNamespaces(Relation classRel, Relation rel,
258                                    Oid oldNspOid, Oid newNspOid,
259                                    const char *newNspName, LOCKMODE lockmode);
260 static void ATExecValidateConstraint(Relation rel, const char *constrName);
261 static int transformColumnNameList(Oid relId, List *colList,
262                                                 int16 *attnums, Oid *atttypids);
263 static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
264                                                    List **attnamelist,
265                                                    int16 *attnums, Oid *atttypids,
266                                                    Oid *opclasses);
267 static Oid transformFkeyCheckAttrs(Relation pkrel,
268                                                 int numattrs, int16 *attnums,
269                                                 Oid *opclasses);
270 static void checkFkeyPermissions(Relation rel, int16 *attnums, int natts);
271 static void validateForeignKeyConstraint(char *conname,
272                                                          Relation rel, Relation pkrel,
273                                                          Oid pkindOid, Oid constraintOid);
274 static void createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
275                                                  Oid constraintOid, Oid indexOid);
276 static void ATController(Relation rel, List *cmds, bool recurse, LOCKMODE lockmode);
277 static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
278                   bool recurse, bool recursing, LOCKMODE lockmode);
279 static void ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode);
280 static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
281                   AlterTableCmd *cmd, LOCKMODE lockmode);
282 static void ATRewriteTables(List **wqueue, LOCKMODE lockmode);
283 static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode);
284 static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel);
285 static void ATSimplePermissions(Relation rel, int allowed_targets);
286 static void ATWrongRelkindError(Relation rel, int allowed_targets);
287 static void ATSimpleRecursion(List **wqueue, Relation rel,
288                                   AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode);
289 static void ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
290                                           LOCKMODE lockmode);
291 static List *find_typed_table_dependencies(Oid typeOid, const char *typeName,
292                                                           DropBehavior behavior);
293 static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
294                                 AlterTableCmd *cmd, LOCKMODE lockmode);
295 static void ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
296                                 ColumnDef *colDef, bool isOid,
297                                 bool recurse, bool recursing, LOCKMODE lockmode);
298 static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid);
299 static void add_column_collation_dependency(Oid relid, int32 attnum, Oid collid);
300 static void ATPrepAddOids(List **wqueue, Relation rel, bool recurse,
301                           AlterTableCmd *cmd, LOCKMODE lockmode);
302 static void ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode);
303 static void ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
304                                  const char *colName, LOCKMODE lockmode);
305 static void ATExecColumnDefault(Relation rel, const char *colName,
306                                         Node *newDefault, LOCKMODE lockmode);
307 static void ATPrepSetStatistics(Relation rel, const char *colName,
308                                         Node *newValue, LOCKMODE lockmode);
309 static void ATExecSetStatistics(Relation rel, const char *colName,
310                                         Node *newValue, LOCKMODE lockmode);
311 static void ATExecSetOptions(Relation rel, const char *colName,
312                                  Node *options, bool isReset, LOCKMODE lockmode);
313 static void ATExecSetStorage(Relation rel, const char *colName,
314                                  Node *newValue, LOCKMODE lockmode);
315 static void ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
316                                  AlterTableCmd *cmd, LOCKMODE lockmode);
317 static void ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
318                                  DropBehavior behavior,
319                                  bool recurse, bool recursing,
320                                  bool missing_ok, LOCKMODE lockmode);
321 static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
322                            IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode);
323 static void ATExecAddConstraint(List **wqueue,
324                                         AlteredTableInfo *tab, Relation rel,
325                                  Constraint *newConstraint, bool recurse, LOCKMODE lockmode);
326 static void ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
327                                                  IndexStmt *stmt, LOCKMODE lockmode);
328 static void ATAddCheckConstraint(List **wqueue,
329                                          AlteredTableInfo *tab, Relation rel,
330                                          Constraint *constr,
331                                          bool recurse, bool recursing, LOCKMODE lockmode);
332 static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
333                                                   Constraint *fkconstraint, LOCKMODE lockmode);
334 static void ATExecDropConstraint(Relation rel, const char *constrName,
335                                          DropBehavior behavior,
336                                          bool recurse, bool recursing,
337                                          bool missing_ok, LOCKMODE lockmode);
338 static void ATPrepAlterColumnType(List **wqueue,
339                                           AlteredTableInfo *tab, Relation rel,
340                                           bool recurse, bool recursing,
341                                           AlterTableCmd *cmd, LOCKMODE lockmode);
342 static bool ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno);
343 static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
344                                           AlterTableCmd *cmd, LOCKMODE lockmode);
345 static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode);
346 static void ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode);
347 static void change_owner_recurse_to_sequences(Oid relationOid,
348                                                                   Oid newOwnerId, LOCKMODE lockmode);
349 static void ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode);
350 static void ATExecDropCluster(Relation rel, LOCKMODE lockmode);
351 static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
352                                         char *tablespacename, LOCKMODE lockmode);
353 static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode);
354 static void ATExecSetRelOptions(Relation rel, List *defList, bool isReset, LOCKMODE lockmode);
355 static void ATExecEnableDisableTrigger(Relation rel, char *trigname,
356                                            char fires_when, bool skip_system, LOCKMODE lockmode);
357 static void ATExecEnableDisableRule(Relation rel, char *rulename,
358                                                 char fires_when, LOCKMODE lockmode);
359 static void ATPrepAddInherit(Relation child_rel);
360 static void ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode);
361 static void ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode);
362 static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid);
363 static void ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode);
364 static void ATExecDropOf(Relation rel, LOCKMODE lockmode);
365 static void ATExecGenericOptions(Relation rel, List *options);
366
367 static void copy_relation_data(SMgrRelation rel, SMgrRelation dst,
368                                    ForkNumber forkNum, char relpersistence);
369 static const char *storage_name(char c);
370
371
372 /* ----------------------------------------------------------------
373  *              DefineRelation
374  *                              Creates a new relation.
375  *
376  * stmt carries parsetree information from an ordinary CREATE TABLE statement.
377  * The other arguments are used to extend the behavior for other cases:
378  * relkind: relkind to assign to the new relation
379  * ownerId: if not InvalidOid, use this as the new relation's owner.
380  *
381  * Note that permissions checks are done against current user regardless of
382  * ownerId.  A nonzero ownerId is used when someone is creating a relation
383  * "on behalf of" someone else, so we still want to see that the current user
384  * has permissions to do it.
385  *
386  * If successful, returns the OID of the new relation.
387  * ----------------------------------------------------------------
388  */
389 Oid
390 DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
391 {
392         char            relname[NAMEDATALEN];
393         Oid                     namespaceId;
394         List       *schema = stmt->tableElts;
395         Oid                     relationId;
396         Oid                     tablespaceId;
397         Relation        rel;
398         TupleDesc       descriptor;
399         List       *inheritOids;
400         List       *old_constraints;
401         bool            localHasOids;
402         int                     parentOidCount;
403         List       *rawDefaults;
404         List       *cookedDefaults;
405         Datum           reloptions;
406         ListCell   *listptr;
407         AttrNumber      attnum;
408         static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
409         Oid                     ofTypeId;
410
411         /*
412          * Truncate relname to appropriate length (probably a waste of time, as
413          * parser should have done this already).
414          */
415         StrNCpy(relname, stmt->relation->relname, NAMEDATALEN);
416
417         /*
418          * Check consistency of arguments
419          */
420         if (stmt->oncommit != ONCOMMIT_NOOP
421                 && stmt->relation->relpersistence != RELPERSISTENCE_TEMP)
422                 ereport(ERROR,
423                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
424                                  errmsg("ON COMMIT can only be used on temporary tables")));
425         if (stmt->constraints != NIL && relkind == RELKIND_FOREIGN_TABLE)
426                 ereport(ERROR,
427                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
428                                  errmsg("constraints on foreign tables are not supported")));
429
430         /*
431          * Security check: disallow creating temp tables from security-restricted
432          * code.  This is needed because calling code might not expect untrusted
433          * tables to appear in pg_temp at the front of its search path.
434          */
435         if (stmt->relation->relpersistence == RELPERSISTENCE_TEMP
436                 && InSecurityRestrictedOperation())
437                 ereport(ERROR,
438                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
439                                  errmsg("cannot create temporary table within security-restricted operation")));
440
441         /*
442          * Look up the namespace in which we are supposed to create the relation,
443          * and check we have permission to create there.
444          */
445         namespaceId = RangeVarGetAndCheckCreationNamespace(stmt->relation);
446
447         /*
448          * Select tablespace to use.  If not specified, use default tablespace
449          * (which may in turn default to database's default).
450          */
451         if (stmt->tablespacename)
452         {
453                 tablespaceId = get_tablespace_oid(stmt->tablespacename, false);
454         }
455         else
456         {
457                 tablespaceId = GetDefaultTablespace(stmt->relation->relpersistence);
458                 /* note InvalidOid is OK in this case */
459         }
460
461         /* Check permissions except when using database's default */
462         if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace)
463         {
464                 AclResult       aclresult;
465
466                 aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
467                                                                                    ACL_CREATE);
468                 if (aclresult != ACLCHECK_OK)
469                         aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
470                                                    get_tablespace_name(tablespaceId));
471         }
472
473         /* In all cases disallow placing user relations in pg_global */
474         if (tablespaceId == GLOBALTABLESPACE_OID)
475                 ereport(ERROR,
476                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
477                                  errmsg("only shared relations can be placed in pg_global tablespace")));
478
479         /* Identify user ID that will own the table */
480         if (!OidIsValid(ownerId))
481                 ownerId = GetUserId();
482
483         /*
484          * Parse and validate reloptions, if any.
485          */
486         reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps,
487                                                                          true, false);
488
489         (void) heap_reloptions(relkind, reloptions, true);
490
491         if (stmt->ofTypename)
492                 ofTypeId = typenameTypeId(NULL, stmt->ofTypename);
493         else
494                 ofTypeId = InvalidOid;
495
496         /*
497          * Look up inheritance ancestors and generate relation schema, including
498          * inherited attributes.
499          */
500         schema = MergeAttributes(schema, stmt->inhRelations,
501                                                          stmt->relation->relpersistence,
502                                                          &inheritOids, &old_constraints, &parentOidCount);
503
504         /*
505          * Create a tuple descriptor from the relation schema.  Note that this
506          * deals with column names, types, and NOT NULL constraints, but not
507          * default values or CHECK constraints; we handle those below.
508          */
509         descriptor = BuildDescForRelation(schema);
510
511         localHasOids = interpretOidsOption(stmt->options);
512         descriptor->tdhasoid = (localHasOids || parentOidCount > 0);
513
514         /*
515          * Find columns with default values and prepare for insertion of the
516          * defaults.  Pre-cooked (that is, inherited) defaults go into a list of
517          * CookedConstraint structs that we'll pass to heap_create_with_catalog,
518          * while raw defaults go into a list of RawColumnDefault structs that will
519          * be processed by AddRelationNewConstraints.  (We can't deal with raw
520          * expressions until we can do transformExpr.)
521          *
522          * We can set the atthasdef flags now in the tuple descriptor; this just
523          * saves StoreAttrDefault from having to do an immediate update of the
524          * pg_attribute rows.
525          */
526         rawDefaults = NIL;
527         cookedDefaults = NIL;
528         attnum = 0;
529
530         foreach(listptr, schema)
531         {
532                 ColumnDef  *colDef = lfirst(listptr);
533
534                 attnum++;
535
536                 if (colDef->raw_default != NULL)
537                 {
538                         RawColumnDefault *rawEnt;
539
540                         if (relkind == RELKIND_FOREIGN_TABLE)
541                                 ereport(ERROR,
542                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
543                                                  errmsg("default values on foreign tables are not supported")));
544
545                         Assert(colDef->cooked_default == NULL);
546
547                         rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
548                         rawEnt->attnum = attnum;
549                         rawEnt->raw_default = colDef->raw_default;
550                         rawDefaults = lappend(rawDefaults, rawEnt);
551                         descriptor->attrs[attnum - 1]->atthasdef = true;
552                 }
553                 else if (colDef->cooked_default != NULL)
554                 {
555                         CookedConstraint *cooked;
556
557                         cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
558                         cooked->contype = CONSTR_DEFAULT;
559                         cooked->name = NULL;
560                         cooked->attnum = attnum;
561                         cooked->expr = colDef->cooked_default;
562                         cooked->is_local = true;        /* not used for defaults */
563                         cooked->inhcount = 0;           /* ditto */
564                         cookedDefaults = lappend(cookedDefaults, cooked);
565                         descriptor->attrs[attnum - 1]->atthasdef = true;
566                 }
567         }
568
569         /*
570          * Create the relation.  Inherited defaults and constraints are passed in
571          * for immediate handling --- since they don't need parsing, they can be
572          * stored immediately.
573          */
574         relationId = heap_create_with_catalog(relname,
575                                                                                   namespaceId,
576                                                                                   tablespaceId,
577                                                                                   InvalidOid,
578                                                                                   InvalidOid,
579                                                                                   ofTypeId,
580                                                                                   ownerId,
581                                                                                   descriptor,
582                                                                                   list_concat(cookedDefaults,
583                                                                                                           old_constraints),
584                                                                                   relkind,
585                                                                                   stmt->relation->relpersistence,
586                                                                                   false,
587                                                                                   false,
588                                                                                   localHasOids,
589                                                                                   parentOidCount,
590                                                                                   stmt->oncommit,
591                                                                                   reloptions,
592                                                                                   true,
593                                                                                   allowSystemTableMods);
594
595         /* Store inheritance information for new rel. */
596         StoreCatalogInheritance(relationId, inheritOids);
597
598         /*
599          * We must bump the command counter to make the newly-created relation
600          * tuple visible for opening.
601          */
602         CommandCounterIncrement();
603
604         /*
605          * Open the new relation and acquire exclusive lock on it.      This isn't
606          * really necessary for locking out other backends (since they can't see
607          * the new rel anyway until we commit), but it keeps the lock manager from
608          * complaining about deadlock risks.
609          */
610         rel = relation_open(relationId, AccessExclusiveLock);
611
612         /*
613          * Now add any newly specified column default values and CHECK constraints
614          * to the new relation.  These are passed to us in the form of raw
615          * parsetrees; we need to transform them to executable expression trees
616          * before they can be added. The most convenient way to do that is to
617          * apply the parser's transformExpr routine, but transformExpr doesn't
618          * work unless we have a pre-existing relation. So, the transformation has
619          * to be postponed to this final step of CREATE TABLE.
620          */
621         if (rawDefaults || stmt->constraints)
622                 AddRelationNewConstraints(rel, rawDefaults, stmt->constraints,
623                                                                   true, true);
624
625         /*
626          * Clean up.  We keep lock on new relation (although it shouldn't be
627          * visible to anyone else anyway, until commit).
628          */
629         relation_close(rel, NoLock);
630
631         return relationId;
632 }
633
634 /*
635  * Emit the right error or warning message for a "DROP" command issued on a
636  * non-existent relation
637  */
638 static void
639 DropErrorMsgNonExistent(const char *relname, char rightkind, bool missing_ok)
640 {
641         const struct dropmsgstrings *rentry;
642
643         for (rentry = dropmsgstringarray; rentry->kind != '\0'; rentry++)
644         {
645                 if (rentry->kind == rightkind)
646                 {
647                         if (!missing_ok)
648                         {
649                                 ereport(ERROR,
650                                                 (errcode(rentry->nonexistent_code),
651                                                  errmsg(rentry->nonexistent_msg, relname)));
652                         }
653                         else
654                         {
655                                 ereport(NOTICE, (errmsg(rentry->skipping_msg, relname)));
656                                 break;
657                         }
658                 }
659         }
660
661         Assert(rentry->kind != '\0');           /* Should be impossible */
662 }
663
664 /*
665  * Emit the right error message for a "DROP" command issued on a
666  * relation of the wrong type
667  */
668 static void
669 DropErrorMsgWrongType(const char *relname, char wrongkind, char rightkind)
670 {
671         const struct dropmsgstrings *rentry;
672         const struct dropmsgstrings *wentry;
673
674         for (rentry = dropmsgstringarray; rentry->kind != '\0'; rentry++)
675                 if (rentry->kind == rightkind)
676                         break;
677         Assert(rentry->kind != '\0');
678
679         for (wentry = dropmsgstringarray; wentry->kind != '\0'; wentry++)
680                 if (wentry->kind == wrongkind)
681                         break;
682         /* wrongkind could be something we don't have in our table... */
683
684         ereport(ERROR,
685                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
686                          errmsg(rentry->nota_msg, relname),
687            (wentry->kind != '\0') ? errhint("%s", _(wentry->drophint_msg)) : 0));
688 }
689
690 /*
691  * RemoveRelations
692  *              Implements DROP TABLE, DROP INDEX, DROP SEQUENCE, DROP VIEW,
693  *              DROP FOREIGN TABLE
694  */
695 void
696 RemoveRelations(DropStmt *drop)
697 {
698         ObjectAddresses *objects;
699         char            relkind;
700         ListCell   *cell;
701
702         /*
703          * First we identify all the relations, then we delete them in a single
704          * performMultipleDeletions() call.  This is to avoid unwanted DROP
705          * RESTRICT errors if one of the relations depends on another.
706          */
707
708         /* Determine required relkind */
709         switch (drop->removeType)
710         {
711                 case OBJECT_TABLE:
712                         relkind = RELKIND_RELATION;
713                         break;
714
715                 case OBJECT_INDEX:
716                         relkind = RELKIND_INDEX;
717                         break;
718
719                 case OBJECT_SEQUENCE:
720                         relkind = RELKIND_SEQUENCE;
721                         break;
722
723                 case OBJECT_VIEW:
724                         relkind = RELKIND_VIEW;
725                         break;
726
727                 case OBJECT_FOREIGN_TABLE:
728                         relkind = RELKIND_FOREIGN_TABLE;
729                         break;
730
731                 default:
732                         elog(ERROR, "unrecognized drop object type: %d",
733                                  (int) drop->removeType);
734                         relkind = 0;            /* keep compiler quiet */
735                         break;
736         }
737
738         /* Lock and validate each relation; build a list of object addresses */
739         objects = new_object_addresses();
740
741         foreach(cell, drop->objects)
742         {
743                 RangeVar   *rel = makeRangeVarFromNameList((List *) lfirst(cell));
744                 Oid                     relOid;
745                 HeapTuple       tuple;
746                 Form_pg_class classform;
747                 ObjectAddress obj;
748
749                 /*
750                  * These next few steps are a great deal like relation_openrv, but we
751                  * don't bother building a relcache entry since we don't need it.
752                  *
753                  * Check for shared-cache-inval messages before trying to access the
754                  * relation.  This is needed to cover the case where the name
755                  * identifies a rel that has been dropped and recreated since the
756                  * start of our transaction: if we don't flush the old syscache entry,
757                  * then we'll latch onto that entry and suffer an error later.
758                  */
759                 AcceptInvalidationMessages();
760
761                 /* Look up the appropriate relation using namespace search */
762                 relOid = RangeVarGetRelid(rel, true);
763
764                 /* Not there? */
765                 if (!OidIsValid(relOid))
766                 {
767                         DropErrorMsgNonExistent(rel->relname, relkind, drop->missing_ok);
768                         continue;
769                 }
770
771                 /*
772                  * In DROP INDEX, attempt to acquire lock on the parent table before
773                  * locking the index.  index_drop() will need this anyway, and since
774                  * regular queries lock tables before their indexes, we risk deadlock
775                  * if we do it the other way around.  No error if we don't find a
776                  * pg_index entry, though --- that most likely means it isn't an
777                  * index, and we'll fail below.
778                  */
779                 if (relkind == RELKIND_INDEX)
780                 {
781                         tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(relOid));
782                         if (HeapTupleIsValid(tuple))
783                         {
784                                 Form_pg_index index = (Form_pg_index) GETSTRUCT(tuple);
785
786                                 LockRelationOid(index->indrelid, AccessExclusiveLock);
787                                 ReleaseSysCache(tuple);
788                         }
789                 }
790
791                 /* Get the lock before trying to fetch the syscache entry */
792                 LockRelationOid(relOid, AccessExclusiveLock);
793
794                 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
795                 if (!HeapTupleIsValid(tuple))
796                         elog(ERROR, "cache lookup failed for relation %u", relOid);
797                 classform = (Form_pg_class) GETSTRUCT(tuple);
798
799                 if (classform->relkind != relkind)
800                         DropErrorMsgWrongType(rel->relname, classform->relkind, relkind);
801
802                 /* Allow DROP to either table owner or schema owner */
803                 if (!pg_class_ownercheck(relOid, GetUserId()) &&
804                         !pg_namespace_ownercheck(classform->relnamespace, GetUserId()))
805                         aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
806                                                    rel->relname);
807
808                 if (!allowSystemTableMods && IsSystemClass(classform))
809                         ereport(ERROR,
810                                         (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
811                                          errmsg("permission denied: \"%s\" is a system catalog",
812                                                         rel->relname)));
813
814                 /* OK, we're ready to delete this one */
815                 obj.classId = RelationRelationId;
816                 obj.objectId = relOid;
817                 obj.objectSubId = 0;
818
819                 add_exact_object_address(&obj, objects);
820
821                 ReleaseSysCache(tuple);
822         }
823
824         performMultipleDeletions(objects, drop->behavior);
825
826         free_object_addresses(objects);
827 }
828
829 /*
830  * ExecuteTruncate
831  *              Executes a TRUNCATE command.
832  *
833  * This is a multi-relation truncate.  We first open and grab exclusive
834  * lock on all relations involved, checking permissions and otherwise
835  * verifying that the relation is OK for truncation.  In CASCADE mode,
836  * relations having FK references to the targeted relations are automatically
837  * added to the group; in RESTRICT mode, we check that all FK references are
838  * internal to the group that's being truncated.  Finally all the relations
839  * are truncated and reindexed.
840  */
841 void
842 ExecuteTruncate(TruncateStmt *stmt)
843 {
844         List       *rels = NIL;
845         List       *relids = NIL;
846         List       *seq_relids = NIL;
847         EState     *estate;
848         ResultRelInfo *resultRelInfos;
849         ResultRelInfo *resultRelInfo;
850         SubTransactionId mySubid;
851         ListCell   *cell;
852
853         /*
854          * Open, exclusive-lock, and check all the explicitly-specified relations
855          */
856         foreach(cell, stmt->relations)
857         {
858                 RangeVar   *rv = lfirst(cell);
859                 Relation        rel;
860                 bool            recurse = interpretInhOption(rv->inhOpt);
861                 Oid                     myrelid;
862
863                 rel = heap_openrv(rv, AccessExclusiveLock);
864                 myrelid = RelationGetRelid(rel);
865                 /* don't throw error for "TRUNCATE foo, foo" */
866                 if (list_member_oid(relids, myrelid))
867                 {
868                         heap_close(rel, AccessExclusiveLock);
869                         continue;
870                 }
871                 truncate_check_rel(rel);
872                 rels = lappend(rels, rel);
873                 relids = lappend_oid(relids, myrelid);
874
875                 if (recurse)
876                 {
877                         ListCell   *child;
878                         List       *children;
879
880                         children = find_all_inheritors(myrelid, AccessExclusiveLock, NULL);
881
882                         foreach(child, children)
883                         {
884                                 Oid                     childrelid = lfirst_oid(child);
885
886                                 if (list_member_oid(relids, childrelid))
887                                         continue;
888
889                                 /* find_all_inheritors already got lock */
890                                 rel = heap_open(childrelid, NoLock);
891                                 truncate_check_rel(rel);
892                                 rels = lappend(rels, rel);
893                                 relids = lappend_oid(relids, childrelid);
894                         }
895                 }
896         }
897
898         /*
899          * In CASCADE mode, suck in all referencing relations as well.  This
900          * requires multiple iterations to find indirectly-dependent relations. At
901          * each phase, we need to exclusive-lock new rels before looking for their
902          * dependencies, else we might miss something.  Also, we check each rel as
903          * soon as we open it, to avoid a faux pas such as holding lock for a long
904          * time on a rel we have no permissions for.
905          */
906         if (stmt->behavior == DROP_CASCADE)
907         {
908                 for (;;)
909                 {
910                         List       *newrelids;
911
912                         newrelids = heap_truncate_find_FKs(relids);
913                         if (newrelids == NIL)
914                                 break;                  /* nothing else to add */
915
916                         foreach(cell, newrelids)
917                         {
918                                 Oid                     relid = lfirst_oid(cell);
919                                 Relation        rel;
920
921                                 rel = heap_open(relid, AccessExclusiveLock);
922                                 ereport(NOTICE,
923                                                 (errmsg("truncate cascades to table \"%s\"",
924                                                                 RelationGetRelationName(rel))));
925                                 truncate_check_rel(rel);
926                                 rels = lappend(rels, rel);
927                                 relids = lappend_oid(relids, relid);
928                         }
929                 }
930         }
931
932         /*
933          * Check foreign key references.  In CASCADE mode, this should be
934          * unnecessary since we just pulled in all the references; but as a
935          * cross-check, do it anyway if in an Assert-enabled build.
936          */
937 #ifdef USE_ASSERT_CHECKING
938         heap_truncate_check_FKs(rels, false);
939 #else
940         if (stmt->behavior == DROP_RESTRICT)
941                 heap_truncate_check_FKs(rels, false);
942 #endif
943
944         /*
945          * If we are asked to restart sequences, find all the sequences, lock them
946          * (we need AccessExclusiveLock for ResetSequence), and check permissions.
947          * We want to do this early since it's pointless to do all the truncation
948          * work only to fail on sequence permissions.
949          */
950         if (stmt->restart_seqs)
951         {
952                 foreach(cell, rels)
953                 {
954                         Relation        rel = (Relation) lfirst(cell);
955                         List       *seqlist = getOwnedSequences(RelationGetRelid(rel));
956                         ListCell   *seqcell;
957
958                         foreach(seqcell, seqlist)
959                         {
960                                 Oid                     seq_relid = lfirst_oid(seqcell);
961                                 Relation        seq_rel;
962
963                                 seq_rel = relation_open(seq_relid, AccessExclusiveLock);
964
965                                 /* This check must match AlterSequence! */
966                                 if (!pg_class_ownercheck(seq_relid, GetUserId()))
967                                         aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
968                                                                    RelationGetRelationName(seq_rel));
969
970                                 seq_relids = lappend_oid(seq_relids, seq_relid);
971
972                                 relation_close(seq_rel, NoLock);
973                         }
974                 }
975         }
976
977         /* Prepare to catch AFTER triggers. */
978         AfterTriggerBeginQuery();
979
980         /*
981          * To fire triggers, we'll need an EState as well as a ResultRelInfo for
982          * each relation.  We don't need to call ExecOpenIndices, though.
983          */
984         estate = CreateExecutorState();
985         resultRelInfos = (ResultRelInfo *)
986                 palloc(list_length(rels) * sizeof(ResultRelInfo));
987         resultRelInfo = resultRelInfos;
988         foreach(cell, rels)
989         {
990                 Relation        rel = (Relation) lfirst(cell);
991
992                 InitResultRelInfo(resultRelInfo,
993                                                   rel,
994                                                   0,    /* dummy rangetable index */
995                                                   0);
996                 resultRelInfo++;
997         }
998         estate->es_result_relations = resultRelInfos;
999         estate->es_num_result_relations = list_length(rels);
1000
1001         /*
1002          * Process all BEFORE STATEMENT TRUNCATE triggers before we begin
1003          * truncating (this is because one of them might throw an error). Also, if
1004          * we were to allow them to prevent statement execution, that would need
1005          * to be handled here.
1006          */
1007         resultRelInfo = resultRelInfos;
1008         foreach(cell, rels)
1009         {
1010                 estate->es_result_relation_info = resultRelInfo;
1011                 ExecBSTruncateTriggers(estate, resultRelInfo);
1012                 resultRelInfo++;
1013         }
1014
1015         /*
1016          * OK, truncate each table.
1017          */
1018         mySubid = GetCurrentSubTransactionId();
1019
1020         foreach(cell, rels)
1021         {
1022                 Relation        rel = (Relation) lfirst(cell);
1023
1024                 /*
1025                  * Normally, we need a transaction-safe truncation here.  However, if
1026                  * the table was either created in the current (sub)transaction or has
1027                  * a new relfilenode in the current (sub)transaction, then we can just
1028                  * truncate it in-place, because a rollback would cause the whole
1029                  * table or the current physical file to be thrown away anyway.
1030                  */
1031                 if (rel->rd_createSubid == mySubid ||
1032                         rel->rd_newRelfilenodeSubid == mySubid)
1033                 {
1034                         /* Immediate, non-rollbackable truncation is OK */
1035                         heap_truncate_one_rel(rel);
1036                 }
1037                 else
1038                 {
1039                         Oid                     heap_relid;
1040                         Oid                     toast_relid;
1041
1042                         /*
1043                          * Need the full transaction-safe pushups.
1044                          *
1045                          * Create a new empty storage file for the relation, and assign it
1046                          * as the relfilenode value. The old storage file is scheduled for
1047                          * deletion at commit.
1048                          */
1049                         RelationSetNewRelfilenode(rel, RecentXmin);
1050
1051                         heap_relid = RelationGetRelid(rel);
1052                         toast_relid = rel->rd_rel->reltoastrelid;
1053
1054                         /*
1055                          * The same for the toast table, if any.
1056                          */
1057                         if (OidIsValid(toast_relid))
1058                         {
1059                                 rel = relation_open(toast_relid, AccessExclusiveLock);
1060                                 RelationSetNewRelfilenode(rel, RecentXmin);
1061                                 heap_close(rel, NoLock);
1062                         }
1063
1064                         /*
1065                          * Reconstruct the indexes to match, and we're done.
1066                          */
1067                         reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST);
1068                 }
1069         }
1070
1071         /*
1072          * Restart owned sequences if we were asked to.
1073          */
1074         foreach(cell, seq_relids)
1075         {
1076                 Oid                     seq_relid = lfirst_oid(cell);
1077
1078                 ResetSequence(seq_relid);
1079         }
1080
1081         /*
1082          * Process all AFTER STATEMENT TRUNCATE triggers.
1083          */
1084         resultRelInfo = resultRelInfos;
1085         foreach(cell, rels)
1086         {
1087                 estate->es_result_relation_info = resultRelInfo;
1088                 ExecASTruncateTriggers(estate, resultRelInfo);
1089                 resultRelInfo++;
1090         }
1091
1092         /* Handle queued AFTER triggers */
1093         AfterTriggerEndQuery(estate);
1094
1095         /* We can clean up the EState now */
1096         FreeExecutorState(estate);
1097
1098         /* And close the rels (can't do this while EState still holds refs) */
1099         foreach(cell, rels)
1100         {
1101                 Relation        rel = (Relation) lfirst(cell);
1102
1103                 heap_close(rel, NoLock);
1104         }
1105 }
1106
1107 /*
1108  * Check that a given rel is safe to truncate.  Subroutine for ExecuteTruncate
1109  */
1110 static void
1111 truncate_check_rel(Relation rel)
1112 {
1113         AclResult       aclresult;
1114
1115         /* Only allow truncate on regular tables */
1116         if (rel->rd_rel->relkind != RELKIND_RELATION)
1117                 ereport(ERROR,
1118                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1119                                  errmsg("\"%s\" is not a table",
1120                                                 RelationGetRelationName(rel))));
1121
1122         /* Permissions checks */
1123         aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
1124                                                                   ACL_TRUNCATE);
1125         if (aclresult != ACLCHECK_OK)
1126                 aclcheck_error(aclresult, ACL_KIND_CLASS,
1127                                            RelationGetRelationName(rel));
1128
1129         if (!allowSystemTableMods && IsSystemRelation(rel))
1130                 ereport(ERROR,
1131                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1132                                  errmsg("permission denied: \"%s\" is a system catalog",
1133                                                 RelationGetRelationName(rel))));
1134
1135         /*
1136          * Don't allow truncate on temp tables of other backends ... their local
1137          * buffer manager is not going to cope.
1138          */
1139         if (RELATION_IS_OTHER_TEMP(rel))
1140                 ereport(ERROR,
1141                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1142                           errmsg("cannot truncate temporary tables of other sessions")));
1143
1144         /*
1145          * Also check for active uses of the relation in the current transaction,
1146          * including open scans and pending AFTER trigger events.
1147          */
1148         CheckTableNotInUse(rel, "TRUNCATE");
1149 }
1150
1151 /*
1152  * storage_name
1153  *        returns the name corresponding to a typstorage/attstorage enum value
1154  */
1155 static const char *
1156 storage_name(char c)
1157 {
1158         switch (c)
1159         {
1160                 case 'p':
1161                         return "PLAIN";
1162                 case 'm':
1163                         return "MAIN";
1164                 case 'x':
1165                         return "EXTENDED";
1166                 case 'e':
1167                         return "EXTERNAL";
1168                 default:
1169                         return "???";
1170         }
1171 }
1172
1173 /*----------
1174  * MergeAttributes
1175  *              Returns new schema given initial schema and superclasses.
1176  *
1177  * Input arguments:
1178  * 'schema' is the column/attribute definition for the table. (It's a list
1179  *              of ColumnDef's.) It is destructively changed.
1180  * 'supers' is a list of names (as RangeVar nodes) of parent relations.
1181  * 'relpersistence' is a persistence type of the table.
1182  *
1183  * Output arguments:
1184  * 'supOids' receives a list of the OIDs of the parent relations.
1185  * 'supconstr' receives a list of constraints belonging to the parents,
1186  *              updated as necessary to be valid for the child.
1187  * 'supOidCount' is set to the number of parents that have OID columns.
1188  *
1189  * Return value:
1190  * Completed schema list.
1191  *
1192  * Notes:
1193  *        The order in which the attributes are inherited is very important.
1194  *        Intuitively, the inherited attributes should come first. If a table
1195  *        inherits from multiple parents, the order of those attributes are
1196  *        according to the order of the parents specified in CREATE TABLE.
1197  *
1198  *        Here's an example:
1199  *
1200  *              create table person (name text, age int4, location point);
1201  *              create table emp (salary int4, manager text) inherits(person);
1202  *              create table student (gpa float8) inherits (person);
1203  *              create table stud_emp (percent int4) inherits (emp, student);
1204  *
1205  *        The order of the attributes of stud_emp is:
1206  *
1207  *                                                      person {1:name, 2:age, 3:location}
1208  *                                                      /        \
1209  *                         {6:gpa}      student   emp {4:salary, 5:manager}
1210  *                                                      \        /
1211  *                                                 stud_emp {7:percent}
1212  *
1213  *         If the same attribute name appears multiple times, then it appears
1214  *         in the result table in the proper location for its first appearance.
1215  *
1216  *         Constraints (including NOT NULL constraints) for the child table
1217  *         are the union of all relevant constraints, from both the child schema
1218  *         and parent tables.
1219  *
1220  *         The default value for a child column is defined as:
1221  *              (1) If the child schema specifies a default, that value is used.
1222  *              (2) If neither the child nor any parent specifies a default, then
1223  *                      the column will not have a default.
1224  *              (3) If conflicting defaults are inherited from different parents
1225  *                      (and not overridden by the child), an error is raised.
1226  *              (4) Otherwise the inherited default is used.
1227  *              Rule (3) is new in Postgres 7.1; in earlier releases you got a
1228  *              rather arbitrary choice of which parent default to use.
1229  *----------
1230  */
1231 static List *
1232 MergeAttributes(List *schema, List *supers, char relpersistence,
1233                                 List **supOids, List **supconstr, int *supOidCount)
1234 {
1235         ListCell   *entry;
1236         List       *inhSchema = NIL;
1237         List       *parentOids = NIL;
1238         List       *constraints = NIL;
1239         int                     parentsWithOids = 0;
1240         bool            have_bogus_defaults = false;
1241         int                     child_attno;
1242         static Node bogus_marker = {0};         /* marks conflicting defaults */
1243
1244         /*
1245          * Check for and reject tables with too many columns. We perform this
1246          * check relatively early for two reasons: (a) we don't run the risk of
1247          * overflowing an AttrNumber in subsequent code (b) an O(n^2) algorithm is
1248          * okay if we're processing <= 1600 columns, but could take minutes to
1249          * execute if the user attempts to create a table with hundreds of
1250          * thousands of columns.
1251          *
1252          * Note that we also need to check that any we do not exceed this figure
1253          * after including columns from inherited relations.
1254          */
1255         if (list_length(schema) > MaxHeapAttributeNumber)
1256                 ereport(ERROR,
1257                                 (errcode(ERRCODE_TOO_MANY_COLUMNS),
1258                                  errmsg("tables can have at most %d columns",
1259                                                 MaxHeapAttributeNumber)));
1260
1261         /*
1262          * Check for duplicate names in the explicit list of attributes.
1263          *
1264          * Although we might consider merging such entries in the same way that we
1265          * handle name conflicts for inherited attributes, it seems to make more
1266          * sense to assume such conflicts are errors.
1267          */
1268         foreach(entry, schema)
1269         {
1270                 ColumnDef  *coldef = lfirst(entry);
1271                 ListCell   *rest = lnext(entry);
1272                 ListCell   *prev = entry;
1273
1274                 if (coldef->typeName == NULL)
1275
1276                         /*
1277                          * Typed table column option that does not belong to a column from
1278                          * the type.  This works because the columns from the type come
1279                          * first in the list.
1280                          */
1281                         ereport(ERROR,
1282                                         (errcode(ERRCODE_UNDEFINED_COLUMN),
1283                                          errmsg("column \"%s\" does not exist",
1284                                                         coldef->colname)));
1285
1286                 while (rest != NULL)
1287                 {
1288                         ColumnDef  *restdef = lfirst(rest);
1289                         ListCell   *next = lnext(rest);         /* need to save it in case we
1290                                                                                                  * delete it */
1291
1292                         if (strcmp(coldef->colname, restdef->colname) == 0)
1293                         {
1294                                 if (coldef->is_from_type)
1295                                 {
1296                                         /*
1297                                          * merge the column options into the column from the type
1298                                          */
1299                                         coldef->is_not_null = restdef->is_not_null;
1300                                         coldef->raw_default = restdef->raw_default;
1301                                         coldef->cooked_default = restdef->cooked_default;
1302                                         coldef->constraints = restdef->constraints;
1303                                         coldef->is_from_type = false;
1304                                         list_delete_cell(schema, rest, prev);
1305                                 }
1306                                 else
1307                                         ereport(ERROR,
1308                                                         (errcode(ERRCODE_DUPLICATE_COLUMN),
1309                                                          errmsg("column \"%s\" specified more than once",
1310                                                                         coldef->colname)));
1311                         }
1312                         prev = rest;
1313                         rest = next;
1314                 }
1315         }
1316
1317         /*
1318          * Scan the parents left-to-right, and merge their attributes to form a
1319          * list of inherited attributes (inhSchema).  Also check to see if we need
1320          * to inherit an OID column.
1321          */
1322         child_attno = 0;
1323         foreach(entry, supers)
1324         {
1325                 RangeVar   *parent = (RangeVar *) lfirst(entry);
1326                 Relation        relation;
1327                 TupleDesc       tupleDesc;
1328                 TupleConstr *constr;
1329                 AttrNumber *newattno;
1330                 AttrNumber      parent_attno;
1331
1332                 /*
1333                  * A self-exclusive lock is needed here.  If two backends attempt to
1334                  * add children to the same parent simultaneously, and that parent has
1335                  * no pre-existing children, then both will attempt to update the
1336                  * parent's relhassubclass field, leading to a "tuple concurrently
1337                  * updated" error.
1338                  */
1339                 relation = heap_openrv(parent, ShareUpdateExclusiveLock);
1340
1341                 if (relation->rd_rel->relkind != RELKIND_RELATION)
1342                         ereport(ERROR,
1343                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1344                                          errmsg("inherited relation \"%s\" is not a table",
1345                                                         parent->relname)));
1346                 /* Permanent rels cannot inherit from temporary ones */
1347                 if (relpersistence != RELPERSISTENCE_TEMP
1348                         && RelationUsesTempNamespace(relation))
1349                         ereport(ERROR,
1350                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1351                                          errmsg("cannot inherit from temporary relation \"%s\"",
1352                                                         parent->relname)));
1353
1354                 /*
1355                  * We should have an UNDER permission flag for this, but for now,
1356                  * demand that creator of a child table own the parent.
1357                  */
1358                 if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
1359                         aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
1360                                                    RelationGetRelationName(relation));
1361
1362                 /*
1363                  * Reject duplications in the list of parents.
1364                  */
1365                 if (list_member_oid(parentOids, RelationGetRelid(relation)))
1366                         ereport(ERROR,
1367                                         (errcode(ERRCODE_DUPLICATE_TABLE),
1368                          errmsg("relation \"%s\" would be inherited from more than once",
1369                                         parent->relname)));
1370
1371                 parentOids = lappend_oid(parentOids, RelationGetRelid(relation));
1372
1373                 if (relation->rd_rel->relhasoids)
1374                         parentsWithOids++;
1375
1376                 tupleDesc = RelationGetDescr(relation);
1377                 constr = tupleDesc->constr;
1378
1379                 /*
1380                  * newattno[] will contain the child-table attribute numbers for the
1381                  * attributes of this parent table.  (They are not the same for
1382                  * parents after the first one, nor if we have dropped columns.)
1383                  */
1384                 newattno = (AttrNumber *)
1385                         palloc(tupleDesc->natts * sizeof(AttrNumber));
1386
1387                 for (parent_attno = 1; parent_attno <= tupleDesc->natts;
1388                          parent_attno++)
1389                 {
1390                         Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
1391                         char       *attributeName = NameStr(attribute->attname);
1392                         int                     exist_attno;
1393                         ColumnDef  *def;
1394
1395                         /*
1396                          * Ignore dropped columns in the parent.
1397                          */
1398                         if (attribute->attisdropped)
1399                         {
1400                                 /*
1401                                  * change_varattnos_of_a_node asserts that this is greater
1402                                  * than zero, so if anything tries to use it, we should find
1403                                  * out.
1404                                  */
1405                                 newattno[parent_attno - 1] = 0;
1406                                 continue;
1407                         }
1408
1409                         /*
1410                          * Does it conflict with some previously inherited column?
1411                          */
1412                         exist_attno = findAttrByName(attributeName, inhSchema);
1413                         if (exist_attno > 0)
1414                         {
1415                                 Oid                     defTypeId;
1416                                 int32           deftypmod;
1417                                 Oid                     defCollId;
1418
1419                                 /*
1420                                  * Yes, try to merge the two column definitions. They must
1421                                  * have the same type, typmod, and collation.
1422                                  */
1423                                 ereport(NOTICE,
1424                                                 (errmsg("merging multiple inherited definitions of column \"%s\"",
1425                                                                 attributeName)));
1426                                 def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
1427                                 typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
1428                                 if (defTypeId != attribute->atttypid ||
1429                                         deftypmod != attribute->atttypmod)
1430                                         ereport(ERROR,
1431                                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
1432                                                 errmsg("inherited column \"%s\" has a type conflict",
1433                                                            attributeName),
1434                                                          errdetail("%s versus %s",
1435                                                                            TypeNameToString(def->typeName),
1436                                                                            format_type_be(attribute->atttypid))));
1437                                 defCollId = GetColumnDefCollation(NULL, def, defTypeId);
1438                                 if (defCollId != attribute->attcollation)
1439                                         ereport(ERROR,
1440                                                         (errcode(ERRCODE_COLLATION_MISMATCH),
1441                                         errmsg("inherited column \"%s\" has a collation conflict",
1442                                                    attributeName),
1443                                                          errdetail("\"%s\" versus \"%s\"",
1444                                                                            get_collation_name(defCollId),
1445                                                           get_collation_name(attribute->attcollation))));
1446
1447                                 /* Copy storage parameter */
1448                                 if (def->storage == 0)
1449                                         def->storage = attribute->attstorage;
1450                                 else if (def->storage != attribute->attstorage)
1451                                         ereport(ERROR,
1452                                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
1453                                                          errmsg("inherited column \"%s\" has a storage parameter conflict",
1454                                                                         attributeName),
1455                                                          errdetail("%s versus %s",
1456                                                                            storage_name(def->storage),
1457                                                                            storage_name(attribute->attstorage))));
1458
1459                                 def->inhcount++;
1460                                 /* Merge of NOT NULL constraints = OR 'em together */
1461                                 def->is_not_null |= attribute->attnotnull;
1462                                 /* Default and other constraints are handled below */
1463                                 newattno[parent_attno - 1] = exist_attno;
1464                         }
1465                         else
1466                         {
1467                                 /*
1468                                  * No, create a new inherited column
1469                                  */
1470                                 def = makeNode(ColumnDef);
1471                                 def->colname = pstrdup(attributeName);
1472                                 def->typeName = makeTypeNameFromOid(attribute->atttypid,
1473                                                                                                         attribute->atttypmod);
1474                                 def->inhcount = 1;
1475                                 def->is_local = false;
1476                                 def->is_not_null = attribute->attnotnull;
1477                                 def->is_from_type = false;
1478                                 def->storage = attribute->attstorage;
1479                                 def->raw_default = NULL;
1480                                 def->cooked_default = NULL;
1481                                 def->collClause = NULL;
1482                                 def->collOid = attribute->attcollation;
1483                                 def->constraints = NIL;
1484                                 inhSchema = lappend(inhSchema, def);
1485                                 newattno[parent_attno - 1] = ++child_attno;
1486                         }
1487
1488                         /*
1489                          * Copy default if any
1490                          */
1491                         if (attribute->atthasdef)
1492                         {
1493                                 Node       *this_default = NULL;
1494                                 AttrDefault *attrdef;
1495                                 int                     i;
1496
1497                                 /* Find default in constraint structure */
1498                                 Assert(constr != NULL);
1499                                 attrdef = constr->defval;
1500                                 for (i = 0; i < constr->num_defval; i++)
1501                                 {
1502                                         if (attrdef[i].adnum == parent_attno)
1503                                         {
1504                                                 this_default = stringToNode(attrdef[i].adbin);
1505                                                 break;
1506                                         }
1507                                 }
1508                                 Assert(this_default != NULL);
1509
1510                                 /*
1511                                  * If default expr could contain any vars, we'd need to fix
1512                                  * 'em, but it can't; so default is ready to apply to child.
1513                                  *
1514                                  * If we already had a default from some prior parent, check
1515                                  * to see if they are the same.  If so, no problem; if not,
1516                                  * mark the column as having a bogus default. Below, we will
1517                                  * complain if the bogus default isn't overridden by the child
1518                                  * schema.
1519                                  */
1520                                 Assert(def->raw_default == NULL);
1521                                 if (def->cooked_default == NULL)
1522                                         def->cooked_default = this_default;
1523                                 else if (!equal(def->cooked_default, this_default))
1524                                 {
1525                                         def->cooked_default = &bogus_marker;
1526                                         have_bogus_defaults = true;
1527                                 }
1528                         }
1529                 }
1530
1531                 /*
1532                  * Now copy the CHECK constraints of this parent, adjusting attnos
1533                  * using the completed newattno[] map.  Identically named constraints
1534                  * are merged if possible, else we throw error.
1535                  */
1536                 if (constr && constr->num_check > 0)
1537                 {
1538                         ConstrCheck *check = constr->check;
1539                         int                     i;
1540
1541                         for (i = 0; i < constr->num_check; i++)
1542                         {
1543                                 char       *name = check[i].ccname;
1544                                 Node       *expr;
1545
1546                                 /* adjust varattnos of ccbin here */
1547                                 expr = stringToNode(check[i].ccbin);
1548                                 change_varattnos_of_a_node(expr, newattno);
1549
1550                                 /* check for duplicate */
1551                                 if (!MergeCheckConstraint(constraints, name, expr))
1552                                 {
1553                                         /* nope, this is a new one */
1554                                         CookedConstraint *cooked;
1555
1556                                         cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
1557                                         cooked->contype = CONSTR_CHECK;
1558                                         cooked->name = pstrdup(name);
1559                                         cooked->attnum = 0; /* not used for constraints */
1560                                         cooked->expr = expr;
1561                                         cooked->is_local = false;
1562                                         cooked->inhcount = 1;
1563                                         constraints = lappend(constraints, cooked);
1564                                 }
1565                         }
1566                 }
1567
1568                 pfree(newattno);
1569
1570                 /*
1571                  * Close the parent rel, but keep our AccessShareLock on it until xact
1572                  * commit.      That will prevent someone else from deleting or ALTERing
1573                  * the parent before the child is committed.
1574                  */
1575                 heap_close(relation, NoLock);
1576         }
1577
1578         /*
1579          * If we had no inherited attributes, the result schema is just the
1580          * explicitly declared columns.  Otherwise, we need to merge the declared
1581          * columns into the inherited schema list.
1582          */
1583         if (inhSchema != NIL)
1584         {
1585                 foreach(entry, schema)
1586                 {
1587                         ColumnDef  *newdef = lfirst(entry);
1588                         char       *attributeName = newdef->colname;
1589                         int                     exist_attno;
1590
1591                         /*
1592                          * Does it conflict with some previously inherited column?
1593                          */
1594                         exist_attno = findAttrByName(attributeName, inhSchema);
1595                         if (exist_attno > 0)
1596                         {
1597                                 ColumnDef  *def;
1598                                 Oid                     defTypeId,
1599                                                         newTypeId;
1600                                 int32           deftypmod,
1601                                                         newtypmod;
1602                                 Oid                     defcollid,
1603                                                         newcollid;
1604
1605                                 /*
1606                                  * Yes, try to merge the two column definitions. They must
1607                                  * have the same type, typmod, and collation.
1608                                  */
1609                                 ereport(NOTICE,
1610                                    (errmsg("merging column \"%s\" with inherited definition",
1611                                                    attributeName)));
1612                                 def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
1613                                 typenameTypeIdAndMod(NULL, def->typeName, &defTypeId, &deftypmod);
1614                                 typenameTypeIdAndMod(NULL, newdef->typeName, &newTypeId, &newtypmod);
1615                                 if (defTypeId != newTypeId || deftypmod != newtypmod)
1616                                         ereport(ERROR,
1617                                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
1618                                                          errmsg("column \"%s\" has a type conflict",
1619                                                                         attributeName),
1620                                                          errdetail("%s versus %s",
1621                                                                            TypeNameToString(def->typeName),
1622                                                                            TypeNameToString(newdef->typeName))));
1623                                 defcollid = GetColumnDefCollation(NULL, def, defTypeId);
1624                                 newcollid = GetColumnDefCollation(NULL, newdef, newTypeId);
1625                                 if (defcollid != newcollid)
1626                                         ereport(ERROR,
1627                                                         (errcode(ERRCODE_COLLATION_MISMATCH),
1628                                                          errmsg("column \"%s\" has a collation conflict",
1629                                                                         attributeName),
1630                                                          errdetail("\"%s\" versus \"%s\"",
1631                                                                            get_collation_name(defcollid),
1632                                                                            get_collation_name(newcollid))));
1633
1634                                 /* Copy storage parameter */
1635                                 if (def->storage == 0)
1636                                         def->storage = newdef->storage;
1637                                 else if (newdef->storage != 0 && def->storage != newdef->storage)
1638                                         ereport(ERROR,
1639                                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
1640                                          errmsg("column \"%s\" has a storage parameter conflict",
1641                                                         attributeName),
1642                                                          errdetail("%s versus %s",
1643                                                                            storage_name(def->storage),
1644                                                                            storage_name(newdef->storage))));
1645
1646                                 /* Mark the column as locally defined */
1647                                 def->is_local = true;
1648                                 /* Merge of NOT NULL constraints = OR 'em together */
1649                                 def->is_not_null |= newdef->is_not_null;
1650                                 /* If new def has a default, override previous default */
1651                                 if (newdef->raw_default != NULL)
1652                                 {
1653                                         def->raw_default = newdef->raw_default;
1654                                         def->cooked_default = newdef->cooked_default;
1655                                 }
1656                         }
1657                         else
1658                         {
1659                                 /*
1660                                  * No, attach new column to result schema
1661                                  */
1662                                 inhSchema = lappend(inhSchema, newdef);
1663                         }
1664                 }
1665
1666                 schema = inhSchema;
1667
1668                 /*
1669                  * Check that we haven't exceeded the legal # of columns after merging
1670                  * in inherited columns.
1671                  */
1672                 if (list_length(schema) > MaxHeapAttributeNumber)
1673                         ereport(ERROR,
1674                                         (errcode(ERRCODE_TOO_MANY_COLUMNS),
1675                                          errmsg("tables can have at most %d columns",
1676                                                         MaxHeapAttributeNumber)));
1677         }
1678
1679         /*
1680          * If we found any conflicting parent default values, check to make sure
1681          * they were overridden by the child.
1682          */
1683         if (have_bogus_defaults)
1684         {
1685                 foreach(entry, schema)
1686                 {
1687                         ColumnDef  *def = lfirst(entry);
1688
1689                         if (def->cooked_default == &bogus_marker)
1690                                 ereport(ERROR,
1691                                                 (errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
1692                                   errmsg("column \"%s\" inherits conflicting default values",
1693                                                  def->colname),
1694                                                  errhint("To resolve the conflict, specify a default explicitly.")));
1695                 }
1696         }
1697
1698         *supOids = parentOids;
1699         *supconstr = constraints;
1700         *supOidCount = parentsWithOids;
1701         return schema;
1702 }
1703
1704
1705 /*
1706  * MergeCheckConstraint
1707  *              Try to merge an inherited CHECK constraint with previous ones
1708  *
1709  * If we inherit identically-named constraints from multiple parents, we must
1710  * merge them, or throw an error if they don't have identical definitions.
1711  *
1712  * constraints is a list of CookedConstraint structs for previous constraints.
1713  *
1714  * Returns TRUE if merged (constraint is a duplicate), or FALSE if it's
1715  * got a so-far-unique name, or throws error if conflict.
1716  */
1717 static bool
1718 MergeCheckConstraint(List *constraints, char *name, Node *expr)
1719 {
1720         ListCell   *lc;
1721
1722         foreach(lc, constraints)
1723         {
1724                 CookedConstraint *ccon = (CookedConstraint *) lfirst(lc);
1725
1726                 Assert(ccon->contype == CONSTR_CHECK);
1727
1728                 /* Non-matching names never conflict */
1729                 if (strcmp(ccon->name, name) != 0)
1730                         continue;
1731
1732                 if (equal(expr, ccon->expr))
1733                 {
1734                         /* OK to merge */
1735                         ccon->inhcount++;
1736                         return true;
1737                 }
1738
1739                 ereport(ERROR,
1740                                 (errcode(ERRCODE_DUPLICATE_OBJECT),
1741                                  errmsg("check constraint name \"%s\" appears multiple times but with different expressions",
1742                                                 name)));
1743         }
1744
1745         return false;
1746 }
1747
1748
1749 /*
1750  * Replace varattno values in an expression tree according to the given
1751  * map array, that is, varattno N is replaced by newattno[N-1].  It is
1752  * caller's responsibility to ensure that the array is long enough to
1753  * define values for all user varattnos present in the tree.  System column
1754  * attnos remain unchanged.
1755  *
1756  * Note that the passed node tree is modified in-place!
1757  */
1758 void
1759 change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
1760 {
1761         /* no setup needed, so away we go */
1762         (void) change_varattnos_walker(node, newattno);
1763 }
1764
1765 static bool
1766 change_varattnos_walker(Node *node, const AttrNumber *newattno)
1767 {
1768         if (node == NULL)
1769                 return false;
1770         if (IsA(node, Var))
1771         {
1772                 Var                *var = (Var *) node;
1773
1774                 if (var->varlevelsup == 0 && var->varno == 1 &&
1775                         var->varattno > 0)
1776                 {
1777                         /*
1778                          * ??? the following may be a problem when the node is multiply
1779                          * referenced though stringToNode() doesn't create such a node
1780                          * currently.
1781                          */
1782                         Assert(newattno[var->varattno - 1] > 0);
1783                         var->varattno = var->varoattno = newattno[var->varattno - 1];
1784                 }
1785                 return false;
1786         }
1787         return expression_tree_walker(node, change_varattnos_walker,
1788                                                                   (void *) newattno);
1789 }
1790
1791 /*
1792  * Generate a map for change_varattnos_of_a_node from old and new TupleDesc's,
1793  * matching according to column name.
1794  */
1795 AttrNumber *
1796 varattnos_map(TupleDesc olddesc, TupleDesc newdesc)
1797 {
1798         AttrNumber *attmap;
1799         int                     i,
1800                                 j;
1801
1802         attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * olddesc->natts);
1803         for (i = 1; i <= olddesc->natts; i++)
1804         {
1805                 if (olddesc->attrs[i - 1]->attisdropped)
1806                         continue;                       /* leave the entry as zero */
1807
1808                 for (j = 1; j <= newdesc->natts; j++)
1809                 {
1810                         if (strcmp(NameStr(olddesc->attrs[i - 1]->attname),
1811                                            NameStr(newdesc->attrs[j - 1]->attname)) == 0)
1812                         {
1813                                 attmap[i - 1] = j;
1814                                 break;
1815                         }
1816                 }
1817         }
1818         return attmap;
1819 }
1820
1821 /*
1822  * Generate a map for change_varattnos_of_a_node from a TupleDesc and a list
1823  * of ColumnDefs
1824  */
1825 AttrNumber *
1826 varattnos_map_schema(TupleDesc old, List *schema)
1827 {
1828         AttrNumber *attmap;
1829         int                     i;
1830
1831         attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * old->natts);
1832         for (i = 1; i <= old->natts; i++)
1833         {
1834                 if (old->attrs[i - 1]->attisdropped)
1835                         continue;                       /* leave the entry as zero */
1836
1837                 attmap[i - 1] = findAttrByName(NameStr(old->attrs[i - 1]->attname),
1838                                                                            schema);
1839         }
1840         return attmap;
1841 }
1842
1843
1844 /*
1845  * StoreCatalogInheritance
1846  *              Updates the system catalogs with proper inheritance information.
1847  *
1848  * supers is a list of the OIDs of the new relation's direct ancestors.
1849  */
1850 static void
1851 StoreCatalogInheritance(Oid relationId, List *supers)
1852 {
1853         Relation        relation;
1854         int16           seqNumber;
1855         ListCell   *entry;
1856
1857         /*
1858          * sanity checks
1859          */
1860         AssertArg(OidIsValid(relationId));
1861
1862         if (supers == NIL)
1863                 return;
1864
1865         /*
1866          * Store INHERITS information in pg_inherits using direct ancestors only.
1867          * Also enter dependencies on the direct ancestors, and make sure they are
1868          * marked with relhassubclass = true.
1869          *
1870          * (Once upon a time, both direct and indirect ancestors were found here
1871          * and then entered into pg_ipl.  Since that catalog doesn't exist
1872          * anymore, there's no need to look for indirect ancestors.)
1873          */
1874         relation = heap_open(InheritsRelationId, RowExclusiveLock);
1875
1876         seqNumber = 1;
1877         foreach(entry, supers)
1878         {
1879                 Oid                     parentOid = lfirst_oid(entry);
1880
1881                 StoreCatalogInheritance1(relationId, parentOid, seqNumber, relation);
1882                 seqNumber++;
1883         }
1884
1885         heap_close(relation, RowExclusiveLock);
1886 }
1887
1888 /*
1889  * Make catalog entries showing relationId as being an inheritance child
1890  * of parentOid.  inhRelation is the already-opened pg_inherits catalog.
1891  */
1892 static void
1893 StoreCatalogInheritance1(Oid relationId, Oid parentOid,
1894                                                  int16 seqNumber, Relation inhRelation)
1895 {
1896         TupleDesc       desc = RelationGetDescr(inhRelation);
1897         Datum           values[Natts_pg_inherits];
1898         bool            nulls[Natts_pg_inherits];
1899         ObjectAddress childobject,
1900                                 parentobject;
1901         HeapTuple       tuple;
1902
1903         /*
1904          * Make the pg_inherits entry
1905          */
1906         values[Anum_pg_inherits_inhrelid - 1] = ObjectIdGetDatum(relationId);
1907         values[Anum_pg_inherits_inhparent - 1] = ObjectIdGetDatum(parentOid);
1908         values[Anum_pg_inherits_inhseqno - 1] = Int16GetDatum(seqNumber);
1909
1910         memset(nulls, 0, sizeof(nulls));
1911
1912         tuple = heap_form_tuple(desc, values, nulls);
1913
1914         simple_heap_insert(inhRelation, tuple);
1915
1916         CatalogUpdateIndexes(inhRelation, tuple);
1917
1918         heap_freetuple(tuple);
1919
1920         /*
1921          * Store a dependency too
1922          */
1923         parentobject.classId = RelationRelationId;
1924         parentobject.objectId = parentOid;
1925         parentobject.objectSubId = 0;
1926         childobject.classId = RelationRelationId;
1927         childobject.objectId = relationId;
1928         childobject.objectSubId = 0;
1929
1930         recordDependencyOn(&childobject, &parentobject, DEPENDENCY_NORMAL);
1931
1932         /*
1933          * Mark the parent as having subclasses.
1934          */
1935         setRelhassubclassInRelation(parentOid, true);
1936 }
1937
1938 /*
1939  * Look for an existing schema entry with the given name.
1940  *
1941  * Returns the index (starting with 1) if attribute already exists in schema,
1942  * 0 if it doesn't.
1943  */
1944 static int
1945 findAttrByName(const char *attributeName, List *schema)
1946 {
1947         ListCell   *s;
1948         int                     i = 1;
1949
1950         foreach(s, schema)
1951         {
1952                 ColumnDef  *def = lfirst(s);
1953
1954                 if (strcmp(attributeName, def->colname) == 0)
1955                         return i;
1956
1957                 i++;
1958         }
1959         return 0;
1960 }
1961
1962 /*
1963  * Update a relation's pg_class.relhassubclass entry to the given value
1964  */
1965 static void
1966 setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
1967 {
1968         Relation        relationRelation;
1969         HeapTuple       tuple;
1970         Form_pg_class classtuple;
1971
1972         /*
1973          * Fetch a modifiable copy of the tuple, modify it, update pg_class.
1974          *
1975          * If the tuple already has the right relhassubclass setting, we don't
1976          * need to update it, but we still need to issue an SI inval message.
1977          */
1978         relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
1979         tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId));
1980         if (!HeapTupleIsValid(tuple))
1981                 elog(ERROR, "cache lookup failed for relation %u", relationId);
1982         classtuple = (Form_pg_class) GETSTRUCT(tuple);
1983
1984         if (classtuple->relhassubclass != relhassubclass)
1985         {
1986                 classtuple->relhassubclass = relhassubclass;
1987                 simple_heap_update(relationRelation, &tuple->t_self, tuple);
1988
1989                 /* keep the catalog indexes up to date */
1990                 CatalogUpdateIndexes(relationRelation, tuple);
1991         }
1992         else
1993         {
1994                 /* no need to change tuple, but force relcache rebuild anyway */
1995                 CacheInvalidateRelcacheByTuple(tuple);
1996         }
1997
1998         heap_freetuple(tuple);
1999         heap_close(relationRelation, RowExclusiveLock);
2000 }
2001
2002
2003 /*
2004  *              renameatt_internal              - workhorse for renameatt
2005  */
2006 static void
2007 renameatt_internal(Oid myrelid,
2008                                    const char *oldattname,
2009                                    const char *newattname,
2010                                    bool recurse,
2011                                    bool recursing,
2012                                    int expected_parents,
2013                                    DropBehavior behavior)
2014 {
2015         Relation        targetrelation;
2016         Relation        attrelation;
2017         HeapTuple       atttup;
2018         Form_pg_attribute attform;
2019         int                     attnum;
2020         char            relkind;
2021
2022         /*
2023          * Grab an exclusive lock on the target table, which we will NOT release
2024          * until end of transaction.
2025          */
2026         targetrelation = relation_open(myrelid, AccessExclusiveLock);
2027
2028         if (targetrelation->rd_rel->reloftype && !recursing)
2029                 ereport(ERROR,
2030                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2031                                  errmsg("cannot rename column of typed table")));
2032
2033         /*
2034          * Renaming the columns of sequences or toast tables doesn't actually
2035          * break anything from the system's point of view, since internal
2036          * references are by attnum.  But it doesn't seem right to allow users to
2037          * change names that are hardcoded into the system, hence the following
2038          * restriction.
2039          */
2040         relkind = RelationGetForm(targetrelation)->relkind;
2041         if (relkind != RELKIND_RELATION &&
2042                 relkind != RELKIND_VIEW &&
2043                 relkind != RELKIND_COMPOSITE_TYPE &&
2044                 relkind != RELKIND_INDEX &&
2045                 relkind != RELKIND_FOREIGN_TABLE)
2046                 ereport(ERROR,
2047                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2048                                  errmsg("\"%s\" is not a table, view, composite type, index or foreign table",
2049                                                 RelationGetRelationName(targetrelation))));
2050
2051         /*
2052          * permissions checking.  only the owner of a class can change its schema.
2053          */
2054         if (!pg_class_ownercheck(myrelid, GetUserId()))
2055                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
2056                                            RelationGetRelationName(targetrelation));
2057         if (!allowSystemTableMods && IsSystemRelation(targetrelation))
2058                 ereport(ERROR,
2059                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2060                                  errmsg("permission denied: \"%s\" is a system catalog",
2061                                                 RelationGetRelationName(targetrelation))));
2062
2063         /*
2064          * if the 'recurse' flag is set then we are supposed to rename this
2065          * attribute in all classes that inherit from 'relname' (as well as in
2066          * 'relname').
2067          *
2068          * any permissions or problems with duplicate attributes will cause the
2069          * whole transaction to abort, which is what we want -- all or nothing.
2070          */
2071         if (recurse)
2072         {
2073                 List       *child_oids,
2074                                    *child_numparents;
2075                 ListCell   *lo,
2076                                    *li;
2077
2078                 /*
2079                  * we need the number of parents for each child so that the recursive
2080                  * calls to renameatt() can determine whether there are any parents
2081                  * outside the inheritance hierarchy being processed.
2082                  */
2083                 child_oids = find_all_inheritors(myrelid, AccessExclusiveLock,
2084                                                                                  &child_numparents);
2085
2086                 /*
2087                  * find_all_inheritors does the recursive search of the inheritance
2088                  * hierarchy, so all we have to do is process all of the relids in the
2089                  * list that it returns.
2090                  */
2091                 forboth(lo, child_oids, li, child_numparents)
2092                 {
2093                         Oid                     childrelid = lfirst_oid(lo);
2094                         int                     numparents = lfirst_int(li);
2095
2096                         if (childrelid == myrelid)
2097                                 continue;
2098                         /* note we need not recurse again */
2099                         renameatt_internal(childrelid, oldattname, newattname, false, true, numparents, behavior);
2100                 }
2101         }
2102         else
2103         {
2104                 /*
2105                  * If we are told not to recurse, there had better not be any child
2106                  * tables; else the rename would put them out of step.
2107                  *
2108                  * expected_parents will only be 0 if we are not already recursing.
2109                  */
2110                 if (expected_parents == 0 &&
2111                         find_inheritance_children(myrelid, NoLock) != NIL)
2112                         ereport(ERROR,
2113                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2114                                          errmsg("inherited column \"%s\" must be renamed in child tables too",
2115                                                         oldattname)));
2116         }
2117
2118         /* rename attributes in typed tables of composite type */
2119         if (targetrelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
2120         {
2121                 List       *child_oids;
2122                 ListCell   *lo;
2123
2124                 child_oids = find_typed_table_dependencies(targetrelation->rd_rel->reltype,
2125                                                                          RelationGetRelationName(targetrelation),
2126                                                                                                    behavior);
2127
2128                 foreach(lo, child_oids)
2129                         renameatt_internal(lfirst_oid(lo), oldattname, newattname, true, true, 0, behavior);
2130         }
2131
2132         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
2133
2134         atttup = SearchSysCacheCopyAttName(myrelid, oldattname);
2135         if (!HeapTupleIsValid(atttup))
2136                 ereport(ERROR,
2137                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
2138                                  errmsg("column \"%s\" does not exist",
2139                                                 oldattname)));
2140         attform = (Form_pg_attribute) GETSTRUCT(atttup);
2141
2142         attnum = attform->attnum;
2143         if (attnum <= 0)
2144                 ereport(ERROR,
2145                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2146                                  errmsg("cannot rename system column \"%s\"",
2147                                                 oldattname)));
2148
2149         /*
2150          * if the attribute is inherited, forbid the renaming.  if this is a
2151          * top-level call to renameatt(), then expected_parents will be 0, so the
2152          * effect of this code will be to prohibit the renaming if the attribute
2153          * is inherited at all.  if this is a recursive call to renameatt(),
2154          * expected_parents will be the number of parents the current relation has
2155          * within the inheritance hierarchy being processed, so we'll prohibit the
2156          * renaming only if there are additional parents from elsewhere.
2157          */
2158         if (attform->attinhcount > expected_parents)
2159                 ereport(ERROR,
2160                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2161                                  errmsg("cannot rename inherited column \"%s\"",
2162                                                 oldattname)));
2163
2164         /* new name should not already exist */
2165
2166         /* this test is deliberately not attisdropped-aware */
2167         if (SearchSysCacheExists2(ATTNAME,
2168                                                           ObjectIdGetDatum(myrelid),
2169                                                           PointerGetDatum(newattname)))
2170                 ereport(ERROR,
2171                                 (errcode(ERRCODE_DUPLICATE_COLUMN),
2172                                  errmsg("column \"%s\" of relation \"%s\" already exists",
2173                                           newattname, RelationGetRelationName(targetrelation))));
2174
2175         /* apply the update */
2176         namestrcpy(&(attform->attname), newattname);
2177
2178         simple_heap_update(attrelation, &atttup->t_self, atttup);
2179
2180         /* keep system catalog indexes current */
2181         CatalogUpdateIndexes(attrelation, atttup);
2182
2183         heap_freetuple(atttup);
2184
2185         heap_close(attrelation, RowExclusiveLock);
2186
2187         relation_close(targetrelation, NoLock);         /* close rel but keep lock */
2188 }
2189
2190
2191 /*
2192  *              renameatt               - changes the name of a attribute in a relation
2193  */
2194 void
2195 renameatt(Oid myrelid, RenameStmt *stmt)
2196 {
2197         renameatt_internal(myrelid,
2198                                            stmt->subname,       /* old att name */
2199                                            stmt->newname,       /* new att name */
2200                                            interpretInhOption(stmt->relation->inhOpt),          /* recursive? */
2201                                            false,       /* recursing? */
2202                                            0,           /* expected inhcount */
2203                                            stmt->behavior);
2204 }
2205
2206
2207 /*
2208  * Execute ALTER TABLE/INDEX/SEQUENCE/VIEW/FOREIGN TABLE RENAME
2209  *
2210  * Caller has already done permissions checks.
2211  */
2212 void
2213 RenameRelation(Oid myrelid, const char *newrelname, ObjectType reltype)
2214 {
2215         Relation        targetrelation;
2216         Oid                     namespaceId;
2217         char            relkind;
2218
2219         /*
2220          * Grab an exclusive lock on the target table, index, sequence or view,
2221          * which we will NOT release until end of transaction.
2222          */
2223         targetrelation = relation_open(myrelid, AccessExclusiveLock);
2224
2225         namespaceId = RelationGetNamespace(targetrelation);
2226         relkind = targetrelation->rd_rel->relkind;
2227
2228         /*
2229          * For compatibility with prior releases, we don't complain if ALTER TABLE
2230          * or ALTER INDEX is used to rename some other type of relation.  But
2231          * ALTER SEQUENCE/VIEW/FOREIGN TABLE are only to be used with relations of
2232          * that type.
2233          */
2234         if (reltype == OBJECT_SEQUENCE && relkind != RELKIND_SEQUENCE)
2235                 ereport(ERROR,
2236                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2237                                  errmsg("\"%s\" is not a sequence",
2238                                                 RelationGetRelationName(targetrelation))));
2239
2240         if (reltype == OBJECT_VIEW && relkind != RELKIND_VIEW)
2241                 ereport(ERROR,
2242                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2243                                  errmsg("\"%s\" is not a view",
2244                                                 RelationGetRelationName(targetrelation))));
2245
2246         if (reltype == OBJECT_FOREIGN_TABLE && relkind != RELKIND_FOREIGN_TABLE)
2247                 ereport(ERROR,
2248                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2249                                  errmsg("\"%s\" is not a foreign table",
2250                                                 RelationGetRelationName(targetrelation))));
2251
2252         /*
2253          * Don't allow ALTER TABLE on composite types. We want people to use ALTER
2254          * TYPE for that.
2255          */
2256         if (relkind == RELKIND_COMPOSITE_TYPE)
2257                 ereport(ERROR,
2258                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2259                                  errmsg("\"%s\" is a composite type",
2260                                                 RelationGetRelationName(targetrelation)),
2261                                  errhint("Use ALTER TYPE instead.")));
2262
2263         /* Do the work */
2264         RenameRelationInternal(myrelid, newrelname, namespaceId);
2265
2266         /*
2267          * Close rel, but keep exclusive lock!
2268          */
2269         relation_close(targetrelation, NoLock);
2270 }
2271
2272 /*
2273  *              RenameRelationInternal - change the name of a relation
2274  *
2275  *              XXX - When renaming sequences, we don't bother to modify the
2276  *                        sequence name that is stored within the sequence itself
2277  *                        (this would cause problems with MVCC). In the future,
2278  *                        the sequence name should probably be removed from the
2279  *                        sequence, AFAIK there's no need for it to be there.
2280  */
2281 void
2282 RenameRelationInternal(Oid myrelid, const char *newrelname, Oid namespaceId)
2283 {
2284         Relation        targetrelation;
2285         Relation        relrelation;    /* for RELATION relation */
2286         HeapTuple       reltup;
2287         Form_pg_class relform;
2288
2289         /*
2290          * Grab an exclusive lock on the target table, index, sequence or view,
2291          * which we will NOT release until end of transaction.
2292          */
2293         targetrelation = relation_open(myrelid, AccessExclusiveLock);
2294
2295         /*
2296          * Find relation's pg_class tuple, and make sure newrelname isn't in use.
2297          */
2298         relrelation = heap_open(RelationRelationId, RowExclusiveLock);
2299
2300         reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(myrelid));
2301         if (!HeapTupleIsValid(reltup))          /* shouldn't happen */
2302                 elog(ERROR, "cache lookup failed for relation %u", myrelid);
2303         relform = (Form_pg_class) GETSTRUCT(reltup);
2304
2305         if (get_relname_relid(newrelname, namespaceId) != InvalidOid)
2306                 ereport(ERROR,
2307                                 (errcode(ERRCODE_DUPLICATE_TABLE),
2308                                  errmsg("relation \"%s\" already exists",
2309                                                 newrelname)));
2310
2311         /*
2312          * Update pg_class tuple with new relname.      (Scribbling on reltup is OK
2313          * because it's a copy...)
2314          */
2315         namestrcpy(&(relform->relname), newrelname);
2316
2317         simple_heap_update(relrelation, &reltup->t_self, reltup);
2318
2319         /* keep the system catalog indexes current */
2320         CatalogUpdateIndexes(relrelation, reltup);
2321
2322         heap_freetuple(reltup);
2323         heap_close(relrelation, RowExclusiveLock);
2324
2325         /*
2326          * Also rename the associated type, if any.
2327          */
2328         if (OidIsValid(targetrelation->rd_rel->reltype))
2329                 RenameTypeInternal(targetrelation->rd_rel->reltype,
2330                                                    newrelname, namespaceId);
2331
2332         /*
2333          * Also rename the associated constraint, if any.
2334          */
2335         if (targetrelation->rd_rel->relkind == RELKIND_INDEX)
2336         {
2337                 Oid                     constraintId = get_index_constraint(myrelid);
2338
2339                 if (OidIsValid(constraintId))
2340                         RenameConstraintById(constraintId, newrelname);
2341         }
2342
2343         /*
2344          * Close rel, but keep exclusive lock!
2345          */
2346         relation_close(targetrelation, NoLock);
2347 }
2348
2349 /*
2350  * Disallow ALTER TABLE (and similar commands) when the current backend has
2351  * any open reference to the target table besides the one just acquired by
2352  * the calling command; this implies there's an open cursor or active plan.
2353  * We need this check because our lock doesn't protect us against stomping
2354  * on our own foot, only other people's feet!
2355  *
2356  * For ALTER TABLE, the only case known to cause serious trouble is ALTER
2357  * COLUMN TYPE, and some changes are obviously pretty benign, so this could
2358  * possibly be relaxed to only error out for certain types of alterations.
2359  * But the use-case for allowing any of these things is not obvious, so we
2360  * won't work hard at it for now.
2361  *
2362  * We also reject these commands if there are any pending AFTER trigger events
2363  * for the rel.  This is certainly necessary for the rewriting variants of
2364  * ALTER TABLE, because they don't preserve tuple TIDs and so the pending
2365  * events would try to fetch the wrong tuples.  It might be overly cautious
2366  * in other cases, but again it seems better to err on the side of paranoia.
2367  *
2368  * REINDEX calls this with "rel" referencing the index to be rebuilt; here
2369  * we are worried about active indexscans on the index.  The trigger-event
2370  * check can be skipped, since we are doing no damage to the parent table.
2371  *
2372  * The statement name (eg, "ALTER TABLE") is passed for use in error messages.
2373  */
2374 void
2375 CheckTableNotInUse(Relation rel, const char *stmt)
2376 {
2377         int                     expected_refcnt;
2378
2379         expected_refcnt = rel->rd_isnailed ? 2 : 1;
2380         if (rel->rd_refcnt != expected_refcnt)
2381                 ereport(ERROR,
2382                                 (errcode(ERRCODE_OBJECT_IN_USE),
2383                 /* translator: first %s is a SQL command, eg ALTER TABLE */
2384                                  errmsg("cannot %s \"%s\" because "
2385                                                 "it is being used by active queries in this session",
2386                                                 stmt, RelationGetRelationName(rel))));
2387
2388         if (rel->rd_rel->relkind != RELKIND_INDEX &&
2389                 AfterTriggerPendingOnRel(RelationGetRelid(rel)))
2390                 ereport(ERROR,
2391                                 (errcode(ERRCODE_OBJECT_IN_USE),
2392                 /* translator: first %s is a SQL command, eg ALTER TABLE */
2393                                  errmsg("cannot %s \"%s\" because "
2394                                                 "it has pending trigger events",
2395                                                 stmt, RelationGetRelationName(rel))));
2396 }
2397
2398 /*
2399  * AlterTable
2400  *              Execute ALTER TABLE, which can be a list of subcommands
2401  *
2402  * ALTER TABLE is performed in three phases:
2403  *              1. Examine subcommands and perform pre-transformation checking.
2404  *              2. Update system catalogs.
2405  *              3. Scan table(s) to check new constraints, and optionally recopy
2406  *                 the data into new table(s).
2407  * Phase 3 is not performed unless one or more of the subcommands requires
2408  * it.  The intention of this design is to allow multiple independent
2409  * updates of the table schema to be performed with only one pass over the
2410  * data.
2411  *
2412  * ATPrepCmd performs phase 1.  A "work queue" entry is created for
2413  * each table to be affected (there may be multiple affected tables if the
2414  * commands traverse a table inheritance hierarchy).  Also we do preliminary
2415  * validation of the subcommands, including parse transformation of those
2416  * expressions that need to be evaluated with respect to the old table
2417  * schema.
2418  *
2419  * ATRewriteCatalogs performs phase 2 for each affected table.  (Note that
2420  * phases 2 and 3 normally do no explicit recursion, since phase 1 already
2421  * did it --- although some subcommands have to recurse in phase 2 instead.)
2422  * Certain subcommands need to be performed before others to avoid
2423  * unnecessary conflicts; for example, DROP COLUMN should come before
2424  * ADD COLUMN.  Therefore phase 1 divides the subcommands into multiple
2425  * lists, one for each logical "pass" of phase 2.
2426  *
2427  * ATRewriteTables performs phase 3 for those tables that need it.
2428  *
2429  * Thanks to the magic of MVCC, an error anywhere along the way rolls back
2430  * the whole operation; we don't have to do anything special to clean up.
2431  *
2432  * We lock the table as the first action, with an appropriate lock level
2433  * for the subcommands requested. Any subcommand that needs to rewrite
2434  * tuples in the table forces the whole command to be executed with
2435  * AccessExclusiveLock. If all subcommands do not require rewrite table
2436  * then we may be able to use lower lock levels. We pass the lock level down
2437  * so that we can apply it recursively to inherited tables. Note that the
2438  * lock level we want as we recurse may well be higher than required for
2439  * that specific subcommand. So we pass down the overall lock requirement,
2440  * rather than reassess it at lower levels.
2441  */
2442 void
2443 AlterTable(AlterTableStmt *stmt)
2444 {
2445         Relation        rel;
2446         LOCKMODE        lockmode = AlterTableGetLockLevel(stmt->cmds);
2447
2448         /*
2449          * Acquire same level of lock as already acquired during parsing.
2450          */
2451         rel = relation_openrv(stmt->relation, lockmode);
2452
2453         CheckTableNotInUse(rel, "ALTER TABLE");
2454
2455         /* Check relation type against type specified in the ALTER command */
2456         switch (stmt->relkind)
2457         {
2458                 case OBJECT_TABLE:
2459
2460                         /*
2461                          * For mostly-historical reasons, we allow ALTER TABLE to apply to
2462                          * almost all relation types.
2463                          */
2464                         if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE
2465                                 || rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2466                                 ereport(ERROR,
2467                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2468                                                  errmsg("\"%s\" is not a table",
2469                                                                 RelationGetRelationName(rel))));
2470                         break;
2471
2472                 case OBJECT_INDEX:
2473                         if (rel->rd_rel->relkind != RELKIND_INDEX)
2474                                 ereport(ERROR,
2475                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2476                                                  errmsg("\"%s\" is not an index",
2477                                                                 RelationGetRelationName(rel))));
2478                         break;
2479
2480                 case OBJECT_SEQUENCE:
2481                         if (rel->rd_rel->relkind != RELKIND_SEQUENCE)
2482                                 ereport(ERROR,
2483                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2484                                                  errmsg("\"%s\" is not a sequence",
2485                                                                 RelationGetRelationName(rel))));
2486                         break;
2487
2488                 case OBJECT_TYPE:
2489                         if (rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
2490                                 ereport(ERROR,
2491                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2492                                                  errmsg("\"%s\" is not a composite type",
2493                                                                 RelationGetRelationName(rel))));
2494                         break;
2495
2496                 case OBJECT_VIEW:
2497                         if (rel->rd_rel->relkind != RELKIND_VIEW)
2498                                 ereport(ERROR,
2499                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2500                                                  errmsg("\"%s\" is not a view",
2501                                                                 RelationGetRelationName(rel))));
2502                         break;
2503
2504                 case OBJECT_FOREIGN_TABLE:
2505                         if (rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
2506                                 ereport(ERROR,
2507                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2508                                                  errmsg("\"%s\" is not a foreign table",
2509                                                                 RelationGetRelationName(rel))));
2510                         break;
2511
2512                 default:
2513                         elog(ERROR, "unrecognized object type: %d", (int) stmt->relkind);
2514         }
2515
2516         ATController(rel, stmt->cmds, interpretInhOption(stmt->relation->inhOpt),
2517                                  lockmode);
2518 }
2519
2520 /*
2521  * AlterTableInternal
2522  *
2523  * ALTER TABLE with target specified by OID
2524  *
2525  * We do not reject if the relation is already open, because it's quite
2526  * likely that one or more layers of caller have it open.  That means it
2527  * is unsafe to use this entry point for alterations that could break
2528  * existing query plans.  On the assumption it's not used for such, we
2529  * don't have to reject pending AFTER triggers, either.
2530  */
2531 void
2532 AlterTableInternal(Oid relid, List *cmds, bool recurse)
2533 {
2534         Relation        rel;
2535         LOCKMODE        lockmode = AlterTableGetLockLevel(cmds);
2536
2537         rel = relation_open(relid, lockmode);
2538
2539         ATController(rel, cmds, recurse, lockmode);
2540 }
2541
2542 /*
2543  * AlterTableGetLockLevel
2544  *
2545  * Sets the overall lock level required for the supplied list of subcommands.
2546  * Policy for doing this set according to needs of AlterTable(), see
2547  * comments there for overall explanation.
2548  *
2549  * Function is called before and after parsing, so it must give same
2550  * answer each time it is called. Some subcommands are transformed
2551  * into other subcommand types, so the transform must never be made to a
2552  * lower lock level than previously assigned. All transforms are noted below.
2553  *
2554  * Since this is called before we lock the table we cannot use table metadata
2555  * to influence the type of lock we acquire.
2556  *
2557  * There should be no lockmodes hardcoded into the subcommand functions. All
2558  * lockmode decisions for ALTER TABLE are made here only. The one exception is
2559  * ALTER TABLE RENAME which is treated as a different statement type T_RenameStmt
2560  * and does not travel through this section of code and cannot be combined with
2561  * any of the subcommands given here.
2562  */
2563 LOCKMODE
2564 AlterTableGetLockLevel(List *cmds)
2565 {
2566         ListCell   *lcmd;
2567         LOCKMODE        lockmode = ShareUpdateExclusiveLock;
2568
2569         foreach(lcmd, cmds)
2570         {
2571                 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
2572                 LOCKMODE        cmd_lockmode = AccessExclusiveLock; /* default for compiler */
2573
2574                 switch (cmd->subtype)
2575                 {
2576                                 /*
2577                                  * Need AccessExclusiveLock for these subcommands because they
2578                                  * affect or potentially affect both read and write
2579                                  * operations.
2580                                  *
2581                                  * New subcommand types should be added here by default.
2582                                  */
2583                         case AT_AddColumn:      /* may rewrite heap, in some cases and visible
2584                                                                  * to SELECT */
2585                         case AT_DropColumn:     /* change visible to SELECT */
2586                         case AT_AddColumnToView:        /* CREATE VIEW */
2587                         case AT_AlterColumnType:        /* must rewrite heap */
2588                         case AT_DropConstraint:         /* as DROP INDEX */
2589                         case AT_AddOids:        /* must rewrite heap */
2590                         case AT_DropOids:       /* calls AT_DropColumn */
2591                         case AT_EnableAlwaysRule:       /* may change SELECT rules */
2592                         case AT_EnableReplicaRule:      /* may change SELECT rules */
2593                         case AT_EnableRule:     /* may change SELECT rules */
2594                         case AT_DisableRule:            /* may change SELECT rules */
2595                         case AT_ChangeOwner:            /* change visible to SELECT */
2596                         case AT_SetTableSpace:          /* must rewrite heap */
2597                         case AT_DropNotNull:            /* may change some SQL plans */
2598                         case AT_SetNotNull:
2599                         case AT_GenericOptions:
2600                                 cmd_lockmode = AccessExclusiveLock;
2601                                 break;
2602
2603                                 /*
2604                                  * These subcommands affect write operations only.
2605                                  */
2606                         case AT_ColumnDefault:
2607                         case AT_ProcessedConstraint:            /* becomes AT_AddConstraint */
2608                         case AT_AddConstraintRecurse:           /* becomes AT_AddConstraint */
2609                         case AT_EnableTrig:
2610                         case AT_EnableAlwaysTrig:
2611                         case AT_EnableReplicaTrig:
2612                         case AT_EnableTrigAll:
2613                         case AT_EnableTrigUser:
2614                         case AT_DisableTrig:
2615                         case AT_DisableTrigAll:
2616                         case AT_DisableTrigUser:
2617                         case AT_AddIndex:       /* from ADD CONSTRAINT */
2618                         case AT_AddIndexConstraint:
2619                                 cmd_lockmode = ShareRowExclusiveLock;
2620                                 break;
2621
2622                         case AT_AddConstraint:
2623                                 if (IsA(cmd->def, Constraint))
2624                                 {
2625                                         Constraint *con = (Constraint *) cmd->def;
2626
2627                                         switch (con->contype)
2628                                         {
2629                                                 case CONSTR_EXCLUSION:
2630                                                 case CONSTR_PRIMARY:
2631                                                 case CONSTR_UNIQUE:
2632
2633                                                         /*
2634                                                          * Cases essentially the same as CREATE INDEX. We
2635                                                          * could reduce the lock strength to ShareLock if
2636                                                          * we can work out how to allow concurrent catalog
2637                                                          * updates.
2638                                                          */
2639                                                         cmd_lockmode = ShareRowExclusiveLock;
2640                                                         break;
2641                                                 case CONSTR_FOREIGN:
2642
2643                                                         /*
2644                                                          * We add triggers to both tables when we add a
2645                                                          * Foreign Key, so the lock level must be at least
2646                                                          * as strong as CREATE TRIGGER.
2647                                                          */
2648                                                         cmd_lockmode = ShareRowExclusiveLock;
2649                                                         break;
2650
2651                                                 default:
2652                                                         cmd_lockmode = ShareRowExclusiveLock;
2653                                         }
2654                                 }
2655                                 break;
2656
2657                                 /*
2658                                  * These subcommands affect inheritance behaviour. Queries
2659                                  * started before us will continue to see the old inheritance
2660                                  * behaviour, while queries started after we commit will see
2661                                  * new behaviour. No need to prevent reads or writes to the
2662                                  * subtable while we hook it up though.
2663                                  */
2664                         case AT_AddInherit:
2665                         case AT_DropInherit:
2666                                 cmd_lockmode = ShareUpdateExclusiveLock;
2667                                 break;
2668
2669                                 /*
2670                                  * These subcommands affect implicit row type conversion. They
2671                                  * have affects similar to CREATE/DROP CAST on queries.  We
2672                                  * don't provide for invalidating parse trees as a result of
2673                                  * such changes.  Do avoid concurrent pg_class updates, though.
2674                                  */
2675                         case AT_AddOf:
2676                         case AT_DropOf:
2677                                 cmd_lockmode = ShareUpdateExclusiveLock;
2678
2679                                 /*
2680                                  * These subcommands affect general strategies for performance
2681                                  * and maintenance, though don't change the semantic results
2682                                  * from normal data reads and writes. Delaying an ALTER TABLE
2683                                  * behind currently active writes only delays the point where
2684                                  * the new strategy begins to take effect, so there is no
2685                                  * benefit in waiting. In this case the minimum restriction
2686                                  * applies: we don't currently allow concurrent catalog
2687                                  * updates.
2688                                  */
2689                         case AT_SetStatistics:
2690                         case AT_ClusterOn:
2691                         case AT_DropCluster:
2692                         case AT_SetRelOptions:
2693                         case AT_ResetRelOptions:
2694                         case AT_SetOptions:
2695                         case AT_ResetOptions:
2696                         case AT_SetStorage:
2697                         case AT_ValidateConstraint:
2698                                 cmd_lockmode = ShareUpdateExclusiveLock;
2699                                 break;
2700
2701                         default:                        /* oops */
2702                                 elog(ERROR, "unrecognized alter table type: %d",
2703                                          (int) cmd->subtype);
2704                                 break;
2705                 }
2706
2707                 /*
2708                  * Take the greatest lockmode from any subcommand
2709                  */
2710                 if (cmd_lockmode > lockmode)
2711                         lockmode = cmd_lockmode;
2712         }
2713
2714         return lockmode;
2715 }
2716
2717 static void
2718 ATController(Relation rel, List *cmds, bool recurse, LOCKMODE lockmode)
2719 {
2720         List       *wqueue = NIL;
2721         ListCell   *lcmd;
2722
2723         /* Phase 1: preliminary examination of commands, create work queue */
2724         foreach(lcmd, cmds)
2725         {
2726                 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
2727
2728                 ATPrepCmd(&wqueue, rel, cmd, recurse, false, lockmode);
2729         }
2730
2731         /* Close the relation, but keep lock until commit */
2732         relation_close(rel, NoLock);
2733
2734         /* Phase 2: update system catalogs */
2735         ATRewriteCatalogs(&wqueue, lockmode);
2736
2737         /* Phase 3: scan/rewrite tables as needed */
2738         ATRewriteTables(&wqueue, lockmode);
2739 }
2740
2741 /*
2742  * ATPrepCmd
2743  *
2744  * Traffic cop for ALTER TABLE Phase 1 operations, including simple
2745  * recursion and permission checks.
2746  *
2747  * Caller must have acquired appropriate lock type on relation already.
2748  * This lock should be held until commit.
2749  */
2750 static void
2751 ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
2752                   bool recurse, bool recursing, LOCKMODE lockmode)
2753 {
2754         AlteredTableInfo *tab;
2755         int                     pass;
2756
2757         /* Find or create work queue entry for this table */
2758         tab = ATGetQueueEntry(wqueue, rel);
2759
2760         /*
2761          * Copy the original subcommand for each table.  This avoids conflicts
2762          * when different child tables need to make different parse
2763          * transformations (for example, the same column may have different column
2764          * numbers in different children).
2765          */
2766         cmd = copyObject(cmd);
2767
2768         /*
2769          * Do permissions checking, recursion to child tables if needed, and any
2770          * additional phase-1 processing needed.
2771          */
2772         switch (cmd->subtype)
2773         {
2774                 case AT_AddColumn:              /* ADD COLUMN */
2775                         ATSimplePermissions(rel,
2776                                                  ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
2777                         ATPrepAddColumn(wqueue, rel, recurse, recursing, cmd, lockmode);
2778                         /* Recursion occurs during execution phase */
2779                         pass = AT_PASS_ADD_COL;
2780                         break;
2781                 case AT_AddColumnToView:                /* add column via CREATE OR REPLACE
2782                                                                                  * VIEW */
2783                         ATSimplePermissions(rel, ATT_VIEW);
2784                         ATPrepAddColumn(wqueue, rel, recurse, recursing, cmd, lockmode);
2785                         /* Recursion occurs during execution phase */
2786                         pass = AT_PASS_ADD_COL;
2787                         break;
2788                 case AT_ColumnDefault:  /* ALTER COLUMN DEFAULT */
2789
2790                         /*
2791                          * We allow defaults on views so that INSERT into a view can have
2792                          * default-ish behavior.  This works because the rewriter
2793                          * substitutes default values into INSERTs before it expands
2794                          * rules.
2795                          */
2796                         ATSimplePermissions(rel, ATT_TABLE | ATT_VIEW);
2797                         ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
2798                         /* No command-specific prep needed */
2799                         pass = cmd->def ? AT_PASS_ADD_CONSTR : AT_PASS_DROP;
2800                         break;
2801                 case AT_DropNotNull:    /* ALTER COLUMN DROP NOT NULL */
2802                         ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE);
2803                         ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
2804                         /* No command-specific prep needed */
2805                         pass = AT_PASS_DROP;
2806                         break;
2807                 case AT_SetNotNull:             /* ALTER COLUMN SET NOT NULL */
2808                         ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE);
2809                         ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
2810                         /* No command-specific prep needed */
2811                         pass = AT_PASS_ADD_CONSTR;
2812                         break;
2813                 case AT_SetStatistics:  /* ALTER COLUMN SET STATISTICS */
2814                         ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
2815                         /* Performs own permission checks */
2816                         ATPrepSetStatistics(rel, cmd->name, cmd->def, lockmode);
2817                         pass = AT_PASS_MISC;
2818                         break;
2819                 case AT_SetOptions:             /* ALTER COLUMN SET ( options ) */
2820                 case AT_ResetOptions:   /* ALTER COLUMN RESET ( options ) */
2821                         ATSimplePermissions(rel, ATT_TABLE | ATT_INDEX);
2822                         /* This command never recurses */
2823                         pass = AT_PASS_MISC;
2824                         break;
2825                 case AT_SetStorage:             /* ALTER COLUMN SET STORAGE */
2826                         ATSimplePermissions(rel, ATT_TABLE);
2827                         ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
2828                         /* No command-specific prep needed */
2829                         pass = AT_PASS_MISC;
2830                         break;
2831                 case AT_DropColumn:             /* DROP COLUMN */
2832                         ATSimplePermissions(rel,
2833                                                  ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
2834                         ATPrepDropColumn(wqueue, rel, recurse, recursing, cmd, lockmode);
2835                         /* Recursion occurs during execution phase */
2836                         pass = AT_PASS_DROP;
2837                         break;
2838                 case AT_AddIndex:               /* ADD INDEX */
2839                         ATSimplePermissions(rel, ATT_TABLE);
2840                         /* This command never recurses */
2841                         /* No command-specific prep needed */
2842                         pass = AT_PASS_ADD_INDEX;
2843                         break;
2844                 case AT_AddConstraint:  /* ADD CONSTRAINT */
2845                         ATSimplePermissions(rel, ATT_TABLE);
2846                         /* Recursion occurs during execution phase */
2847                         /* No command-specific prep needed except saving recurse flag */
2848                         if (recurse)
2849                                 cmd->subtype = AT_AddConstraintRecurse;
2850                         pass = AT_PASS_ADD_CONSTR;
2851                         break;
2852                 case AT_AddIndexConstraint:             /* ADD CONSTRAINT USING INDEX */
2853                         ATSimplePermissions(rel, ATT_TABLE);
2854                         /* This command never recurses */
2855                         /* No command-specific prep needed */
2856                         pass = AT_PASS_ADD_CONSTR;
2857                         break;
2858                 case AT_DropConstraint: /* DROP CONSTRAINT */
2859                         ATSimplePermissions(rel, ATT_TABLE);
2860                         /* Recursion occurs during execution phase */
2861                         /* No command-specific prep needed except saving recurse flag */
2862                         if (recurse)
2863                                 cmd->subtype = AT_DropConstraintRecurse;
2864                         pass = AT_PASS_DROP;
2865                         break;
2866                 case AT_AlterColumnType:                /* ALTER COLUMN TYPE */
2867                         ATSimplePermissions(rel,
2868                                                  ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
2869                         /* Performs own recursion */
2870                         ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd, lockmode);
2871                         pass = AT_PASS_ALTER_TYPE;
2872                         break;
2873                 case AT_ChangeOwner:    /* ALTER OWNER */
2874                         /* This command never recurses */
2875                         /* No command-specific prep needed */
2876                         pass = AT_PASS_MISC;
2877                         break;
2878                 case AT_ClusterOn:              /* CLUSTER ON */
2879                 case AT_DropCluster:    /* SET WITHOUT CLUSTER */
2880                         ATSimplePermissions(rel, ATT_TABLE);
2881                         /* These commands never recurse */
2882                         /* No command-specific prep needed */
2883                         pass = AT_PASS_MISC;
2884                         break;
2885                 case AT_AddOids:                /* SET WITH OIDS */
2886                         ATSimplePermissions(rel, ATT_TABLE);
2887                         if (!rel->rd_rel->relhasoids || recursing)
2888                                 ATPrepAddOids(wqueue, rel, recurse, cmd, lockmode);
2889                         /* Recursion occurs during execution phase */
2890                         pass = AT_PASS_ADD_COL;
2891                         break;
2892                 case AT_DropOids:               /* SET WITHOUT OIDS */
2893                         ATSimplePermissions(rel, ATT_TABLE);
2894                         /* Performs own recursion */
2895                         if (rel->rd_rel->relhasoids)
2896                         {
2897                                 AlterTableCmd *dropCmd = makeNode(AlterTableCmd);
2898
2899                                 dropCmd->subtype = AT_DropColumn;
2900                                 dropCmd->name = pstrdup("oid");
2901                                 dropCmd->behavior = cmd->behavior;
2902                                 ATPrepCmd(wqueue, rel, dropCmd, recurse, false, lockmode);
2903                         }
2904                         pass = AT_PASS_DROP;
2905                         break;
2906                 case AT_SetTableSpace:  /* SET TABLESPACE */
2907                         ATSimplePermissions(rel, ATT_TABLE | ATT_INDEX);
2908                         /* This command never recurses */
2909                         ATPrepSetTableSpace(tab, rel, cmd->name, lockmode);
2910                         pass = AT_PASS_MISC;    /* doesn't actually matter */
2911                         break;
2912                 case AT_SetRelOptions:  /* SET (...) */
2913                 case AT_ResetRelOptions:                /* RESET (...) */
2914                         ATSimplePermissions(rel, ATT_TABLE | ATT_INDEX);
2915                         /* This command never recurses */
2916                         /* No command-specific prep needed */
2917                         pass = AT_PASS_MISC;
2918                         break;
2919                 case AT_AddInherit:             /* INHERIT */
2920                         ATSimplePermissions(rel, ATT_TABLE);
2921                         /* This command never recurses */
2922                         ATPrepAddInherit(rel);
2923                         pass = AT_PASS_MISC;
2924                         break;
2925                 case AT_ValidateConstraint:
2926                 case AT_EnableTrig:             /* ENABLE TRIGGER variants */
2927                 case AT_EnableAlwaysTrig:
2928                 case AT_EnableReplicaTrig:
2929                 case AT_EnableTrigAll:
2930                 case AT_EnableTrigUser:
2931                 case AT_DisableTrig:    /* DISABLE TRIGGER variants */
2932                 case AT_DisableTrigAll:
2933                 case AT_DisableTrigUser:
2934                 case AT_EnableRule:             /* ENABLE/DISABLE RULE variants */
2935                 case AT_EnableAlwaysRule:
2936                 case AT_EnableReplicaRule:
2937                 case AT_DisableRule:
2938                 case AT_DropInherit:    /* NO INHERIT */
2939                 case AT_AddOf:                  /* OF */
2940                 case AT_DropOf:                 /* NOT OF */
2941                         ATSimplePermissions(rel, ATT_TABLE);
2942                         /* These commands never recurse */
2943                         /* No command-specific prep needed */
2944                         pass = AT_PASS_MISC;
2945                         break;
2946                 case AT_GenericOptions:
2947                         ATSimplePermissions(rel, ATT_FOREIGN_TABLE);
2948                         /* No command-specific prep needed */
2949                         pass = AT_PASS_MISC;
2950                         break;
2951                 default:                                /* oops */
2952                         elog(ERROR, "unrecognized alter table type: %d",
2953                                  (int) cmd->subtype);
2954                         pass = 0;                       /* keep compiler quiet */
2955                         break;
2956         }
2957
2958         /* Add the subcommand to the appropriate list for phase 2 */
2959         tab->subcmds[pass] = lappend(tab->subcmds[pass], cmd);
2960 }
2961
2962 /*
2963  * ATRewriteCatalogs
2964  *
2965  * Traffic cop for ALTER TABLE Phase 2 operations.      Subcommands are
2966  * dispatched in a "safe" execution order (designed to avoid unnecessary
2967  * conflicts).
2968  */
2969 static void
2970 ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode)
2971 {
2972         int                     pass;
2973         ListCell   *ltab;
2974
2975         /*
2976          * We process all the tables "in parallel", one pass at a time.  This is
2977          * needed because we may have to propagate work from one table to another
2978          * (specifically, ALTER TYPE on a foreign key's PK has to dispatch the
2979          * re-adding of the foreign key constraint to the other table).  Work can
2980          * only be propagated into later passes, however.
2981          */
2982         for (pass = 0; pass < AT_NUM_PASSES; pass++)
2983         {
2984                 /* Go through each table that needs to be processed */
2985                 foreach(ltab, *wqueue)
2986                 {
2987                         AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
2988                         List       *subcmds = tab->subcmds[pass];
2989                         Relation        rel;
2990                         ListCell   *lcmd;
2991
2992                         if (subcmds == NIL)
2993                                 continue;
2994
2995                         /*
2996                          * Appropriate lock was obtained by phase 1, needn't get it again
2997                          */
2998                         rel = relation_open(tab->relid, NoLock);
2999
3000                         foreach(lcmd, subcmds)
3001                                 ATExecCmd(wqueue, tab, rel, (AlterTableCmd *) lfirst(lcmd), lockmode);
3002
3003                         /*
3004                          * After the ALTER TYPE pass, do cleanup work (this is not done in
3005                          * ATExecAlterColumnType since it should be done only once if
3006                          * multiple columns of a table are altered).
3007                          */
3008                         if (pass == AT_PASS_ALTER_TYPE)
3009                                 ATPostAlterTypeCleanup(wqueue, tab, lockmode);
3010
3011                         relation_close(rel, NoLock);
3012                 }
3013         }
3014
3015         /* Check to see if a toast table must be added. */
3016         foreach(ltab, *wqueue)
3017         {
3018                 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
3019
3020                 if (tab->relkind == RELKIND_RELATION)
3021                         AlterTableCreateToastTable(tab->relid, (Datum) 0);
3022         }
3023 }
3024
3025 /*
3026  * ATExecCmd: dispatch a subcommand to appropriate execution routine
3027  */
3028 static void
3029 ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
3030                   AlterTableCmd *cmd, LOCKMODE lockmode)
3031 {
3032         switch (cmd->subtype)
3033         {
3034                 case AT_AddColumn:              /* ADD COLUMN */
3035                 case AT_AddColumnToView:                /* add column via CREATE OR REPLACE
3036                                                                                  * VIEW */
3037                         ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3038                                                         false, false, false, lockmode);
3039                         break;
3040                 case AT_AddColumnRecurse:
3041                         ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3042                                                         false, true, false, lockmode);
3043                         break;
3044                 case AT_ColumnDefault:  /* ALTER COLUMN DEFAULT */
3045                         ATExecColumnDefault(rel, cmd->name, cmd->def, lockmode);
3046                         break;
3047                 case AT_DropNotNull:    /* ALTER COLUMN DROP NOT NULL */
3048                         ATExecDropNotNull(rel, cmd->name, lockmode);
3049                         break;
3050                 case AT_SetNotNull:             /* ALTER COLUMN SET NOT NULL */
3051                         ATExecSetNotNull(tab, rel, cmd->name, lockmode);
3052                         break;
3053                 case AT_SetStatistics:  /* ALTER COLUMN SET STATISTICS */
3054                         ATExecSetStatistics(rel, cmd->name, cmd->def, lockmode);
3055                         break;
3056                 case AT_SetOptions:             /* ALTER COLUMN SET ( options ) */
3057                         ATExecSetOptions(rel, cmd->name, cmd->def, false, lockmode);
3058                         break;
3059                 case AT_ResetOptions:   /* ALTER COLUMN RESET ( options ) */
3060                         ATExecSetOptions(rel, cmd->name, cmd->def, true, lockmode);
3061                         break;
3062                 case AT_SetStorage:             /* ALTER COLUMN SET STORAGE */
3063                         ATExecSetStorage(rel, cmd->name, cmd->def, lockmode);
3064                         break;
3065                 case AT_DropColumn:             /* DROP COLUMN */
3066                         ATExecDropColumn(wqueue, rel, cmd->name,
3067                                          cmd->behavior, false, false, cmd->missing_ok, lockmode);
3068                         break;
3069                 case AT_DropColumnRecurse:              /* DROP COLUMN with recursion */
3070                         ATExecDropColumn(wqueue, rel, cmd->name,
3071                                           cmd->behavior, true, false, cmd->missing_ok, lockmode);
3072                         break;
3073                 case AT_AddIndex:               /* ADD INDEX */
3074                         ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, false, lockmode);
3075                         break;
3076                 case AT_ReAddIndex:             /* ADD INDEX */
3077                         ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true, lockmode);
3078                         break;
3079                 case AT_AddConstraint:  /* ADD CONSTRAINT */
3080                         ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
3081                                                                 false, lockmode);
3082                         break;
3083                 case AT_AddConstraintRecurse:   /* ADD CONSTRAINT with recursion */
3084                         ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
3085                                                                 true, lockmode);
3086                         break;
3087                 case AT_AddIndexConstraint:             /* ADD CONSTRAINT USING INDEX */
3088                         ATExecAddIndexConstraint(tab, rel, (IndexStmt *) cmd->def, lockmode);
3089                         break;
3090                 case AT_ValidateConstraint:
3091                         ATExecValidateConstraint(rel, cmd->name);
3092                         break;
3093                 case AT_DropConstraint: /* DROP CONSTRAINT */
3094                         ATExecDropConstraint(rel, cmd->name, cmd->behavior,
3095                                                                  false, false,
3096                                                                  cmd->missing_ok, lockmode);
3097                         break;
3098                 case AT_DropConstraintRecurse:  /* DROP CONSTRAINT with recursion */
3099                         ATExecDropConstraint(rel, cmd->name, cmd->behavior,
3100                                                                  true, false,
3101                                                                  cmd->missing_ok, lockmode);
3102                         break;
3103                 case AT_AlterColumnType:                /* ALTER COLUMN TYPE */
3104                         ATExecAlterColumnType(tab, rel, cmd, lockmode);
3105                         break;
3106                 case AT_ChangeOwner:    /* ALTER OWNER */
3107                         ATExecChangeOwner(RelationGetRelid(rel),
3108                                                           get_role_oid(cmd->name, false),
3109                                                           false, lockmode);
3110                         break;
3111                 case AT_ClusterOn:              /* CLUSTER ON */
3112                         ATExecClusterOn(rel, cmd->name, lockmode);
3113                         break;
3114                 case AT_DropCluster:    /* SET WITHOUT CLUSTER */
3115                         ATExecDropCluster(rel, lockmode);
3116                         break;
3117                 case AT_AddOids:                /* SET WITH OIDS */
3118                         /* Use the ADD COLUMN code, unless prep decided to do nothing */
3119                         if (cmd->def != NULL)
3120                                 ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3121                                                                 true, false, false, lockmode);
3122                         break;
3123                 case AT_AddOidsRecurse: /* SET WITH OIDS */
3124                         /* Use the ADD COLUMN code, unless prep decided to do nothing */
3125                         if (cmd->def != NULL)
3126                                 ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
3127                                                                 true, true, false, lockmode);
3128                         break;
3129                 case AT_DropOids:               /* SET WITHOUT OIDS */
3130
3131                         /*
3132                          * Nothing to do here; we'll have generated a DropColumn
3133                          * subcommand to do the real work
3134                          */
3135                         break;
3136                 case AT_SetTableSpace:  /* SET TABLESPACE */
3137
3138                         /*
3139                          * Nothing to do here; Phase 3 does the work
3140                          */
3141                         break;
3142                 case AT_SetRelOptions:  /* SET (...) */
3143                         ATExecSetRelOptions(rel, (List *) cmd->def, false, lockmode);
3144                         break;
3145                 case AT_ResetRelOptions:                /* RESET (...) */
3146                         ATExecSetRelOptions(rel, (List *) cmd->def, true, lockmode);
3147                         break;
3148
3149                 case AT_EnableTrig:             /* ENABLE TRIGGER name */
3150                         ATExecEnableDisableTrigger(rel, cmd->name,
3151                                                                    TRIGGER_FIRES_ON_ORIGIN, false, lockmode);
3152                         break;
3153                 case AT_EnableAlwaysTrig:               /* ENABLE ALWAYS TRIGGER name */
3154                         ATExecEnableDisableTrigger(rel, cmd->name,
3155                                                                            TRIGGER_FIRES_ALWAYS, false, lockmode);
3156                         break;
3157                 case AT_EnableReplicaTrig:              /* ENABLE REPLICA TRIGGER name */
3158                         ATExecEnableDisableTrigger(rel, cmd->name,
3159                                                                   TRIGGER_FIRES_ON_REPLICA, false, lockmode);
3160                         break;
3161                 case AT_DisableTrig:    /* DISABLE TRIGGER name */
3162                         ATExecEnableDisableTrigger(rel, cmd->name,
3163                                                                            TRIGGER_DISABLED, false, lockmode);
3164                         break;
3165                 case AT_EnableTrigAll:  /* ENABLE TRIGGER ALL */
3166                         ATExecEnableDisableTrigger(rel, NULL,
3167                                                                    TRIGGER_FIRES_ON_ORIGIN, false, lockmode);
3168                         break;
3169                 case AT_DisableTrigAll: /* DISABLE TRIGGER ALL */
3170                         ATExecEnableDisableTrigger(rel, NULL,
3171                                                                            TRIGGER_DISABLED, false, lockmode);
3172                         break;
3173                 case AT_EnableTrigUser: /* ENABLE TRIGGER USER */
3174                         ATExecEnableDisableTrigger(rel, NULL,
3175                                                                         TRIGGER_FIRES_ON_ORIGIN, true, lockmode);
3176                         break;
3177                 case AT_DisableTrigUser:                /* DISABLE TRIGGER USER */
3178                         ATExecEnableDisableTrigger(rel, NULL,
3179                                                                            TRIGGER_DISABLED, true, lockmode);
3180                         break;
3181
3182                 case AT_EnableRule:             /* ENABLE RULE name */
3183                         ATExecEnableDisableRule(rel, cmd->name,
3184                                                                         RULE_FIRES_ON_ORIGIN, lockmode);
3185                         break;
3186                 case AT_EnableAlwaysRule:               /* ENABLE ALWAYS RULE name */
3187                         ATExecEnableDisableRule(rel, cmd->name,
3188                                                                         RULE_FIRES_ALWAYS, lockmode);
3189                         break;
3190                 case AT_EnableReplicaRule:              /* ENABLE REPLICA RULE name */
3191                         ATExecEnableDisableRule(rel, cmd->name,
3192                                                                         RULE_FIRES_ON_REPLICA, lockmode);
3193                         break;
3194                 case AT_DisableRule:    /* DISABLE RULE name */
3195                         ATExecEnableDisableRule(rel, cmd->name,
3196                                                                         RULE_DISABLED, lockmode);
3197                         break;
3198
3199                 case AT_AddInherit:
3200                         ATExecAddInherit(rel, (RangeVar *) cmd->def, lockmode);
3201                         break;
3202                 case AT_DropInherit:
3203                         ATExecDropInherit(rel, (RangeVar *) cmd->def, lockmode);
3204                         break;
3205                 case AT_AddOf:
3206                         ATExecAddOf(rel, (TypeName *) cmd->def, lockmode);
3207                         break;
3208                 case AT_DropOf:
3209                         ATExecDropOf(rel, lockmode);
3210                         break;
3211                 case AT_GenericOptions:
3212                         ATExecGenericOptions(rel, (List *) cmd->def);
3213                         break;
3214                 default:                                /* oops */
3215                         elog(ERROR, "unrecognized alter table type: %d",
3216                                  (int) cmd->subtype);
3217                         break;
3218         }
3219
3220         /*
3221          * Bump the command counter to ensure the next subcommand in the sequence
3222          * can see the changes so far
3223          */
3224         CommandCounterIncrement();
3225 }
3226
3227 /*
3228  * ATRewriteTables: ALTER TABLE phase 3
3229  */
3230 static void
3231 ATRewriteTables(List **wqueue, LOCKMODE lockmode)
3232 {
3233         ListCell   *ltab;
3234
3235         /* Go through each table that needs to be checked or rewritten */
3236         foreach(ltab, *wqueue)
3237         {
3238                 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
3239
3240                 /* Foreign tables have no storage. */
3241                 if (tab->relkind == RELKIND_FOREIGN_TABLE)
3242                         continue;
3243
3244                 /*
3245                  * If we change column data types or add/remove OIDs, the operation
3246                  * has to be propagated to tables that use this table's rowtype as a
3247                  * column type.  tab->newvals will also be non-NULL in the case where
3248                  * we're adding a column with a default.  We choose to forbid that
3249                  * case as well, since composite types might eventually support
3250                  * defaults.
3251                  *
3252                  * (Eventually we'll probably need to check for composite type
3253                  * dependencies even when we're just scanning the table without a
3254                  * rewrite, but at the moment a composite type does not enforce any
3255                  * constraints, so it's not necessary/appropriate to enforce them just
3256                  * during ALTER.)
3257                  */
3258                 if (tab->newvals != NIL || tab->rewrite)
3259                 {
3260                         Relation        rel;
3261
3262                         rel = heap_open(tab->relid, NoLock);
3263                         find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
3264                         heap_close(rel, NoLock);
3265                 }
3266
3267                 /*
3268                  * We only need to rewrite the table if at least one column needs to
3269                  * be recomputed, or we are adding/removing the OID column.
3270                  */
3271                 if (tab->rewrite)
3272                 {
3273                         /* Build a temporary relation and copy data */
3274                         Relation        OldHeap;
3275                         Oid                     OIDNewHeap;
3276                         Oid                     NewTableSpace;
3277
3278                         OldHeap = heap_open(tab->relid, NoLock);
3279
3280                         /*
3281                          * We don't support rewriting of system catalogs; there are too
3282                          * many corner cases and too little benefit.  In particular this
3283                          * is certainly not going to work for mapped catalogs.
3284                          */
3285                         if (IsSystemRelation(OldHeap))
3286                                 ereport(ERROR,
3287                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3288                                                  errmsg("cannot rewrite system relation \"%s\"",
3289                                                                 RelationGetRelationName(OldHeap))));
3290
3291                         /*
3292                          * Don't allow rewrite on temp tables of other backends ... their
3293                          * local buffer manager is not going to cope.
3294                          */
3295                         if (RELATION_IS_OTHER_TEMP(OldHeap))
3296                                 ereport(ERROR,
3297                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3298                                 errmsg("cannot rewrite temporary tables of other sessions")));
3299
3300                         /*
3301                          * Select destination tablespace (same as original unless user
3302                          * requested a change)
3303                          */
3304                         if (tab->newTableSpace)
3305                                 NewTableSpace = tab->newTableSpace;
3306                         else
3307                                 NewTableSpace = OldHeap->rd_rel->reltablespace;
3308
3309                         heap_close(OldHeap, NoLock);
3310
3311                         /* Create transient table that will receive the modified data */
3312                         OIDNewHeap = make_new_heap(tab->relid, NewTableSpace);
3313
3314                         /*
3315                          * Copy the heap data into the new table with the desired
3316                          * modifications, and test the current data within the table
3317                          * against new constraints generated by ALTER TABLE commands.
3318                          */
3319                         ATRewriteTable(tab, OIDNewHeap, lockmode);
3320
3321                         /*
3322                          * Swap the physical files of the old and new heaps, then rebuild
3323                          * indexes and discard the old heap.  We can use RecentXmin for
3324                          * the table's new relfrozenxid because we rewrote all the tuples
3325                          * in ATRewriteTable, so no older Xid remains in the table.  Also,
3326                          * we never try to swap toast tables by content, since we have no
3327                          * interest in letting this code work on system catalogs.
3328                          */
3329                         finish_heap_swap(tab->relid, OIDNewHeap,
3330                                                          false, false, true, RecentXmin);
3331                 }
3332                 else
3333                 {
3334                         /*
3335                          * Test the current data within the table against new constraints
3336                          * generated by ALTER TABLE commands, but don't rebuild data.
3337                          */
3338                         if (tab->constraints != NIL || tab->new_notnull)
3339                                 ATRewriteTable(tab, InvalidOid, lockmode);
3340
3341                         /*
3342                          * If we had SET TABLESPACE but no reason to reconstruct tuples,
3343                          * just do a block-by-block copy.
3344                          */
3345                         if (tab->newTableSpace)
3346                                 ATExecSetTableSpace(tab->relid, tab->newTableSpace, lockmode);
3347                 }
3348         }
3349
3350         /*
3351          * Foreign key constraints are checked in a final pass, since (a) it's
3352          * generally best to examine each one separately, and (b) it's at least
3353          * theoretically possible that we have changed both relations of the
3354          * foreign key, and we'd better have finished both rewrites before we try
3355          * to read the tables.
3356          */
3357         foreach(ltab, *wqueue)
3358         {
3359                 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
3360                 Relation        rel = NULL;
3361                 ListCell   *lcon;
3362
3363                 foreach(lcon, tab->constraints)
3364                 {
3365                         NewConstraint *con = lfirst(lcon);
3366
3367                         if (con->contype == CONSTR_FOREIGN)
3368                         {
3369                                 Constraint *fkconstraint = (Constraint *) con->qual;
3370                                 Relation        refrel;
3371
3372                                 if (rel == NULL)
3373                                         /* Long since locked, no need for another */
3374                                         rel = heap_open(tab->relid, NoLock);
3375
3376                                 /*
3377                                  * We're adding a trigger to both tables, so the lock level
3378                                  * here should sensibly reflect that.
3379                                  */
3380                                 refrel = heap_open(con->refrelid, ShareRowExclusiveLock);
3381
3382                                 validateForeignKeyConstraint(fkconstraint->conname, rel, refrel,
3383                                                                                          con->refindid,
3384                                                                                          con->conid);
3385
3386                                 /*
3387                                  * No need to mark the constraint row as validated, we did
3388                                  * that when we inserted the row earlier.
3389                                  */
3390
3391                                 heap_close(refrel, NoLock);
3392                         }
3393                 }
3394
3395                 if (rel)
3396                         heap_close(rel, NoLock);
3397         }
3398 }
3399
3400 /*
3401  * ATRewriteTable: scan or rewrite one table
3402  *
3403  * OIDNewHeap is InvalidOid if we don't need to rewrite
3404  */
3405 static void
3406 ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
3407 {
3408         Relation        oldrel;
3409         Relation        newrel;
3410         TupleDesc       oldTupDesc;
3411         TupleDesc       newTupDesc;
3412         bool            needscan = false;
3413         List       *notnull_attrs;
3414         int                     i;
3415         ListCell   *l;
3416         EState     *estate;
3417         CommandId       mycid;
3418         BulkInsertState bistate;
3419         int                     hi_options;
3420
3421         /*
3422          * Open the relation(s).  We have surely already locked the existing
3423          * table.
3424          */
3425         oldrel = heap_open(tab->relid, NoLock);
3426         oldTupDesc = tab->oldDesc;
3427         newTupDesc = RelationGetDescr(oldrel);          /* includes all mods */
3428
3429         if (OidIsValid(OIDNewHeap))
3430                 newrel = heap_open(OIDNewHeap, lockmode);
3431         else
3432                 newrel = NULL;
3433
3434         /*
3435          * Prepare a BulkInsertState and options for heap_insert. Because we're
3436          * building a new heap, we can skip WAL-logging and fsync it to disk at
3437          * the end instead (unless WAL-logging is required for archiving or
3438          * streaming replication). The FSM is empty too, so don't bother using it.
3439          */
3440         if (newrel)
3441         {
3442                 mycid = GetCurrentCommandId(true);
3443                 bistate = GetBulkInsertState();
3444
3445                 hi_options = HEAP_INSERT_SKIP_FSM;
3446                 if (!XLogIsNeeded())
3447                         hi_options |= HEAP_INSERT_SKIP_WAL;
3448         }
3449         else
3450         {
3451                 /* keep compiler quiet about using these uninitialized */
3452                 mycid = 0;
3453                 bistate = NULL;
3454                 hi_options = 0;
3455         }
3456
3457         /*
3458          * Generate the constraint and default execution states
3459          */
3460
3461         estate = CreateExecutorState();
3462
3463         /* Build the needed expression execution states */
3464         foreach(l, tab->constraints)
3465         {
3466                 NewConstraint *con = lfirst(l);
3467
3468                 switch (con->contype)
3469                 {
3470                         case CONSTR_CHECK:
3471                                 needscan = true;
3472                                 con->qualstate = (List *)
3473                                         ExecPrepareExpr((Expr *) con->qual, estate);
3474                                 break;
3475                         case CONSTR_FOREIGN:
3476                                 /* Nothing to do here */
3477                                 break;
3478                         default:
3479                                 elog(ERROR, "unrecognized constraint type: %d",
3480                                          (int) con->contype);
3481                 }
3482         }
3483
3484         foreach(l, tab->newvals)
3485         {
3486                 NewColumnValue *ex = lfirst(l);
3487
3488                 ex->exprstate = ExecPrepareExpr((Expr *) ex->expr, estate);
3489         }
3490
3491         notnull_attrs = NIL;
3492         if (newrel || tab->new_notnull)
3493         {
3494                 /*
3495                  * If we are rebuilding the tuples OR if we added any new NOT NULL
3496                  * constraints, check all not-null constraints.  This is a bit of
3497                  * overkill but it minimizes risk of bugs, and heap_attisnull is a
3498                  * pretty cheap test anyway.
3499                  */
3500                 for (i = 0; i < newTupDesc->natts; i++)
3501                 {
3502                         if (newTupDesc->attrs[i]->attnotnull &&
3503                                 !newTupDesc->attrs[i]->attisdropped)
3504                                 notnull_attrs = lappend_int(notnull_attrs, i);
3505                 }
3506                 if (notnull_attrs)
3507                         needscan = true;
3508         }
3509
3510         if (newrel || needscan)
3511         {
3512                 ExprContext *econtext;
3513                 Datum      *values;
3514                 bool       *isnull;
3515                 TupleTableSlot *oldslot;
3516                 TupleTableSlot *newslot;
3517                 HeapScanDesc scan;
3518                 HeapTuple       tuple;
3519                 MemoryContext oldCxt;
3520                 List       *dropped_attrs = NIL;
3521                 ListCell   *lc;
3522
3523                 if (newrel)
3524                         ereport(DEBUG1,
3525                                         (errmsg("rewriting table \"%s\"",
3526                                                         RelationGetRelationName(oldrel))));
3527                 else
3528                         ereport(DEBUG1,
3529                                         (errmsg("verifying table \"%s\"",
3530                                                         RelationGetRelationName(oldrel))));
3531
3532                 econtext = GetPerTupleExprContext(estate);
3533
3534                 /*
3535                  * Make tuple slots for old and new tuples.  Note that even when the
3536                  * tuples are the same, the tupDescs might not be (consider ADD COLUMN
3537                  * without a default).
3538                  */
3539                 oldslot = MakeSingleTupleTableSlot(oldTupDesc);
3540                 newslot = MakeSingleTupleTableSlot(newTupDesc);
3541
3542                 /* Preallocate values/isnull arrays */
3543                 i = Max(newTupDesc->natts, oldTupDesc->natts);
3544                 values = (Datum *) palloc(i * sizeof(Datum));
3545                 isnull = (bool *) palloc(i * sizeof(bool));
3546                 memset(values, 0, i * sizeof(Datum));
3547                 memset(isnull, true, i * sizeof(bool));
3548
3549                 /*
3550                  * Any attributes that are dropped according to the new tuple
3551                  * descriptor can be set to NULL. We precompute the list of dropped
3552                  * attributes to avoid needing to do so in the per-tuple loop.
3553                  */
3554                 for (i = 0; i < newTupDesc->natts; i++)
3555                 {
3556                         if (newTupDesc->attrs[i]->attisdropped)
3557                                 dropped_attrs = lappend_int(dropped_attrs, i);
3558                 }
3559
3560                 /*
3561                  * Scan through the rows, generating a new row if needed and then
3562                  * checking all the constraints.
3563                  */
3564                 scan = heap_beginscan(oldrel, SnapshotNow, 0, NULL);
3565
3566                 /*
3567                  * Switch to per-tuple memory context and reset it for each tuple
3568                  * produced, so we don't leak memory.
3569                  */
3570                 oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
3571
3572                 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
3573                 {
3574                         if (tab->rewrite)
3575                         {
3576                                 Oid                     tupOid = InvalidOid;
3577
3578                                 /* Extract data from old tuple */
3579                                 heap_deform_tuple(tuple, oldTupDesc, values, isnull);
3580                                 if (oldTupDesc->tdhasoid)
3581                                         tupOid = HeapTupleGetOid(tuple);
3582
3583                                 /* Set dropped attributes to null in new tuple */
3584                                 foreach(lc, dropped_attrs)
3585                                         isnull[lfirst_int(lc)] = true;
3586
3587                                 /*
3588                                  * Process supplied expressions to replace selected columns.
3589                                  * Expression inputs come from the old tuple.
3590                                  */
3591                                 ExecStoreTuple(tuple, oldslot, InvalidBuffer, false);
3592                                 econtext->ecxt_scantuple = oldslot;
3593
3594                                 foreach(l, tab->newvals)
3595                                 {
3596                                         NewColumnValue *ex = lfirst(l);
3597
3598                                         values[ex->attnum - 1] = ExecEvalExpr(ex->exprstate,
3599                                                                                                                   econtext,
3600                                                                                                          &isnull[ex->attnum - 1],
3601                                                                                                                   NULL);
3602                                 }
3603
3604                                 /*
3605                                  * Form the new tuple. Note that we don't explicitly pfree it,
3606                                  * since the per-tuple memory context will be reset shortly.
3607                                  */
3608                                 tuple = heap_form_tuple(newTupDesc, values, isnull);
3609
3610                                 /* Preserve OID, if any */
3611                                 if (newTupDesc->tdhasoid)
3612                                         HeapTupleSetOid(tuple, tupOid);
3613                         }
3614
3615                         /* Now check any constraints on the possibly-changed tuple */
3616                         ExecStoreTuple(tuple, newslot, InvalidBuffer, false);
3617                         econtext->ecxt_scantuple = newslot;
3618
3619                         foreach(l, notnull_attrs)
3620                         {
3621                                 int                     attn = lfirst_int(l);
3622
3623                                 if (heap_attisnull(tuple, attn + 1))
3624                                         ereport(ERROR,
3625                                                         (errcode(ERRCODE_NOT_NULL_VIOLATION),
3626                                                          errmsg("column \"%s\" contains null values",
3627                                                                 NameStr(newTupDesc->attrs[attn]->attname))));
3628                         }
3629
3630                         foreach(l, tab->constraints)
3631                         {
3632                                 NewConstraint *con = lfirst(l);
3633
3634                                 switch (con->contype)
3635                                 {
3636                                         case CONSTR_CHECK:
3637                                                 if (!ExecQual(con->qualstate, econtext, true))
3638                                                         ereport(ERROR,
3639                                                                         (errcode(ERRCODE_CHECK_VIOLATION),
3640                                                                          errmsg("check constraint \"%s\" is violated by some row",
3641                                                                                         con->name)));
3642                                                 break;
3643                                         case CONSTR_FOREIGN:
3644                                                 /* Nothing to do here */
3645                                                 break;
3646                                         default:
3647                                                 elog(ERROR, "unrecognized constraint type: %d",
3648                                                          (int) con->contype);
3649                                 }
3650                         }
3651
3652                         /* Write the tuple out to the new relation */
3653                         if (newrel)
3654                                 heap_insert(newrel, tuple, mycid, hi_options, bistate);
3655
3656                         ResetExprContext(econtext);
3657
3658                         CHECK_FOR_INTERRUPTS();
3659                 }
3660
3661                 MemoryContextSwitchTo(oldCxt);
3662                 heap_endscan(scan);
3663
3664                 ExecDropSingleTupleTableSlot(oldslot);
3665                 ExecDropSingleTupleTableSlot(newslot);
3666         }
3667
3668         FreeExecutorState(estate);
3669
3670         heap_close(oldrel, NoLock);
3671         if (newrel)
3672         {
3673                 FreeBulkInsertState(bistate);
3674
3675                 /* If we skipped writing WAL, then we need to sync the heap. */
3676                 if (hi_options & HEAP_INSERT_SKIP_WAL)
3677                         heap_sync(newrel);
3678
3679                 heap_close(newrel, NoLock);
3680         }
3681 }
3682
3683 /*
3684  * ATGetQueueEntry: find or create an entry in the ALTER TABLE work queue
3685  */
3686 static AlteredTableInfo *
3687 ATGetQueueEntry(List **wqueue, Relation rel)
3688 {
3689         Oid                     relid = RelationGetRelid(rel);
3690         AlteredTableInfo *tab;
3691         ListCell   *ltab;
3692
3693         foreach(ltab, *wqueue)
3694         {
3695                 tab = (AlteredTableInfo *) lfirst(ltab);
3696                 if (tab->relid == relid)
3697                         return tab;
3698         }
3699
3700         /*
3701          * Not there, so add it.  Note that we make a copy of the relation's
3702          * existing descriptor before anything interesting can happen to it.
3703          */
3704         tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo));
3705         tab->relid = relid;
3706         tab->relkind = rel->rd_rel->relkind;
3707         tab->oldDesc = CreateTupleDescCopy(RelationGetDescr(rel));
3708
3709         *wqueue = lappend(*wqueue, tab);
3710
3711         return tab;
3712 }
3713
3714 /*
3715  * ATSimplePermissions
3716  *
3717  * - Ensure that it is a relation (or possibly a view)
3718  * - Ensure this user is the owner
3719  * - Ensure that it is not a system table
3720  */
3721 static void
3722 ATSimplePermissions(Relation rel, int allowed_targets)
3723 {
3724         int                     actual_target;
3725
3726         switch (rel->rd_rel->relkind)
3727         {
3728                 case RELKIND_RELATION:
3729                         actual_target = ATT_TABLE;
3730                         break;
3731                 case RELKIND_VIEW:
3732                         actual_target = ATT_VIEW;
3733                         break;
3734                 case RELKIND_INDEX:
3735                         actual_target = ATT_INDEX;
3736                         break;
3737                 case RELKIND_COMPOSITE_TYPE:
3738                         actual_target = ATT_COMPOSITE_TYPE;
3739                         break;
3740                 case RELKIND_FOREIGN_TABLE:
3741                         actual_target = ATT_FOREIGN_TABLE;
3742                         break;
3743                 default:
3744                         actual_target = 0;
3745                         break;
3746         }
3747
3748         /* Wrong target type? */
3749         if ((actual_target & allowed_targets) == 0)
3750                 ATWrongRelkindError(rel, allowed_targets);
3751
3752         /* Permissions checks */
3753         if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
3754                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
3755                                            RelationGetRelationName(rel));
3756
3757         if (!allowSystemTableMods && IsSystemRelation(rel))
3758                 ereport(ERROR,
3759                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3760                                  errmsg("permission denied: \"%s\" is a system catalog",
3761                                                 RelationGetRelationName(rel))));
3762 }
3763
3764 /*
3765  * ATWrongRelkindError
3766  *
3767  * Throw an error when a relation has been determined to be of the wrong
3768  * type.
3769  */
3770 static void
3771 ATWrongRelkindError(Relation rel, int allowed_targets)
3772 {
3773         char       *msg;
3774
3775         switch (allowed_targets)
3776         {
3777                 case ATT_TABLE:
3778                         msg = _("\"%s\" is not a table");
3779                         break;
3780                 case ATT_TABLE | ATT_INDEX:
3781                         msg = _("\"%s\" is not a table or index");
3782                         break;
3783                 case ATT_TABLE | ATT_VIEW:
3784                         msg = _("\"%s\" is not a table or view");
3785                         break;
3786                 case ATT_TABLE | ATT_FOREIGN_TABLE:
3787                         msg = _("\"%s\" is not a table or foreign table");
3788                         break;
3789                 case ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE:
3790                         msg = _("\"%s\" is not a table, composite type, or foreign table");
3791                         break;
3792                 case ATT_VIEW:
3793                         msg = _("\"%s\" is not a view");
3794                         break;
3795                 case ATT_FOREIGN_TABLE:
3796                         msg = _("\"%s\" is not a foreign table");
3797                         break;
3798                 default:
3799                         /* shouldn't get here, add all necessary cases above */
3800                         msg = _("\"%s\" is of the wrong type");
3801                         break;
3802         }
3803
3804         ereport(ERROR,
3805                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
3806                          errmsg(msg, RelationGetRelationName(rel))));
3807 }
3808
3809 /*
3810  * ATSimpleRecursion
3811  *
3812  * Simple table recursion sufficient for most ALTER TABLE operations.
3813  * All direct and indirect children are processed in an unspecified order.
3814  * Note that if a child inherits from the original table via multiple
3815  * inheritance paths, it will be visited just once.
3816  */
3817 static void
3818 ATSimpleRecursion(List **wqueue, Relation rel,
3819                                   AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode)
3820 {
3821         /*
3822          * Propagate to children if desired.  Non-table relations never have
3823          * children, so no need to search in that case.
3824          */
3825         if (recurse && rel->rd_rel->relkind == RELKIND_RELATION)
3826         {
3827                 Oid                     relid = RelationGetRelid(rel);
3828                 ListCell   *child;
3829                 List       *children;
3830
3831                 children = find_all_inheritors(relid, lockmode, NULL);
3832
3833                 /*
3834                  * find_all_inheritors does the recursive search of the inheritance
3835                  * hierarchy, so all we have to do is process all of the relids in the
3836                  * list that it returns.
3837                  */
3838                 foreach(child, children)
3839                 {
3840                         Oid                     childrelid = lfirst_oid(child);
3841                         Relation        childrel;
3842
3843                         if (childrelid == relid)
3844                                 continue;
3845                         /* find_all_inheritors already got lock */
3846                         childrel = relation_open(childrelid, NoLock);
3847                         CheckTableNotInUse(childrel, "ALTER TABLE");
3848                         ATPrepCmd(wqueue, childrel, cmd, false, true, lockmode);
3849                         relation_close(childrel, NoLock);
3850                 }
3851         }
3852 }
3853
3854 /*
3855  * ATTypedTableRecursion
3856  *
3857  * Propagate ALTER TYPE operations to the typed tables of that type.
3858  * Also check the RESTRICT/CASCADE behavior.  Given CASCADE, also permit
3859  * recursion to inheritance children of the typed tables.
3860  */
3861 static void
3862 ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
3863                                           LOCKMODE lockmode)
3864 {
3865         ListCell   *child;
3866         List       *children;
3867
3868         Assert(rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE);
3869
3870         children = find_typed_table_dependencies(rel->rd_rel->reltype,
3871                                                                                          RelationGetRelationName(rel),
3872                                                                                          cmd->behavior);
3873
3874         foreach(child, children)
3875         {
3876                 Oid                     childrelid = lfirst_oid(child);
3877                 Relation        childrel;
3878
3879                 childrel = relation_open(childrelid, lockmode);
3880                 CheckTableNotInUse(childrel, "ALTER TABLE");
3881                 ATPrepCmd(wqueue, childrel, cmd, true, true, lockmode);
3882                 relation_close(childrel, NoLock);
3883         }
3884 }
3885
3886
3887 /*
3888  * find_composite_type_dependencies
3889  *
3890  * Check to see if a composite type is being used as a column in some
3891  * other table (possibly nested several levels deep in composite types!).
3892  * Eventually, we'd like to propagate the check or rewrite operation
3893  * into other such tables, but for now, just error out if we find any.
3894  *
3895  * Caller should provide either a table name or a type name (not both) to
3896  * report in the error message, if any.
3897  *
3898  * We assume that functions and views depending on the type are not reasons
3899  * to reject the ALTER.  (How safe is this really?)
3900  */
3901 void
3902 find_composite_type_dependencies(Oid typeOid, Relation origRelation,
3903                                                                  const char *origTypeName)
3904 {
3905         Relation        depRel;
3906         ScanKeyData key[2];
3907         SysScanDesc depScan;
3908         HeapTuple       depTup;
3909         Oid                     arrayOid;
3910
3911         /*
3912          * We scan pg_depend to find those things that depend on the rowtype. (We
3913          * assume we can ignore refobjsubid for a rowtype.)
3914          */
3915         depRel = heap_open(DependRelationId, AccessShareLock);
3916
3917         ScanKeyInit(&key[0],
3918                                 Anum_pg_depend_refclassid,
3919                                 BTEqualStrategyNumber, F_OIDEQ,
3920                                 ObjectIdGetDatum(TypeRelationId));
3921         ScanKeyInit(&key[1],
3922                                 Anum_pg_depend_refobjid,
3923                                 BTEqualStrategyNumber, F_OIDEQ,
3924                                 ObjectIdGetDatum(typeOid));
3925
3926         depScan = systable_beginscan(depRel, DependReferenceIndexId, true,
3927                                                                  SnapshotNow, 2, key);
3928
3929         while (HeapTupleIsValid(depTup = systable_getnext(depScan)))
3930         {
3931                 Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
3932                 Relation        rel;
3933                 Form_pg_attribute att;
3934
3935                 /* Ignore dependees that aren't user columns of relations */
3936                 /* (we assume system columns are never of rowtypes) */
3937                 if (pg_depend->classid != RelationRelationId ||
3938                         pg_depend->objsubid <= 0)
3939                         continue;
3940
3941                 rel = relation_open(pg_depend->objid, AccessShareLock);
3942                 att = rel->rd_att->attrs[pg_depend->objsubid - 1];
3943
3944                 if (rel->rd_rel->relkind == RELKIND_RELATION)
3945                 {
3946                         if (origTypeName)
3947                                 ereport(ERROR,
3948                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3949                                                  errmsg("cannot alter type \"%s\" because column \"%s\".\"%s\" uses it",
3950                                                                 origTypeName,
3951                                                                 RelationGetRelationName(rel),
3952                                                                 NameStr(att->attname))));
3953                         else if (origRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
3954                                 ereport(ERROR,
3955                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3956                                                  errmsg("cannot alter type \"%s\" because column \"%s\".\"%s\" uses it",
3957                                                                 RelationGetRelationName(origRelation),
3958                                                                 RelationGetRelationName(rel),
3959                                                                 NameStr(att->attname))));
3960                         else if (origRelation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
3961                                 ereport(ERROR,
3962                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3963                                                  errmsg("cannot alter foreign table \"%s\" because column \"%s\".\"%s\" uses its rowtype",
3964                                                                 RelationGetRelationName(origRelation),
3965                                                                 RelationGetRelationName(rel),
3966                                                                 NameStr(att->attname))));
3967                         else
3968                                 ereport(ERROR,
3969                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3970                                                  errmsg("cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype",
3971                                                                 RelationGetRelationName(origRelation),
3972                                                                 RelationGetRelationName(rel),
3973                                                                 NameStr(att->attname))));
3974                 }
3975                 else if (OidIsValid(rel->rd_rel->reltype))
3976                 {
3977                         /*
3978                          * A view or composite type itself isn't a problem, but we must
3979                          * recursively check for indirect dependencies via its rowtype.
3980                          */
3981                         find_composite_type_dependencies(rel->rd_rel->reltype,
3982                                                                                          origRelation, origTypeName);
3983                 }
3984
3985                 relation_close(rel, AccessShareLock);
3986         }
3987
3988         systable_endscan(depScan);
3989
3990         relation_close(depRel, AccessShareLock);
3991
3992         /*
3993          * If there's an array type for the rowtype, must check for uses of it,
3994          * too.
3995          */
3996         arrayOid = get_array_type(typeOid);
3997         if (OidIsValid(arrayOid))
3998                 find_composite_type_dependencies(arrayOid, origRelation, origTypeName);
3999 }
4000
4001
4002 /*
4003  * find_typed_table_dependencies
4004  *
4005  * Check to see if a composite type is being used as the type of a
4006  * typed table.  Abort if any are found and behavior is RESTRICT.
4007  * Else return the list of tables.
4008  */
4009 static List *
4010 find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior behavior)
4011 {
4012         Relation        classRel;
4013         ScanKeyData key[1];
4014         HeapScanDesc scan;
4015         HeapTuple       tuple;
4016         List       *result = NIL;
4017
4018         classRel = heap_open(RelationRelationId, AccessShareLock);
4019
4020         ScanKeyInit(&key[0],
4021                                 Anum_pg_class_reloftype,
4022                                 BTEqualStrategyNumber, F_OIDEQ,
4023                                 ObjectIdGetDatum(typeOid));
4024
4025         scan = heap_beginscan(classRel, SnapshotNow, 1, key);
4026
4027         while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
4028         {
4029                 if (behavior == DROP_RESTRICT)
4030                         ereport(ERROR,
4031                                         (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
4032                                          errmsg("cannot alter type \"%s\" because it is the type of a typed table",
4033                                                         typeName),
4034                         errhint("Use ALTER ... CASCADE to alter the typed tables too.")));
4035                 else
4036                         result = lappend_oid(result, HeapTupleGetOid(tuple));
4037         }
4038
4039         heap_endscan(scan);
4040         heap_close(classRel, AccessShareLock);
4041
4042         return result;
4043 }
4044
4045
4046 /*
4047  * check_of_type
4048  *
4049  * Check whether a type is suitable for CREATE TABLE OF/ALTER TABLE OF.  If it
4050  * isn't suitable, throw an error.  Currently, we require that the type
4051  * originated with CREATE TYPE AS.  We could support any row type, but doing so
4052  * would require handling a number of extra corner cases in the DDL commands.
4053  */
4054 void
4055 check_of_type(HeapTuple typetuple)
4056 {
4057         Form_pg_type typ = (Form_pg_type) GETSTRUCT(typetuple);
4058         bool            typeOk = false;
4059
4060         if (typ->typtype == TYPTYPE_COMPOSITE)
4061         {
4062                 Relation        typeRelation;
4063
4064                 Assert(OidIsValid(typ->typrelid));
4065                 typeRelation = relation_open(typ->typrelid, AccessShareLock);
4066                 typeOk = (typeRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE);
4067                 /*
4068                  * Close the parent rel, but keep our AccessShareLock on it until xact
4069                  * commit.      That will prevent someone else from deleting or ALTERing
4070                  * the type before the typed table creation/conversion commits.
4071                  */
4072                 relation_close(typeRelation, NoLock);
4073         }
4074         if (!typeOk)
4075                 ereport(ERROR,
4076                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4077                                  errmsg("type %s is not a composite type",
4078                                                 format_type_be(HeapTupleGetOid(typetuple)))));
4079 }
4080
4081
4082 /*
4083  * ALTER TABLE ADD COLUMN
4084  *
4085  * Adds an additional attribute to a relation making the assumption that
4086  * CHECK, NOT NULL, and FOREIGN KEY constraints will be removed from the
4087  * AT_AddColumn AlterTableCmd by parse_utilcmd.c and added as independent
4088  * AlterTableCmd's.
4089  *
4090  * ADD COLUMN cannot use the normal ALTER TABLE recursion mechanism, because we
4091  * have to decide at runtime whether to recurse or not depending on whether we
4092  * actually add a column or merely merge with an existing column.  (We can't
4093  * check this in a static pre-pass because it won't handle multiple inheritance
4094  * situations correctly.)
4095  */
4096 static void
4097 ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
4098                                 AlterTableCmd *cmd, LOCKMODE lockmode)
4099 {
4100         if (rel->rd_rel->reloftype && !recursing)
4101                 ereport(ERROR,
4102                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4103                                  errmsg("cannot add column to typed table")));
4104
4105         if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
4106                 ATTypedTableRecursion(wqueue, rel, cmd, lockmode);
4107
4108         if (recurse)
4109                 cmd->subtype = AT_AddColumnRecurse;
4110 }
4111
4112 static void
4113 ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
4114                                 ColumnDef *colDef, bool isOid,
4115                                 bool recurse, bool recursing, LOCKMODE lockmode)
4116 {
4117         Oid                     myrelid = RelationGetRelid(rel);
4118         Relation        pgclass,
4119                                 attrdesc;
4120         HeapTuple       reltup;
4121         FormData_pg_attribute attribute;
4122         int                     newattnum;
4123         char            relkind;
4124         HeapTuple       typeTuple;
4125         Oid                     typeOid;
4126         int32           typmod;
4127         Oid                     collOid;
4128         Form_pg_type tform;
4129         Expr       *defval;
4130         List       *children;
4131         ListCell   *child;
4132
4133         /* At top level, permission check was done in ATPrepCmd, else do it */
4134         if (recursing)
4135                 ATSimplePermissions(rel, ATT_TABLE);
4136
4137         attrdesc = heap_open(AttributeRelationId, RowExclusiveLock);
4138
4139         /*
4140          * Are we adding the column to a recursion child?  If so, check whether to
4141          * merge with an existing definition for the column.  If we do merge, we
4142          * must not recurse.  Children will already have the column, and recursing
4143          * into them would mess up attinhcount.
4144          */
4145         if (colDef->inhcount > 0)
4146         {
4147                 HeapTuple       tuple;
4148
4149                 /* Does child already have a column by this name? */
4150                 tuple = SearchSysCacheCopyAttName(myrelid, colDef->colname);
4151                 if (HeapTupleIsValid(tuple))
4152                 {
4153                         Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
4154                         Oid                     ctypeId;
4155                         int32           ctypmod;
4156                         Oid                     ccollid;
4157
4158                         /* Child column must match on type, typmod, and collation */
4159                         typenameTypeIdAndMod(NULL, colDef->typeName, &ctypeId, &ctypmod);
4160                         if (ctypeId != childatt->atttypid ||
4161                                 ctypmod != childatt->atttypmod)
4162                                 ereport(ERROR,
4163                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
4164                                                  errmsg("child table \"%s\" has different type for column \"%s\"",
4165                                                         RelationGetRelationName(rel), colDef->colname)));
4166                         ccollid = GetColumnDefCollation(NULL, colDef, ctypeId);
4167                         if (ccollid != childatt->attcollation)
4168                                 ereport(ERROR,
4169                                                 (errcode(ERRCODE_COLLATION_MISMATCH),
4170                                                  errmsg("child table \"%s\" has different collation for column \"%s\"",
4171                                                           RelationGetRelationName(rel), colDef->colname),
4172                                                  errdetail("\"%s\" versus \"%s\"",
4173                                                                    get_collation_name(ccollid),
4174                                                            get_collation_name(childatt->attcollation))));
4175
4176                         /* If it's OID, child column must actually be OID */
4177                         if (isOid && childatt->attnum != ObjectIdAttributeNumber)
4178                                 ereport(ERROR,
4179                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
4180                                  errmsg("child table \"%s\" has a conflicting \"%s\" column",
4181                                                 RelationGetRelationName(rel), colDef->colname)));
4182
4183                         /* Bump the existing child att's inhcount */
4184                         childatt->attinhcount++;
4185                         simple_heap_update(attrdesc, &tuple->t_self, tuple);
4186                         CatalogUpdateIndexes(attrdesc, tuple);
4187
4188                         heap_freetuple(tuple);
4189
4190                         /* Inform the user about the merge */
4191                         ereport(NOTICE,
4192                           (errmsg("merging definition of column \"%s\" for child \"%s\"",
4193                                           colDef->colname, RelationGetRelationName(rel))));
4194
4195                         heap_close(attrdesc, RowExclusiveLock);
4196                         return;
4197                 }
4198         }
4199
4200         pgclass = heap_open(RelationRelationId, RowExclusiveLock);
4201
4202         reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(myrelid));
4203         if (!HeapTupleIsValid(reltup))
4204                 elog(ERROR, "cache lookup failed for relation %u", myrelid);
4205         relkind = ((Form_pg_class) GETSTRUCT(reltup))->relkind;
4206
4207         /*
4208          * this test is deliberately not attisdropped-aware, since if one tries to
4209          * add a column matching a dropped column name, it's gonna fail anyway.
4210          */
4211         if (SearchSysCacheExists2(ATTNAME,
4212                                                           ObjectIdGetDatum(myrelid),
4213                                                           PointerGetDatum(colDef->colname)))
4214                 ereport(ERROR,
4215                                 (errcode(ERRCODE_DUPLICATE_COLUMN),
4216                                  errmsg("column \"%s\" of relation \"%s\" already exists",
4217                                                 colDef->colname, RelationGetRelationName(rel))));
4218
4219         /* Determine the new attribute's number */
4220         if (isOid)
4221                 newattnum = ObjectIdAttributeNumber;
4222         else
4223         {
4224                 newattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts + 1;
4225                 if (newattnum > MaxHeapAttributeNumber)
4226                         ereport(ERROR,
4227                                         (errcode(ERRCODE_TOO_MANY_COLUMNS),
4228                                          errmsg("tables can have at most %d columns",
4229                                                         MaxHeapAttributeNumber)));
4230         }
4231
4232         typeTuple = typenameType(NULL, colDef->typeName, &typmod);
4233         tform = (Form_pg_type) GETSTRUCT(typeTuple);
4234         typeOid = HeapTupleGetOid(typeTuple);
4235         collOid = GetColumnDefCollation(NULL, colDef, typeOid);
4236
4237         /* make sure datatype is legal for a column */
4238         CheckAttributeType(colDef->colname, typeOid, collOid,
4239                                            list_make1_oid(rel->rd_rel->reltype),
4240                                            false);
4241
4242         /* construct new attribute's pg_attribute entry */
4243         attribute.attrelid = myrelid;
4244         namestrcpy(&(attribute.attname), colDef->colname);
4245         attribute.atttypid = typeOid;
4246         attribute.attstattarget = (newattnum > 0) ? -1 : 0;
4247         attribute.attlen = tform->typlen;
4248         attribute.attcacheoff = -1;
4249         attribute.atttypmod = typmod;
4250         attribute.attnum = newattnum;
4251         attribute.attbyval = tform->typbyval;
4252         attribute.attndims = list_length(colDef->typeName->arrayBounds);
4253         attribute.attstorage = tform->typstorage;
4254         attribute.attalign = tform->typalign;
4255         attribute.attnotnull = colDef->is_not_null;
4256         attribute.atthasdef = false;
4257         attribute.attisdropped = false;
4258         attribute.attislocal = colDef->is_local;
4259         attribute.attinhcount = colDef->inhcount;
4260         attribute.attcollation = collOid;
4261         /* attribute.attacl is handled by InsertPgAttributeTuple */
4262
4263         ReleaseSysCache(typeTuple);
4264
4265         InsertPgAttributeTuple(attrdesc, &attribute, NULL);
4266
4267         heap_close(attrdesc, RowExclusiveLock);
4268
4269         /*
4270          * Update pg_class tuple as appropriate
4271          */
4272         if (isOid)
4273                 ((Form_pg_class) GETSTRUCT(reltup))->relhasoids = true;
4274         else
4275                 ((Form_pg_class) GETSTRUCT(reltup))->relnatts = newattnum;
4276
4277         simple_heap_update(pgclass, &reltup->t_self, reltup);
4278
4279         /* keep catalog indexes current */
4280         CatalogUpdateIndexes(pgclass, reltup);
4281
4282         heap_freetuple(reltup);
4283
4284         /* Post creation hook for new attribute */
4285         InvokeObjectAccessHook(OAT_POST_CREATE,
4286                                                    RelationRelationId, myrelid, newattnum);
4287
4288         heap_close(pgclass, RowExclusiveLock);
4289
4290         /* Make the attribute's catalog entry visible */
4291         CommandCounterIncrement();
4292
4293         /*
4294          * Store the DEFAULT, if any, in the catalogs
4295          */
4296         if (colDef->raw_default)
4297         {
4298                 RawColumnDefault *rawEnt;
4299
4300                 if (relkind == RELKIND_FOREIGN_TABLE)
4301                         ereport(ERROR,
4302                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4303                           errmsg("default values on foreign tables are not supported")));
4304
4305                 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
4306                 rawEnt->attnum = attribute.attnum;
4307                 rawEnt->raw_default = copyObject(colDef->raw_default);
4308
4309                 /*
4310                  * This function is intended for CREATE TABLE, so it processes a
4311                  * _list_ of defaults, but we just do one.
4312                  */
4313                 AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true);
4314
4315                 /* Make the additional catalog changes visible */
4316                 CommandCounterIncrement();
4317         }
4318
4319         /*
4320          * Tell Phase 3 to fill in the default expression, if there is one.
4321          *
4322          * If there is no default, Phase 3 doesn't have to do anything, because
4323          * that effectively means that the default is NULL.  The heap tuple access
4324          * routines always check for attnum > # of attributes in tuple, and return
4325          * NULL if so, so without any modification of the tuple data we will get
4326          * the effect of NULL values in the new column.
4327          *
4328          * An exception occurs when the new column is of a domain type: the domain
4329          * might have a NOT NULL constraint, or a check constraint that indirectly
4330          * rejects nulls.  If there are any domain constraints then we construct
4331          * an explicit NULL default value that will be passed through
4332          * CoerceToDomain processing.  (This is a tad inefficient, since it causes
4333          * rewriting the table which we really don't have to do, but the present
4334          * design of domain processing doesn't offer any simple way of checking
4335          * the constraints more directly.)
4336          *
4337          * Note: we use build_column_default, and not just the cooked default
4338          * returned by AddRelationNewConstraints, so that the right thing happens
4339          * when a datatype's default applies.
4340          *
4341          * We skip this step completely for views and foreign tables.  For a view,
4342          * we can only get here from CREATE OR REPLACE VIEW, which historically
4343          * doesn't set up defaults, not even for domain-typed columns.  And in any
4344          * case we mustn't invoke Phase 3 on a view or foreign table, since they
4345          * have no storage.
4346          */
4347         if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE
4348                 && relkind != RELKIND_FOREIGN_TABLE && attribute.attnum > 0)
4349         {
4350                 defval = (Expr *) build_column_default(rel, attribute.attnum);
4351
4352                 if (!defval && GetDomainConstraints(typeOid) != NIL)
4353                 {
4354                         Oid                     baseTypeId;
4355                         int32           baseTypeMod;
4356                         Oid                     baseTypeColl;
4357
4358                         baseTypeMod = typmod;
4359                         baseTypeId = getBaseTypeAndTypmod(typeOid, &baseTypeMod);
4360                         baseTypeColl = get_typcollation(baseTypeId);
4361                         defval = (Expr *) makeNullConst(baseTypeId, baseTypeMod, baseTypeColl);
4362                         defval = (Expr *) coerce_to_target_type(NULL,
4363                                                                                                         (Node *) defval,
4364                                                                                                         baseTypeId,
4365                                                                                                         typeOid,
4366                                                                                                         typmod,
4367                                                                                                         COERCION_ASSIGNMENT,
4368                                                                                                         COERCE_IMPLICIT_CAST,
4369                                                                                                         -1);
4370                         if (defval == NULL) /* should not happen */
4371                                 elog(ERROR, "failed to coerce base type to domain");
4372                 }
4373
4374                 if (defval)
4375                 {
4376                         NewColumnValue *newval;
4377
4378                         newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
4379                         newval->attnum = attribute.attnum;
4380                         newval->expr = defval;
4381
4382                         tab->newvals = lappend(tab->newvals, newval);
4383                         tab->rewrite = true;
4384                 }
4385
4386                 /*
4387                  * If the new column is NOT NULL, tell Phase 3 it needs to test that.
4388                  * (Note we don't do this for an OID column.  OID will be marked not
4389                  * null, but since it's filled specially, there's no need to test
4390                  * anything.)
4391                  */
4392                 tab->new_notnull |= colDef->is_not_null;
4393         }
4394
4395         /*
4396          * If we are adding an OID column, we have to tell Phase 3 to rewrite the
4397          * table to fix that.
4398          */
4399         if (isOid)
4400                 tab->rewrite = true;
4401
4402         /*
4403          * Add needed dependency entries for the new column.
4404          */
4405         add_column_datatype_dependency(myrelid, newattnum, attribute.atttypid);
4406         add_column_collation_dependency(myrelid, newattnum, attribute.attcollation);
4407
4408         /*
4409          * Propagate to children as appropriate.  Unlike most other ALTER
4410          * routines, we have to do this one level of recursion at a time; we can't
4411          * use find_all_inheritors to do it in one pass.
4412          */
4413         children = find_inheritance_children(RelationGetRelid(rel), lockmode);
4414
4415         /*
4416          * If we are told not to recurse, there had better not be any child
4417          * tables; else the addition would put them out of step.
4418          */
4419         if (children && !recurse)
4420                 ereport(ERROR,
4421                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4422                                  errmsg("column must be added to child tables too")));
4423
4424         /* Children should see column as singly inherited */
4425         if (!recursing)
4426         {
4427                 colDef = copyObject(colDef);
4428                 colDef->inhcount = 1;
4429                 colDef->is_local = false;
4430         }
4431
4432         foreach(child, children)
4433         {
4434                 Oid                     childrelid = lfirst_oid(child);
4435                 Relation        childrel;
4436                 AlteredTableInfo *childtab;
4437
4438                 /* find_inheritance_children already got lock */
4439                 childrel = heap_open(childrelid, NoLock);
4440                 CheckTableNotInUse(childrel, "ALTER TABLE");
4441
4442                 /* Find or create work queue entry for this table */
4443                 childtab = ATGetQueueEntry(wqueue, childrel);
4444
4445                 /* Recurse to child */
4446                 ATExecAddColumn(wqueue, childtab, childrel,
4447                                                 colDef, isOid, recurse, true, lockmode);
4448
4449                 heap_close(childrel, NoLock);
4450         }
4451 }
4452
4453 /*
4454  * Install a column's dependency on its datatype.
4455  */
4456 static void
4457 add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid)
4458 {
4459         ObjectAddress myself,
4460                                 referenced;
4461
4462         myself.classId = RelationRelationId;
4463         myself.objectId = relid;
4464         myself.objectSubId = attnum;
4465         referenced.classId = TypeRelationId;
4466         referenced.objectId = typid;
4467         referenced.objectSubId = 0;
4468         recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
4469 }
4470
4471 /*
4472  * Install a column's dependency on its collation.
4473  */
4474 static void
4475 add_column_collation_dependency(Oid relid, int32 attnum, Oid collid)
4476 {
4477         ObjectAddress myself,
4478                                 referenced;
4479
4480         /* We know the default collation is pinned, so don't bother recording it */
4481         if (OidIsValid(collid) && collid != DEFAULT_COLLATION_OID)
4482         {
4483                 myself.classId = RelationRelationId;
4484                 myself.objectId = relid;
4485                 myself.objectSubId = attnum;
4486                 referenced.classId = CollationRelationId;
4487                 referenced.objectId = collid;
4488                 referenced.objectSubId = 0;
4489                 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
4490         }
4491 }
4492
4493 /*
4494  * ALTER TABLE SET WITH OIDS
4495  *
4496  * Basically this is an ADD COLUMN for the special OID column.  We have
4497  * to cons up a ColumnDef node because the ADD COLUMN code needs one.
4498  */
4499 static void
4500 ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd, LOCKMODE lockmode)
4501 {
4502         /* If we're recursing to a child table, the ColumnDef is already set up */
4503         if (cmd->def == NULL)
4504         {
4505                 ColumnDef  *cdef = makeNode(ColumnDef);
4506
4507                 cdef->colname = pstrdup("oid");
4508                 cdef->typeName = makeTypeNameFromOid(OIDOID, -1);
4509                 cdef->inhcount = 0;
4510                 cdef->is_local = true;
4511                 cdef->is_not_null = true;
4512                 cdef->storage = 0;
4513                 cmd->def = (Node *) cdef;
4514         }
4515         ATPrepAddColumn(wqueue, rel, recurse, false, cmd, lockmode);
4516
4517         if (recurse)
4518                 cmd->subtype = AT_AddOidsRecurse;
4519 }
4520
4521 /*
4522  * ALTER TABLE ALTER COLUMN DROP NOT NULL
4523  */
4524 static void
4525 ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode)
4526 {
4527         HeapTuple       tuple;
4528         AttrNumber      attnum;
4529         Relation        attr_rel;
4530         List       *indexoidlist;
4531         ListCell   *indexoidscan;
4532
4533         /*
4534          * lookup the attribute
4535          */
4536         attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
4537
4538         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4539
4540         if (!HeapTupleIsValid(tuple))
4541                 ereport(ERROR,
4542                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
4543                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
4544                                                 colName, RelationGetRelationName(rel))));
4545
4546         attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
4547
4548         /* Prevent them from altering a system attribute */
4549         if (attnum <= 0)
4550                 ereport(ERROR,
4551                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4552                                  errmsg("cannot alter system column \"%s\"",
4553                                                 colName)));
4554
4555         /*
4556          * Check that the attribute is not in a primary key
4557          */
4558
4559         /* Loop over all indexes on the relation */
4560         indexoidlist = RelationGetIndexList(rel);
4561
4562         foreach(indexoidscan, indexoidlist)
4563         {
4564                 Oid                     indexoid = lfirst_oid(indexoidscan);
4565                 HeapTuple       indexTuple;
4566                 Form_pg_index indexStruct;
4567                 int                     i;
4568
4569                 indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
4570                 if (!HeapTupleIsValid(indexTuple))
4571                         elog(ERROR, "cache lookup failed for index %u", indexoid);
4572                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
4573
4574                 /* If the index is not a primary key, skip the check */
4575                 if (indexStruct->indisprimary)
4576                 {
4577                         /*
4578                          * Loop over each attribute in the primary key and see if it
4579                          * matches the to-be-altered attribute
4580                          */
4581                         for (i = 0; i < indexStruct->indnatts; i++)
4582                         {
4583                                 if (indexStruct->indkey.values[i] == attnum)
4584                                         ereport(ERROR,
4585                                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4586                                                          errmsg("column \"%s\" is in a primary key",
4587                                                                         colName)));
4588                         }
4589                 }
4590
4591                 ReleaseSysCache(indexTuple);
4592         }
4593
4594         list_free(indexoidlist);
4595
4596         /*
4597          * Okay, actually perform the catalog change ... if needed
4598          */
4599         if (((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
4600         {
4601                 ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = FALSE;
4602
4603                 simple_heap_update(attr_rel, &tuple->t_self, tuple);
4604
4605                 /* keep the system catalog indexes current */
4606                 CatalogUpdateIndexes(attr_rel, tuple);
4607         }
4608
4609         heap_close(attr_rel, RowExclusiveLock);
4610 }
4611
4612 /*
4613  * ALTER TABLE ALTER COLUMN SET NOT NULL
4614  */
4615 static void
4616 ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
4617                                  const char *colName, LOCKMODE lockmode)
4618 {
4619         HeapTuple       tuple;
4620         AttrNumber      attnum;
4621         Relation        attr_rel;
4622
4623         /*
4624          * lookup the attribute
4625          */
4626         attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
4627
4628         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4629
4630         if (!HeapTupleIsValid(tuple))
4631                 ereport(ERROR,
4632                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
4633                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
4634                                                 colName, RelationGetRelationName(rel))));
4635
4636         attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
4637
4638         /* Prevent them from altering a system attribute */
4639         if (attnum <= 0)
4640                 ereport(ERROR,
4641                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4642                                  errmsg("cannot alter system column \"%s\"",
4643                                                 colName)));
4644
4645         /*
4646          * Okay, actually perform the catalog change ... if needed
4647          */
4648         if (!((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
4649         {
4650                 ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = TRUE;
4651
4652                 simple_heap_update(attr_rel, &tuple->t_self, tuple);
4653
4654                 /* keep the system catalog indexes current */
4655                 CatalogUpdateIndexes(attr_rel, tuple);
4656
4657                 /* Tell Phase 3 it needs to test the constraint */
4658                 tab->new_notnull = true;
4659         }
4660
4661         heap_close(attr_rel, RowExclusiveLock);
4662 }
4663
4664 /*
4665  * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
4666  */
4667 static void
4668 ATExecColumnDefault(Relation rel, const char *colName,
4669                                         Node *newDefault, LOCKMODE lockmode)
4670 {
4671         AttrNumber      attnum;
4672
4673         /*
4674          * get the number of the attribute
4675          */
4676         attnum = get_attnum(RelationGetRelid(rel), colName);
4677         if (attnum == InvalidAttrNumber)
4678                 ereport(ERROR,
4679                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
4680                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
4681                                                 colName, RelationGetRelationName(rel))));
4682
4683         /* Prevent them from altering a system attribute */
4684         if (attnum <= 0)
4685                 ereport(ERROR,
4686                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4687                                  errmsg("cannot alter system column \"%s\"",
4688                                                 colName)));
4689
4690         /*
4691          * Remove any old default for the column.  We use RESTRICT here for
4692          * safety, but at present we do not expect anything to depend on the
4693          * default.
4694          */
4695         RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false);
4696
4697         if (newDefault)
4698         {
4699                 /* SET DEFAULT */
4700                 RawColumnDefault *rawEnt;
4701
4702                 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
4703                 rawEnt->attnum = attnum;
4704                 rawEnt->raw_default = newDefault;
4705
4706                 /*
4707                  * This function is intended for CREATE TABLE, so it processes a
4708                  * _list_ of defaults, but we just do one.
4709                  */
4710                 AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true);
4711         }
4712 }
4713
4714 /*
4715  * ALTER TABLE ALTER COLUMN SET STATISTICS
4716  */
4717 static void
4718 ATPrepSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
4719 {
4720         /*
4721          * We do our own permission checking because (a) we want to allow SET
4722          * STATISTICS on indexes (for expressional index columns), and (b) we want
4723          * to allow SET STATISTICS on system catalogs without requiring
4724          * allowSystemTableMods to be turned on.
4725          */
4726         if (rel->rd_rel->relkind != RELKIND_RELATION &&
4727                 rel->rd_rel->relkind != RELKIND_INDEX)
4728                 ereport(ERROR,
4729                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4730                                  errmsg("\"%s\" is not a table or index",
4731                                                 RelationGetRelationName(rel))));
4732
4733         /* Permissions checks */
4734         if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
4735                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
4736                                            RelationGetRelationName(rel));
4737 }
4738
4739 static void
4740 ATExecSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
4741 {
4742         int                     newtarget;
4743         Relation        attrelation;
4744         HeapTuple       tuple;
4745         Form_pg_attribute attrtuple;
4746
4747         Assert(IsA(newValue, Integer));
4748         newtarget = intVal(newValue);
4749
4750         /*
4751          * Limit target to a sane range
4752          */
4753         if (newtarget < -1)
4754         {
4755                 ereport(ERROR,
4756                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4757                                  errmsg("statistics target %d is too low",
4758                                                 newtarget)));
4759         }
4760         else if (newtarget > 10000)
4761         {
4762                 newtarget = 10000;
4763                 ereport(WARNING,
4764                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4765                                  errmsg("lowering statistics target to %d",
4766                                                 newtarget)));
4767         }
4768
4769         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
4770
4771         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4772
4773         if (!HeapTupleIsValid(tuple))
4774                 ereport(ERROR,
4775                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
4776                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
4777                                                 colName, RelationGetRelationName(rel))));
4778         attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
4779
4780         if (attrtuple->attnum <= 0)
4781                 ereport(ERROR,
4782                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4783                                  errmsg("cannot alter system column \"%s\"",
4784                                                 colName)));
4785
4786         attrtuple->attstattarget = newtarget;
4787
4788         simple_heap_update(attrelation, &tuple->t_self, tuple);
4789
4790         /* keep system catalog indexes current */
4791         CatalogUpdateIndexes(attrelation, tuple);
4792
4793         heap_freetuple(tuple);
4794
4795         heap_close(attrelation, RowExclusiveLock);
4796 }
4797
4798 static void
4799 ATExecSetOptions(Relation rel, const char *colName, Node *options,
4800                                  bool isReset, LOCKMODE lockmode)
4801 {
4802         Relation        attrelation;
4803         HeapTuple       tuple,
4804                                 newtuple;
4805         Form_pg_attribute attrtuple;
4806         Datum           datum,
4807                                 newOptions;
4808         bool            isnull;
4809         Datum           repl_val[Natts_pg_attribute];
4810         bool            repl_null[Natts_pg_attribute];
4811         bool            repl_repl[Natts_pg_attribute];
4812
4813         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
4814
4815         tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
4816
4817         if (!HeapTupleIsValid(tuple))
4818                 ereport(ERROR,
4819                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
4820                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
4821                                                 colName, RelationGetRelationName(rel))));
4822         attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
4823
4824         if (attrtuple->attnum <= 0)
4825                 ereport(ERROR,
4826                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4827                                  errmsg("cannot alter system column \"%s\"",
4828                                                 colName)));
4829
4830         /* Generate new proposed attoptions (text array) */
4831         Assert(IsA(options, List));
4832         datum = SysCacheGetAttr(ATTNAME, tuple, Anum_pg_attribute_attoptions,
4833                                                         &isnull);
4834         newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
4835                                                                          (List *) options, NULL, NULL, false,
4836                                                                          isReset);
4837         /* Validate new options */
4838         (void) attribute_reloptions(newOptions, true);
4839
4840         /* Build new tuple. */
4841         memset(repl_null, false, sizeof(repl_null));
4842         memset(repl_repl, false, sizeof(repl_repl));
4843         if (newOptions != (Datum) 0)
4844                 repl_val[Anum_pg_attribute_attoptions - 1] = newOptions;
4845         else
4846                 repl_null[Anum_pg_attribute_attoptions - 1] = true;
4847         repl_repl[Anum_pg_attribute_attoptions - 1] = true;
4848         newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrelation),
4849                                                                  repl_val, repl_null, repl_repl);
4850         ReleaseSysCache(tuple);
4851
4852         /* Update system catalog. */
4853         simple_heap_update(attrelation, &newtuple->t_self, newtuple);
4854         CatalogUpdateIndexes(attrelation, newtuple);
4855         heap_freetuple(newtuple);
4856
4857         heap_close(attrelation, RowExclusiveLock);
4858 }
4859
4860 /*
4861  * ALTER TABLE ALTER COLUMN SET STORAGE
4862  */
4863 static void
4864 ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
4865 {
4866         char       *storagemode;
4867         char            newstorage;
4868         Relation        attrelation;
4869         HeapTuple       tuple;
4870         Form_pg_attribute attrtuple;
4871
4872         Assert(IsA(newValue, String));
4873         storagemode = strVal(newValue);
4874
4875         if (pg_strcasecmp(storagemode, "plain") == 0)
4876                 newstorage = 'p';
4877         else if (pg_strcasecmp(storagemode, "external") == 0)
4878                 newstorage = 'e';
4879         else if (pg_strcasecmp(storagemode, "extended") == 0)
4880                 newstorage = 'x';
4881         else if (pg_strcasecmp(storagemode, "main") == 0)
4882                 newstorage = 'm';
4883         else
4884         {
4885                 ereport(ERROR,
4886                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4887                                  errmsg("invalid storage type \"%s\"",
4888                                                 storagemode)));
4889                 newstorage = 0;                 /* keep compiler quiet */
4890         }
4891
4892         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
4893
4894         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4895
4896         if (!HeapTupleIsValid(tuple))
4897                 ereport(ERROR,
4898                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
4899                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
4900                                                 colName, RelationGetRelationName(rel))));
4901         attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
4902
4903         if (attrtuple->attnum <= 0)
4904                 ereport(ERROR,
4905                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4906                                  errmsg("cannot alter system column \"%s\"",
4907                                                 colName)));
4908
4909         /*
4910          * safety check: do not allow toasted storage modes unless column datatype
4911          * is TOAST-aware.
4912          */
4913         if (newstorage == 'p' || TypeIsToastable(attrtuple->atttypid))
4914                 attrtuple->attstorage = newstorage;
4915         else
4916                 ereport(ERROR,
4917                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4918                                  errmsg("column data type %s can only have storage PLAIN",
4919                                                 format_type_be(attrtuple->atttypid))));
4920
4921         simple_heap_update(attrelation, &tuple->t_self, tuple);
4922
4923         /* keep system catalog indexes current */
4924         CatalogUpdateIndexes(attrelation, tuple);
4925
4926         heap_freetuple(tuple);
4927
4928         heap_close(attrelation, RowExclusiveLock);
4929 }
4930
4931
4932 /*
4933  * ALTER TABLE DROP COLUMN
4934  *
4935  * DROP COLUMN cannot use the normal ALTER TABLE recursion mechanism,
4936  * because we have to decide at runtime whether to recurse or not depending
4937  * on whether attinhcount goes to zero or not.  (We can't check this in a
4938  * static pre-pass because it won't handle multiple inheritance situations
4939  * correctly.)
4940  */
4941 static void
4942 ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
4943                                  AlterTableCmd *cmd, LOCKMODE lockmode)
4944 {
4945         if (rel->rd_rel->reloftype && !recursing)
4946                 ereport(ERROR,
4947                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4948                                  errmsg("cannot drop column from typed table")));
4949
4950         if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
4951                 ATTypedTableRecursion(wqueue, rel, cmd, lockmode);
4952
4953         if (recurse)
4954                 cmd->subtype = AT_DropColumnRecurse;
4955 }
4956
4957 static void
4958 ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
4959                                  DropBehavior behavior,
4960                                  bool recurse, bool recursing,
4961                                  bool missing_ok, LOCKMODE lockmode)
4962 {
4963         HeapTuple       tuple;
4964         Form_pg_attribute targetatt;
4965         AttrNumber      attnum;
4966         List       *children;
4967         ObjectAddress object;
4968
4969         /* At top level, permission check was done in ATPrepCmd, else do it */
4970         if (recursing)
4971                 ATSimplePermissions(rel, ATT_TABLE);
4972
4973         /*
4974          * get the number of the attribute
4975          */
4976         tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
4977         if (!HeapTupleIsValid(tuple))
4978         {
4979                 if (!missing_ok)
4980                 {
4981                         ereport(ERROR,
4982                                         (errcode(ERRCODE_UNDEFINED_COLUMN),
4983                                          errmsg("column \"%s\" of relation \"%s\" does not exist",
4984                                                         colName, RelationGetRelationName(rel))));
4985                 }
4986                 else
4987                 {
4988                         ereport(NOTICE,
4989                                         (errmsg("column \"%s\" of relation \"%s\" does not exist, skipping",
4990                                                         colName, RelationGetRelationName(rel))));
4991                         return;
4992                 }
4993         }
4994         targetatt = (Form_pg_attribute) GETSTRUCT(tuple);
4995
4996         attnum = targetatt->attnum;
4997
4998         /* Can't drop a system attribute, except OID */
4999         if (attnum <= 0 && attnum != ObjectIdAttributeNumber)
5000                 ereport(ERROR,
5001                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5002                                  errmsg("cannot drop system column \"%s\"",
5003                                                 colName)));
5004
5005         /* Don't drop inherited columns */
5006         if (targetatt->attinhcount > 0 && !recursing)
5007                 ereport(ERROR,
5008                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5009                                  errmsg("cannot drop inherited column \"%s\"",
5010                                                 colName)));
5011
5012         ReleaseSysCache(tuple);
5013
5014         /*
5015          * Propagate to children as appropriate.  Unlike most other ALTER
5016          * routines, we have to do this one level of recursion at a time; we can't
5017          * use find_all_inheritors to do it in one pass.
5018          */
5019         children = find_inheritance_children(RelationGetRelid(rel), lockmode);
5020
5021         if (children)
5022         {
5023                 Relation        attr_rel;
5024                 ListCell   *child;
5025
5026                 attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
5027                 foreach(child, children)
5028                 {
5029                         Oid                     childrelid = lfirst_oid(child);
5030                         Relation        childrel;
5031                         Form_pg_attribute childatt;
5032
5033                         /* find_inheritance_children already got lock */
5034                         childrel = heap_open(childrelid, NoLock);
5035                         CheckTableNotInUse(childrel, "ALTER TABLE");
5036
5037                         tuple = SearchSysCacheCopyAttName(childrelid, colName);
5038                         if (!HeapTupleIsValid(tuple))           /* shouldn't happen */
5039                                 elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
5040                                          colName, childrelid);
5041                         childatt = (Form_pg_attribute) GETSTRUCT(tuple);
5042
5043                         if (childatt->attinhcount <= 0)         /* shouldn't happen */
5044                                 elog(ERROR, "relation %u has non-inherited attribute \"%s\"",
5045                                          childrelid, colName);
5046
5047                         if (recurse)
5048                         {
5049                                 /*
5050                                  * If the child column has other definition sources, just
5051                                  * decrement its inheritance count; if not, recurse to delete
5052                                  * it.
5053                                  */
5054                                 if (childatt->attinhcount == 1 && !childatt->attislocal)
5055                                 {
5056                                         /* Time to delete this child column, too */
5057                                         ATExecDropColumn(wqueue, childrel, colName,
5058                                                                          behavior, true, true,
5059                                                                          false, lockmode);
5060                                 }
5061                                 else
5062                                 {
5063                                         /* Child column must survive my deletion */
5064                                         childatt->attinhcount--;
5065
5066                                         simple_heap_update(attr_rel, &tuple->t_self, tuple);
5067
5068                                         /* keep the system catalog indexes current */
5069                                         CatalogUpdateIndexes(attr_rel, tuple);
5070
5071                                         /* Make update visible */
5072                                         CommandCounterIncrement();
5073                                 }
5074                         }
5075                         else
5076                         {
5077                                 /*
5078                                  * If we were told to drop ONLY in this table (no recursion),
5079                                  * we need to mark the inheritors' attributes as locally
5080                                  * defined rather than inherited.
5081                                  */
5082                                 childatt->attinhcount--;
5083                                 childatt->attislocal = true;
5084
5085                                 simple_heap_update(attr_rel, &tuple->t_self, tuple);
5086
5087                                 /* keep the system catalog indexes current */
5088                                 CatalogUpdateIndexes(attr_rel, tuple);
5089
5090                                 /* Make update visible */
5091                                 CommandCounterIncrement();
5092                         }
5093
5094                         heap_freetuple(tuple);
5095
5096                         heap_close(childrel, NoLock);
5097                 }
5098                 heap_close(attr_rel, RowExclusiveLock);
5099         }
5100
5101         /*
5102          * Perform the actual column deletion
5103          */
5104         object.classId = RelationRelationId;
5105         object.objectId = RelationGetRelid(rel);
5106         object.objectSubId = attnum;
5107
5108         performDeletion(&object, behavior);
5109
5110         /*
5111          * If we dropped the OID column, must adjust pg_class.relhasoids and tell
5112          * Phase 3 to physically get rid of the column.  We formerly left the
5113          * column in place physically, but this caused subtle problems.  See
5114          * http://archives.postgresql.org/pgsql-hackers/2009-02/msg00363.php
5115          */
5116         if (attnum == ObjectIdAttributeNumber)
5117         {
5118                 Relation        class_rel;
5119                 Form_pg_class tuple_class;
5120                 AlteredTableInfo *tab;
5121
5122                 class_rel = heap_open(RelationRelationId, RowExclusiveLock);
5123
5124                 tuple = SearchSysCacheCopy1(RELOID,
5125                                                                         ObjectIdGetDatum(RelationGetRelid(rel)));
5126                 if (!HeapTupleIsValid(tuple))
5127                         elog(ERROR, "cache lookup failed for relation %u",
5128                                  RelationGetRelid(rel));
5129                 tuple_class = (Form_pg_class) GETSTRUCT(tuple);
5130
5131                 tuple_class->relhasoids = false;
5132                 simple_heap_update(class_rel, &tuple->t_self, tuple);
5133
5134                 /* Keep the catalog indexes up to date */
5135                 CatalogUpdateIndexes(class_rel, tuple);
5136
5137                 heap_close(class_rel, RowExclusiveLock);
5138
5139                 /* Find or create work queue entry for this table */
5140                 tab = ATGetQueueEntry(wqueue, rel);
5141
5142                 /* Tell Phase 3 to physically remove the OID column */
5143                 tab->rewrite = true;
5144         }
5145 }
5146
5147 /*
5148  * ALTER TABLE ADD INDEX
5149  *
5150  * There is no such command in the grammar, but parse_utilcmd.c converts
5151  * UNIQUE and PRIMARY KEY constraints into AT_AddIndex subcommands.  This lets
5152  * us schedule creation of the index at the appropriate time during ALTER.
5153  */
5154 static void
5155 ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
5156                            IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode)
5157 {
5158         bool            check_rights;
5159         bool            skip_build;
5160         bool            quiet;
5161
5162         Assert(IsA(stmt, IndexStmt));
5163
5164         /* suppress schema rights check when rebuilding existing index */
5165         check_rights = !is_rebuild;
5166         /* skip index build if phase 3 will have to rewrite table anyway */
5167         skip_build = tab->rewrite;
5168         /* suppress notices when rebuilding existing index */
5169         quiet = is_rebuild;
5170
5171         /* The IndexStmt has already been through transformIndexStmt */
5172
5173         DefineIndex(stmt->relation, /* relation */
5174                                 stmt->idxname,  /* index name */
5175                                 InvalidOid,             /* no predefined OID */
5176                                 stmt->accessMethod,             /* am name */
5177                                 stmt->tableSpace,
5178                                 stmt->indexParams,              /* parameters */
5179                                 (Expr *) stmt->whereClause,
5180                                 stmt->options,
5181                                 stmt->excludeOpNames,
5182                                 stmt->unique,
5183                                 stmt->primary,
5184                                 stmt->isconstraint,
5185                                 stmt->deferrable,
5186                                 stmt->initdeferred,
5187                                 true,                   /* is_alter_table */
5188                                 check_rights,
5189                                 skip_build,
5190                                 quiet,
5191                                 false);
5192 }
5193
5194 /*
5195  * ALTER TABLE ADD CONSTRAINT USING INDEX
5196  */
5197 static void
5198 ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
5199                                                  IndexStmt *stmt, LOCKMODE lockmode)
5200 {
5201         Oid                     index_oid = stmt->indexOid;
5202         Relation        indexRel;
5203         char       *indexName;
5204         IndexInfo  *indexInfo;
5205         char       *constraintName;
5206         char            constraintType;
5207
5208         Assert(IsA(stmt, IndexStmt));
5209         Assert(OidIsValid(index_oid));
5210         Assert(stmt->isconstraint);
5211
5212         indexRel = index_open(index_oid, AccessShareLock);
5213
5214         indexName = pstrdup(RelationGetRelationName(indexRel));
5215
5216         indexInfo = BuildIndexInfo(indexRel);
5217
5218         /* this should have been checked at parse time */
5219         if (!indexInfo->ii_Unique)
5220                 elog(ERROR, "index \"%s\" is not unique", indexName);
5221
5222         /*
5223          * Determine name to assign to constraint.      We require a constraint to
5224          * have the same name as the underlying index; therefore, use the index's
5225          * existing name as the default constraint name, and if the user
5226          * explicitly gives some other name for the constraint, rename the index
5227          * to match.
5228          */
5229         constraintName = stmt->idxname;
5230         if (constraintName == NULL)
5231                 constraintName = indexName;
5232         else if (strcmp(constraintName, indexName) != 0)
5233         {
5234                 ereport(NOTICE,
5235                                 (errmsg("ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"",
5236                                                 indexName, constraintName)));
5237                 RenameRelation(index_oid, constraintName, OBJECT_INDEX);
5238         }
5239
5240         /* Extra checks needed if making primary key */
5241         if (stmt->primary)
5242                 index_check_primary_key(rel, indexInfo, true);
5243
5244         /* Note we currently don't support EXCLUSION constraints here */
5245         if (stmt->primary)
5246                 constraintType = CONSTRAINT_PRIMARY;
5247         else
5248                 constraintType = CONSTRAINT_UNIQUE;
5249
5250         /* Create the catalog entries for the constraint */
5251         index_constraint_create(rel,
5252                                                         index_oid,
5253                                                         indexInfo,
5254                                                         constraintName,
5255                                                         constraintType,
5256                                                         stmt->deferrable,
5257                                                         stmt->initdeferred,
5258                                                         stmt->primary,
5259                                                         true,
5260                                                         allowSystemTableMods);
5261
5262         index_close(indexRel, NoLock);
5263 }
5264
5265 /*
5266  * ALTER TABLE ADD CONSTRAINT
5267  */
5268 static void
5269 ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
5270                                   Constraint *newConstraint, bool recurse, LOCKMODE lockmode)
5271 {
5272         Assert(IsA(newConstraint, Constraint));
5273
5274         /*
5275          * Currently, we only expect to see CONSTR_CHECK and CONSTR_FOREIGN nodes
5276          * arriving here (see the preprocessing done in parse_utilcmd.c).  Use a
5277          * switch anyway to make it easier to add more code later.
5278          */
5279         switch (newConstraint->contype)
5280         {
5281                 case CONSTR_CHECK:
5282                         ATAddCheckConstraint(wqueue, tab, rel,
5283                                                                  newConstraint, recurse, false, lockmode);
5284                         break;
5285
5286                 case CONSTR_FOREIGN:
5287
5288                         /*
5289                          * Note that we currently never recurse for FK constraints, so the
5290                          * "recurse" flag is silently ignored.
5291                          *
5292                          * Assign or validate constraint name
5293                          */
5294                         if (newConstraint->conname)
5295                         {
5296                                 if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
5297                                                                                  RelationGetRelid(rel),
5298                                                                                  RelationGetNamespace(rel),
5299                                                                                  newConstraint->conname))
5300                                         ereport(ERROR,
5301                                                         (errcode(ERRCODE_DUPLICATE_OBJECT),
5302                                                          errmsg("constraint \"%s\" for relation \"%s\" already exists",
5303                                                                         newConstraint->conname,
5304                                                                         RelationGetRelationName(rel))));
5305                         }
5306                         else
5307                                 newConstraint->conname =
5308                                         ChooseConstraintName(RelationGetRelationName(rel),
5309                                                                    strVal(linitial(newConstraint->fk_attrs)),
5310                                                                                  "fkey",
5311                                                                                  RelationGetNamespace(rel),
5312                                                                                  NIL);
5313
5314                         ATAddForeignKeyConstraint(tab, rel, newConstraint, lockmode);
5315                         break;
5316
5317                 default:
5318                         elog(ERROR, "unrecognized constraint type: %d",
5319                                  (int) newConstraint->contype);
5320         }
5321 }
5322
5323 /*
5324  * Add a check constraint to a single table and its children
5325  *
5326  * Subroutine for ATExecAddConstraint.
5327  *
5328  * We must recurse to child tables during execution, rather than using
5329  * ALTER TABLE's normal prep-time recursion.  The reason is that all the
5330  * constraints *must* be given the same name, else they won't be seen as
5331  * related later.  If the user didn't explicitly specify a name, then
5332  * AddRelationNewConstraints would normally assign different names to the
5333  * child constraints.  To fix that, we must capture the name assigned at
5334  * the parent table and pass that down.
5335  */
5336 static void
5337 ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
5338                                          Constraint *constr, bool recurse, bool recursing,
5339                                          LOCKMODE lockmode)
5340 {
5341         List       *newcons;
5342         ListCell   *lcon;
5343         List       *children;
5344         ListCell   *child;
5345
5346         /* At top level, permission check was done in ATPrepCmd, else do it */
5347         if (recursing)
5348                 ATSimplePermissions(rel, ATT_TABLE);
5349
5350         /*
5351          * Call AddRelationNewConstraints to do the work, making sure it works on
5352          * a copy of the Constraint so transformExpr can't modify the original. It
5353          * returns a list of cooked constraints.
5354          *
5355          * If the constraint ends up getting merged with a pre-existing one, it's
5356          * omitted from the returned list, which is what we want: we do not need
5357          * to do any validation work.  That can only happen at child tables,
5358          * though, since we disallow merging at the top level.
5359          */
5360         newcons = AddRelationNewConstraints(rel, NIL,
5361                                                                                 list_make1(copyObject(constr)),
5362                                                                                 recursing, !recursing);
5363
5364         /* Add each constraint to Phase 3's queue */
5365         foreach(lcon, newcons)
5366         {
5367                 CookedConstraint *ccon = (CookedConstraint *) lfirst(lcon);
5368                 NewConstraint *newcon;
5369
5370                 newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
5371                 newcon->name = ccon->name;
5372                 newcon->contype = ccon->contype;
5373                 /* ExecQual wants implicit-AND format */
5374                 newcon->qual = (Node *) make_ands_implicit((Expr *) ccon->expr);
5375
5376                 tab->constraints = lappend(tab->constraints, newcon);
5377
5378                 /* Save the actually assigned name if it was defaulted */
5379                 if (constr->conname == NULL)
5380                         constr->conname = ccon->name;
5381         }
5382
5383         /* At this point we must have a locked-down name to use */
5384         Assert(constr->conname != NULL);
5385
5386         /* Advance command counter in case same table is visited multiple times */
5387         CommandCounterIncrement();
5388
5389         /*
5390          * If the constraint got merged with an existing constraint, we're done.
5391          * We mustn't recurse to child tables in this case, because they've
5392          * already got the constraint, and visiting them again would lead to an
5393          * incorrect value for coninhcount.
5394          */
5395         if (newcons == NIL)
5396                 return;
5397
5398         /*
5399          * Propagate to children as appropriate.  Unlike most other ALTER
5400          * routines, we have to do this one level of recursion at a time; we can't
5401          * use find_all_inheritors to do it in one pass.
5402          */
5403         children = find_inheritance_children(RelationGetRelid(rel), lockmode);
5404
5405         /*
5406          * If we are told not to recurse, there had better not be any child
5407          * tables; else the addition would put them out of step.
5408          */
5409         if (children && !recurse)
5410                 ereport(ERROR,
5411                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5412                                  errmsg("constraint must be added to child tables too")));
5413
5414         foreach(child, children)
5415         {
5416                 Oid                     childrelid = lfirst_oid(child);
5417                 Relation        childrel;
5418                 AlteredTableInfo *childtab;
5419
5420                 /* find_inheritance_children already got lock */
5421                 childrel = heap_open(childrelid, NoLock);
5422                 CheckTableNotInUse(childrel, "ALTER TABLE");
5423
5424                 /* Find or create work queue entry for this table */
5425                 childtab = ATGetQueueEntry(wqueue, childrel);
5426
5427                 /* Recurse to child */
5428                 ATAddCheckConstraint(wqueue, childtab, childrel,
5429                                                          constr, recurse, true, lockmode);
5430
5431                 heap_close(childrel, NoLock);
5432         }
5433 }
5434
5435 /*
5436  * Add a foreign-key constraint to a single table
5437  *
5438  * Subroutine for ATExecAddConstraint.  Must already hold exclusive
5439  * lock on the rel, and have done appropriate validity checks for it.
5440  * We do permissions checks here, however.
5441  */
5442 static void
5443 ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
5444                                                   Constraint *fkconstraint, LOCKMODE lockmode)
5445 {
5446         Relation        pkrel;
5447         int16           pkattnum[INDEX_MAX_KEYS];
5448         int16           fkattnum[INDEX_MAX_KEYS];
5449         Oid                     pktypoid[INDEX_MAX_KEYS];
5450         Oid                     fktypoid[INDEX_MAX_KEYS];
5451         Oid                     opclasses[INDEX_MAX_KEYS];
5452         Oid                     pfeqoperators[INDEX_MAX_KEYS];
5453         Oid                     ppeqoperators[INDEX_MAX_KEYS];
5454         Oid                     ffeqoperators[INDEX_MAX_KEYS];
5455         int                     i;
5456         int                     numfks,
5457                                 numpks;
5458         Oid                     indexOid;
5459         Oid                     constrOid;
5460
5461         pkrel = heap_openrv(fkconstraint->pktable, lockmode);
5462
5463         /*
5464          * Validity checks (permission checks wait till we have the column
5465          * numbers)
5466          */
5467         if (pkrel->rd_rel->relkind != RELKIND_RELATION)
5468                 ereport(ERROR,
5469                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5470                                  errmsg("referenced relation \"%s\" is not a table",
5471                                                 RelationGetRelationName(pkrel))));
5472
5473         if (!allowSystemTableMods && IsSystemRelation(pkrel))
5474                 ereport(ERROR,
5475                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5476                                  errmsg("permission denied: \"%s\" is a system catalog",
5477                                                 RelationGetRelationName(pkrel))));
5478
5479         /*
5480          * References from permanent or unlogged tables to temp tables, and from
5481          * permanent tables to unlogged tables, are disallowed because the
5482          * referenced data can vanish out from under us.  References from temp
5483          * tables to any other table type are also disallowed, because other
5484          * backends might need to run the RI triggers on the perm table, but they
5485          * can't reliably see tuples in the local buffers of other backends.
5486          */
5487         switch (rel->rd_rel->relpersistence)
5488         {
5489                 case RELPERSISTENCE_PERMANENT:
5490                         if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT)
5491                                 ereport(ERROR,
5492                                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5493                                                  errmsg("constraints on permanent tables may reference only permanent tables")));
5494                         break;
5495                 case RELPERSISTENCE_UNLOGGED:
5496                         if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT
5497                                 && pkrel->rd_rel->relpersistence != RELPERSISTENCE_UNLOGGED)
5498                                 ereport(ERROR,
5499                                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5500                                                  errmsg("constraints on unlogged tables may reference only permanent or unlogged tables")));
5501                         break;
5502                 case RELPERSISTENCE_TEMP:
5503                         if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_TEMP)
5504                                 ereport(ERROR,
5505                                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5506                                                  errmsg("constraints on temporary tables may reference only temporary tables")));
5507                         break;
5508         }
5509
5510         /*
5511          * Look up the referencing attributes to make sure they exist, and record
5512          * their attnums and type OIDs.
5513          */
5514         MemSet(pkattnum, 0, sizeof(pkattnum));
5515         MemSet(fkattnum, 0, sizeof(fkattnum));
5516         MemSet(pktypoid, 0, sizeof(pktypoid));
5517         MemSet(fktypoid, 0, sizeof(fktypoid));
5518         MemSet(opclasses, 0, sizeof(opclasses));
5519         MemSet(pfeqoperators, 0, sizeof(pfeqoperators));
5520         MemSet(ppeqoperators, 0, sizeof(ppeqoperators));
5521         MemSet(ffeqoperators, 0, sizeof(ffeqoperators));
5522
5523         numfks = transformColumnNameList(RelationGetRelid(rel),
5524                                                                          fkconstraint->fk_attrs,
5525                                                                          fkattnum, fktypoid);
5526
5527         /*
5528          * If the attribute list for the referenced table was omitted, lookup the
5529          * definition of the primary key and use it.  Otherwise, validate the
5530          * supplied attribute list.  In either case, discover the index OID and
5531          * index opclasses, and the attnums and type OIDs of the attributes.
5532          */
5533         if (fkconstraint->pk_attrs == NIL)
5534         {
5535                 numpks = transformFkeyGetPrimaryKey(pkrel, &indexOid,
5536                                                                                         &fkconstraint->pk_attrs,
5537                                                                                         pkattnum, pktypoid,
5538                                                                                         opclasses);
5539         }
5540         else
5541         {
5542                 numpks = transformColumnNameList(RelationGetRelid(pkrel),
5543                                                                                  fkconstraint->pk_attrs,
5544                                                                                  pkattnum, pktypoid);
5545                 /* Look for an index matching the column list */
5546                 indexOid = transformFkeyCheckAttrs(pkrel, numpks, pkattnum,
5547                                                                                    opclasses);
5548         }
5549
5550         /*
5551          * Now we can check permissions.
5552          */
5553         checkFkeyPermissions(pkrel, pkattnum, numpks);
5554         checkFkeyPermissions(rel, fkattnum, numfks);
5555
5556         /*
5557          * Look up the equality operators to use in the constraint.
5558          *
5559          * Note that we have to be careful about the difference between the actual
5560          * PK column type and the opclass' declared input type, which might be
5561          * only binary-compatible with it.      The declared opcintype is the right
5562          * thing to probe pg_amop with.
5563          */
5564         if (numfks != numpks)
5565                 ereport(ERROR,
5566                                 (errcode(ERRCODE_INVALID_FOREIGN_KEY),
5567                                  errmsg("number of referencing and referenced columns for foreign key disagree")));
5568
5569         for (i = 0; i < numpks; i++)
5570         {
5571                 Oid                     pktype = pktypoid[i];
5572                 Oid                     fktype = fktypoid[i];
5573                 Oid                     fktyped;
5574                 HeapTuple       cla_ht;
5575                 Form_pg_opclass cla_tup;
5576                 Oid                     amid;
5577                 Oid                     opfamily;
5578                 Oid                     opcintype;
5579                 Oid                     pfeqop;
5580                 Oid                     ppeqop;
5581                 Oid                     ffeqop;
5582                 int16           eqstrategy;
5583
5584                 /* We need several fields out of the pg_opclass entry */
5585                 cla_ht = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclasses[i]));
5586                 if (!HeapTupleIsValid(cla_ht))
5587                         elog(ERROR, "cache lookup failed for opclass %u", opclasses[i]);
5588                 cla_tup = (Form_pg_opclass) GETSTRUCT(cla_ht);
5589                 amid = cla_tup->opcmethod;
5590                 opfamily = cla_tup->opcfamily;
5591                 opcintype = cla_tup->opcintype;
5592                 ReleaseSysCache(cla_ht);
5593
5594                 /*
5595                  * Check it's a btree; currently this can never fail since no other
5596                  * index AMs support unique indexes.  If we ever did have other types
5597                  * of unique indexes, we'd need a way to determine which operator
5598                  * strategy number is equality.  (Is it reasonable to insist that
5599                  * every such index AM use btree's number for equality?)
5600                  */
5601                 if (amid != BTREE_AM_OID)
5602                         elog(ERROR, "only b-tree indexes are supported for foreign keys");
5603                 eqstrategy = BTEqualStrategyNumber;
5604
5605                 /*
5606                  * There had better be a primary equality operator for the index.
5607                  * We'll use it for PK = PK comparisons.
5608                  */
5609                 ppeqop = get_opfamily_member(opfamily, opcintype, opcintype,
5610                                                                          eqstrategy);
5611
5612                 if (!OidIsValid(ppeqop))
5613                         elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
5614                                  eqstrategy, opcintype, opcintype, opfamily);
5615
5616                 /*
5617                  * Are there equality operators that take exactly the FK type? Assume
5618                  * we should look through any domain here.
5619                  */
5620                 fktyped = getBaseType(fktype);
5621
5622                 pfeqop = get_opfamily_member(opfamily, opcintype, fktyped,
5623                                                                          eqstrategy);
5624                 if (OidIsValid(pfeqop))
5625                         ffeqop = get_opfamily_member(opfamily, fktyped, fktyped,
5626                                                                                  eqstrategy);
5627                 else
5628                         ffeqop = InvalidOid;    /* keep compiler quiet */
5629
5630                 if (!(OidIsValid(pfeqop) && OidIsValid(ffeqop)))
5631                 {
5632                         /*
5633                          * Otherwise, look for an implicit cast from the FK type to the
5634                          * opcintype, and if found, use the primary equality operator.
5635                          * This is a bit tricky because opcintype might be a polymorphic
5636                          * type such as ANYARRAY or ANYENUM; so what we have to test is
5637                          * whether the two actual column types can be concurrently cast to
5638                          * that type.  (Otherwise, we'd fail to reject combinations such
5639                          * as int[] and point[].)
5640                          */
5641                         Oid                     input_typeids[2];
5642                         Oid                     target_typeids[2];
5643
5644                         input_typeids[0] = pktype;
5645                         input_typeids[1] = fktype;
5646                         target_typeids[0] = opcintype;
5647                         target_typeids[1] = opcintype;
5648                         if (can_coerce_type(2, input_typeids, target_typeids,
5649                                                                 COERCION_IMPLICIT))
5650                                 pfeqop = ffeqop = ppeqop;
5651                 }
5652
5653                 if (!(OidIsValid(pfeqop) && OidIsValid(ffeqop)))
5654                         ereport(ERROR,
5655                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
5656                                          errmsg("foreign key constraint \"%s\" "
5657                                                         "cannot be implemented",
5658                                                         fkconstraint->conname),
5659                                          errdetail("Key columns \"%s\" and \"%s\" "
5660                                                            "are of incompatible types: %s and %s.",
5661                                                            strVal(list_nth(fkconstraint->fk_attrs, i)),
5662                                                            strVal(list_nth(fkconstraint->pk_attrs, i)),
5663                                                            format_type_be(fktype),
5664                                                            format_type_be(pktype))));
5665
5666                 pfeqoperators[i] = pfeqop;
5667                 ppeqoperators[i] = ppeqop;
5668                 ffeqoperators[i] = ffeqop;
5669         }
5670
5671         /*
5672          * Record the FK constraint in pg_constraint.
5673          */
5674         constrOid = CreateConstraintEntry(fkconstraint->conname,
5675                                                                           RelationGetNamespace(rel),
5676                                                                           CONSTRAINT_FOREIGN,
5677                                                                           fkconstraint->deferrable,
5678                                                                           fkconstraint->initdeferred,
5679                                                                           fkconstraint->initially_valid,
5680                                                                           RelationGetRelid(rel),
5681                                                                           fkattnum,
5682                                                                           numfks,
5683                                                                           InvalidOid,           /* not a domain
5684                                                                                                                  * constraint */
5685                                                                           indexOid,
5686                                                                           RelationGetRelid(pkrel),
5687                                                                           pkattnum,
5688                                                                           pfeqoperators,
5689                                                                           ppeqoperators,
5690                                                                           ffeqoperators,
5691                                                                           numpks,
5692                                                                           fkconstraint->fk_upd_action,
5693                                                                           fkconstraint->fk_del_action,
5694                                                                           fkconstraint->fk_matchtype,
5695                                                                           NULL,         /* no exclusion constraint */
5696                                                                           NULL,         /* no check constraint */
5697                                                                           NULL,
5698                                                                           NULL,
5699                                                                           true,         /* islocal */
5700                                                                           0);           /* inhcount */
5701
5702         /*
5703          * Create the triggers that will enforce the constraint.
5704          */
5705         createForeignKeyTriggers(rel, fkconstraint, constrOid, indexOid);
5706
5707         /*
5708          * Tell Phase 3 to check that the constraint is satisfied by existing rows
5709          * We can skip this during table creation or if requested explicitly by
5710          * specifying NOT VALID on an alter table statement.
5711          */
5712         if (!fkconstraint->skip_validation)
5713         {
5714                 NewConstraint *newcon;
5715
5716                 newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
5717                 newcon->name = fkconstraint->conname;
5718                 newcon->contype = CONSTR_FOREIGN;
5719                 newcon->refrelid = RelationGetRelid(pkrel);
5720                 newcon->refindid = indexOid;
5721                 newcon->conid = constrOid;
5722                 newcon->qual = (Node *) fkconstraint;
5723
5724                 tab->constraints = lappend(tab->constraints, newcon);
5725         }
5726
5727         /*
5728          * Close pk table, but keep lock until we've committed.
5729          */
5730         heap_close(pkrel, NoLock);
5731 }
5732
5733 /*
5734  * ALTER TABLE VALIDATE CONSTRAINT
5735  */
5736 static void
5737 ATExecValidateConstraint(Relation rel, const char *constrName)
5738 {
5739         Relation        conrel;
5740         SysScanDesc scan;
5741         ScanKeyData key;
5742         HeapTuple       tuple;
5743         Form_pg_constraint con = NULL;
5744         bool            found = false;
5745
5746         conrel = heap_open(ConstraintRelationId, RowExclusiveLock);
5747
5748         /*
5749          * Find and check the target constraint
5750          */
5751         ScanKeyInit(&key,
5752                                 Anum_pg_constraint_conrelid,
5753                                 BTEqualStrategyNumber, F_OIDEQ,
5754                                 ObjectIdGetDatum(RelationGetRelid(rel)));
5755         scan = systable_beginscan(conrel, ConstraintRelidIndexId,
5756                                                           true, SnapshotNow, 1, &key);
5757
5758         while (HeapTupleIsValid(tuple = systable_getnext(scan)))
5759         {
5760                 con = (Form_pg_constraint) GETSTRUCT(tuple);
5761                 if (con->contype == CONSTRAINT_FOREIGN &&
5762                         strcmp(NameStr(con->conname), constrName) == 0)
5763                 {
5764                         found = true;
5765                         break;
5766                 }
5767         }
5768
5769         if (!found)
5770                 ereport(ERROR,
5771                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
5772                                  errmsg("foreign key constraint \"%s\" of relation \"%s\" does not exist",
5773                                                 constrName, RelationGetRelationName(rel))));
5774
5775         if (!con->convalidated)
5776         {
5777                 Oid                     conid = HeapTupleGetOid(tuple);
5778                 HeapTuple       copyTuple = heap_copytuple(tuple);
5779                 Form_pg_constraint copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
5780                 Relation        refrel;
5781
5782                 /*
5783                  * Triggers are already in place on both tables, so a concurrent write
5784                  * that alters the result here is not possible. Normally we can run a
5785                  * query here to do the validation, which would only require
5786                  * AccessShareLock. In some cases, it is possible that we might need
5787                  * to fire triggers to perform the check, so we take a lock at
5788                  * RowShareLock level just in case.
5789                  */
5790                 refrel = heap_open(con->confrelid, RowShareLock);
5791
5792                 validateForeignKeyConstraint((char *) constrName, rel, refrel,
5793                                                                          con->conindid,
5794                                                                          conid);
5795
5796                 /*
5797                  * Now update the catalog, while we have the door open.
5798                  */
5799                 copy_con->convalidated = true;
5800                 simple_heap_update(conrel, &copyTuple->t_self, copyTuple);
5801                 CatalogUpdateIndexes(conrel, copyTuple);
5802                 heap_freetuple(copyTuple);
5803
5804                 heap_close(refrel, NoLock);
5805         }
5806
5807         systable_endscan(scan);
5808
5809         heap_close(conrel, RowExclusiveLock);
5810 }
5811
5812 /*
5813  * transformColumnNameList - transform list of column names
5814  *
5815  * Lookup each name and return its attnum and type OID
5816  */
5817 static int
5818 transformColumnNameList(Oid relId, List *colList,
5819                                                 int16 *attnums, Oid *atttypids)
5820 {
5821         ListCell   *l;
5822         int                     attnum;
5823
5824         attnum = 0;
5825         foreach(l, colList)
5826         {
5827                 char       *attname = strVal(lfirst(l));
5828                 HeapTuple       atttuple;
5829
5830                 atttuple = SearchSysCacheAttName(relId, attname);
5831                 if (!HeapTupleIsValid(atttuple))
5832                         ereport(ERROR,
5833                                         (errcode(ERRCODE_UNDEFINED_COLUMN),
5834                                          errmsg("column \"%s\" referenced in foreign key constraint does not exist",
5835                                                         attname)));
5836                 if (attnum >= INDEX_MAX_KEYS)
5837                         ereport(ERROR,
5838                                         (errcode(ERRCODE_TOO_MANY_COLUMNS),
5839                                          errmsg("cannot have more than %d keys in a foreign key",
5840                                                         INDEX_MAX_KEYS)));
5841                 attnums[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->attnum;
5842                 atttypids[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
5843                 ReleaseSysCache(atttuple);
5844                 attnum++;
5845         }
5846
5847         return attnum;
5848 }
5849
5850 /*
5851  * transformFkeyGetPrimaryKey -
5852  *
5853  *      Look up the names, attnums, and types of the primary key attributes
5854  *      for the pkrel.  Also return the index OID and index opclasses of the
5855  *      index supporting the primary key.
5856  *
5857  *      All parameters except pkrel are output parameters.      Also, the function
5858  *      return value is the number of attributes in the primary key.
5859  *
5860  *      Used when the column list in the REFERENCES specification is omitted.
5861  */
5862 static int
5863 transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
5864                                                    List **attnamelist,
5865                                                    int16 *attnums, Oid *atttypids,
5866                                                    Oid *opclasses)
5867 {
5868         List       *indexoidlist;
5869         ListCell   *indexoidscan;
5870         HeapTuple       indexTuple = NULL;
5871         Form_pg_index indexStruct = NULL;
5872         Datum           indclassDatum;
5873         bool            isnull;
5874         oidvector  *indclass;
5875         int                     i;
5876
5877         /*
5878          * Get the list of index OIDs for the table from the relcache, and look up
5879          * each one in the pg_index syscache until we find one marked primary key
5880          * (hopefully there isn't more than one such).
5881          */
5882         *indexOid = InvalidOid;
5883
5884         indexoidlist = RelationGetIndexList(pkrel);
5885
5886         foreach(indexoidscan, indexoidlist)
5887         {
5888                 Oid                     indexoid = lfirst_oid(indexoidscan);
5889
5890                 indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
5891                 if (!HeapTupleIsValid(indexTuple))
5892                         elog(ERROR, "cache lookup failed for index %u", indexoid);
5893                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
5894                 if (indexStruct->indisprimary)
5895                 {
5896                         /*
5897                          * Refuse to use a deferrable primary key.      This is per SQL spec,
5898                          * and there would be a lot of interesting semantic problems if we
5899                          * tried to allow it.
5900                          */
5901                         if (!indexStruct->indimmediate)
5902                                 ereport(ERROR,
5903                                                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5904                                                  errmsg("cannot use a deferrable primary key for referenced table \"%s\"",
5905                                                                 RelationGetRelationName(pkrel))));
5906
5907                         *indexOid = indexoid;
5908                         break;
5909                 }
5910                 ReleaseSysCache(indexTuple);
5911         }
5912
5913         list_free(indexoidlist);
5914
5915         /*
5916          * Check that we found it
5917          */
5918         if (!OidIsValid(*indexOid))
5919                 ereport(ERROR,
5920                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
5921                                  errmsg("there is no primary key for referenced table \"%s\"",
5922                                                 RelationGetRelationName(pkrel))));
5923
5924         /* Must get indclass the hard way */
5925         indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
5926                                                                         Anum_pg_index_indclass, &isnull);
5927         Assert(!isnull);
5928         indclass = (oidvector *) DatumGetPointer(indclassDatum);
5929
5930         /*
5931          * Now build the list of PK attributes from the indkey definition (we
5932          * assume a primary key cannot have expressional elements)
5933          */
5934         *attnamelist = NIL;
5935         for (i = 0; i < indexStruct->indnatts; i++)
5936         {
5937                 int                     pkattno = indexStruct->indkey.values[i];
5938
5939                 attnums[i] = pkattno;
5940                 atttypids[i] = attnumTypeId(pkrel, pkattno);
5941                 opclasses[i] = indclass->values[i];
5942                 *attnamelist = lappend(*attnamelist,
5943                            makeString(pstrdup(NameStr(*attnumAttName(pkrel, pkattno)))));
5944         }
5945
5946         ReleaseSysCache(indexTuple);
5947
5948         return i;
5949 }
5950
5951 /*
5952  * transformFkeyCheckAttrs -
5953  *
5954  *      Make sure that the attributes of a referenced table belong to a unique
5955  *      (or primary key) constraint.  Return the OID of the index supporting
5956  *      the constraint, as well as the opclasses associated with the index
5957  *      columns.
5958  */
5959 static Oid
5960 transformFkeyCheckAttrs(Relation pkrel,
5961                                                 int numattrs, int16 *attnums,
5962                                                 Oid *opclasses) /* output parameter */
5963 {
5964         Oid                     indexoid = InvalidOid;
5965         bool            found = false;
5966         bool            found_deferrable = false;
5967         List       *indexoidlist;
5968         ListCell   *indexoidscan;
5969
5970         /*
5971          * Get the list of index OIDs for the table from the relcache, and look up
5972          * each one in the pg_index syscache, and match unique indexes to the list
5973          * of attnums we are given.
5974          */
5975         indexoidlist = RelationGetIndexList(pkrel);
5976
5977         foreach(indexoidscan, indexoidlist)
5978         {
5979                 HeapTuple       indexTuple;
5980                 Form_pg_index indexStruct;
5981                 int                     i,
5982                                         j;
5983
5984                 indexoid = lfirst_oid(indexoidscan);
5985                 indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
5986                 if (!HeapTupleIsValid(indexTuple))
5987                         elog(ERROR, "cache lookup failed for index %u", indexoid);
5988                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
5989
5990                 /*
5991                  * Must have the right number of columns; must be unique and not a
5992                  * partial index; forget it if there are any expressions, too
5993                  */
5994                 if (indexStruct->indnatts == numattrs &&
5995                         indexStruct->indisunique &&
5996                         heap_attisnull(indexTuple, Anum_pg_index_indpred) &&
5997                         heap_attisnull(indexTuple, Anum_pg_index_indexprs))
5998                 {
5999                         /* Must get indclass the hard way */
6000                         Datum           indclassDatum;
6001                         bool            isnull;
6002                         oidvector  *indclass;
6003
6004                         indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
6005                                                                                         Anum_pg_index_indclass, &isnull);
6006                         Assert(!isnull);
6007                         indclass = (oidvector *) DatumGetPointer(indclassDatum);
6008
6009                         /*
6010                          * The given attnum list may match the index columns in any order.
6011                          * Check that each list is a subset of the other.
6012                          */
6013                         for (i = 0; i < numattrs; i++)
6014                         {
6015                                 found = false;
6016                                 for (j = 0; j < numattrs; j++)
6017                                 {
6018                                         if (attnums[i] == indexStruct->indkey.values[j])
6019                                         {
6020                                                 found = true;
6021                                                 break;
6022                                         }
6023                                 }
6024                                 if (!found)
6025                                         break;
6026                         }
6027                         if (found)
6028                         {
6029                                 for (i = 0; i < numattrs; i++)
6030                                 {
6031                                         found = false;
6032                                         for (j = 0; j < numattrs; j++)
6033                                         {
6034                                                 if (attnums[j] == indexStruct->indkey.values[i])
6035                                                 {
6036                                                         opclasses[j] = indclass->values[i];
6037                                                         found = true;
6038                                                         break;
6039                                                 }
6040                                         }
6041                                         if (!found)
6042                                                 break;
6043                                 }
6044                         }
6045
6046                         /*
6047                          * Refuse to use a deferrable unique/primary key.  This is per SQL
6048                          * spec, and there would be a lot of interesting semantic problems
6049                          * if we tried to allow it.
6050                          */
6051                         if (found && !indexStruct->indimmediate)
6052                         {
6053                                 /*
6054                                  * Remember that we found an otherwise matching index, so that
6055                                  * we can generate a more appropriate error message.
6056                                  */
6057                                 found_deferrable = true;
6058                                 found = false;
6059                         }
6060                 }
6061                 ReleaseSysCache(indexTuple);
6062                 if (found)
6063                         break;
6064         }
6065
6066         if (!found)
6067         {
6068                 if (found_deferrable)
6069                         ereport(ERROR,
6070                                         (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6071                                          errmsg("cannot use a deferrable unique constraint for referenced table \"%s\"",
6072                                                         RelationGetRelationName(pkrel))));
6073                 else
6074                         ereport(ERROR,
6075                                         (errcode(ERRCODE_INVALID_FOREIGN_KEY),
6076                                          errmsg("there is no unique constraint matching given keys for referenced table \"%s\"",
6077                                                         RelationGetRelationName(pkrel))));
6078         }
6079
6080         list_free(indexoidlist);
6081
6082         return indexoid;
6083 }
6084
6085 /* Permissions checks for ADD FOREIGN KEY */
6086 static void
6087 checkFkeyPermissions(Relation rel, int16 *attnums, int natts)
6088 {
6089         Oid                     roleid = GetUserId();
6090         AclResult       aclresult;
6091         int                     i;
6092
6093         /* Okay if we have relation-level REFERENCES permission */
6094         aclresult = pg_class_aclcheck(RelationGetRelid(rel), roleid,
6095                                                                   ACL_REFERENCES);
6096         if (aclresult == ACLCHECK_OK)
6097                 return;
6098         /* Else we must have REFERENCES on each column */
6099         for (i = 0; i < natts; i++)
6100         {
6101                 aclresult = pg_attribute_aclcheck(RelationGetRelid(rel), attnums[i],
6102                                                                                   roleid, ACL_REFERENCES);
6103                 if (aclresult != ACLCHECK_OK)
6104                         aclcheck_error(aclresult, ACL_KIND_CLASS,
6105                                                    RelationGetRelationName(rel));
6106         }
6107 }
6108
6109 /*
6110  * Scan the existing rows in a table to verify they meet a proposed FK
6111  * constraint.
6112  *
6113  * Caller must have opened and locked both relations appropriately.
6114  */
6115 static void
6116 validateForeignKeyConstraint(char *conname,
6117                                                          Relation rel,
6118                                                          Relation pkrel,
6119                                                          Oid pkindOid,
6120                                                          Oid constraintOid)
6121 {
6122         HeapScanDesc scan;
6123         HeapTuple       tuple;
6124         Trigger         trig;
6125
6126         ereport(DEBUG1,
6127                         (errmsg("validating foreign key constraint \"%s\"", conname)));
6128
6129         /*
6130          * Build a trigger call structure; we'll need it either way.
6131          */
6132         MemSet(&trig, 0, sizeof(trig));
6133         trig.tgoid = InvalidOid;
6134         trig.tgname = conname;
6135         trig.tgenabled = TRIGGER_FIRES_ON_ORIGIN;
6136         trig.tgisinternal = TRUE;
6137         trig.tgconstrrelid = RelationGetRelid(pkrel);
6138         trig.tgconstrindid = pkindOid;
6139         trig.tgconstraint = constraintOid;
6140         trig.tgdeferrable = FALSE;
6141         trig.tginitdeferred = FALSE;
6142         /* we needn't fill in tgargs or tgqual */
6143
6144         /*
6145          * See if we can do it with a single LEFT JOIN query.  A FALSE result
6146          * indicates we must proceed with the fire-the-trigger method.
6147          */
6148         if (RI_Initial_Check(&trig, rel, pkrel))
6149                 return;
6150
6151         /*
6152          * Scan through each tuple, calling RI_FKey_check_ins (insert trigger) as
6153          * if that tuple had just been inserted.  If any of those fail, it should
6154          * ereport(ERROR) and that's that.
6155          */
6156         scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
6157
6158         while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
6159         {
6160                 FunctionCallInfoData fcinfo;
6161                 TriggerData trigdata;
6162
6163                 /*
6164                  * Make a call to the trigger function
6165                  *
6166                  * No parameters are passed, but we do set a context
6167                  */
6168                 MemSet(&fcinfo, 0, sizeof(fcinfo));
6169
6170                 /*
6171                  * We assume RI_FKey_check_ins won't look at flinfo...
6172                  */
6173                 trigdata.type = T_TriggerData;
6174                 trigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
6175                 trigdata.tg_relation = rel;
6176                 trigdata.tg_trigtuple = tuple;
6177                 trigdata.tg_newtuple = NULL;
6178                 trigdata.tg_trigger = &trig;
6179                 trigdata.tg_trigtuplebuf = scan->rs_cbuf;
6180                 trigdata.tg_newtuplebuf = InvalidBuffer;
6181
6182                 fcinfo.context = (Node *) &trigdata;
6183
6184                 RI_FKey_check_ins(&fcinfo);
6185         }
6186
6187         heap_endscan(scan);
6188 }
6189
6190 static void
6191 CreateFKCheckTrigger(RangeVar *myRel, Constraint *fkconstraint,
6192                                          Oid constraintOid, Oid indexOid, bool on_insert)
6193 {
6194         CreateTrigStmt *fk_trigger;
6195
6196         fk_trigger = makeNode(CreateTrigStmt);
6197         fk_trigger->trigname = "RI_ConstraintTrigger";
6198         fk_trigger->relation = myRel;
6199         fk_trigger->row = true;
6200         fk_trigger->timing = TRIGGER_TYPE_AFTER;
6201
6202         /* Either ON INSERT or ON UPDATE */
6203         if (on_insert)
6204         {
6205                 fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
6206                 fk_trigger->events = TRIGGER_TYPE_INSERT;
6207         }
6208         else
6209         {
6210                 fk_trigger->funcname = SystemFuncName("RI_FKey_check_upd");
6211                 fk_trigger->events = TRIGGER_TYPE_UPDATE;
6212         }
6213
6214         fk_trigger->columns = NIL;
6215         fk_trigger->whenClause = NULL;
6216         fk_trigger->isconstraint = true;
6217         fk_trigger->deferrable = fkconstraint->deferrable;
6218         fk_trigger->initdeferred = fkconstraint->initdeferred;
6219         fk_trigger->constrrel = fkconstraint->pktable;
6220         fk_trigger->args = NIL;
6221
6222         (void) CreateTrigger(fk_trigger, NULL, constraintOid, indexOid, true);
6223
6224         /* Make changes-so-far visible */
6225         CommandCounterIncrement();
6226 }
6227
6228 /*
6229  * Create the triggers that implement an FK constraint.
6230  */
6231 static void
6232 createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
6233                                                  Oid constraintOid, Oid indexOid)
6234 {
6235         RangeVar   *myRel;
6236         CreateTrigStmt *fk_trigger;
6237
6238         /*
6239          * Reconstruct a RangeVar for my relation (not passed in, unfortunately).
6240          */
6241         myRel = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
6242                                                  pstrdup(RelationGetRelationName(rel)),
6243                                                  -1);
6244
6245         /* Make changes-so-far visible */
6246         CommandCounterIncrement();
6247
6248         /*
6249          * Build and execute a CREATE CONSTRAINT TRIGGER statement for the CHECK
6250          * action for both INSERTs and UPDATEs on the referencing table.
6251          */
6252         CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, indexOid, true);
6253         CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, indexOid, false);
6254
6255         /*
6256          * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
6257          * DELETE action on the referenced table.
6258          */
6259         fk_trigger = makeNode(CreateTrigStmt);
6260         fk_trigger->trigname = "RI_ConstraintTrigger";
6261         fk_trigger->relation = fkconstraint->pktable;
6262         fk_trigger->row = true;
6263         fk_trigger->timing = TRIGGER_TYPE_AFTER;
6264         fk_trigger->events = TRIGGER_TYPE_DELETE;
6265         fk_trigger->columns = NIL;
6266         fk_trigger->whenClause = NULL;
6267         fk_trigger->isconstraint = true;
6268         fk_trigger->constrrel = myRel;
6269         switch (fkconstraint->fk_del_action)
6270         {
6271                 case FKCONSTR_ACTION_NOACTION:
6272                         fk_trigger->deferrable = fkconstraint->deferrable;
6273                         fk_trigger->initdeferred = fkconstraint->initdeferred;
6274                         fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_del");
6275                         break;
6276                 case FKCONSTR_ACTION_RESTRICT:
6277                         fk_trigger->deferrable = false;
6278                         fk_trigger->initdeferred = false;
6279                         fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_del");
6280                         break;
6281                 case FKCONSTR_ACTION_CASCADE:
6282                         fk_trigger->deferrable = false;
6283                         fk_trigger->initdeferred = false;
6284                         fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del");
6285                         break;
6286                 case FKCONSTR_ACTION_SETNULL:
6287                         fk_trigger->deferrable = false;
6288                         fk_trigger->initdeferred = false;
6289                         fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del");
6290                         break;
6291                 case FKCONSTR_ACTION_SETDEFAULT:
6292                         fk_trigger->deferrable = false;
6293                         fk_trigger->initdeferred = false;
6294                         fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del");
6295                         break;
6296                 default:
6297                         elog(ERROR, "unrecognized FK action type: %d",
6298                                  (int) fkconstraint->fk_del_action);
6299                         break;
6300         }
6301         fk_trigger->args = NIL;
6302
6303         (void) CreateTrigger(fk_trigger, NULL, constraintOid, indexOid, true);
6304
6305         /* Make changes-so-far visible */
6306         CommandCounterIncrement();
6307
6308         /*
6309          * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
6310          * UPDATE action on the referenced table.
6311          */
6312         fk_trigger = makeNode(CreateTrigStmt);
6313         fk_trigger->trigname = "RI_ConstraintTrigger";
6314         fk_trigger->relation = fkconstraint->pktable;
6315         fk_trigger->row = true;
6316         fk_trigger->timing = TRIGGER_TYPE_AFTER;
6317         fk_trigger->events = TRIGGER_TYPE_UPDATE;
6318         fk_trigger->columns = NIL;
6319         fk_trigger->whenClause = NULL;
6320         fk_trigger->isconstraint = true;
6321         fk_trigger->constrrel = myRel;
6322         switch (fkconstraint->fk_upd_action)
6323         {
6324                 case FKCONSTR_ACTION_NOACTION:
6325                         fk_trigger->deferrable = fkconstraint->deferrable;
6326                         fk_trigger->initdeferred = fkconstraint->initdeferred;
6327                         fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_upd");
6328                         break;
6329                 case FKCONSTR_ACTION_RESTRICT:
6330                         fk_trigger->deferrable = false;
6331                         fk_trigger->initdeferred = false;
6332                         fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_upd");
6333                         break;
6334                 case FKCONSTR_ACTION_CASCADE:
6335                         fk_trigger->deferrable = false;
6336                         fk_trigger->initdeferred = false;
6337                         fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd");
6338                         break;
6339                 case FKCONSTR_ACTION_SETNULL:
6340                         fk_trigger->deferrable = false;
6341                         fk_trigger->initdeferred = false;
6342                         fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd");
6343                         break;
6344                 case FKCONSTR_ACTION_SETDEFAULT:
6345                         fk_trigger->deferrable = false;
6346                         fk_trigger->initdeferred = false;
6347                         fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd");
6348                         break;
6349                 default:
6350                         elog(ERROR, "unrecognized FK action type: %d",
6351                                  (int) fkconstraint->fk_upd_action);
6352                         break;
6353         }
6354         fk_trigger->args = NIL;
6355
6356         (void) CreateTrigger(fk_trigger, NULL, constraintOid, indexOid, true);
6357 }
6358
6359 /*
6360  * ALTER TABLE DROP CONSTRAINT
6361  *
6362  * Like DROP COLUMN, we can't use the normal ALTER TABLE recursion mechanism.
6363  */
6364 static void
6365 ATExecDropConstraint(Relation rel, const char *constrName,
6366                                          DropBehavior behavior,
6367                                          bool recurse, bool recursing,
6368                                          bool missing_ok, LOCKMODE lockmode)
6369 {
6370         List       *children;
6371         ListCell   *child;
6372         Relation        conrel;
6373         Form_pg_constraint con;
6374         SysScanDesc scan;
6375         ScanKeyData key;
6376         HeapTuple       tuple;
6377         bool            found = false;
6378         bool            is_check_constraint = false;
6379
6380         /* At top level, permission check was done in ATPrepCmd, else do it */
6381         if (recursing)
6382                 ATSimplePermissions(rel, ATT_TABLE);
6383
6384         conrel = heap_open(ConstraintRelationId, RowExclusiveLock);
6385
6386         /*
6387          * Find and drop the target constraint
6388          */
6389         ScanKeyInit(&key,
6390                                 Anum_pg_constraint_conrelid,
6391                                 BTEqualStrategyNumber, F_OIDEQ,
6392                                 ObjectIdGetDatum(RelationGetRelid(rel)));
6393         scan = systable_beginscan(conrel, ConstraintRelidIndexId,
6394                                                           true, SnapshotNow, 1, &key);
6395
6396         while (HeapTupleIsValid(tuple = systable_getnext(scan)))
6397         {
6398                 ObjectAddress conobj;
6399
6400                 con = (Form_pg_constraint) GETSTRUCT(tuple);
6401
6402                 if (strcmp(NameStr(con->conname), constrName) != 0)
6403                         continue;
6404
6405                 /* Don't drop inherited constraints */
6406                 if (con->coninhcount > 0 && !recursing)
6407                         ereport(ERROR,
6408                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
6409                                          errmsg("cannot drop inherited constraint \"%s\" of relation \"%s\"",
6410                                                         constrName, RelationGetRelationName(rel))));
6411
6412                 /* Right now only CHECK constraints can be inherited */
6413                 if (con->contype == CONSTRAINT_CHECK)
6414                         is_check_constraint = true;
6415
6416                 /*
6417                  * Perform the actual constraint deletion
6418                  */
6419                 conobj.classId = ConstraintRelationId;
6420                 conobj.objectId = HeapTupleGetOid(tuple);
6421                 conobj.objectSubId = 0;
6422
6423                 performDeletion(&conobj, behavior);
6424
6425                 found = true;
6426         }
6427
6428         systable_endscan(scan);
6429
6430         if (!found)
6431         {
6432                 if (!missing_ok)
6433                 {
6434                         ereport(ERROR,
6435                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
6436                                 errmsg("constraint \"%s\" of relation \"%s\" does not exist",
6437                                            constrName, RelationGetRelationName(rel))));
6438                 }
6439                 else
6440                 {
6441                         ereport(NOTICE,
6442                                         (errmsg("constraint \"%s\" of relation \"%s\" does not exist, skipping",
6443                                                         constrName, RelationGetRelationName(rel))));
6444                         heap_close(conrel, RowExclusiveLock);
6445                         return;
6446                 }
6447         }
6448
6449         /*
6450          * Propagate to children as appropriate.  Unlike most other ALTER
6451          * routines, we have to do this one level of recursion at a time; we can't
6452          * use find_all_inheritors to do it in one pass.
6453          */
6454         if (is_check_constraint)
6455                 children = find_inheritance_children(RelationGetRelid(rel), lockmode);
6456         else
6457                 children = NIL;
6458
6459         foreach(child, children)
6460         {
6461                 Oid                     childrelid = lfirst_oid(child);
6462                 Relation        childrel;
6463
6464                 /* find_inheritance_children already got lock */
6465                 childrel = heap_open(childrelid, NoLock);
6466                 CheckTableNotInUse(childrel, "ALTER TABLE");
6467
6468                 ScanKeyInit(&key,
6469                                         Anum_pg_constraint_conrelid,
6470                                         BTEqualStrategyNumber, F_OIDEQ,
6471                                         ObjectIdGetDatum(childrelid));
6472                 scan = systable_beginscan(conrel, ConstraintRelidIndexId,
6473                                                                   true, SnapshotNow, 1, &key);
6474
6475                 found = false;
6476
6477                 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
6478                 {
6479                         HeapTuple       copy_tuple;
6480
6481                         con = (Form_pg_constraint) GETSTRUCT(tuple);
6482
6483                         /* Right now only CHECK constraints can be inherited */
6484                         if (con->contype != CONSTRAINT_CHECK)
6485                                 continue;
6486
6487                         if (strcmp(NameStr(con->conname), constrName) != 0)
6488                                 continue;
6489
6490                         found = true;
6491
6492                         if (con->coninhcount <= 0)      /* shouldn't happen */
6493                                 elog(ERROR, "relation %u has non-inherited constraint \"%s\"",
6494                                          childrelid, constrName);
6495
6496                         copy_tuple = heap_copytuple(tuple);
6497                         con = (Form_pg_constraint) GETSTRUCT(copy_tuple);
6498
6499                         if (recurse)
6500                         {
6501                                 /*
6502                                  * If the child constraint has other definition sources, just
6503                                  * decrement its inheritance count; if not, recurse to delete
6504                                  * it.
6505                                  */
6506                                 if (con->coninhcount == 1 && !con->conislocal)
6507                                 {
6508                                         /* Time to delete this child constraint, too */
6509                                         ATExecDropConstraint(childrel, constrName, behavior,
6510                                                                                  true, true,
6511                                                                                  false, lockmode);
6512                                 }
6513                                 else
6514                                 {
6515                                         /* Child constraint must survive my deletion */
6516                                         con->coninhcount--;
6517                                         simple_heap_update(conrel, &copy_tuple->t_self, copy_tuple);
6518                                         CatalogUpdateIndexes(conrel, copy_tuple);
6519
6520                                         /* Make update visible */
6521                                         CommandCounterIncrement();
6522                                 }
6523                         }
6524                         else
6525                         {
6526                                 /*
6527                                  * If we were told to drop ONLY in this table (no recursion),
6528                                  * we need to mark the inheritors' constraints as locally
6529                                  * defined rather than inherited.
6530                                  */
6531                                 con->coninhcount--;
6532                                 con->conislocal = true;
6533
6534                                 simple_heap_update(conrel, &copy_tuple->t_self, copy_tuple);
6535                                 CatalogUpdateIndexes(conrel, copy_tuple);
6536
6537                                 /* Make update visible */
6538                                 CommandCounterIncrement();
6539                         }
6540
6541                         heap_freetuple(copy_tuple);
6542                 }
6543
6544                 systable_endscan(scan);
6545
6546                 if (!found)
6547                         ereport(ERROR,
6548                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
6549                                 errmsg("constraint \"%s\" of relation \"%s\" does not exist",
6550                                            constrName,
6551                                            RelationGetRelationName(childrel))));
6552
6553                 heap_close(childrel, NoLock);
6554         }
6555
6556         heap_close(conrel, RowExclusiveLock);
6557 }
6558
6559 /*
6560  * ALTER COLUMN TYPE
6561  */
6562 static void
6563 ATPrepAlterColumnType(List **wqueue,
6564                                           AlteredTableInfo *tab, Relation rel,
6565                                           bool recurse, bool recursing,
6566                                           AlterTableCmd *cmd, LOCKMODE lockmode)
6567 {
6568         char       *colName = cmd->name;
6569         ColumnDef  *def = (ColumnDef *) cmd->def;
6570         TypeName   *typeName = def->typeName;
6571         Node       *transform = def->raw_default;
6572         HeapTuple       tuple;
6573         Form_pg_attribute attTup;
6574         AttrNumber      attnum;
6575         Oid                     targettype;
6576         int32           targettypmod;
6577         Oid                     targetcollid;
6578         NewColumnValue *newval;
6579         ParseState *pstate = make_parsestate(NULL);
6580
6581         if (rel->rd_rel->reloftype && !recursing)
6582                 ereport(ERROR,
6583                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
6584                                  errmsg("cannot alter column type of typed table")));
6585
6586         /* lookup the attribute so we can check inheritance status */
6587         tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
6588         if (!HeapTupleIsValid(tuple))
6589                 ereport(ERROR,
6590                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
6591                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
6592                                                 colName, RelationGetRelationName(rel))));
6593         attTup = (Form_pg_attribute) GETSTRUCT(tuple);
6594         attnum = attTup->attnum;
6595
6596         /* Can't alter a system attribute */
6597         if (attnum <= 0)
6598                 ereport(ERROR,
6599                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6600                                  errmsg("cannot alter system column \"%s\"",
6601                                                 colName)));
6602
6603         /* Don't alter inherited columns */
6604         if (attTup->attinhcount > 0 && !recursing)
6605                 ereport(ERROR,
6606                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
6607                                  errmsg("cannot alter inherited column \"%s\"",
6608                                                 colName)));
6609
6610         /* Look up the target type */
6611         typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod);
6612
6613         /* And the collation */
6614         targetcollid = GetColumnDefCollation(NULL, def, targettype);
6615
6616         /* make sure datatype is legal for a column */
6617         CheckAttributeType(colName, targettype, targetcollid,
6618                                            list_make1_oid(rel->rd_rel->reltype),
6619                                            false);
6620
6621         if (tab->relkind == RELKIND_RELATION)
6622         {
6623                 /*
6624                  * Set up an expression to transform the old data value to the new
6625                  * type. If a USING option was given, transform and use that
6626                  * expression, else just take the old value and try to coerce it.  We
6627                  * do this first so that type incompatibility can be detected before
6628                  * we waste effort, and because we need the expression to be parsed
6629                  * against the original table rowtype.
6630                  */
6631                 if (transform)
6632                 {
6633                         RangeTblEntry *rte;
6634
6635                         /* Expression must be able to access vars of old table */
6636                         rte = addRangeTableEntryForRelation(pstate,
6637                                                                                                 rel,
6638                                                                                                 NULL,
6639                                                                                                 false,
6640                                                                                                 true);
6641                         addRTEtoQuery(pstate, rte, false, true, true);
6642
6643                         transform = transformExpr(pstate, transform);
6644
6645                         /* It can't return a set */
6646                         if (expression_returns_set(transform))
6647                                 ereport(ERROR,
6648                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
6649                                           errmsg("transform expression must not return a set")));
6650
6651                         /* No subplans or aggregates, either... */
6652                         if (pstate->p_hasSubLinks)
6653                                 ereport(ERROR,
6654                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6655                                          errmsg("cannot use subquery in transform expression")));
6656                         if (pstate->p_hasAggs)
6657                                 ereport(ERROR,
6658                                                 (errcode(ERRCODE_GROUPING_ERROR),
6659                                                  errmsg("cannot use aggregate function in transform expression")));
6660                         if (pstate->p_hasWindowFuncs)
6661                                 ereport(ERROR,
6662                                                 (errcode(ERRCODE_WINDOWING_ERROR),
6663                                                  errmsg("cannot use window function in transform expression")));
6664                 }
6665                 else
6666                 {
6667                         transform = (Node *) makeVar(1, attnum,
6668                                                                                  attTup->atttypid, attTup->atttypmod,
6669                                                                                  attTup->attcollation,
6670                                                                                  0);
6671                 }
6672
6673                 transform = coerce_to_target_type(pstate,
6674                                                                                   transform, exprType(transform),
6675                                                                                   targettype, targettypmod,
6676                                                                                   COERCION_ASSIGNMENT,
6677                                                                                   COERCE_IMPLICIT_CAST,
6678                                                                                   -1);
6679                 if (transform == NULL)
6680                         ereport(ERROR,
6681                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
6682                                          errmsg("column \"%s\" cannot be cast to type %s",
6683                                                         colName, format_type_be(targettype))));
6684
6685                 /* Fix collations after all else */
6686                 assign_expr_collations(pstate, transform);
6687
6688                 /*
6689                  * Add a work queue item to make ATRewriteTable update the column
6690                  * contents.
6691                  */
6692                 newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
6693                 newval->attnum = attnum;
6694                 newval->expr = (Expr *) transform;
6695
6696                 tab->newvals = lappend(tab->newvals, newval);
6697                 if (ATColumnChangeRequiresRewrite(transform, attnum))
6698                         tab->rewrite = true;
6699         }
6700         else if (transform)
6701                 ereport(ERROR,
6702                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
6703                           errmsg("ALTER TYPE USING is only supported on plain tables")));
6704
6705         if (tab->relkind == RELKIND_COMPOSITE_TYPE ||
6706                 tab->relkind == RELKIND_FOREIGN_TABLE)
6707         {
6708                 /*
6709                  * For composite types, do this check now.      Tables will check it later
6710                  * when the table is being rewritten.
6711                  */
6712                 find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
6713         }
6714
6715         ReleaseSysCache(tuple);
6716
6717         /*
6718          * The recursion case is handled by ATSimpleRecursion.  However, if we are
6719          * told not to recurse, there had better not be any child tables; else the
6720          * alter would put them out of step.
6721          */
6722         if (recurse)
6723                 ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
6724         else if (!recursing &&
6725                          find_inheritance_children(RelationGetRelid(rel), NoLock) != NIL)
6726                 ereport(ERROR,
6727                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
6728                                  errmsg("type of inherited column \"%s\" must be changed in child tables too",
6729                                                 colName)));
6730
6731         if (tab->relkind == RELKIND_COMPOSITE_TYPE)
6732                 ATTypedTableRecursion(wqueue, rel, cmd, lockmode);
6733 }
6734
6735 /*
6736  * When the data type of a column is changed, a rewrite might not be required
6737  * if the new type is sufficiently identical to the old one, and the USING
6738  * clause isn't trying to insert some other value.  It's safe to skip the
6739  * rewrite if the old type is binary coercible to the new type, or if the
6740  * new type is an unconstrained domain over the old type.  In the case of a
6741  * constrained domain, we could get by with scanning the table and checking
6742  * the constraint rather than actually rewriting it, but we don't currently
6743  * try to do that.
6744  */
6745 static bool
6746 ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno)
6747 {
6748         Assert(expr != NULL);
6749
6750         for (;;)
6751         {
6752                 /* only one varno, so no need to check that */
6753                 if (IsA(expr, Var) &&((Var *) expr)->varattno == varattno)
6754                         return false;
6755                 else if (IsA(expr, RelabelType))
6756                         expr = (Node *) ((RelabelType *) expr)->arg;
6757                 else if (IsA(expr, CoerceToDomain))
6758                 {
6759                         CoerceToDomain *d = (CoerceToDomain *) expr;
6760
6761                         if (GetDomainConstraints(d->resulttype) != NIL)
6762                                 return true;
6763                         expr = (Node *) d->arg;
6764                 }
6765                 else
6766                         return true;
6767         }
6768 }
6769
6770 static void
6771 ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
6772                                           AlterTableCmd *cmd, LOCKMODE lockmode)
6773 {
6774         char       *colName = cmd->name;
6775         ColumnDef  *def = (ColumnDef *) cmd->def;
6776         TypeName   *typeName = def->typeName;
6777         HeapTuple       heapTup;
6778         Form_pg_attribute attTup;
6779         AttrNumber      attnum;
6780         HeapTuple       typeTuple;
6781         Form_pg_type tform;
6782         Oid                     targettype;
6783         int32           targettypmod;
6784         Oid                     targetcollid;
6785         Node       *defaultexpr;
6786         Relation        attrelation;
6787         Relation        depRel;
6788         ScanKeyData key[3];
6789         SysScanDesc scan;
6790         HeapTuple       depTup;
6791
6792         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
6793
6794         /* Look up the target column */
6795         heapTup = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
6796         if (!HeapTupleIsValid(heapTup))         /* shouldn't happen */
6797                 ereport(ERROR,
6798                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
6799                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
6800                                                 colName, RelationGetRelationName(rel))));
6801         attTup = (Form_pg_attribute) GETSTRUCT(heapTup);
6802         attnum = attTup->attnum;
6803
6804         /* Check for multiple ALTER TYPE on same column --- can't cope */
6805         if (attTup->atttypid != tab->oldDesc->attrs[attnum - 1]->atttypid ||
6806                 attTup->atttypmod != tab->oldDesc->attrs[attnum - 1]->atttypmod)
6807                 ereport(ERROR,
6808                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6809                                  errmsg("cannot alter type of column \"%s\" twice",
6810                                                 colName)));
6811
6812         /* Look up the target type (should not fail, since prep found it) */
6813         typeTuple = typenameType(NULL, typeName, &targettypmod);
6814         tform = (Form_pg_type) GETSTRUCT(typeTuple);
6815         targettype = HeapTupleGetOid(typeTuple);
6816         /* And the collation */
6817         targetcollid = GetColumnDefCollation(NULL, def, targettype);
6818
6819         /*
6820          * If there is a default expression for the column, get it and ensure we
6821          * can coerce it to the new datatype.  (We must do this before changing
6822          * the column type, because build_column_default itself will try to
6823          * coerce, and will not issue the error message we want if it fails.)
6824          *
6825          * We remove any implicit coercion steps at the top level of the old
6826          * default expression; this has been agreed to satisfy the principle of
6827          * least surprise.      (The conversion to the new column type should act like
6828          * it started from what the user sees as the stored expression, and the
6829          * implicit coercions aren't going to be shown.)
6830          */
6831         if (attTup->atthasdef)
6832         {
6833                 defaultexpr = build_column_default(rel, attnum);
6834                 Assert(defaultexpr);
6835                 defaultexpr = strip_implicit_coercions(defaultexpr);
6836                 defaultexpr = coerce_to_target_type(NULL,               /* no UNKNOWN params */
6837                                                                                   defaultexpr, exprType(defaultexpr),
6838                                                                                         targettype, targettypmod,
6839                                                                                         COERCION_ASSIGNMENT,
6840                                                                                         COERCE_IMPLICIT_CAST,
6841                                                                                         -1);
6842                 if (defaultexpr == NULL)
6843                         ereport(ERROR,
6844                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
6845                                 errmsg("default for column \"%s\" cannot be cast to type %s",
6846                                            colName, format_type_be(targettype))));
6847         }
6848         else
6849                 defaultexpr = NULL;
6850
6851         /*
6852          * Find everything that depends on the column (constraints, indexes, etc),
6853          * and record enough information to let us recreate the objects.
6854          *
6855          * The actual recreation does not happen here, but only after we have
6856          * performed all the individual ALTER TYPE operations.  We have to save
6857          * the info before executing ALTER TYPE, though, else the deparser will
6858          * get confused.
6859          *
6860          * There could be multiple entries for the same object, so we must check
6861          * to ensure we process each one only once.  Note: we assume that an index
6862          * that implements a constraint will not show a direct dependency on the
6863          * column.
6864          */
6865         depRel = heap_open(DependRelationId, RowExclusiveLock);
6866
6867         ScanKeyInit(&key[0],
6868                                 Anum_pg_depend_refclassid,
6869                                 BTEqualStrategyNumber, F_OIDEQ,
6870                                 ObjectIdGetDatum(RelationRelationId));
6871         ScanKeyInit(&key[1],
6872                                 Anum_pg_depend_refobjid,
6873                                 BTEqualStrategyNumber, F_OIDEQ,
6874                                 ObjectIdGetDatum(RelationGetRelid(rel)));
6875         ScanKeyInit(&key[2],
6876                                 Anum_pg_depend_refobjsubid,
6877                                 BTEqualStrategyNumber, F_INT4EQ,
6878                                 Int32GetDatum((int32) attnum));
6879
6880         scan = systable_beginscan(depRel, DependReferenceIndexId, true,
6881                                                           SnapshotNow, 3, key);
6882
6883         while (HeapTupleIsValid(depTup = systable_getnext(scan)))
6884         {
6885                 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
6886                 ObjectAddress foundObject;
6887
6888                 /* We don't expect any PIN dependencies on columns */
6889                 if (foundDep->deptype == DEPENDENCY_PIN)
6890                         elog(ERROR, "cannot alter type of a pinned column");
6891
6892                 foundObject.classId = foundDep->classid;
6893                 foundObject.objectId = foundDep->objid;
6894                 foundObject.objectSubId = foundDep->objsubid;
6895
6896                 switch (getObjectClass(&foundObject))
6897                 {
6898                         case OCLASS_CLASS:
6899                                 {
6900                                         char            relKind = get_rel_relkind(foundObject.objectId);
6901
6902                                         if (relKind == RELKIND_INDEX)
6903                                         {
6904                                                 Assert(foundObject.objectSubId == 0);
6905                                                 if (!list_member_oid(tab->changedIndexOids, foundObject.objectId))
6906                                                 {
6907                                                         tab->changedIndexOids = lappend_oid(tab->changedIndexOids,
6908                                                                                                            foundObject.objectId);
6909                                                         tab->changedIndexDefs = lappend(tab->changedIndexDefs,
6910                                                            pg_get_indexdef_string(foundObject.objectId));
6911                                                 }
6912                                         }
6913                                         else if (relKind == RELKIND_SEQUENCE)
6914                                         {
6915                                                 /*
6916                                                  * This must be a SERIAL column's sequence.  We need
6917                                                  * not do anything to it.
6918                                                  */
6919                                                 Assert(foundObject.objectSubId == 0);
6920                                         }
6921                                         else
6922                                         {
6923                                                 /* Not expecting any other direct dependencies... */
6924                                                 elog(ERROR, "unexpected object depending on column: %s",
6925                                                          getObjectDescription(&foundObject));
6926                                         }
6927                                         break;
6928                                 }
6929
6930                         case OCLASS_CONSTRAINT:
6931                                 Assert(foundObject.objectSubId == 0);
6932                                 if (!list_member_oid(tab->changedConstraintOids,
6933                                                                          foundObject.objectId))
6934                                 {
6935                                         char       *defstring = pg_get_constraintdef_string(foundObject.objectId);
6936
6937                                         /*
6938                                          * Put NORMAL dependencies at the front of the list and
6939                                          * AUTO dependencies at the back.  This makes sure that
6940                                          * foreign-key constraints depending on this column will
6941                                          * be dropped before unique or primary-key constraints of
6942                                          * the column; which we must have because the FK
6943                                          * constraints depend on the indexes belonging to the
6944                                          * unique constraints.
6945                                          */
6946                                         if (foundDep->deptype == DEPENDENCY_NORMAL)
6947                                         {
6948                                                 tab->changedConstraintOids =
6949                                                         lcons_oid(foundObject.objectId,
6950                                                                           tab->changedConstraintOids);
6951                                                 tab->changedConstraintDefs =
6952                                                         lcons(defstring,
6953                                                                   tab->changedConstraintDefs);
6954                                         }
6955                                         else
6956                                         {
6957                                                 tab->changedConstraintOids =
6958                                                         lappend_oid(tab->changedConstraintOids,
6959                                                                                 foundObject.objectId);
6960                                                 tab->changedConstraintDefs =
6961                                                         lappend(tab->changedConstraintDefs,
6962                                                                         defstring);
6963                                         }
6964                                 }
6965                                 break;
6966
6967                         case OCLASS_REWRITE:
6968                                 /* XXX someday see if we can cope with revising views */
6969                                 ereport(ERROR,
6970                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6971                                                  errmsg("cannot alter type of a column used by a view or rule"),
6972                                                  errdetail("%s depends on column \"%s\"",
6973                                                                    getObjectDescription(&foundObject),
6974                                                                    colName)));
6975                                 break;
6976
6977                         case OCLASS_TRIGGER:
6978
6979                                 /*
6980                                  * A trigger can depend on a column because the column is
6981                                  * specified as an update target, or because the column is
6982                                  * used in the trigger's WHEN condition.  The first case would
6983                                  * not require any extra work, but the second case would
6984                                  * require updating the WHEN expression, which will take a
6985                                  * significant amount of new code.      Since we can't easily tell
6986                                  * which case applies, we punt for both.  FIXME someday.
6987                                  */
6988                                 ereport(ERROR,
6989                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6990                                                  errmsg("cannot alter type of a column used in a trigger definition"),
6991                                                  errdetail("%s depends on column \"%s\"",
6992                                                                    getObjectDescription(&foundObject),
6993                                                                    colName)));
6994                                 break;
6995
6996                         case OCLASS_DEFAULT:
6997
6998                                 /*
6999                                  * Ignore the column's default expression, since we will fix
7000                                  * it below.
7001                                  */
7002                                 Assert(defaultexpr);
7003                                 break;
7004
7005                         case OCLASS_PROC:
7006                         case OCLASS_TYPE:
7007                         case OCLASS_CAST:
7008                         case OCLASS_COLLATION:
7009                         case OCLASS_CONVERSION:
7010                         case OCLASS_LANGUAGE:
7011                         case OCLASS_LARGEOBJECT:
7012                         case OCLASS_OPERATOR:
7013                         case OCLASS_OPCLASS:
7014                         case OCLASS_OPFAMILY:
7015                         case OCLASS_AMOP:
7016                         case OCLASS_AMPROC:
7017                         case OCLASS_SCHEMA:
7018                         case OCLASS_TSPARSER:
7019                         case OCLASS_TSDICT:
7020                         case OCLASS_TSTEMPLATE:
7021                         case OCLASS_TSCONFIG:
7022                         case OCLASS_ROLE:
7023                         case OCLASS_DATABASE:
7024                         case OCLASS_TBLSPACE:
7025                         case OCLASS_FDW:
7026                         case OCLASS_FOREIGN_SERVER:
7027                         case OCLASS_USER_MAPPING:
7028                         case OCLASS_DEFACL:
7029                         case OCLASS_EXTENSION:
7030
7031                                 /*
7032                                  * We don't expect any of these sorts of objects to depend on
7033                                  * a column.
7034                                  */
7035                                 elog(ERROR, "unexpected object depending on column: %s",
7036                                          getObjectDescription(&foundObject));
7037                                 break;
7038
7039                         default:
7040                                 elog(ERROR, "unrecognized object class: %u",
7041                                          foundObject.classId);
7042                 }
7043         }
7044
7045         systable_endscan(scan);
7046
7047         /*
7048          * Now scan for dependencies of this column on other things.  The only
7049          * thing we should find is the dependency on the column datatype, which we
7050          * want to remove, and possibly a collation dependency.
7051          */
7052         ScanKeyInit(&key[0],
7053                                 Anum_pg_depend_classid,
7054                                 BTEqualStrategyNumber, F_OIDEQ,
7055                                 ObjectIdGetDatum(RelationRelationId));
7056         ScanKeyInit(&key[1],
7057                                 Anum_pg_depend_objid,
7058                                 BTEqualStrategyNumber, F_OIDEQ,
7059                                 ObjectIdGetDatum(RelationGetRelid(rel)));
7060         ScanKeyInit(&key[2],
7061                                 Anum_pg_depend_objsubid,
7062                                 BTEqualStrategyNumber, F_INT4EQ,
7063                                 Int32GetDatum((int32) attnum));
7064
7065         scan = systable_beginscan(depRel, DependDependerIndexId, true,
7066                                                           SnapshotNow, 3, key);
7067
7068         while (HeapTupleIsValid(depTup = systable_getnext(scan)))
7069         {
7070                 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
7071
7072                 if (foundDep->deptype != DEPENDENCY_NORMAL)
7073                         elog(ERROR, "found unexpected dependency type '%c'",
7074                                  foundDep->deptype);
7075                 if (!(foundDep->refclassid == TypeRelationId &&
7076                           foundDep->refobjid == attTup->atttypid) &&
7077                         !(foundDep->refclassid == CollationRelationId &&
7078                           foundDep->refobjid == attTup->attcollation))
7079                         elog(ERROR, "found unexpected dependency for column");
7080
7081                 simple_heap_delete(depRel, &depTup->t_self);
7082         }
7083
7084         systable_endscan(scan);
7085
7086         heap_close(depRel, RowExclusiveLock);
7087
7088         /*
7089          * Here we go --- change the recorded column type and collation.  (Note
7090          * heapTup is a copy of the syscache entry, so okay to scribble on.)
7091          */
7092         attTup->atttypid = targettype;
7093         attTup->atttypmod = targettypmod;
7094         attTup->attcollation = targetcollid;
7095         attTup->attndims = list_length(typeName->arrayBounds);
7096         attTup->attlen = tform->typlen;
7097         attTup->attbyval = tform->typbyval;
7098         attTup->attalign = tform->typalign;
7099         attTup->attstorage = tform->typstorage;
7100
7101         ReleaseSysCache(typeTuple);
7102
7103         simple_heap_update(attrelation, &heapTup->t_self, heapTup);
7104
7105         /* keep system catalog indexes current */
7106         CatalogUpdateIndexes(attrelation, heapTup);
7107
7108         heap_close(attrelation, RowExclusiveLock);
7109
7110         /* Install dependencies on new datatype and collation */
7111         add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype);
7112         add_column_collation_dependency(RelationGetRelid(rel), attnum, targetcollid);
7113
7114         /*
7115          * Drop any pg_statistic entry for the column, since it's now wrong type
7116          */
7117         RemoveStatistics(RelationGetRelid(rel), attnum);
7118
7119         /*
7120          * Update the default, if present, by brute force --- remove and re-add
7121          * the default.  Probably unsafe to take shortcuts, since the new version
7122          * may well have additional dependencies.  (It's okay to do this now,
7123          * rather than after other ALTER TYPE commands, since the default won't
7124          * depend on other column types.)
7125          */
7126         if (defaultexpr)
7127         {
7128                 /* Must make new row visible since it will be updated again */
7129                 CommandCounterIncrement();
7130
7131                 /*
7132                  * We use RESTRICT here for safety, but at present we do not expect
7133                  * anything to depend on the default.
7134                  */
7135                 RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true);
7136
7137                 StoreAttrDefault(rel, attnum, defaultexpr);
7138         }
7139
7140         /* Cleanup */
7141         heap_freetuple(heapTup);
7142 }
7143
7144 /*
7145  * Cleanup after we've finished all the ALTER TYPE operations for a
7146  * particular relation.  We have to drop and recreate all the indexes
7147  * and constraints that depend on the altered columns.
7148  */
7149 static void
7150 ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
7151 {
7152         ObjectAddress obj;
7153         ListCell   *l;
7154
7155         /*
7156          * Re-parse the index and constraint definitions, and attach them to the
7157          * appropriate work queue entries.      We do this before dropping because in
7158          * the case of a FOREIGN KEY constraint, we might not yet have exclusive
7159          * lock on the table the constraint is attached to, and we need to get
7160          * that before dropping.  It's safe because the parser won't actually look
7161          * at the catalogs to detect the existing entry.
7162          */
7163         foreach(l, tab->changedIndexDefs)
7164                 ATPostAlterTypeParse((char *) lfirst(l), wqueue, lockmode);
7165         foreach(l, tab->changedConstraintDefs)
7166                 ATPostAlterTypeParse((char *) lfirst(l), wqueue, lockmode);
7167
7168         /*
7169          * Now we can drop the existing constraints and indexes --- constraints
7170          * first, since some of them might depend on the indexes.  In fact, we
7171          * have to delete FOREIGN KEY constraints before UNIQUE constraints, but
7172          * we already ordered the constraint list to ensure that would happen. It
7173          * should be okay to use DROP_RESTRICT here, since nothing else should be
7174          * depending on these objects.
7175          */
7176         foreach(l, tab->changedConstraintOids)
7177         {
7178                 obj.classId = ConstraintRelationId;
7179                 obj.objectId = lfirst_oid(l);
7180                 obj.objectSubId = 0;
7181                 performDeletion(&obj, DROP_RESTRICT);
7182         }
7183
7184         foreach(l, tab->changedIndexOids)
7185         {
7186                 obj.classId = RelationRelationId;
7187                 obj.objectId = lfirst_oid(l);
7188                 obj.objectSubId = 0;
7189                 performDeletion(&obj, DROP_RESTRICT);
7190         }
7191
7192         /*
7193          * The objects will get recreated during subsequent passes over the work
7194          * queue.
7195          */
7196 }
7197
7198 static void
7199 ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode)
7200 {
7201         List       *raw_parsetree_list;
7202         List       *querytree_list;
7203         ListCell   *list_item;
7204
7205         /*
7206          * We expect that we will get only ALTER TABLE and CREATE INDEX
7207          * statements. Hence, there is no need to pass them through
7208          * parse_analyze() or the rewriter, but instead we need to pass them
7209          * through parse_utilcmd.c to make them ready for execution.
7210          */
7211         raw_parsetree_list = raw_parser(cmd);
7212         querytree_list = NIL;
7213         foreach(list_item, raw_parsetree_list)
7214         {
7215                 Node       *stmt = (Node *) lfirst(list_item);
7216
7217                 if (IsA(stmt, IndexStmt))
7218                         querytree_list = lappend(querytree_list,
7219                                                                          transformIndexStmt((IndexStmt *) stmt,
7220                                                                                                                 cmd));
7221                 else if (IsA(stmt, AlterTableStmt))
7222                         querytree_list = list_concat(querytree_list,
7223                                                          transformAlterTableStmt((AlterTableStmt *) stmt,
7224                                                                                                          cmd));
7225                 else
7226                         querytree_list = lappend(querytree_list, stmt);
7227         }
7228
7229         /*
7230          * Attach each generated command to the proper place in the work queue.
7231          * Note this could result in creation of entirely new work-queue entries.
7232          */
7233         foreach(list_item, querytree_list)
7234         {
7235                 Node       *stm = (Node *) lfirst(list_item);
7236                 Relation        rel;
7237                 AlteredTableInfo *tab;
7238
7239                 switch (nodeTag(stm))
7240                 {
7241                         case T_IndexStmt:
7242                                 {
7243                                         IndexStmt  *stmt = (IndexStmt *) stm;
7244                                         AlterTableCmd *newcmd;
7245
7246                                         rel = relation_openrv(stmt->relation, lockmode);
7247                                         tab = ATGetQueueEntry(wqueue, rel);
7248                                         newcmd = makeNode(AlterTableCmd);
7249                                         newcmd->subtype = AT_ReAddIndex;
7250                                         newcmd->def = (Node *) stmt;
7251                                         tab->subcmds[AT_PASS_OLD_INDEX] =
7252                                                 lappend(tab->subcmds[AT_PASS_OLD_INDEX], newcmd);
7253                                         relation_close(rel, NoLock);
7254                                         break;
7255                                 }
7256                         case T_AlterTableStmt:
7257                                 {
7258                                         AlterTableStmt *stmt = (AlterTableStmt *) stm;
7259                                         ListCell   *lcmd;
7260
7261                                         rel = relation_openrv(stmt->relation, lockmode);
7262                                         tab = ATGetQueueEntry(wqueue, rel);
7263                                         foreach(lcmd, stmt->cmds)
7264                                         {
7265                                                 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
7266
7267                                                 switch (cmd->subtype)
7268                                                 {
7269                                                         case AT_AddIndex:
7270                                                                 cmd->subtype = AT_ReAddIndex;
7271                                                                 tab->subcmds[AT_PASS_OLD_INDEX] =
7272                                                                         lappend(tab->subcmds[AT_PASS_OLD_INDEX], cmd);
7273                                                                 break;
7274                                                         case AT_AddConstraint:
7275                                                                 tab->subcmds[AT_PASS_OLD_CONSTR] =
7276                                                                         lappend(tab->subcmds[AT_PASS_OLD_CONSTR], cmd);
7277                                                                 break;
7278                                                         default:
7279                                                                 elog(ERROR, "unexpected statement type: %d",
7280                                                                          (int) cmd->subtype);
7281                                                 }
7282                                         }
7283                                         relation_close(rel, NoLock);
7284                                         break;
7285                                 }
7286                         default:
7287                                 elog(ERROR, "unexpected statement type: %d",
7288                                          (int) nodeTag(stm));
7289                 }
7290         }
7291 }
7292
7293
7294 /*
7295  * ALTER TABLE OWNER
7296  *
7297  * recursing is true if we are recursing from a table to its indexes,
7298  * sequences, or toast table.  We don't allow the ownership of those things to
7299  * be changed separately from the parent table.  Also, we can skip permission
7300  * checks (this is necessary not just an optimization, else we'd fail to
7301  * handle toast tables properly).
7302  *
7303  * recursing is also true if ALTER TYPE OWNER is calling us to fix up a
7304  * free-standing composite type.
7305  */
7306 void
7307 ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lockmode)
7308 {
7309         Relation        target_rel;
7310         Relation        class_rel;
7311         HeapTuple       tuple;
7312         Form_pg_class tuple_class;
7313
7314         /*
7315          * Get exclusive lock till end of transaction on the target table. Use
7316          * relation_open so that we can work on indexes and sequences.
7317          */
7318         target_rel = relation_open(relationOid, lockmode);
7319
7320         /* Get its pg_class tuple, too */
7321         class_rel = heap_open(RelationRelationId, RowExclusiveLock);
7322
7323         tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relationOid));
7324         if (!HeapTupleIsValid(tuple))
7325                 elog(ERROR, "cache lookup failed for relation %u", relationOid);
7326         tuple_class = (Form_pg_class) GETSTRUCT(tuple);
7327
7328         /* Can we change the ownership of this tuple? */
7329         switch (tuple_class->relkind)
7330         {
7331                 case RELKIND_RELATION:
7332                 case RELKIND_VIEW:
7333                 case RELKIND_FOREIGN_TABLE:
7334                         /* ok to change owner */
7335                         break;
7336                 case RELKIND_INDEX:
7337                         if (!recursing)
7338                         {
7339                                 /*
7340                                  * Because ALTER INDEX OWNER used to be allowed, and in fact
7341                                  * is generated by old versions of pg_dump, we give a warning
7342                                  * and do nothing rather than erroring out.  Also, to avoid
7343                                  * unnecessary chatter while restoring those old dumps, say
7344                                  * nothing at all if the command would be a no-op anyway.
7345                                  */
7346                                 if (tuple_class->relowner != newOwnerId)
7347                                         ereport(WARNING,
7348                                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7349                                                          errmsg("cannot change owner of index \"%s\"",
7350                                                                         NameStr(tuple_class->relname)),
7351                                                          errhint("Change the ownership of the index's table, instead.")));
7352                                 /* quick hack to exit via the no-op path */
7353                                 newOwnerId = tuple_class->relowner;
7354                         }
7355                         break;
7356                 case RELKIND_SEQUENCE:
7357                         if (!recursing &&
7358                                 tuple_class->relowner != newOwnerId)
7359                         {
7360                                 /* if it's an owned sequence, disallow changing it by itself */
7361                                 Oid                     tableId;
7362                                 int32           colId;
7363
7364                                 if (sequenceIsOwned(relationOid, &tableId, &colId))
7365                                         ereport(ERROR,
7366                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7367                                                          errmsg("cannot change owner of sequence \"%s\"",
7368                                                                         NameStr(tuple_class->relname)),
7369                                           errdetail("Sequence \"%s\" is linked to table \"%s\".",
7370                                                                 NameStr(tuple_class->relname),
7371                                                                 get_rel_name(tableId))));
7372                         }
7373                         break;
7374                 case RELKIND_COMPOSITE_TYPE:
7375                         if (recursing)
7376                                 break;
7377                         ereport(ERROR,
7378                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7379                                          errmsg("\"%s\" is a composite type",
7380                                                         NameStr(tuple_class->relname)),
7381                                          errhint("Use ALTER TYPE instead.")));
7382                         break;
7383                 case RELKIND_TOASTVALUE:
7384                         if (recursing)
7385                                 break;
7386                         /* FALL THRU */
7387                 default:
7388                         ereport(ERROR,
7389                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7390                                          errmsg("\"%s\" is not a table, view, sequence, or foreign tabl, or foreign tablee",
7391                                                         NameStr(tuple_class->relname))));
7392         }
7393
7394         /*
7395          * If the new owner is the same as the existing owner, consider the
7396          * command to have succeeded.  This is for dump restoration purposes.
7397          */
7398         if (tuple_class->relowner != newOwnerId)
7399         {
7400                 Datum           repl_val[Natts_pg_class];
7401                 bool            repl_null[Natts_pg_class];
7402                 bool            repl_repl[Natts_pg_class];
7403                 Acl                *newAcl;
7404                 Datum           aclDatum;
7405                 bool            isNull;
7406                 HeapTuple       newtuple;
7407
7408                 /* skip permission checks when recursing to index or toast table */
7409                 if (!recursing)
7410                 {
7411                         /* Superusers can always do it */
7412                         if (!superuser())
7413                         {
7414                                 Oid                     namespaceOid = tuple_class->relnamespace;
7415                                 AclResult       aclresult;
7416
7417                                 /* Otherwise, must be owner of the existing object */
7418                                 if (!pg_class_ownercheck(relationOid, GetUserId()))
7419                                         aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
7420                                                                    RelationGetRelationName(target_rel));
7421
7422                                 /* Must be able to become new owner */
7423                                 check_is_member_of_role(GetUserId(), newOwnerId);
7424
7425                                 /* New owner must have CREATE privilege on namespace */
7426                                 aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
7427                                                                                                   ACL_CREATE);
7428                                 if (aclresult != ACLCHECK_OK)
7429                                         aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
7430                                                                    get_namespace_name(namespaceOid));
7431                         }
7432                 }
7433
7434                 memset(repl_null, false, sizeof(repl_null));
7435                 memset(repl_repl, false, sizeof(repl_repl));
7436
7437                 repl_repl[Anum_pg_class_relowner - 1] = true;
7438                 repl_val[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(newOwnerId);
7439
7440                 /*
7441                  * Determine the modified ACL for the new owner.  This is only
7442                  * necessary when the ACL is non-null.
7443                  */
7444                 aclDatum = SysCacheGetAttr(RELOID, tuple,
7445                                                                    Anum_pg_class_relacl,
7446                                                                    &isNull);
7447                 if (!isNull)
7448                 {
7449                         newAcl = aclnewowner(DatumGetAclP(aclDatum),
7450                                                                  tuple_class->relowner, newOwnerId);
7451                         repl_repl[Anum_pg_class_relacl - 1] = true;
7452                         repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl);
7453                 }
7454
7455                 newtuple = heap_modify_tuple(tuple, RelationGetDescr(class_rel), repl_val, repl_null, repl_repl);
7456
7457                 simple_heap_update(class_rel, &newtuple->t_self, newtuple);
7458                 CatalogUpdateIndexes(class_rel, newtuple);
7459
7460                 heap_freetuple(newtuple);
7461
7462                 /*
7463                  * Update owner dependency reference, if any.  A composite type has
7464                  * none, because it's tracked for the pg_type entry instead of here;
7465                  * indexes and TOAST tables don't have their own entries either.
7466                  */
7467                 if (tuple_class->relkind != RELKIND_COMPOSITE_TYPE &&
7468                         tuple_class->relkind != RELKIND_INDEX &&
7469                         tuple_class->relkind != RELKIND_TOASTVALUE)
7470                         changeDependencyOnOwner(RelationRelationId, relationOid,
7471                                                                         newOwnerId);
7472
7473                 /*
7474                  * Also change the ownership of the table's rowtype, if it has one
7475                  */
7476                 if (tuple_class->relkind != RELKIND_INDEX)
7477                         AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId,
7478                                                          tuple_class->relkind == RELKIND_COMPOSITE_TYPE);
7479
7480                 /*
7481                  * If we are operating on a table, also change the ownership of any
7482                  * indexes and sequences that belong to the table, as well as the
7483                  * table's toast table (if it has one)
7484                  */
7485                 if (tuple_class->relkind == RELKIND_RELATION ||
7486                         tuple_class->relkind == RELKIND_TOASTVALUE)
7487                 {
7488                         List       *index_oid_list;
7489                         ListCell   *i;
7490
7491                         /* Find all the indexes belonging to this relation */
7492                         index_oid_list = RelationGetIndexList(target_rel);
7493
7494                         /* For each index, recursively change its ownership */
7495                         foreach(i, index_oid_list)
7496                                 ATExecChangeOwner(lfirst_oid(i), newOwnerId, true, lockmode);
7497
7498                         list_free(index_oid_list);
7499                 }
7500
7501                 if (tuple_class->relkind == RELKIND_RELATION)
7502                 {
7503                         /* If it has a toast table, recurse to change its ownership */
7504                         if (tuple_class->reltoastrelid != InvalidOid)
7505                                 ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId,
7506                                                                   true, lockmode);
7507
7508                         /* If it has dependent sequences, recurse to change them too */
7509                         change_owner_recurse_to_sequences(relationOid, newOwnerId, lockmode);
7510                 }
7511         }
7512
7513         ReleaseSysCache(tuple);
7514         heap_close(class_rel, RowExclusiveLock);
7515         relation_close(target_rel, NoLock);
7516 }
7517
7518 /*
7519  * change_owner_recurse_to_sequences
7520  *
7521  * Helper function for ATExecChangeOwner.  Examines pg_depend searching
7522  * for sequences that are dependent on serial columns, and changes their
7523  * ownership.
7524  */
7525 static void
7526 change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId, LOCKMODE lockmode)
7527 {
7528         Relation        depRel;
7529         SysScanDesc scan;
7530         ScanKeyData key[2];
7531         HeapTuple       tup;
7532
7533         /*
7534          * SERIAL sequences are those having an auto dependency on one of the
7535          * table's columns (we don't care *which* column, exactly).
7536          */
7537         depRel = heap_open(DependRelationId, AccessShareLock);
7538
7539         ScanKeyInit(&key[0],
7540                                 Anum_pg_depend_refclassid,
7541                                 BTEqualStrategyNumber, F_OIDEQ,
7542                                 ObjectIdGetDatum(RelationRelationId));
7543         ScanKeyInit(&key[1],
7544                                 Anum_pg_depend_refobjid,
7545                                 BTEqualStrategyNumber, F_OIDEQ,
7546                                 ObjectIdGetDatum(relationOid));
7547         /* we leave refobjsubid unspecified */
7548
7549         scan = systable_beginscan(depRel, DependReferenceIndexId, true,
7550                                                           SnapshotNow, 2, key);
7551
7552         while (HeapTupleIsValid(tup = systable_getnext(scan)))
7553         {
7554                 Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
7555                 Relation        seqRel;
7556
7557                 /* skip dependencies other than auto dependencies on columns */
7558                 if (depForm->refobjsubid == 0 ||
7559                         depForm->classid != RelationRelationId ||
7560                         depForm->objsubid != 0 ||
7561                         depForm->deptype != DEPENDENCY_AUTO)
7562                         continue;
7563
7564                 /* Use relation_open just in case it's an index */
7565                 seqRel = relation_open(depForm->objid, lockmode);
7566
7567                 /* skip non-sequence relations */
7568                 if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
7569                 {
7570                         /* No need to keep the lock */
7571                         relation_close(seqRel, lockmode);
7572                         continue;
7573                 }
7574
7575                 /* We don't need to close the sequence while we alter it. */
7576                 ATExecChangeOwner(depForm->objid, newOwnerId, true, lockmode);
7577
7578                 /* Now we can close it.  Keep the lock till end of transaction. */
7579                 relation_close(seqRel, NoLock);
7580         }
7581
7582         systable_endscan(scan);
7583
7584         relation_close(depRel, AccessShareLock);
7585 }
7586
7587 /*
7588  * ALTER TABLE CLUSTER ON
7589  *
7590  * The only thing we have to do is to change the indisclustered bits.
7591  */
7592 static void
7593 ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode)
7594 {
7595         Oid                     indexOid;
7596
7597         indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace);
7598
7599         if (!OidIsValid(indexOid))
7600                 ereport(ERROR,
7601                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
7602                                  errmsg("index \"%s\" for table \"%s\" does not exist",
7603                                                 indexName, RelationGetRelationName(rel))));
7604
7605         /* Check index is valid to cluster on */
7606         check_index_is_clusterable(rel, indexOid, false, lockmode);
7607
7608         /* And do the work */
7609         mark_index_clustered(rel, indexOid);
7610 }
7611
7612 /*
7613  * ALTER TABLE SET WITHOUT CLUSTER
7614  *
7615  * We have to find any indexes on the table that have indisclustered bit
7616  * set and turn it off.
7617  */
7618 static void
7619 ATExecDropCluster(Relation rel, LOCKMODE lockmode)
7620 {
7621         mark_index_clustered(rel, InvalidOid);
7622 }
7623
7624 /*
7625  * ALTER TABLE SET TABLESPACE
7626  */
7627 static void
7628 ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename, LOCKMODE lockmode)
7629 {
7630         Oid                     tablespaceId;
7631         AclResult       aclresult;
7632
7633         /* Check that the tablespace exists */
7634         tablespaceId = get_tablespace_oid(tablespacename, false);
7635
7636         /* Check its permissions */
7637         aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), ACL_CREATE);
7638         if (aclresult != ACLCHECK_OK)
7639                 aclcheck_error(aclresult, ACL_KIND_TABLESPACE, tablespacename);
7640
7641         /* Save info for Phase 3 to do the real work */
7642         if (OidIsValid(tab->newTableSpace))
7643                 ereport(ERROR,
7644                                 (errcode(ERRCODE_SYNTAX_ERROR),
7645                                  errmsg("cannot have multiple SET TABLESPACE subcommands")));
7646         tab->newTableSpace = tablespaceId;
7647 }
7648
7649 /*
7650  * ALTER TABLE/INDEX SET (...) or RESET (...)
7651  */
7652 static void
7653 ATExecSetRelOptions(Relation rel, List *defList, bool isReset, LOCKMODE lockmode)
7654 {
7655         Oid                     relid;
7656         Relation        pgclass;
7657         HeapTuple       tuple;
7658         HeapTuple       newtuple;
7659         Datum           datum;
7660         bool            isnull;
7661         Datum           newOptions;
7662         Datum           repl_val[Natts_pg_class];
7663         bool            repl_null[Natts_pg_class];
7664         bool            repl_repl[Natts_pg_class];
7665         static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
7666
7667         if (defList == NIL)
7668                 return;                                 /* nothing to do */
7669
7670         pgclass = heap_open(RelationRelationId, RowExclusiveLock);
7671
7672         /* Get the old reloptions */
7673         relid = RelationGetRelid(rel);
7674         tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
7675         if (!HeapTupleIsValid(tuple))
7676                 elog(ERROR, "cache lookup failed for relation %u", relid);
7677
7678         datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
7679
7680         /* Generate new proposed reloptions (text array) */
7681         newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
7682                                                                    defList, NULL, validnsps, false, isReset);
7683
7684         /* Validate */
7685         switch (rel->rd_rel->relkind)
7686         {
7687                 case RELKIND_RELATION:
7688                 case RELKIND_TOASTVALUE:
7689                         (void) heap_reloptions(rel->rd_rel->relkind, newOptions, true);
7690                         break;
7691                 case RELKIND_INDEX:
7692                         (void) index_reloptions(rel->rd_am->amoptions, newOptions, true);
7693                         break;
7694                 default:
7695                         ereport(ERROR,
7696                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7697                                          errmsg("\"%s\" is not a table, index, or TOAST table",
7698                                                         RelationGetRelationName(rel))));
7699                         break;
7700         }
7701
7702         /*
7703          * All we need do here is update the pg_class row; the new options will be
7704          * propagated into relcaches during post-commit cache inval.
7705          */
7706         memset(repl_val, 0, sizeof(repl_val));
7707         memset(repl_null, false, sizeof(repl_null));
7708         memset(repl_repl, false, sizeof(repl_repl));
7709
7710         if (newOptions != (Datum) 0)
7711                 repl_val[Anum_pg_class_reloptions - 1] = newOptions;
7712         else
7713                 repl_null[Anum_pg_class_reloptions - 1] = true;
7714
7715         repl_repl[Anum_pg_class_reloptions - 1] = true;
7716
7717         newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass),
7718                                                                  repl_val, repl_null, repl_repl);
7719
7720         simple_heap_update(pgclass, &newtuple->t_self, newtuple);
7721
7722         CatalogUpdateIndexes(pgclass, newtuple);
7723
7724         heap_freetuple(newtuple);
7725
7726         ReleaseSysCache(tuple);
7727
7728         /* repeat the whole exercise for the toast table, if there's one */
7729         if (OidIsValid(rel->rd_rel->reltoastrelid))
7730         {
7731                 Relation        toastrel;
7732                 Oid                     toastid = rel->rd_rel->reltoastrelid;
7733
7734                 toastrel = heap_open(toastid, lockmode);
7735
7736                 /* Get the old reloptions */
7737                 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid));
7738                 if (!HeapTupleIsValid(tuple))
7739                         elog(ERROR, "cache lookup failed for relation %u", toastid);
7740
7741                 datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
7742
7743                 newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
7744                                                                 defList, "toast", validnsps, false, isReset);
7745
7746                 (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true);
7747
7748                 memset(repl_val, 0, sizeof(repl_val));
7749                 memset(repl_null, false, sizeof(repl_null));
7750                 memset(repl_repl, false, sizeof(repl_repl));
7751
7752                 if (newOptions != (Datum) 0)
7753                         repl_val[Anum_pg_class_reloptions - 1] = newOptions;
7754                 else
7755                         repl_null[Anum_pg_class_reloptions - 1] = true;
7756
7757                 repl_repl[Anum_pg_class_reloptions - 1] = true;
7758
7759                 newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass),
7760                                                                          repl_val, repl_null, repl_repl);
7761
7762                 simple_heap_update(pgclass, &newtuple->t_self, newtuple);
7763
7764                 CatalogUpdateIndexes(pgclass, newtuple);
7765
7766                 heap_freetuple(newtuple);
7767
7768                 ReleaseSysCache(tuple);
7769
7770                 heap_close(toastrel, NoLock);
7771         }
7772
7773         heap_close(pgclass, RowExclusiveLock);
7774 }
7775
7776 /*
7777  * Execute ALTER TABLE SET TABLESPACE for cases where there is no tuple
7778  * rewriting to be done, so we just want to copy the data as fast as possible.
7779  */
7780 static void
7781 ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
7782 {
7783         Relation        rel;
7784         Oid                     oldTableSpace;
7785         Oid                     reltoastrelid;
7786         Oid                     reltoastidxid;
7787         Oid                     newrelfilenode;
7788         RelFileNode newrnode;
7789         SMgrRelation dstrel;
7790         Relation        pg_class;
7791         HeapTuple       tuple;
7792         Form_pg_class rd_rel;
7793         ForkNumber      forkNum;
7794
7795         /*
7796          * Need lock here in case we are recursing to toast table or index
7797          */
7798         rel = relation_open(tableOid, lockmode);
7799
7800         /*
7801          * No work if no change in tablespace.
7802          */
7803         oldTableSpace = rel->rd_rel->reltablespace;
7804         if (newTableSpace == oldTableSpace ||
7805                 (newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0))
7806         {
7807                 relation_close(rel, NoLock);
7808                 return;
7809         }
7810
7811         /*
7812          * We cannot support moving mapped relations into different tablespaces.
7813          * (In particular this eliminates all shared catalogs.)
7814          */
7815         if (RelationIsMapped(rel))
7816                 ereport(ERROR,
7817                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7818                                  errmsg("cannot move system relation \"%s\"",
7819                                                 RelationGetRelationName(rel))));
7820
7821         /* Can't move a non-shared relation into pg_global */
7822         if (newTableSpace == GLOBALTABLESPACE_OID)
7823                 ereport(ERROR,
7824                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
7825                                  errmsg("only shared relations can be placed in pg_global tablespace")));
7826
7827         /*
7828          * Don't allow moving temp tables of other backends ... their local buffer
7829          * manager is not going to cope.
7830          */
7831         if (RELATION_IS_OTHER_TEMP(rel))
7832                 ereport(ERROR,
7833                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7834                                  errmsg("cannot move temporary tables of other sessions")));
7835
7836         reltoastrelid = rel->rd_rel->reltoastrelid;
7837         reltoastidxid = rel->rd_rel->reltoastidxid;
7838
7839         /* Get a modifiable copy of the relation's pg_class row */
7840         pg_class = heap_open(RelationRelationId, RowExclusiveLock);
7841
7842         tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(tableOid));
7843         if (!HeapTupleIsValid(tuple))
7844                 elog(ERROR, "cache lookup failed for relation %u", tableOid);
7845         rd_rel = (Form_pg_class) GETSTRUCT(tuple);
7846
7847         /*
7848          * Since we copy the file directly without looking at the shared buffers,
7849          * we'd better first flush out any pages of the source relation that are
7850          * in shared buffers.  We assume no new changes will be made while we are
7851          * holding exclusive lock on the rel.
7852          */
7853         FlushRelationBuffers(rel);
7854
7855         /*
7856          * Relfilenodes are not unique across tablespaces, so we need to allocate
7857          * a new one in the new tablespace.
7858          */
7859         newrelfilenode = GetNewRelFileNode(newTableSpace, NULL,
7860                                                                            rel->rd_rel->relpersistence);
7861
7862         /* Open old and new relation */
7863         newrnode = rel->rd_node;
7864         newrnode.relNode = newrelfilenode;
7865         newrnode.spcNode = newTableSpace;
7866         dstrel = smgropen(newrnode, rel->rd_backend);
7867
7868         RelationOpenSmgr(rel);
7869
7870         /*
7871          * Create and copy all forks of the relation, and schedule unlinking of
7872          * old physical files.
7873          *
7874          * NOTE: any conflict in relfilenode value will be caught in
7875          * RelationCreateStorage().
7876          */
7877         RelationCreateStorage(newrnode, rel->rd_rel->relpersistence);
7878
7879         /* copy main fork */
7880         copy_relation_data(rel->rd_smgr, dstrel, MAIN_FORKNUM,
7881                                            rel->rd_rel->relpersistence);
7882
7883         /* copy those extra forks that exist */
7884         for (forkNum = MAIN_FORKNUM + 1; forkNum <= MAX_FORKNUM; forkNum++)
7885         {
7886                 if (smgrexists(rel->rd_smgr, forkNum))
7887                 {
7888                         smgrcreate(dstrel, forkNum, false);
7889                         copy_relation_data(rel->rd_smgr, dstrel, forkNum,
7890                                                            rel->rd_rel->relpersistence);
7891                 }
7892         }
7893
7894         /* drop old relation, and close new one */
7895         RelationDropStorage(rel);
7896         smgrclose(dstrel);
7897
7898         /* update the pg_class row */
7899         rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace;
7900         rd_rel->relfilenode = newrelfilenode;
7901         simple_heap_update(pg_class, &tuple->t_self, tuple);
7902         CatalogUpdateIndexes(pg_class, tuple);
7903
7904         heap_freetuple(tuple);
7905
7906         heap_close(pg_class, RowExclusiveLock);
7907
7908         relation_close(rel, NoLock);
7909
7910         /* Make sure the reltablespace change is visible */
7911         CommandCounterIncrement();
7912
7913         /* Move associated toast relation and/or index, too */
7914         if (OidIsValid(reltoastrelid))
7915                 ATExecSetTableSpace(reltoastrelid, newTableSpace, lockmode);
7916         if (OidIsValid(reltoastidxid))
7917                 ATExecSetTableSpace(reltoastidxid, newTableSpace, lockmode);
7918 }
7919
7920 /*
7921  * Copy data, block by block
7922  */
7923 static void
7924 copy_relation_data(SMgrRelation src, SMgrRelation dst,
7925                                    ForkNumber forkNum, char relpersistence)
7926 {
7927         char       *buf;
7928         Page            page;
7929         bool            use_wal;
7930         BlockNumber nblocks;
7931         BlockNumber blkno;
7932
7933         /*
7934          * palloc the buffer so that it's MAXALIGN'd.  If it were just a local
7935          * char[] array, the compiler might align it on any byte boundary, which
7936          * can seriously hurt transfer speed to and from the kernel; not to
7937          * mention possibly making log_newpage's accesses to the page header fail.
7938          */
7939         buf = (char *) palloc(BLCKSZ);
7940         page = (Page) buf;
7941
7942         /*
7943          * We need to log the copied data in WAL iff WAL archiving/streaming is
7944          * enabled AND it's a permanent relation.
7945          */
7946         use_wal = XLogIsNeeded() && relpersistence == RELPERSISTENCE_PERMANENT;
7947
7948         nblocks = smgrnblocks(src, forkNum);
7949
7950         for (blkno = 0; blkno < nblocks; blkno++)
7951         {
7952                 /* If we got a cancel signal during the copy of the data, quit */
7953                 CHECK_FOR_INTERRUPTS();
7954
7955                 smgrread(src, forkNum, blkno, buf);
7956
7957                 /* XLOG stuff */
7958                 if (use_wal)
7959                         log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page);
7960
7961                 /*
7962                  * Now write the page.  We say isTemp = true even if it's not a temp
7963                  * rel, because there's no need for smgr to schedule an fsync for this
7964                  * write; we'll do it ourselves below.
7965                  */
7966                 smgrextend(dst, forkNum, blkno, buf, true);
7967         }
7968
7969         pfree(buf);
7970
7971         /*
7972          * If the rel isn't temp, we must fsync it down to disk before it's safe
7973          * to commit the transaction.  (For a temp rel we don't care since the rel
7974          * will be uninteresting after a crash anyway.)
7975          *
7976          * It's obvious that we must do this when not WAL-logging the copy. It's
7977          * less obvious that we have to do it even if we did WAL-log the copied
7978          * pages. The reason is that since we're copying outside shared buffers, a
7979          * CHECKPOINT occurring during the copy has no way to flush the previously
7980          * written data to disk (indeed it won't know the new rel even exists).  A
7981          * crash later on would replay WAL from the checkpoint, therefore it
7982          * wouldn't replay our earlier WAL entries. If we do not fsync those pages
7983          * here, they might still not be on disk when the crash occurs.
7984          */
7985         if (relpersistence == RELPERSISTENCE_PERMANENT)
7986                 smgrimmedsync(dst, forkNum);
7987 }
7988
7989 /*
7990  * ALTER TABLE ENABLE/DISABLE TRIGGER
7991  *
7992  * We just pass this off to trigger.c.
7993  */
7994 static void
7995 ATExecEnableDisableTrigger(Relation rel, char *trigname,
7996                                                 char fires_when, bool skip_system, LOCKMODE lockmode)
7997 {
7998         EnableDisableTrigger(rel, trigname, fires_when, skip_system);
7999 }
8000
8001 /*
8002  * ALTER TABLE ENABLE/DISABLE RULE
8003  *
8004  * We just pass this off to rewriteDefine.c.
8005  */
8006 static void
8007 ATExecEnableDisableRule(Relation rel, char *trigname,
8008                                                 char fires_when, LOCKMODE lockmode)
8009 {
8010         EnableDisableRule(rel, trigname, fires_when);
8011 }
8012
8013 /*
8014  * ALTER TABLE INHERIT
8015  *
8016  * Add a parent to the child's parents. This verifies that all the columns and
8017  * check constraints of the parent appear in the child and that they have the
8018  * same data types and expressions.
8019  */
8020 static void
8021 ATPrepAddInherit(Relation child_rel)
8022 {
8023         if (child_rel->rd_rel->reloftype)
8024                 ereport(ERROR,
8025                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8026                                  errmsg("cannot change inheritance of typed table")));
8027 }
8028
8029 static void
8030 ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode)
8031 {
8032         Relation        parent_rel,
8033                                 catalogRelation;
8034         SysScanDesc scan;
8035         ScanKeyData key;
8036         HeapTuple       inheritsTuple;
8037         int32           inhseqno;
8038         List       *children;
8039
8040         /*
8041          * A self-exclusive lock is needed here.  See the similar case in
8042          * MergeAttributes() for a full explanation.
8043          */
8044         parent_rel = heap_openrv(parent, ShareUpdateExclusiveLock);
8045
8046         /*
8047          * Must be owner of both parent and child -- child was checked by
8048          * ATSimplePermissions call in ATPrepCmd
8049          */
8050         ATSimplePermissions(parent_rel, ATT_TABLE);
8051
8052         /* Permanent rels cannot inherit from temporary ones */
8053         if (RelationUsesTempNamespace(parent_rel)
8054                 && !RelationUsesTempNamespace(child_rel))
8055                 ereport(ERROR,
8056                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8057                                  errmsg("cannot inherit from temporary relation \"%s\"",
8058                                                 RelationGetRelationName(parent_rel))));
8059
8060         /*
8061          * Check for duplicates in the list of parents, and determine the highest
8062          * inhseqno already present; we'll use the next one for the new parent.
8063          * (Note: get RowExclusiveLock because we will write pg_inherits below.)
8064          *
8065          * Note: we do not reject the case where the child already inherits from
8066          * the parent indirectly; CREATE TABLE doesn't reject comparable cases.
8067          */
8068         catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
8069         ScanKeyInit(&key,
8070                                 Anum_pg_inherits_inhrelid,
8071                                 BTEqualStrategyNumber, F_OIDEQ,
8072                                 ObjectIdGetDatum(RelationGetRelid(child_rel)));
8073         scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId,
8074                                                           true, SnapshotNow, 1, &key);
8075
8076         /* inhseqno sequences start at 1 */
8077         inhseqno = 0;
8078         while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan)))
8079         {
8080                 Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inheritsTuple);
8081
8082                 if (inh->inhparent == RelationGetRelid(parent_rel))
8083                         ereport(ERROR,
8084                                         (errcode(ERRCODE_DUPLICATE_TABLE),
8085                          errmsg("relation \"%s\" would be inherited from more than once",
8086                                         RelationGetRelationName(parent_rel))));
8087                 if (inh->inhseqno > inhseqno)
8088                         inhseqno = inh->inhseqno;
8089         }
8090         systable_endscan(scan);
8091
8092         /*
8093          * Prevent circularity by seeing if proposed parent inherits from child.
8094          * (In particular, this disallows making a rel inherit from itself.)
8095          *
8096          * This is not completely bulletproof because of race conditions: in
8097          * multi-level inheritance trees, someone else could concurrently be
8098          * making another inheritance link that closes the loop but does not join
8099          * either of the rels we have locked.  Preventing that seems to require
8100          * exclusive locks on the entire inheritance tree, which is a cure worse
8101          * than the disease.  find_all_inheritors() will cope with circularity
8102          * anyway, so don't sweat it too much.
8103          *
8104          * We use weakest lock we can on child's children, namely AccessShareLock.
8105          */
8106         children = find_all_inheritors(RelationGetRelid(child_rel),
8107                                                                    AccessShareLock, NULL);
8108
8109         if (list_member_oid(children, RelationGetRelid(parent_rel)))
8110                 ereport(ERROR,
8111                                 (errcode(ERRCODE_DUPLICATE_TABLE),
8112                                  errmsg("circular inheritance not allowed"),
8113                                  errdetail("\"%s\" is already a child of \"%s\".",
8114                                                    parent->relname,
8115                                                    RelationGetRelationName(child_rel))));
8116
8117         /* If parent has OIDs then child must have OIDs */
8118         if (parent_rel->rd_rel->relhasoids && !child_rel->rd_rel->relhasoids)
8119                 ereport(ERROR,
8120                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8121                                  errmsg("table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs",
8122                                                 RelationGetRelationName(child_rel),
8123                                                 RelationGetRelationName(parent_rel))));
8124
8125         /* Match up the columns and bump attinhcount as needed */
8126         MergeAttributesIntoExisting(child_rel, parent_rel);
8127
8128         /* Match up the constraints and bump coninhcount as needed */
8129         MergeConstraintsIntoExisting(child_rel, parent_rel);
8130
8131         /*
8132          * OK, it looks valid.  Make the catalog entries that show inheritance.
8133          */
8134         StoreCatalogInheritance1(RelationGetRelid(child_rel),
8135                                                          RelationGetRelid(parent_rel),
8136                                                          inhseqno + 1,
8137                                                          catalogRelation);
8138
8139         /* Now we're done with pg_inherits */
8140         heap_close(catalogRelation, RowExclusiveLock);
8141
8142         /* keep our lock on the parent relation until commit */
8143         heap_close(parent_rel, NoLock);
8144 }
8145
8146 /*
8147  * Obtain the source-text form of the constraint expression for a check
8148  * constraint, given its pg_constraint tuple
8149  */
8150 static char *
8151 decompile_conbin(HeapTuple contup, TupleDesc tupdesc)
8152 {
8153         Form_pg_constraint con;
8154         bool            isnull;
8155         Datum           attr;
8156         Datum           expr;
8157
8158         con = (Form_pg_constraint) GETSTRUCT(contup);
8159         attr = heap_getattr(contup, Anum_pg_constraint_conbin, tupdesc, &isnull);
8160         if (isnull)
8161                 elog(ERROR, "null conbin for constraint %u", HeapTupleGetOid(contup));
8162
8163         expr = DirectFunctionCall2(pg_get_expr, attr,
8164                                                            ObjectIdGetDatum(con->conrelid));
8165         return TextDatumGetCString(expr);
8166 }
8167
8168 /*
8169  * Determine whether two check constraints are functionally equivalent
8170  *
8171  * The test we apply is to see whether they reverse-compile to the same
8172  * source string.  This insulates us from issues like whether attributes
8173  * have the same physical column numbers in parent and child relations.
8174  */
8175 static bool
8176 constraints_equivalent(HeapTuple a, HeapTuple b, TupleDesc tupleDesc)
8177 {
8178         Form_pg_constraint acon = (Form_pg_constraint) GETSTRUCT(a);
8179         Form_pg_constraint bcon = (Form_pg_constraint) GETSTRUCT(b);
8180
8181         if (acon->condeferrable != bcon->condeferrable ||
8182                 acon->condeferred != bcon->condeferred ||
8183                 strcmp(decompile_conbin(a, tupleDesc),
8184                            decompile_conbin(b, tupleDesc)) != 0)
8185                 return false;
8186         else
8187                 return true;
8188 }
8189
8190 /*
8191  * Check columns in child table match up with columns in parent, and increment
8192  * their attinhcount.
8193  *
8194  * Called by ATExecAddInherit
8195  *
8196  * Currently all parent columns must be found in child. Missing columns are an
8197  * error.  One day we might consider creating new columns like CREATE TABLE
8198  * does.  However, that is widely unpopular --- in the common use case of
8199  * partitioned tables it's a foot-gun.
8200  *
8201  * The data type must match exactly. If the parent column is NOT NULL then
8202  * the child must be as well. Defaults are not compared, however.
8203  */
8204 static void
8205 MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel)
8206 {
8207         Relation        attrrel;
8208         AttrNumber      parent_attno;
8209         int                     parent_natts;
8210         TupleDesc       tupleDesc;
8211         HeapTuple       tuple;
8212
8213         attrrel = heap_open(AttributeRelationId, RowExclusiveLock);
8214
8215         tupleDesc = RelationGetDescr(parent_rel);
8216         parent_natts = tupleDesc->natts;
8217
8218         for (parent_attno = 1; parent_attno <= parent_natts; parent_attno++)
8219         {
8220                 Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
8221                 char       *attributeName = NameStr(attribute->attname);
8222
8223                 /* Ignore dropped columns in the parent. */
8224                 if (attribute->attisdropped)
8225                         continue;
8226
8227                 /* Find same column in child (matching on column name). */
8228                 tuple = SearchSysCacheCopyAttName(RelationGetRelid(child_rel),
8229                                                                                   attributeName);
8230                 if (HeapTupleIsValid(tuple))
8231                 {
8232                         /* Check they are same type, typmod, and collation */
8233                         Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
8234
8235                         if (attribute->atttypid != childatt->atttypid ||
8236                                 attribute->atttypmod != childatt->atttypmod)
8237                                 ereport(ERROR,
8238                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
8239                                                  errmsg("child table \"%s\" has different type for column \"%s\"",
8240                                                                 RelationGetRelationName(child_rel),
8241                                                                 attributeName)));
8242
8243                         if (attribute->attcollation != childatt->attcollation)
8244                                 ereport(ERROR,
8245                                                 (errcode(ERRCODE_COLLATION_MISMATCH),
8246                                                  errmsg("child table \"%s\" has different collation for column \"%s\"",
8247                                                                 RelationGetRelationName(child_rel),
8248                                                                 attributeName)));
8249
8250                         /*
8251                          * Check child doesn't discard NOT NULL property.  (Other
8252                          * constraints are checked elsewhere.)
8253                          */
8254                         if (attribute->attnotnull && !childatt->attnotnull)
8255                                 ereport(ERROR,
8256                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
8257                                 errmsg("column \"%s\" in child table must be marked NOT NULL",
8258                                            attributeName)));
8259
8260                         /*
8261                          * OK, bump the child column's inheritance count.  (If we fail
8262                          * later on, this change will just roll back.)
8263                          */
8264                         childatt->attinhcount++;
8265                         simple_heap_update(attrrel, &tuple->t_self, tuple);
8266                         CatalogUpdateIndexes(attrrel, tuple);
8267                         heap_freetuple(tuple);
8268                 }
8269                 else
8270                 {
8271                         ereport(ERROR,
8272                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
8273                                          errmsg("child table is missing column \"%s\"",
8274                                                         attributeName)));
8275                 }
8276         }
8277
8278         heap_close(attrrel, RowExclusiveLock);
8279 }
8280
8281 /*
8282  * Check constraints in child table match up with constraints in parent,
8283  * and increment their coninhcount.
8284  *
8285  * Called by ATExecAddInherit
8286  *
8287  * Currently all constraints in parent must be present in the child. One day we
8288  * may consider adding new constraints like CREATE TABLE does. We may also want
8289  * to allow an optional flag on parent table constraints indicating they are
8290  * intended to ONLY apply to the master table, not to the children. That would
8291  * make it possible to ensure no records are mistakenly inserted into the
8292  * master in partitioned tables rather than the appropriate child.
8293  *
8294  * XXX This is O(N^2) which may be an issue with tables with hundreds of
8295  * constraints. As long as tables have more like 10 constraints it shouldn't be
8296  * a problem though. Even 100 constraints ought not be the end of the world.
8297  */
8298 static void
8299 MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
8300 {
8301         Relation        catalog_relation;
8302         TupleDesc       tuple_desc;
8303         SysScanDesc parent_scan;
8304         ScanKeyData parent_key;
8305         HeapTuple       parent_tuple;
8306
8307         catalog_relation = heap_open(ConstraintRelationId, RowExclusiveLock);
8308         tuple_desc = RelationGetDescr(catalog_relation);
8309
8310         /* Outer loop scans through the parent's constraint definitions */
8311         ScanKeyInit(&parent_key,
8312                                 Anum_pg_constraint_conrelid,
8313                                 BTEqualStrategyNumber, F_OIDEQ,
8314                                 ObjectIdGetDatum(RelationGetRelid(parent_rel)));
8315         parent_scan = systable_beginscan(catalog_relation, ConstraintRelidIndexId,
8316                                                                          true, SnapshotNow, 1, &parent_key);
8317
8318         while (HeapTupleIsValid(parent_tuple = systable_getnext(parent_scan)))
8319         {
8320                 Form_pg_constraint parent_con = (Form_pg_constraint) GETSTRUCT(parent_tuple);
8321                 SysScanDesc child_scan;
8322                 ScanKeyData child_key;
8323                 HeapTuple       child_tuple;
8324                 bool            found = false;
8325
8326                 if (parent_con->contype != CONSTRAINT_CHECK)
8327                         continue;
8328
8329                 /* Search for a child constraint matching this one */
8330                 ScanKeyInit(&child_key,
8331                                         Anum_pg_constraint_conrelid,
8332                                         BTEqualStrategyNumber, F_OIDEQ,
8333                                         ObjectIdGetDatum(RelationGetRelid(child_rel)));
8334                 child_scan = systable_beginscan(catalog_relation, ConstraintRelidIndexId,
8335                                                                                 true, SnapshotNow, 1, &child_key);
8336
8337                 while (HeapTupleIsValid(child_tuple = systable_getnext(child_scan)))
8338                 {
8339                         Form_pg_constraint child_con = (Form_pg_constraint) GETSTRUCT(child_tuple);
8340                         HeapTuple       child_copy;
8341
8342                         if (child_con->contype != CONSTRAINT_CHECK)
8343                                 continue;
8344
8345                         if (strcmp(NameStr(parent_con->conname),
8346                                            NameStr(child_con->conname)) != 0)
8347                                 continue;
8348
8349                         if (!constraints_equivalent(parent_tuple, child_tuple, tuple_desc))
8350                                 ereport(ERROR,
8351                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
8352                                                  errmsg("child table \"%s\" has different definition for check constraint \"%s\"",
8353                                                                 RelationGetRelationName(child_rel),
8354                                                                 NameStr(parent_con->conname))));
8355
8356                         /*
8357                          * OK, bump the child constraint's inheritance count.  (If we fail
8358                          * later on, this change will just roll back.)
8359                          */
8360                         child_copy = heap_copytuple(child_tuple);
8361                         child_con = (Form_pg_constraint) GETSTRUCT(child_copy);
8362                         child_con->coninhcount++;
8363                         simple_heap_update(catalog_relation, &child_copy->t_self, child_copy);
8364                         CatalogUpdateIndexes(catalog_relation, child_copy);
8365                         heap_freetuple(child_copy);
8366
8367                         found = true;
8368                         break;
8369                 }
8370
8371                 systable_endscan(child_scan);
8372
8373                 if (!found)
8374                         ereport(ERROR,
8375                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
8376                                          errmsg("child table is missing constraint \"%s\"",
8377                                                         NameStr(parent_con->conname))));
8378         }
8379
8380         systable_endscan(parent_scan);
8381         heap_close(catalog_relation, RowExclusiveLock);
8382 }
8383
8384 /*
8385  * ALTER TABLE NO INHERIT
8386  *
8387  * Drop a parent from the child's parents. This just adjusts the attinhcount
8388  * and attislocal of the columns and removes the pg_inherit and pg_depend
8389  * entries.
8390  *
8391  * If attinhcount goes to 0 then attislocal gets set to true. If it goes back
8392  * up attislocal stays true, which means if a child is ever removed from a
8393  * parent then its columns will never be automatically dropped which may
8394  * surprise. But at least we'll never surprise by dropping columns someone
8395  * isn't expecting to be dropped which would actually mean data loss.
8396  *
8397  * coninhcount and conislocal for inherited constraints are adjusted in
8398  * exactly the same way.
8399  */
8400 static void
8401 ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode)
8402 {
8403         Relation        parent_rel;
8404         Relation        catalogRelation;
8405         SysScanDesc scan;
8406         ScanKeyData key[3];
8407         HeapTuple       inheritsTuple,
8408                                 attributeTuple,
8409                                 constraintTuple;
8410         List       *connames;
8411         bool            found = false;
8412
8413         /*
8414          * AccessShareLock on the parent is probably enough, seeing that DROP
8415          * TABLE doesn't lock parent tables at all.  We need some lock since we'll
8416          * be inspecting the parent's schema.
8417          */
8418         parent_rel = heap_openrv(parent, AccessShareLock);
8419
8420         /*
8421          * We don't bother to check ownership of the parent table --- ownership of
8422          * the child is presumed enough rights.
8423          */
8424
8425         /*
8426          * Find and destroy the pg_inherits entry linking the two, or error out if
8427          * there is none.
8428          */
8429         catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
8430         ScanKeyInit(&key[0],
8431                                 Anum_pg_inherits_inhrelid,
8432                                 BTEqualStrategyNumber, F_OIDEQ,
8433                                 ObjectIdGetDatum(RelationGetRelid(rel)));
8434         scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId,
8435                                                           true, SnapshotNow, 1, key);
8436
8437         while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan)))
8438         {
8439                 Oid                     inhparent;
8440
8441                 inhparent = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhparent;
8442                 if (inhparent == RelationGetRelid(parent_rel))
8443                 {
8444                         simple_heap_delete(catalogRelation, &inheritsTuple->t_self);
8445                         found = true;
8446                         break;
8447                 }
8448         }
8449
8450         systable_endscan(scan);
8451         heap_close(catalogRelation, RowExclusiveLock);
8452
8453         if (!found)
8454                 ereport(ERROR,
8455                                 (errcode(ERRCODE_UNDEFINED_TABLE),
8456                                  errmsg("relation \"%s\" is not a parent of relation \"%s\"",
8457                                                 RelationGetRelationName(parent_rel),
8458                                                 RelationGetRelationName(rel))));
8459
8460         /*
8461          * Search through child columns looking for ones matching parent rel
8462          */
8463         catalogRelation = heap_open(AttributeRelationId, RowExclusiveLock);
8464         ScanKeyInit(&key[0],
8465                                 Anum_pg_attribute_attrelid,
8466                                 BTEqualStrategyNumber, F_OIDEQ,
8467                                 ObjectIdGetDatum(RelationGetRelid(rel)));
8468         scan = systable_beginscan(catalogRelation, AttributeRelidNumIndexId,
8469                                                           true, SnapshotNow, 1, key);
8470         while (HeapTupleIsValid(attributeTuple = systable_getnext(scan)))
8471         {
8472                 Form_pg_attribute att = (Form_pg_attribute) GETSTRUCT(attributeTuple);
8473
8474                 /* Ignore if dropped or not inherited */
8475                 if (att->attisdropped)
8476                         continue;
8477                 if (att->attinhcount <= 0)
8478                         continue;
8479
8480                 if (SearchSysCacheExistsAttName(RelationGetRelid(parent_rel),
8481                                                                                 NameStr(att->attname)))
8482                 {
8483                         /* Decrement inhcount and possibly set islocal to true */
8484                         HeapTuple       copyTuple = heap_copytuple(attributeTuple);
8485                         Form_pg_attribute copy_att = (Form_pg_attribute) GETSTRUCT(copyTuple);
8486
8487                         copy_att->attinhcount--;
8488                         if (copy_att->attinhcount == 0)
8489                                 copy_att->attislocal = true;
8490
8491                         simple_heap_update(catalogRelation, &copyTuple->t_self, copyTuple);
8492                         CatalogUpdateIndexes(catalogRelation, copyTuple);
8493                         heap_freetuple(copyTuple);
8494                 }
8495         }
8496         systable_endscan(scan);
8497         heap_close(catalogRelation, RowExclusiveLock);
8498
8499         /*
8500          * Likewise, find inherited check constraints and disinherit them. To do
8501          * this, we first need a list of the names of the parent's check
8502          * constraints.  (We cheat a bit by only checking for name matches,
8503          * assuming that the expressions will match.)
8504          */
8505         catalogRelation = heap_open(ConstraintRelationId, RowExclusiveLock);
8506         ScanKeyInit(&key[0],
8507                                 Anum_pg_constraint_conrelid,
8508                                 BTEqualStrategyNumber, F_OIDEQ,
8509                                 ObjectIdGetDatum(RelationGetRelid(parent_rel)));
8510         scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId,
8511                                                           true, SnapshotNow, 1, key);
8512
8513         connames = NIL;
8514
8515         while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
8516         {
8517                 Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
8518
8519                 if (con->contype == CONSTRAINT_CHECK)
8520                         connames = lappend(connames, pstrdup(NameStr(con->conname)));
8521         }
8522
8523         systable_endscan(scan);
8524
8525         /* Now scan the child's constraints */
8526         ScanKeyInit(&key[0],
8527                                 Anum_pg_constraint_conrelid,
8528                                 BTEqualStrategyNumber, F_OIDEQ,
8529                                 ObjectIdGetDatum(RelationGetRelid(rel)));
8530         scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId,
8531                                                           true, SnapshotNow, 1, key);
8532
8533         while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
8534         {
8535                 Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
8536                 bool            match;
8537                 ListCell   *lc;
8538
8539                 if (con->contype != CONSTRAINT_CHECK)
8540                         continue;
8541
8542                 match = false;
8543                 foreach(lc, connames)
8544                 {
8545                         if (strcmp(NameStr(con->conname), (char *) lfirst(lc)) == 0)
8546                         {
8547                                 match = true;
8548                                 break;
8549                         }
8550                 }
8551
8552                 if (match)
8553                 {
8554                         /* Decrement inhcount and possibly set islocal to true */
8555                         HeapTuple       copyTuple = heap_copytuple(constraintTuple);
8556                         Form_pg_constraint copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
8557
8558                         if (copy_con->coninhcount <= 0)         /* shouldn't happen */
8559                                 elog(ERROR, "relation %u has non-inherited constraint \"%s\"",
8560                                          RelationGetRelid(rel), NameStr(copy_con->conname));
8561
8562                         copy_con->coninhcount--;
8563                         if (copy_con->coninhcount == 0)
8564                                 copy_con->conislocal = true;
8565
8566                         simple_heap_update(catalogRelation, &copyTuple->t_self, copyTuple);
8567                         CatalogUpdateIndexes(catalogRelation, copyTuple);
8568                         heap_freetuple(copyTuple);
8569                 }
8570         }
8571
8572         systable_endscan(scan);
8573         heap_close(catalogRelation, RowExclusiveLock);
8574
8575         drop_parent_dependency(RelationGetRelid(rel),
8576                                                    RelationRelationId,
8577                                                    RelationGetRelid(parent_rel));
8578
8579         /* keep our lock on the parent relation until commit */
8580         heap_close(parent_rel, NoLock);
8581 }
8582
8583 /*
8584  * Drop the dependency created by StoreCatalogInheritance1 (CREATE TABLE
8585  * INHERITS/ALTER TABLE INHERIT -- refclassid will be RelationRelationId) or
8586  * heap_create_with_catalog (CREATE TABLE OF/ALTER TABLE OF -- refclassid will
8587  * be TypeRelationId).  There's no convenient way to do this, so go trawling
8588  * through pg_depend.
8589  */
8590 static void
8591 drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid)
8592 {
8593         Relation        catalogRelation;
8594         SysScanDesc scan;
8595         ScanKeyData key[3];
8596         HeapTuple       depTuple;
8597
8598         catalogRelation = heap_open(DependRelationId, RowExclusiveLock);
8599
8600         ScanKeyInit(&key[0],
8601                                 Anum_pg_depend_classid,
8602                                 BTEqualStrategyNumber, F_OIDEQ,
8603                                 ObjectIdGetDatum(RelationRelationId));
8604         ScanKeyInit(&key[1],
8605                                 Anum_pg_depend_objid,
8606                                 BTEqualStrategyNumber, F_OIDEQ,
8607                                 ObjectIdGetDatum(relid));
8608         ScanKeyInit(&key[2],
8609                                 Anum_pg_depend_objsubid,
8610                                 BTEqualStrategyNumber, F_INT4EQ,
8611                                 Int32GetDatum(0));
8612
8613         scan = systable_beginscan(catalogRelation, DependDependerIndexId, true,
8614                                                           SnapshotNow, 3, key);
8615
8616         while (HeapTupleIsValid(depTuple = systable_getnext(scan)))
8617         {
8618                 Form_pg_depend dep = (Form_pg_depend) GETSTRUCT(depTuple);
8619
8620                 if (dep->refclassid == refclassid &&
8621                         dep->refobjid == refobjid &&
8622                         dep->refobjsubid == 0 &&
8623                         dep->deptype == DEPENDENCY_NORMAL)
8624                         simple_heap_delete(catalogRelation, &depTuple->t_self);
8625         }
8626
8627         systable_endscan(scan);
8628         heap_close(catalogRelation, RowExclusiveLock);
8629 }
8630
8631 /*
8632  * ALTER TABLE OF
8633  *
8634  * Attach a table to a composite type, as though it had been created with CREATE
8635  * TABLE OF.  All attname, atttypid, atttypmod and attcollation must match.  The
8636  * subject table must not have inheritance parents.  These restrictions ensure
8637  * that you cannot create a configuration impossible with CREATE TABLE OF alone.
8638  */
8639 static void
8640 ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode)
8641 {
8642         Oid                     relid = RelationGetRelid(rel);
8643         Type            typetuple;
8644         Form_pg_type typ;
8645         Oid                     typeid;
8646         Relation        inheritsRelation,
8647                                 relationRelation;
8648         SysScanDesc scan;
8649         ScanKeyData key;
8650         AttrNumber      table_attno,
8651                                 type_attno;
8652         TupleDesc       typeTupleDesc,
8653                                 tableTupleDesc;
8654         ObjectAddress tableobj,
8655                                 typeobj;
8656         HeapTuple       classtuple;
8657
8658         /* Validate the type. */
8659         typetuple = typenameType(NULL, ofTypename, NULL);
8660         check_of_type(typetuple);
8661         typ = (Form_pg_type) GETSTRUCT(typetuple);
8662         typeid = HeapTupleGetOid(typetuple);
8663
8664         /* Fail if the table has any inheritance parents. */
8665         inheritsRelation = heap_open(InheritsRelationId, AccessShareLock);
8666         ScanKeyInit(&key,
8667                                 Anum_pg_inherits_inhrelid,
8668                                 BTEqualStrategyNumber, F_OIDEQ,
8669                                 ObjectIdGetDatum(relid));
8670         scan = systable_beginscan(inheritsRelation, InheritsRelidSeqnoIndexId,
8671                                                           true, SnapshotNow, 1, &key);
8672         if (HeapTupleIsValid(systable_getnext(scan)))
8673                 ereport(ERROR,
8674                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8675                                  errmsg("typed tables cannot inherit")));
8676         systable_endscan(scan);
8677         heap_close(inheritsRelation, AccessShareLock);
8678
8679         /*
8680          * Check the tuple descriptors for compatibility.  Unlike inheritance, we
8681          * require that the order also match.  However, attnotnull need not match.
8682          * Also unlike inheritance, we do not require matching relhasoids.
8683          */
8684         typeTupleDesc = lookup_rowtype_tupdesc(typeid, -1);
8685         tableTupleDesc = RelationGetDescr(rel);
8686         table_attno = 1;
8687         for (type_attno = 1; type_attno <= typeTupleDesc->natts; type_attno++)
8688         {
8689                 Form_pg_attribute type_attr,
8690                                         table_attr;
8691                 const char *type_attname,
8692                                    *table_attname;
8693
8694                 /* Get the next non-dropped type attribute. */
8695                 type_attr = typeTupleDesc->attrs[type_attno - 1];
8696                 if (type_attr->attisdropped)
8697                         continue;
8698                 type_attname = NameStr(type_attr->attname);
8699
8700                 /* Get the next non-dropped table attribute. */
8701                 do
8702                 {
8703                         if (table_attno > tableTupleDesc->natts)
8704                                 ereport(ERROR,
8705                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
8706                                                  errmsg("table is missing column \"%s\"",
8707                                                                 type_attname)));
8708                         table_attr = tableTupleDesc->attrs[table_attno++ - 1];
8709                 } while (table_attr->attisdropped);
8710                 table_attname = NameStr(table_attr->attname);
8711
8712                 /* Compare name. */
8713                 if (strncmp(table_attname, type_attname, NAMEDATALEN) != 0)
8714                         ereport(ERROR,
8715                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
8716                                          errmsg("table has column \"%s\" where type requires \"%s\"",
8717                                                         table_attname, type_attname)));
8718
8719                 /* Compare type. */
8720                 if (table_attr->atttypid != type_attr->atttypid ||
8721                         table_attr->atttypmod != type_attr->atttypmod ||
8722                         table_attr->attcollation != type_attr->attcollation)
8723                         ereport(ERROR,
8724                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
8725                                          errmsg("table \"%s\" has different type for column \"%s\"",
8726                                                         RelationGetRelationName(rel), type_attname)));
8727         }
8728         DecrTupleDescRefCount(typeTupleDesc);
8729
8730         /* Any remaining columns at the end of the table had better be dropped. */
8731         for (; table_attno <= tableTupleDesc->natts; table_attno++)
8732         {
8733                 Form_pg_attribute table_attr = tableTupleDesc->attrs[table_attno - 1];
8734                 if (!table_attr->attisdropped)
8735                         ereport(ERROR,
8736                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
8737                                          errmsg("table has extra column \"%s\"",
8738                                                         NameStr(table_attr->attname))));
8739         }
8740
8741         /* If the table was already typed, drop the existing dependency. */
8742         if (rel->rd_rel->reloftype)
8743                 drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype);
8744
8745         /* Record a dependency on the new type. */
8746         tableobj.classId = RelationRelationId;
8747         tableobj.objectId = relid;
8748         tableobj.objectSubId = 0;
8749         typeobj.classId = TypeRelationId;
8750         typeobj.objectId = typeid;
8751         typeobj.objectSubId = 0;
8752         recordDependencyOn(&tableobj, &typeobj, DEPENDENCY_NORMAL);
8753
8754         /* Update pg_class.reloftype */
8755         relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
8756         classtuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
8757         if (!HeapTupleIsValid(classtuple))
8758                 elog(ERROR, "cache lookup failed for relation %u", relid);
8759         ((Form_pg_class) GETSTRUCT(classtuple))->reloftype = typeid;
8760         simple_heap_update(relationRelation, &classtuple->t_self, classtuple);
8761         CatalogUpdateIndexes(relationRelation, classtuple);
8762         heap_freetuple(classtuple);
8763         heap_close(relationRelation, RowExclusiveLock);
8764
8765         ReleaseSysCache(typetuple);
8766 }
8767
8768 /*
8769  * ALTER TABLE NOT OF
8770  *
8771  * Detach a typed table from its originating type.  Just clear reloftype and
8772  * remove the dependency.
8773  */
8774 static void
8775 ATExecDropOf(Relation rel, LOCKMODE lockmode)
8776 {
8777         Oid                     relid = RelationGetRelid(rel);
8778         Relation        relationRelation;
8779         HeapTuple       tuple;
8780
8781         if (!OidIsValid(rel->rd_rel->reloftype))
8782                 ereport(ERROR,
8783                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8784                                  errmsg("\"%s\" is not a typed table",
8785                                                 RelationGetRelationName(rel))));
8786
8787         /*
8788          * We don't bother to check ownership of the type --- ownership of the table
8789          * is presumed enough rights.  No lock required on the type, either.
8790          */
8791
8792         drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype);
8793
8794         /* Clear pg_class.reloftype */
8795         relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
8796         tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
8797         if (!HeapTupleIsValid(tuple))
8798                 elog(ERROR, "cache lookup failed for relation %u", relid);
8799         ((Form_pg_class) GETSTRUCT(tuple))->reloftype = InvalidOid;
8800         simple_heap_update(relationRelation, &tuple->t_self, tuple);
8801         CatalogUpdateIndexes(relationRelation, tuple);
8802         heap_freetuple(tuple);
8803         heap_close(relationRelation, RowExclusiveLock);
8804 }
8805
8806 /*
8807  * ALTER FOREIGN TABLE <name> OPTIONS (...)
8808  */
8809 static void
8810 ATExecGenericOptions(Relation rel, List *options)
8811 {
8812         Relation        ftrel;
8813         ForeignServer *server;
8814         ForeignDataWrapper *fdw;
8815         HeapTuple       tuple;
8816         bool            isnull;
8817         Datum           repl_val[Natts_pg_foreign_table];
8818         bool            repl_null[Natts_pg_foreign_table];
8819         bool            repl_repl[Natts_pg_foreign_table];
8820         Datum           datum;
8821         Form_pg_foreign_table tableform;
8822
8823         if (options == NIL)
8824                 return;
8825
8826         ftrel = heap_open(ForeignTableRelationId, RowExclusiveLock);
8827
8828         tuple = SearchSysCacheCopy1(FOREIGNTABLEREL, rel->rd_id);
8829         if (!HeapTupleIsValid(tuple))
8830                 ereport(ERROR,
8831                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
8832                                  errmsg("foreign table \"%s\" does not exist",
8833                                                 RelationGetRelationName(rel))));
8834         tableform = (Form_pg_foreign_table) GETSTRUCT(tuple);
8835         server = GetForeignServer(tableform->ftserver);
8836         fdw = GetForeignDataWrapper(server->fdwid);
8837
8838         memset(repl_val, 0, sizeof(repl_val));
8839         memset(repl_null, false, sizeof(repl_null));
8840         memset(repl_repl, false, sizeof(repl_repl));
8841
8842         /* Extract the current options */
8843         datum = SysCacheGetAttr(FOREIGNTABLEREL,
8844                                                         tuple,
8845                                                         Anum_pg_foreign_table_ftoptions,
8846                                                         &isnull);
8847         if (isnull)
8848                 datum = PointerGetDatum(NULL);
8849
8850         /* Transform the options */
8851         datum = transformGenericOptions(ForeignTableRelationId,
8852                                                                         datum,
8853                                                                         options,
8854                                                                         fdw->fdwvalidator);
8855
8856         if (PointerIsValid(DatumGetPointer(datum)))
8857                 repl_val[Anum_pg_foreign_table_ftoptions - 1] = datum;
8858         else
8859                 repl_null[Anum_pg_foreign_table_ftoptions - 1] = true;
8860
8861         repl_repl[Anum_pg_foreign_table_ftoptions - 1] = true;
8862
8863         /* Everything looks good - update the tuple */
8864
8865         tuple = heap_modify_tuple(tuple, RelationGetDescr(ftrel),
8866                                                           repl_val, repl_null, repl_repl);
8867
8868         simple_heap_update(ftrel, &tuple->t_self, tuple);
8869         CatalogUpdateIndexes(ftrel, tuple);
8870
8871         heap_close(ftrel, RowExclusiveLock);
8872
8873         heap_freetuple(tuple);
8874 }
8875
8876
8877 /*
8878  * Execute ALTER TABLE SET SCHEMA
8879  *
8880  * Note: caller must have checked ownership of the relation already
8881  */
8882 void
8883 AlterTableNamespace(RangeVar *relation, const char *newschema,
8884                                         ObjectType stmttype, LOCKMODE lockmode)
8885 {
8886         Relation        rel;
8887         Oid                     relid;
8888         Oid                     oldNspOid;
8889         Oid                     nspOid;
8890         Relation        classRel;
8891
8892         rel = relation_openrv(relation, lockmode);
8893
8894         relid = RelationGetRelid(rel);
8895         oldNspOid = RelationGetNamespace(rel);
8896
8897         /* Check relation type against type specified in the ALTER command */
8898         switch (stmttype)
8899         {
8900                 case OBJECT_TABLE:
8901
8902                         /*
8903                          * For mostly-historical reasons, we allow ALTER TABLE to apply to
8904                          * all relation types.
8905                          */
8906                         break;
8907
8908                 case OBJECT_SEQUENCE:
8909                         if (rel->rd_rel->relkind != RELKIND_SEQUENCE)
8910                                 ereport(ERROR,
8911                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8912                                                  errmsg("\"%s\" is not a sequence",
8913                                                                 RelationGetRelationName(rel))));
8914                         break;
8915
8916                 case OBJECT_VIEW:
8917                         if (rel->rd_rel->relkind != RELKIND_VIEW)
8918                                 ereport(ERROR,
8919                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8920                                                  errmsg("\"%s\" is not a view",
8921                                                                 RelationGetRelationName(rel))));
8922                         break;
8923
8924                 case OBJECT_FOREIGN_TABLE:
8925                         if (rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
8926                                 ereport(ERROR,
8927                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8928                                                  errmsg("\"%s\" is not a foreign table",
8929                                                                 RelationGetRelationName(rel))));
8930                         break;
8931
8932                 default:
8933                         elog(ERROR, "unrecognized object type: %d", (int) stmttype);
8934         }
8935
8936         /* Can we change the schema of this tuple? */
8937         switch (rel->rd_rel->relkind)
8938         {
8939                 case RELKIND_RELATION:
8940                 case RELKIND_VIEW:
8941                 case RELKIND_FOREIGN_TABLE:
8942                         /* ok to change schema */
8943                         break;
8944                 case RELKIND_SEQUENCE:
8945                         {
8946                                 /* if it's an owned sequence, disallow moving it by itself */
8947                                 Oid                     tableId;
8948                                 int32           colId;
8949
8950                                 if (sequenceIsOwned(relid, &tableId, &colId))
8951                                         ereport(ERROR,
8952                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8953                                                          errmsg("cannot move an owned sequence into another schema"),
8954                                           errdetail("Sequence \"%s\" is linked to table \"%s\".",
8955                                                                 RelationGetRelationName(rel),
8956                                                                 get_rel_name(tableId))));
8957                         }
8958                         break;
8959                 case RELKIND_COMPOSITE_TYPE:
8960                         ereport(ERROR,
8961                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8962                                          errmsg("\"%s\" is a composite type",
8963                                                         RelationGetRelationName(rel)),
8964                                          errhint("Use ALTER TYPE instead.")));
8965                         break;
8966                 case RELKIND_INDEX:
8967                 case RELKIND_TOASTVALUE:
8968                         /* FALL THRU */
8969                 default:
8970                         ereport(ERROR,
8971                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8972                         errmsg("\"%s\" is not a table, view, sequence, or foreign table",
8973                                    RelationGetRelationName(rel))));
8974         }
8975
8976         /* get schema OID and check its permissions */
8977         nspOid = LookupCreationNamespace(newschema);
8978
8979         /* common checks on switching namespaces */
8980         CheckSetNamespace(oldNspOid, nspOid, RelationRelationId, relid);
8981
8982         /* OK, modify the pg_class row and pg_depend entry */
8983         classRel = heap_open(RelationRelationId, RowExclusiveLock);
8984
8985         AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true);
8986
8987         /* Fix the table's rowtype too */
8988         AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false, false);
8989
8990         /* Fix other dependent stuff */
8991         if (rel->rd_rel->relkind == RELKIND_RELATION)
8992         {
8993                 AlterIndexNamespaces(classRel, rel, oldNspOid, nspOid);
8994                 AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid, newschema, lockmode);
8995                 AlterConstraintNamespaces(relid, oldNspOid, nspOid, false);
8996         }
8997
8998         heap_close(classRel, RowExclusiveLock);
8999
9000         /* close rel, but keep lock until commit */
9001         relation_close(rel, NoLock);
9002 }
9003
9004 /*
9005  * The guts of relocating a relation to another namespace: fix the pg_class
9006  * entry, and the pg_depend entry if any.  Caller must already have
9007  * opened and write-locked pg_class.
9008  */
9009 void
9010 AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
9011                                                            Oid oldNspOid, Oid newNspOid,
9012                                                            bool hasDependEntry)
9013 {
9014         HeapTuple       classTup;
9015         Form_pg_class classForm;
9016
9017         classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relOid));
9018         if (!HeapTupleIsValid(classTup))
9019                 elog(ERROR, "cache lookup failed for relation %u", relOid);
9020         classForm = (Form_pg_class) GETSTRUCT(classTup);
9021
9022         Assert(classForm->relnamespace == oldNspOid);
9023
9024         /* check for duplicate name (more friendly than unique-index failure) */
9025         if (get_relname_relid(NameStr(classForm->relname),
9026                                                   newNspOid) != InvalidOid)
9027                 ereport(ERROR,
9028                                 (errcode(ERRCODE_DUPLICATE_TABLE),
9029                                  errmsg("relation \"%s\" already exists in schema \"%s\"",
9030                                                 NameStr(classForm->relname),
9031                                                 get_namespace_name(newNspOid))));
9032
9033         /* classTup is a copy, so OK to scribble on */
9034         classForm->relnamespace = newNspOid;
9035
9036         simple_heap_update(classRel, &classTup->t_self, classTup);
9037         CatalogUpdateIndexes(classRel, classTup);
9038
9039         /* Update dependency on schema if caller said so */
9040         if (hasDependEntry &&
9041                 changeDependencyFor(RelationRelationId, relOid,
9042                                                         NamespaceRelationId, oldNspOid, newNspOid) != 1)
9043                 elog(ERROR, "failed to change schema dependency for relation \"%s\"",
9044                          NameStr(classForm->relname));
9045
9046         heap_freetuple(classTup);
9047 }
9048
9049 /*
9050  * Move all indexes for the specified relation to another namespace.
9051  *
9052  * Note: we assume adequate permission checking was done by the caller,
9053  * and that the caller has a suitable lock on the owning relation.
9054  */
9055 static void
9056 AlterIndexNamespaces(Relation classRel, Relation rel,
9057                                          Oid oldNspOid, Oid newNspOid)
9058 {
9059         List       *indexList;
9060         ListCell   *l;
9061
9062         indexList = RelationGetIndexList(rel);
9063
9064         foreach(l, indexList)
9065         {
9066                 Oid                     indexOid = lfirst_oid(l);
9067
9068                 /*
9069                  * Note: currently, the index will not have its own dependency on the
9070                  * namespace, so we don't need to do changeDependencyFor(). There's no
9071                  * rowtype in pg_type, either.
9072                  */
9073                 AlterRelationNamespaceInternal(classRel, indexOid,
9074                                                                            oldNspOid, newNspOid,
9075                                                                            false);
9076         }
9077
9078         list_free(indexList);
9079 }
9080
9081 /*
9082  * Move all SERIAL-column sequences of the specified relation to another
9083  * namespace.
9084  *
9085  * Note: we assume adequate permission checking was done by the caller,
9086  * and that the caller has a suitable lock on the owning relation.
9087  */
9088 static void
9089 AlterSeqNamespaces(Relation classRel, Relation rel,
9090          Oid oldNspOid, Oid newNspOid, const char *newNspName, LOCKMODE lockmode)
9091 {
9092         Relation        depRel;
9093         SysScanDesc scan;
9094         ScanKeyData key[2];
9095         HeapTuple       tup;
9096
9097         /*
9098          * SERIAL sequences are those having an auto dependency on one of the
9099          * table's columns (we don't care *which* column, exactly).
9100          */
9101         depRel = heap_open(DependRelationId, AccessShareLock);
9102
9103         ScanKeyInit(&key[0],
9104                                 Anum_pg_depend_refclassid,
9105                                 BTEqualStrategyNumber, F_OIDEQ,
9106                                 ObjectIdGetDatum(RelationRelationId));
9107         ScanKeyInit(&key[1],
9108                                 Anum_pg_depend_refobjid,
9109                                 BTEqualStrategyNumber, F_OIDEQ,
9110                                 ObjectIdGetDatum(RelationGetRelid(rel)));
9111         /* we leave refobjsubid unspecified */
9112
9113         scan = systable_beginscan(depRel, DependReferenceIndexId, true,
9114                                                           SnapshotNow, 2, key);
9115
9116         while (HeapTupleIsValid(tup = systable_getnext(scan)))
9117         {
9118                 Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
9119                 Relation        seqRel;
9120
9121                 /* skip dependencies other than auto dependencies on columns */
9122                 if (depForm->refobjsubid == 0 ||
9123                         depForm->classid != RelationRelationId ||
9124                         depForm->objsubid != 0 ||
9125                         depForm->deptype != DEPENDENCY_AUTO)
9126                         continue;
9127
9128                 /* Use relation_open just in case it's an index */
9129                 seqRel = relation_open(depForm->objid, lockmode);
9130
9131                 /* skip non-sequence relations */
9132                 if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
9133                 {
9134                         /* No need to keep the lock */
9135                         relation_close(seqRel, lockmode);
9136                         continue;
9137                 }
9138
9139                 /* Fix the pg_class and pg_depend entries */
9140                 AlterRelationNamespaceInternal(classRel, depForm->objid,
9141                                                                            oldNspOid, newNspOid,
9142                                                                            true);
9143
9144                 /*
9145                  * Sequences have entries in pg_type. We need to be careful to move
9146                  * them to the new namespace, too.
9147                  */
9148                 AlterTypeNamespaceInternal(RelationGetForm(seqRel)->reltype,
9149                                                                    newNspOid, false, false);
9150
9151                 /* Now we can close it.  Keep the lock till end of transaction. */
9152                 relation_close(seqRel, NoLock);
9153         }
9154
9155         systable_endscan(scan);
9156
9157         relation_close(depRel, AccessShareLock);
9158 }
9159
9160
9161 /*
9162  * This code supports
9163  *      CREATE TEMP TABLE ... ON COMMIT { DROP | PRESERVE ROWS | DELETE ROWS }
9164  *
9165  * Because we only support this for TEMP tables, it's sufficient to remember
9166  * the state in a backend-local data structure.
9167  */
9168
9169 /*
9170  * Register a newly-created relation's ON COMMIT action.
9171  */
9172 void
9173 register_on_commit_action(Oid relid, OnCommitAction action)
9174 {
9175         OnCommitItem *oc;
9176         MemoryContext oldcxt;
9177
9178         /*
9179          * We needn't bother registering the relation unless there is an ON COMMIT
9180          * action we need to take.
9181          */
9182         if (action == ONCOMMIT_NOOP || action == ONCOMMIT_PRESERVE_ROWS)
9183                 return;
9184
9185         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
9186
9187         oc = (OnCommitItem *) palloc(sizeof(OnCommitItem));
9188         oc->relid = relid;
9189         oc->oncommit = action;
9190         oc->creating_subid = GetCurrentSubTransactionId();
9191         oc->deleting_subid = InvalidSubTransactionId;
9192
9193         on_commits = lcons(oc, on_commits);
9194
9195         MemoryContextSwitchTo(oldcxt);
9196 }
9197
9198 /*
9199  * Unregister any ON COMMIT action when a relation is deleted.
9200  *
9201  * Actually, we only mark the OnCommitItem entry as to be deleted after commit.
9202  */
9203 void
9204 remove_on_commit_action(Oid relid)
9205 {
9206         ListCell   *l;
9207
9208         foreach(l, on_commits)
9209         {
9210                 OnCommitItem *oc = (OnCommitItem *) lfirst(l);
9211
9212                 if (oc->relid == relid)
9213                 {
9214                         oc->deleting_subid = GetCurrentSubTransactionId();
9215                         break;
9216                 }
9217         }
9218 }
9219
9220 /*
9221  * Perform ON COMMIT actions.
9222  *
9223  * This is invoked just before actually committing, since it's possible
9224  * to encounter errors.
9225  */
9226 void
9227 PreCommit_on_commit_actions(void)
9228 {
9229         ListCell   *l;
9230         List       *oids_to_truncate = NIL;
9231
9232         foreach(l, on_commits)
9233         {
9234                 OnCommitItem *oc = (OnCommitItem *) lfirst(l);
9235
9236                 /* Ignore entry if already dropped in this xact */
9237                 if (oc->deleting_subid != InvalidSubTransactionId)
9238                         continue;
9239
9240                 switch (oc->oncommit)
9241                 {
9242                         case ONCOMMIT_NOOP:
9243                         case ONCOMMIT_PRESERVE_ROWS:
9244                                 /* Do nothing (there shouldn't be such entries, actually) */
9245                                 break;
9246                         case ONCOMMIT_DELETE_ROWS:
9247                                 oids_to_truncate = lappend_oid(oids_to_truncate, oc->relid);
9248                                 break;
9249                         case ONCOMMIT_DROP:
9250                                 {
9251                                         ObjectAddress object;
9252
9253                                         object.classId = RelationRelationId;
9254                                         object.objectId = oc->relid;
9255                                         object.objectSubId = 0;
9256                                         performDeletion(&object, DROP_CASCADE);
9257
9258                                         /*
9259                                          * Note that table deletion will call
9260                                          * remove_on_commit_action, so the entry should get marked
9261                                          * as deleted.
9262                                          */
9263                                         Assert(oc->deleting_subid != InvalidSubTransactionId);
9264                                         break;
9265                                 }
9266                 }
9267         }
9268         if (oids_to_truncate != NIL)
9269         {
9270                 heap_truncate(oids_to_truncate);
9271                 CommandCounterIncrement();              /* XXX needed? */
9272         }
9273 }
9274
9275 /*
9276  * Post-commit or post-abort cleanup for ON COMMIT management.
9277  *
9278  * All we do here is remove no-longer-needed OnCommitItem entries.
9279  *
9280  * During commit, remove entries that were deleted during this transaction;
9281  * during abort, remove those created during this transaction.
9282  */
9283 void
9284 AtEOXact_on_commit_actions(bool isCommit)
9285 {
9286         ListCell   *cur_item;
9287         ListCell   *prev_item;
9288
9289         prev_item = NULL;
9290         cur_item = list_head(on_commits);
9291
9292         while (cur_item != NULL)
9293         {
9294                 OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
9295
9296                 if (isCommit ? oc->deleting_subid != InvalidSubTransactionId :
9297                         oc->creating_subid != InvalidSubTransactionId)
9298                 {
9299                         /* cur_item must be removed */
9300                         on_commits = list_delete_cell(on_commits, cur_item, prev_item);
9301                         pfree(oc);
9302                         if (prev_item)
9303                                 cur_item = lnext(prev_item);
9304                         else
9305                                 cur_item = list_head(on_commits);
9306                 }
9307                 else
9308                 {
9309                         /* cur_item must be preserved */
9310                         oc->creating_subid = InvalidSubTransactionId;
9311                         oc->deleting_subid = InvalidSubTransactionId;
9312                         prev_item = cur_item;
9313                         cur_item = lnext(prev_item);
9314                 }
9315         }
9316 }
9317
9318 /*
9319  * Post-subcommit or post-subabort cleanup for ON COMMIT management.
9320  *
9321  * During subabort, we can immediately remove entries created during this
9322  * subtransaction.      During subcommit, just relabel entries marked during
9323  * this subtransaction as being the parent's responsibility.
9324  */
9325 void
9326 AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid,
9327                                                           SubTransactionId parentSubid)
9328 {
9329         ListCell   *cur_item;
9330         ListCell   *prev_item;
9331
9332         prev_item = NULL;
9333         cur_item = list_head(on_commits);
9334
9335         while (cur_item != NULL)
9336         {
9337                 OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
9338
9339                 if (!isCommit && oc->creating_subid == mySubid)
9340                 {
9341                         /* cur_item must be removed */
9342                         on_commits = list_delete_cell(on_commits, cur_item, prev_item);
9343                         pfree(oc);
9344                         if (prev_item)
9345                                 cur_item = lnext(prev_item);
9346                         else
9347                                 cur_item = list_head(on_commits);
9348                 }
9349                 else
9350                 {
9351                         /* cur_item must be preserved */
9352                         if (oc->creating_subid == mySubid)
9353                                 oc->creating_subid = parentSubid;
9354                         if (oc->deleting_subid == mySubid)
9355                                 oc->deleting_subid = isCommit ? parentSubid : InvalidSubTransactionId;
9356                         prev_item = cur_item;
9357                         cur_item = lnext(prev_item);
9358                 }
9359         }
9360 }