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