]> granicus.if.org Git - postgresql/blob - src/backend/commands/tablecmds.c
ALTER TABLE ... ALTER CONSTRAINT for FKs
[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 are 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 | ATT_MATVIEW);
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);
3545
3546                         /*
3547                          * Copy the heap data into the new table with the desired
3548                          * modifications, and test the current data within the table
3549                          * against new constraints generated by ALTER TABLE commands.
3550                          */
3551                         ATRewriteTable(tab, OIDNewHeap, lockmode);
3552
3553                         /*
3554                          * Swap the physical files of the old and new heaps, then rebuild
3555                          * indexes and discard the old heap.  We can use RecentXmin for
3556                          * the table's new relfrozenxid because we rewrote all the tuples
3557                          * in ATRewriteTable, so no older Xid remains in the table.  Also,
3558                          * we never try to swap toast tables by content, since we have no
3559                          * interest in letting this code work on system catalogs.
3560                          */
3561                         finish_heap_swap(tab->relid, OIDNewHeap,
3562                                                          false, false, true,
3563                                                          !OidIsValid(tab->newTableSpace),
3564                                                          RecentXmin,
3565                                                          ReadNextMultiXactId());
3566                 }
3567                 else
3568                 {
3569                         /*
3570                          * Test the current data within the table against new constraints
3571                          * generated by ALTER TABLE commands, but don't rebuild data.
3572                          */
3573                         if (tab->constraints != NIL || tab->new_notnull)
3574                                 ATRewriteTable(tab, InvalidOid, lockmode);
3575
3576                         /*
3577                          * If we had SET TABLESPACE but no reason to reconstruct tuples,
3578                          * just do a block-by-block copy.
3579                          */
3580                         if (tab->newTableSpace)
3581                                 ATExecSetTableSpace(tab->relid, tab->newTableSpace, lockmode);
3582                 }
3583         }
3584
3585         /*
3586          * Foreign key constraints are checked in a final pass, since (a) it's
3587          * generally best to examine each one separately, and (b) it's at least
3588          * theoretically possible that we have changed both relations of the
3589          * foreign key, and we'd better have finished both rewrites before we try
3590          * to read the tables.
3591          */
3592         foreach(ltab, *wqueue)
3593         {
3594                 AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
3595                 Relation        rel = NULL;
3596                 ListCell   *lcon;
3597
3598                 foreach(lcon, tab->constraints)
3599                 {
3600                         NewConstraint *con = lfirst(lcon);
3601
3602                         if (con->contype == CONSTR_FOREIGN)
3603                         {
3604                                 Constraint *fkconstraint = (Constraint *) con->qual;
3605                                 Relation        refrel;
3606
3607                                 if (rel == NULL)
3608                                 {
3609                                         /* Long since locked, no need for another */
3610                                         rel = heap_open(tab->relid, NoLock);
3611                                 }
3612
3613                                 refrel = heap_open(con->refrelid, RowShareLock);
3614
3615                                 validateForeignKeyConstraint(fkconstraint->conname, rel, refrel,
3616                                                                                          con->refindid,
3617                                                                                          con->conid);
3618
3619                                 /*
3620                                  * No need to mark the constraint row as validated, we did
3621                                  * that when we inserted the row earlier.
3622                                  */
3623
3624                                 heap_close(refrel, NoLock);
3625                         }
3626                 }
3627
3628                 if (rel)
3629                         heap_close(rel, NoLock);
3630         }
3631 }
3632
3633 /*
3634  * ATRewriteTable: scan or rewrite one table
3635  *
3636  * OIDNewHeap is InvalidOid if we don't need to rewrite
3637  */
3638 static void
3639 ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
3640 {
3641         Relation        oldrel;
3642         Relation        newrel;
3643         TupleDesc       oldTupDesc;
3644         TupleDesc       newTupDesc;
3645         bool            needscan = false;
3646         List       *notnull_attrs;
3647         int                     i;
3648         ListCell   *l;
3649         EState     *estate;
3650         CommandId       mycid;
3651         BulkInsertState bistate;
3652         int                     hi_options;
3653
3654         /*
3655          * Open the relation(s).  We have surely already locked the existing
3656          * table.
3657          */
3658         oldrel = heap_open(tab->relid, NoLock);
3659         oldTupDesc = tab->oldDesc;
3660         newTupDesc = RelationGetDescr(oldrel);          /* includes all mods */
3661
3662         if (OidIsValid(OIDNewHeap))
3663                 newrel = heap_open(OIDNewHeap, lockmode);
3664         else
3665                 newrel = NULL;
3666
3667         /*
3668          * Prepare a BulkInsertState and options for heap_insert. Because we're
3669          * building a new heap, we can skip WAL-logging and fsync it to disk at
3670          * the end instead (unless WAL-logging is required for archiving or
3671          * streaming replication). The FSM is empty too, so don't bother using it.
3672          */
3673         if (newrel)
3674         {
3675                 mycid = GetCurrentCommandId(true);
3676                 bistate = GetBulkInsertState();
3677
3678                 hi_options = HEAP_INSERT_SKIP_FSM;
3679                 if (!XLogIsNeeded())
3680                         hi_options |= HEAP_INSERT_SKIP_WAL;
3681         }
3682         else
3683         {
3684                 /* keep compiler quiet about using these uninitialized */
3685                 mycid = 0;
3686                 bistate = NULL;
3687                 hi_options = 0;
3688         }
3689
3690         /*
3691          * Generate the constraint and default execution states
3692          */
3693
3694         estate = CreateExecutorState();
3695
3696         /* Build the needed expression execution states */
3697         foreach(l, tab->constraints)
3698         {
3699                 NewConstraint *con = lfirst(l);
3700
3701                 switch (con->contype)
3702                 {
3703                         case CONSTR_CHECK:
3704                                 needscan = true;
3705                                 con->qualstate = (List *)
3706                                         ExecPrepareExpr((Expr *) con->qual, estate);
3707                                 break;
3708                         case CONSTR_FOREIGN:
3709                                 /* Nothing to do here */
3710                                 break;
3711                         default:
3712                                 elog(ERROR, "unrecognized constraint type: %d",
3713                                          (int) con->contype);
3714                 }
3715         }
3716
3717         foreach(l, tab->newvals)
3718         {
3719                 NewColumnValue *ex = lfirst(l);
3720
3721                 /* expr already planned */
3722                 ex->exprstate = ExecInitExpr((Expr *) ex->expr, NULL);
3723         }
3724
3725         notnull_attrs = NIL;
3726         if (newrel || tab->new_notnull)
3727         {
3728                 /*
3729                  * If we are rebuilding the tuples OR if we added any new NOT NULL
3730                  * constraints, check all not-null constraints.  This is a bit of
3731                  * overkill but it minimizes risk of bugs, and heap_attisnull is a
3732                  * pretty cheap test anyway.
3733                  */
3734                 for (i = 0; i < newTupDesc->natts; i++)
3735                 {
3736                         if (newTupDesc->attrs[i]->attnotnull &&
3737                                 !newTupDesc->attrs[i]->attisdropped)
3738                                 notnull_attrs = lappend_int(notnull_attrs, i);
3739                 }
3740                 if (notnull_attrs)
3741                         needscan = true;
3742         }
3743
3744         if (newrel || needscan)
3745         {
3746                 ExprContext *econtext;
3747                 Datum      *values;
3748                 bool       *isnull;
3749                 TupleTableSlot *oldslot;
3750                 TupleTableSlot *newslot;
3751                 HeapScanDesc scan;
3752                 HeapTuple       tuple;
3753                 MemoryContext oldCxt;
3754                 List       *dropped_attrs = NIL;
3755                 ListCell   *lc;
3756
3757                 if (newrel)
3758                         ereport(DEBUG1,
3759                                         (errmsg("rewriting table \"%s\"",
3760                                                         RelationGetRelationName(oldrel))));
3761                 else
3762                         ereport(DEBUG1,
3763                                         (errmsg("verifying table \"%s\"",
3764                                                         RelationGetRelationName(oldrel))));
3765
3766                 if (newrel)
3767                 {
3768                         /*
3769                          * All predicate locks on the tuples or pages are about to be made
3770                          * invalid, because we move tuples around.      Promote them to
3771                          * relation locks.
3772                          */
3773                         TransferPredicateLocksToHeapRelation(oldrel);
3774                 }
3775
3776                 econtext = GetPerTupleExprContext(estate);
3777
3778                 /*
3779                  * Make tuple slots for old and new tuples.  Note that even when the
3780                  * tuples are the same, the tupDescs might not be (consider ADD COLUMN
3781                  * without a default).
3782                  */
3783                 oldslot = MakeSingleTupleTableSlot(oldTupDesc);
3784                 newslot = MakeSingleTupleTableSlot(newTupDesc);
3785
3786                 /* Preallocate values/isnull arrays */
3787                 i = Max(newTupDesc->natts, oldTupDesc->natts);
3788                 values = (Datum *) palloc(i * sizeof(Datum));
3789                 isnull = (bool *) palloc(i * sizeof(bool));
3790                 memset(values, 0, i * sizeof(Datum));
3791                 memset(isnull, true, i * sizeof(bool));
3792
3793                 /*
3794                  * Any attributes that are dropped according to the new tuple
3795                  * descriptor can be set to NULL. We precompute the list of dropped
3796                  * attributes to avoid needing to do so in the per-tuple loop.
3797                  */
3798                 for (i = 0; i < newTupDesc->natts; i++)
3799                 {
3800                         if (newTupDesc->attrs[i]->attisdropped)
3801                                 dropped_attrs = lappend_int(dropped_attrs, i);
3802                 }
3803
3804                 /*
3805                  * Scan through the rows, generating a new row if needed and then
3806                  * checking all the constraints.
3807                  */
3808                 scan = heap_beginscan(oldrel, SnapshotNow, 0, NULL);
3809
3810                 /*
3811                  * Switch to per-tuple memory context and reset it for each tuple
3812                  * produced, so we don't leak memory.
3813                  */
3814                 oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
3815
3816                 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
3817                 {
3818                         if (tab->rewrite)
3819                         {
3820                                 Oid                     tupOid = InvalidOid;
3821
3822                                 /* Extract data from old tuple */
3823                                 heap_deform_tuple(tuple, oldTupDesc, values, isnull);
3824                                 if (oldTupDesc->tdhasoid)
3825                                         tupOid = HeapTupleGetOid(tuple);
3826
3827                                 /* Set dropped attributes to null in new tuple */
3828                                 foreach(lc, dropped_attrs)
3829                                         isnull[lfirst_int(lc)] = true;
3830
3831                                 /*
3832                                  * Process supplied expressions to replace selected columns.
3833                                  * Expression inputs come from the old tuple.
3834                                  */
3835                                 ExecStoreTuple(tuple, oldslot, InvalidBuffer, false);
3836                                 econtext->ecxt_scantuple = oldslot;
3837
3838                                 foreach(l, tab->newvals)
3839                                 {
3840                                         NewColumnValue *ex = lfirst(l);
3841
3842                                         values[ex->attnum - 1] = ExecEvalExpr(ex->exprstate,
3843                                                                                                                   econtext,
3844                                                                                                          &isnull[ex->attnum - 1],
3845                                                                                                                   NULL);
3846                                 }
3847
3848                                 /*
3849                                  * Form the new tuple. Note that we don't explicitly pfree it,
3850                                  * since the per-tuple memory context will be reset shortly.
3851                                  */
3852                                 tuple = heap_form_tuple(newTupDesc, values, isnull);
3853
3854                                 /* Preserve OID, if any */
3855                                 if (newTupDesc->tdhasoid)
3856                                         HeapTupleSetOid(tuple, tupOid);
3857                         }
3858
3859                         /* Now check any constraints on the possibly-changed tuple */
3860                         ExecStoreTuple(tuple, newslot, InvalidBuffer, false);
3861                         econtext->ecxt_scantuple = newslot;
3862
3863                         foreach(l, notnull_attrs)
3864                         {
3865                                 int                     attn = lfirst_int(l);
3866
3867                                 if (heap_attisnull(tuple, attn + 1))
3868                                         ereport(ERROR,
3869                                                         (errcode(ERRCODE_NOT_NULL_VIOLATION),
3870                                                          errmsg("column \"%s\" contains null values",
3871                                                                   NameStr(newTupDesc->attrs[attn]->attname)),
3872                                                          errtablecol(oldrel, attn + 1)));
3873                         }
3874
3875                         foreach(l, tab->constraints)
3876                         {
3877                                 NewConstraint *con = lfirst(l);
3878
3879                                 switch (con->contype)
3880                                 {
3881                                         case CONSTR_CHECK:
3882                                                 if (!ExecQual(con->qualstate, econtext, true))
3883                                                         ereport(ERROR,
3884                                                                         (errcode(ERRCODE_CHECK_VIOLATION),
3885                                                                          errmsg("check constraint \"%s\" is violated by some row",
3886                                                                                         con->name),
3887                                                                          errtableconstraint(oldrel, con->name)));
3888                                                 break;
3889                                         case CONSTR_FOREIGN:
3890                                                 /* Nothing to do here */
3891                                                 break;
3892                                         default:
3893                                                 elog(ERROR, "unrecognized constraint type: %d",
3894                                                          (int) con->contype);
3895                                 }
3896                         }
3897
3898                         /* Write the tuple out to the new relation */
3899                         if (newrel)
3900                                 heap_insert(newrel, tuple, mycid, hi_options, bistate);
3901
3902                         ResetExprContext(econtext);
3903
3904                         CHECK_FOR_INTERRUPTS();
3905                 }
3906
3907                 MemoryContextSwitchTo(oldCxt);
3908                 heap_endscan(scan);
3909
3910                 ExecDropSingleTupleTableSlot(oldslot);
3911                 ExecDropSingleTupleTableSlot(newslot);
3912         }
3913
3914         FreeExecutorState(estate);
3915
3916         heap_close(oldrel, NoLock);
3917         if (newrel)
3918         {
3919                 FreeBulkInsertState(bistate);
3920
3921                 /* If we skipped writing WAL, then we need to sync the heap. */
3922                 if (hi_options & HEAP_INSERT_SKIP_WAL)
3923                         heap_sync(newrel);
3924
3925                 heap_close(newrel, NoLock);
3926         }
3927 }
3928
3929 /*
3930  * ATGetQueueEntry: find or create an entry in the ALTER TABLE work queue
3931  */
3932 static AlteredTableInfo *
3933 ATGetQueueEntry(List **wqueue, Relation rel)
3934 {
3935         Oid                     relid = RelationGetRelid(rel);
3936         AlteredTableInfo *tab;
3937         ListCell   *ltab;
3938
3939         foreach(ltab, *wqueue)
3940         {
3941                 tab = (AlteredTableInfo *) lfirst(ltab);
3942                 if (tab->relid == relid)
3943                         return tab;
3944         }
3945
3946         /*
3947          * Not there, so add it.  Note that we make a copy of the relation's
3948          * existing descriptor before anything interesting can happen to it.
3949          */
3950         tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo));
3951         tab->relid = relid;
3952         tab->relkind = rel->rd_rel->relkind;
3953         tab->oldDesc = CreateTupleDescCopy(RelationGetDescr(rel));
3954
3955         *wqueue = lappend(*wqueue, tab);
3956
3957         return tab;
3958 }
3959
3960 /*
3961  * ATSimplePermissions
3962  *
3963  * - Ensure that it is a relation (or possibly a view)
3964  * - Ensure this user is the owner
3965  * - Ensure that it is not a system table
3966  */
3967 static void
3968 ATSimplePermissions(Relation rel, int allowed_targets)
3969 {
3970         int                     actual_target;
3971
3972         switch (rel->rd_rel->relkind)
3973         {
3974                 case RELKIND_RELATION:
3975                         actual_target = ATT_TABLE;
3976                         break;
3977                 case RELKIND_VIEW:
3978                         actual_target = ATT_VIEW;
3979                         break;
3980                 case RELKIND_MATVIEW:
3981                         actual_target = ATT_MATVIEW;
3982                         break;
3983                 case RELKIND_INDEX:
3984                         actual_target = ATT_INDEX;
3985                         break;
3986                 case RELKIND_COMPOSITE_TYPE:
3987                         actual_target = ATT_COMPOSITE_TYPE;
3988                         break;
3989                 case RELKIND_FOREIGN_TABLE:
3990                         actual_target = ATT_FOREIGN_TABLE;
3991                         break;
3992                 default:
3993                         actual_target = 0;
3994                         break;
3995         }
3996
3997         /* Wrong target type? */
3998         if ((actual_target & allowed_targets) == 0)
3999                 ATWrongRelkindError(rel, allowed_targets);
4000
4001         /* Permissions checks */
4002         if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
4003                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
4004                                            RelationGetRelationName(rel));
4005
4006         if (!allowSystemTableMods && IsSystemRelation(rel))
4007                 ereport(ERROR,
4008                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4009                                  errmsg("permission denied: \"%s\" is a system catalog",
4010                                                 RelationGetRelationName(rel))));
4011 }
4012
4013 /*
4014  * ATWrongRelkindError
4015  *
4016  * Throw an error when a relation has been determined to be of the wrong
4017  * type.
4018  */
4019 static void
4020 ATWrongRelkindError(Relation rel, int allowed_targets)
4021 {
4022         char       *msg;
4023
4024         switch (allowed_targets)
4025         {
4026                 case ATT_TABLE:
4027                         msg = _("\"%s\" is not a table");
4028                         break;
4029                 case ATT_TABLE | ATT_VIEW:
4030                         msg = _("\"%s\" is not a table or view");
4031                         break;
4032                 case ATT_TABLE | ATT_VIEW | ATT_MATVIEW | ATT_INDEX:
4033                         msg = _("\"%s\" is not a table, view, materialized view, or index");
4034                         break;
4035                 case ATT_TABLE | ATT_MATVIEW:
4036                         msg = _("\"%s\" is not a table or materialized view");
4037                         break;
4038                 case ATT_TABLE | ATT_MATVIEW | ATT_INDEX:
4039                         msg = _("\"%s\" is not a table, materialized view, or index");
4040                         break;
4041                 case ATT_TABLE | ATT_FOREIGN_TABLE:
4042                         msg = _("\"%s\" is not a table or foreign table");
4043                         break;
4044                 case ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE:
4045                         msg = _("\"%s\" is not a table, composite type, or foreign table");
4046                         break;
4047                 case ATT_TABLE | ATT_MATVIEW | ATT_INDEX | ATT_FOREIGN_TABLE:
4048                         msg = _("\"%s\" is not a table, materialized view, composite type, or foreign table");
4049                         break;
4050                 case ATT_VIEW:
4051                         msg = _("\"%s\" is not a view");
4052                         break;
4053                 case ATT_FOREIGN_TABLE:
4054                         msg = _("\"%s\" is not a foreign table");
4055                         break;
4056                 default:
4057                         /* shouldn't get here, add all necessary cases above */
4058                         msg = _("\"%s\" is of the wrong type");
4059                         break;
4060         }
4061
4062         ereport(ERROR,
4063                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4064                          errmsg(msg, RelationGetRelationName(rel))));
4065 }
4066
4067 /*
4068  * ATSimpleRecursion
4069  *
4070  * Simple table recursion sufficient for most ALTER TABLE operations.
4071  * All direct and indirect children are processed in an unspecified order.
4072  * Note that if a child inherits from the original table via multiple
4073  * inheritance paths, it will be visited just once.
4074  */
4075 static void
4076 ATSimpleRecursion(List **wqueue, Relation rel,
4077                                   AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode)
4078 {
4079         /*
4080          * Propagate to children if desired.  Non-table relations never have
4081          * children, so no need to search in that case.
4082          */
4083         if (recurse && rel->rd_rel->relkind == RELKIND_RELATION)
4084         {
4085                 Oid                     relid = RelationGetRelid(rel);
4086                 ListCell   *child;
4087                 List       *children;
4088
4089                 children = find_all_inheritors(relid, lockmode, NULL);
4090
4091                 /*
4092                  * find_all_inheritors does the recursive search of the inheritance
4093                  * hierarchy, so all we have to do is process all of the relids in the
4094                  * list that it returns.
4095                  */
4096                 foreach(child, children)
4097                 {
4098                         Oid                     childrelid = lfirst_oid(child);
4099                         Relation        childrel;
4100
4101                         if (childrelid == relid)
4102                                 continue;
4103                         /* find_all_inheritors already got lock */
4104                         childrel = relation_open(childrelid, NoLock);
4105                         CheckTableNotInUse(childrel, "ALTER TABLE");
4106                         ATPrepCmd(wqueue, childrel, cmd, false, true, lockmode);
4107                         relation_close(childrel, NoLock);
4108                 }
4109         }
4110 }
4111
4112 /*
4113  * ATTypedTableRecursion
4114  *
4115  * Propagate ALTER TYPE operations to the typed tables of that type.
4116  * Also check the RESTRICT/CASCADE behavior.  Given CASCADE, also permit
4117  * recursion to inheritance children of the typed tables.
4118  */
4119 static void
4120 ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd,
4121                                           LOCKMODE lockmode)
4122 {
4123         ListCell   *child;
4124         List       *children;
4125
4126         Assert(rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE);
4127
4128         children = find_typed_table_dependencies(rel->rd_rel->reltype,
4129                                                                                          RelationGetRelationName(rel),
4130                                                                                          cmd->behavior);
4131
4132         foreach(child, children)
4133         {
4134                 Oid                     childrelid = lfirst_oid(child);
4135                 Relation        childrel;
4136
4137                 childrel = relation_open(childrelid, lockmode);
4138                 CheckTableNotInUse(childrel, "ALTER TABLE");
4139                 ATPrepCmd(wqueue, childrel, cmd, true, true, lockmode);
4140                 relation_close(childrel, NoLock);
4141         }
4142 }
4143
4144
4145 /*
4146  * find_composite_type_dependencies
4147  *
4148  * Check to see if a composite type is being used as a column in some
4149  * other table (possibly nested several levels deep in composite types!).
4150  * Eventually, we'd like to propagate the check or rewrite operation
4151  * into other such tables, but for now, just error out if we find any.
4152  *
4153  * Caller should provide either a table name or a type name (not both) to
4154  * report in the error message, if any.
4155  *
4156  * We assume that functions and views depending on the type are not reasons
4157  * to reject the ALTER.  (How safe is this really?)
4158  */
4159 void
4160 find_composite_type_dependencies(Oid typeOid, Relation origRelation,
4161                                                                  const char *origTypeName)
4162 {
4163         Relation        depRel;
4164         ScanKeyData key[2];
4165         SysScanDesc depScan;
4166         HeapTuple       depTup;
4167         Oid                     arrayOid;
4168
4169         /*
4170          * We scan pg_depend to find those things that depend on the rowtype. (We
4171          * assume we can ignore refobjsubid for a rowtype.)
4172          */
4173         depRel = heap_open(DependRelationId, AccessShareLock);
4174
4175         ScanKeyInit(&key[0],
4176                                 Anum_pg_depend_refclassid,
4177                                 BTEqualStrategyNumber, F_OIDEQ,
4178                                 ObjectIdGetDatum(TypeRelationId));
4179         ScanKeyInit(&key[1],
4180                                 Anum_pg_depend_refobjid,
4181                                 BTEqualStrategyNumber, F_OIDEQ,
4182                                 ObjectIdGetDatum(typeOid));
4183
4184         depScan = systable_beginscan(depRel, DependReferenceIndexId, true,
4185                                                                  SnapshotNow, 2, key);
4186
4187         while (HeapTupleIsValid(depTup = systable_getnext(depScan)))
4188         {
4189                 Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
4190                 Relation        rel;
4191                 Form_pg_attribute att;
4192
4193                 /* Ignore dependees that aren't user columns of relations */
4194                 /* (we assume system columns are never of rowtypes) */
4195                 if (pg_depend->classid != RelationRelationId ||
4196                         pg_depend->objsubid <= 0)
4197                         continue;
4198
4199                 rel = relation_open(pg_depend->objid, AccessShareLock);
4200                 att = rel->rd_att->attrs[pg_depend->objsubid - 1];
4201
4202                 if (rel->rd_rel->relkind == RELKIND_RELATION ||
4203                         rel->rd_rel->relkind == RELKIND_MATVIEW)
4204                 {
4205                         if (origTypeName)
4206                                 ereport(ERROR,
4207                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4208                                                  errmsg("cannot alter type \"%s\" because column \"%s.%s\" uses it",
4209                                                                 origTypeName,
4210                                                                 RelationGetRelationName(rel),
4211                                                                 NameStr(att->attname))));
4212                         else if (origRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
4213                                 ereport(ERROR,
4214                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4215                                                  errmsg("cannot alter type \"%s\" because column \"%s.%s\" uses it",
4216                                                                 RelationGetRelationName(origRelation),
4217                                                                 RelationGetRelationName(rel),
4218                                                                 NameStr(att->attname))));
4219                         else if (origRelation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
4220                                 ereport(ERROR,
4221                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4222                                                  errmsg("cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type",
4223                                                                 RelationGetRelationName(origRelation),
4224                                                                 RelationGetRelationName(rel),
4225                                                                 NameStr(att->attname))));
4226                         else
4227                                 ereport(ERROR,
4228                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4229                                                  errmsg("cannot alter table \"%s\" because column \"%s.%s\" uses its row type",
4230                                                                 RelationGetRelationName(origRelation),
4231                                                                 RelationGetRelationName(rel),
4232                                                                 NameStr(att->attname))));
4233                 }
4234                 else if (OidIsValid(rel->rd_rel->reltype))
4235                 {
4236                         /*
4237                          * A view or composite type itself isn't a problem, but we must
4238                          * recursively check for indirect dependencies via its rowtype.
4239                          */
4240                         find_composite_type_dependencies(rel->rd_rel->reltype,
4241                                                                                          origRelation, origTypeName);
4242                 }
4243
4244                 relation_close(rel, AccessShareLock);
4245         }
4246
4247         systable_endscan(depScan);
4248
4249         relation_close(depRel, AccessShareLock);
4250
4251         /*
4252          * If there's an array type for the rowtype, must check for uses of it,
4253          * too.
4254          */
4255         arrayOid = get_array_type(typeOid);
4256         if (OidIsValid(arrayOid))
4257                 find_composite_type_dependencies(arrayOid, origRelation, origTypeName);
4258 }
4259
4260
4261 /*
4262  * find_typed_table_dependencies
4263  *
4264  * Check to see if a composite type is being used as the type of a
4265  * typed table.  Abort if any are found and behavior is RESTRICT.
4266  * Else return the list of tables.
4267  */
4268 static List *
4269 find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior behavior)
4270 {
4271         Relation        classRel;
4272         ScanKeyData key[1];
4273         HeapScanDesc scan;
4274         HeapTuple       tuple;
4275         List       *result = NIL;
4276
4277         classRel = heap_open(RelationRelationId, AccessShareLock);
4278
4279         ScanKeyInit(&key[0],
4280                                 Anum_pg_class_reloftype,
4281                                 BTEqualStrategyNumber, F_OIDEQ,
4282                                 ObjectIdGetDatum(typeOid));
4283
4284         scan = heap_beginscan(classRel, SnapshotNow, 1, key);
4285
4286         while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
4287         {
4288                 if (behavior == DROP_RESTRICT)
4289                         ereport(ERROR,
4290                                         (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
4291                                          errmsg("cannot alter type \"%s\" because it is the type of a typed table",
4292                                                         typeName),
4293                         errhint("Use ALTER ... CASCADE to alter the typed tables too.")));
4294                 else
4295                         result = lappend_oid(result, HeapTupleGetOid(tuple));
4296         }
4297
4298         heap_endscan(scan);
4299         heap_close(classRel, AccessShareLock);
4300
4301         return result;
4302 }
4303
4304
4305 /*
4306  * check_of_type
4307  *
4308  * Check whether a type is suitable for CREATE TABLE OF/ALTER TABLE OF.  If it
4309  * isn't suitable, throw an error.  Currently, we require that the type
4310  * originated with CREATE TYPE AS.      We could support any row type, but doing so
4311  * would require handling a number of extra corner cases in the DDL commands.
4312  */
4313 void
4314 check_of_type(HeapTuple typetuple)
4315 {
4316         Form_pg_type typ = (Form_pg_type) GETSTRUCT(typetuple);
4317         bool            typeOk = false;
4318
4319         if (typ->typtype == TYPTYPE_COMPOSITE)
4320         {
4321                 Relation        typeRelation;
4322
4323                 Assert(OidIsValid(typ->typrelid));
4324                 typeRelation = relation_open(typ->typrelid, AccessShareLock);
4325                 typeOk = (typeRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE);
4326
4327                 /*
4328                  * Close the parent rel, but keep our AccessShareLock on it until xact
4329                  * commit.      That will prevent someone else from deleting or ALTERing
4330                  * the type before the typed table creation/conversion commits.
4331                  */
4332                 relation_close(typeRelation, NoLock);
4333         }
4334         if (!typeOk)
4335                 ereport(ERROR,
4336                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4337                                  errmsg("type %s is not a composite type",
4338                                                 format_type_be(HeapTupleGetOid(typetuple)))));
4339 }
4340
4341
4342 /*
4343  * ALTER TABLE ADD COLUMN
4344  *
4345  * Adds an additional attribute to a relation making the assumption that
4346  * CHECK, NOT NULL, and FOREIGN KEY constraints will be removed from the
4347  * AT_AddColumn AlterTableCmd by parse_utilcmd.c and added as independent
4348  * AlterTableCmd's.
4349  *
4350  * ADD COLUMN cannot use the normal ALTER TABLE recursion mechanism, because we
4351  * have to decide at runtime whether to recurse or not depending on whether we
4352  * actually add a column or merely merge with an existing column.  (We can't
4353  * check this in a static pre-pass because it won't handle multiple inheritance
4354  * situations correctly.)
4355  */
4356 static void
4357 ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
4358                                 AlterTableCmd *cmd, LOCKMODE lockmode)
4359 {
4360         if (rel->rd_rel->reloftype && !recursing)
4361                 ereport(ERROR,
4362                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
4363                                  errmsg("cannot add column to typed table")));
4364
4365         if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
4366                 ATTypedTableRecursion(wqueue, rel, cmd, lockmode);
4367
4368         if (recurse)
4369                 cmd->subtype = AT_AddColumnRecurse;
4370 }
4371
4372 static void
4373 ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
4374                                 ColumnDef *colDef, bool isOid,
4375                                 bool recurse, bool recursing, LOCKMODE lockmode)
4376 {
4377         Oid                     myrelid = RelationGetRelid(rel);
4378         Relation        pgclass,
4379                                 attrdesc;
4380         HeapTuple       reltup;
4381         FormData_pg_attribute attribute;
4382         int                     newattnum;
4383         char            relkind;
4384         HeapTuple       typeTuple;
4385         Oid                     typeOid;
4386         int32           typmod;
4387         Oid                     collOid;
4388         Form_pg_type tform;
4389         Expr       *defval;
4390         List       *children;
4391         ListCell   *child;
4392         AclResult       aclresult;
4393
4394         /* At top level, permission check was done in ATPrepCmd, else do it */
4395         if (recursing)
4396                 ATSimplePermissions(rel, ATT_TABLE);
4397
4398         attrdesc = heap_open(AttributeRelationId, RowExclusiveLock);
4399
4400         /*
4401          * Are we adding the column to a recursion child?  If so, check whether to
4402          * merge with an existing definition for the column.  If we do merge, we
4403          * must not recurse.  Children will already have the column, and recursing
4404          * into them would mess up attinhcount.
4405          */
4406         if (colDef->inhcount > 0)
4407         {
4408                 HeapTuple       tuple;
4409
4410                 /* Does child already have a column by this name? */
4411                 tuple = SearchSysCacheCopyAttName(myrelid, colDef->colname);
4412                 if (HeapTupleIsValid(tuple))
4413                 {
4414                         Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
4415                         Oid                     ctypeId;
4416                         int32           ctypmod;
4417                         Oid                     ccollid;
4418
4419                         /* Child column must match on type, typmod, and collation */
4420                         typenameTypeIdAndMod(NULL, colDef->typeName, &ctypeId, &ctypmod);
4421                         if (ctypeId != childatt->atttypid ||
4422                                 ctypmod != childatt->atttypmod)
4423                                 ereport(ERROR,
4424                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
4425                                                  errmsg("child table \"%s\" has different type for column \"%s\"",
4426                                                         RelationGetRelationName(rel), colDef->colname)));
4427                         ccollid = GetColumnDefCollation(NULL, colDef, ctypeId);
4428                         if (ccollid != childatt->attcollation)
4429                                 ereport(ERROR,
4430                                                 (errcode(ERRCODE_COLLATION_MISMATCH),
4431                                                  errmsg("child table \"%s\" has different collation for column \"%s\"",
4432                                                           RelationGetRelationName(rel), colDef->colname),
4433                                                  errdetail("\"%s\" versus \"%s\"",
4434                                                                    get_collation_name(ccollid),
4435                                                            get_collation_name(childatt->attcollation))));
4436
4437                         /* If it's OID, child column must actually be OID */
4438                         if (isOid && childatt->attnum != ObjectIdAttributeNumber)
4439                                 ereport(ERROR,
4440                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
4441                                  errmsg("child table \"%s\" has a conflicting \"%s\" column",
4442                                                 RelationGetRelationName(rel), colDef->colname)));
4443
4444                         /* Bump the existing child att's inhcount */
4445                         childatt->attinhcount++;
4446                         simple_heap_update(attrdesc, &tuple->t_self, tuple);
4447                         CatalogUpdateIndexes(attrdesc, tuple);
4448
4449                         heap_freetuple(tuple);
4450
4451                         /* Inform the user about the merge */
4452                         ereport(NOTICE,
4453                           (errmsg("merging definition of column \"%s\" for child \"%s\"",
4454                                           colDef->colname, RelationGetRelationName(rel))));
4455
4456                         heap_close(attrdesc, RowExclusiveLock);
4457                         return;
4458                 }
4459         }
4460
4461         pgclass = heap_open(RelationRelationId, RowExclusiveLock);
4462
4463         reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(myrelid));
4464         if (!HeapTupleIsValid(reltup))
4465                 elog(ERROR, "cache lookup failed for relation %u", myrelid);
4466         relkind = ((Form_pg_class) GETSTRUCT(reltup))->relkind;
4467
4468         /* new name should not already exist */
4469         check_for_column_name_collision(rel, colDef->colname);
4470
4471         /* Determine the new attribute's number */
4472         if (isOid)
4473                 newattnum = ObjectIdAttributeNumber;
4474         else
4475         {
4476                 newattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts + 1;
4477                 if (newattnum > MaxHeapAttributeNumber)
4478                         ereport(ERROR,
4479                                         (errcode(ERRCODE_TOO_MANY_COLUMNS),
4480                                          errmsg("tables can have at most %d columns",
4481                                                         MaxHeapAttributeNumber)));
4482         }
4483
4484         typeTuple = typenameType(NULL, colDef->typeName, &typmod);
4485         tform = (Form_pg_type) GETSTRUCT(typeTuple);
4486         typeOid = HeapTupleGetOid(typeTuple);
4487
4488         aclresult = pg_type_aclcheck(typeOid, GetUserId(), ACL_USAGE);
4489         if (aclresult != ACLCHECK_OK)
4490                 aclcheck_error_type(aclresult, typeOid);
4491
4492         collOid = GetColumnDefCollation(NULL, colDef, typeOid);
4493
4494         /* make sure datatype is legal for a column */
4495         CheckAttributeType(colDef->colname, typeOid, collOid,
4496                                            list_make1_oid(rel->rd_rel->reltype),
4497                                            false);
4498
4499         /* construct new attribute's pg_attribute entry */
4500         attribute.attrelid = myrelid;
4501         namestrcpy(&(attribute.attname), colDef->colname);
4502         attribute.atttypid = typeOid;
4503         attribute.attstattarget = (newattnum > 0) ? -1 : 0;
4504         attribute.attlen = tform->typlen;
4505         attribute.attcacheoff = -1;
4506         attribute.atttypmod = typmod;
4507         attribute.attnum = newattnum;
4508         attribute.attbyval = tform->typbyval;
4509         attribute.attndims = list_length(colDef->typeName->arrayBounds);
4510         attribute.attstorage = tform->typstorage;
4511         attribute.attalign = tform->typalign;
4512         attribute.attnotnull = colDef->is_not_null;
4513         attribute.atthasdef = false;
4514         attribute.attisdropped = false;
4515         attribute.attislocal = colDef->is_local;
4516         attribute.attinhcount = colDef->inhcount;
4517         attribute.attcollation = collOid;
4518         /* attribute.attacl is handled by InsertPgAttributeTuple */
4519
4520         ReleaseSysCache(typeTuple);
4521
4522         InsertPgAttributeTuple(attrdesc, &attribute, NULL);
4523
4524         heap_close(attrdesc, RowExclusiveLock);
4525
4526         /*
4527          * Update pg_class tuple as appropriate
4528          */
4529         if (isOid)
4530                 ((Form_pg_class) GETSTRUCT(reltup))->relhasoids = true;
4531         else
4532                 ((Form_pg_class) GETSTRUCT(reltup))->relnatts = newattnum;
4533
4534         simple_heap_update(pgclass, &reltup->t_self, reltup);
4535
4536         /* keep catalog indexes current */
4537         CatalogUpdateIndexes(pgclass, reltup);
4538
4539         heap_freetuple(reltup);
4540
4541         /* Post creation hook for new attribute */
4542         InvokeObjectPostCreateHook(RelationRelationId, myrelid, newattnum);
4543
4544         heap_close(pgclass, RowExclusiveLock);
4545
4546         /* Make the attribute's catalog entry visible */
4547         CommandCounterIncrement();
4548
4549         /*
4550          * Store the DEFAULT, if any, in the catalogs
4551          */
4552         if (colDef->raw_default)
4553         {
4554                 RawColumnDefault *rawEnt;
4555
4556                 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
4557                 rawEnt->attnum = attribute.attnum;
4558                 rawEnt->raw_default = copyObject(colDef->raw_default);
4559
4560                 /*
4561                  * This function is intended for CREATE TABLE, so it processes a
4562                  * _list_ of defaults, but we just do one.
4563                  */
4564                 AddRelationNewConstraints(rel, list_make1(rawEnt), NIL,
4565                                                                   false, true, false);
4566
4567                 /* Make the additional catalog changes visible */
4568                 CommandCounterIncrement();
4569         }
4570
4571         /*
4572          * Tell Phase 3 to fill in the default expression, if there is one.
4573          *
4574          * If there is no default, Phase 3 doesn't have to do anything, because
4575          * that effectively means that the default is NULL.  The heap tuple access
4576          * routines always check for attnum > # of attributes in tuple, and return
4577          * NULL if so, so without any modification of the tuple data we will get
4578          * the effect of NULL values in the new column.
4579          *
4580          * An exception occurs when the new column is of a domain type: the domain
4581          * might have a NOT NULL constraint, or a check constraint that indirectly
4582          * rejects nulls.  If there are any domain constraints then we construct
4583          * an explicit NULL default value that will be passed through
4584          * CoerceToDomain processing.  (This is a tad inefficient, since it causes
4585          * rewriting the table which we really don't have to do, but the present
4586          * design of domain processing doesn't offer any simple way of checking
4587          * the constraints more directly.)
4588          *
4589          * Note: we use build_column_default, and not just the cooked default
4590          * returned by AddRelationNewConstraints, so that the right thing happens
4591          * when a datatype's default applies.
4592          *
4593          * We skip this step completely for views and foreign tables.  For a view,
4594          * we can only get here from CREATE OR REPLACE VIEW, which historically
4595          * doesn't set up defaults, not even for domain-typed columns.  And in any
4596          * case we mustn't invoke Phase 3 on a view or foreign table, since they
4597          * have no storage.
4598          */
4599         if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE
4600                 && relkind != RELKIND_FOREIGN_TABLE && attribute.attnum > 0)
4601         {
4602                 defval = (Expr *) build_column_default(rel, attribute.attnum);
4603
4604                 if (!defval && GetDomainConstraints(typeOid) != NIL)
4605                 {
4606                         Oid                     baseTypeId;
4607                         int32           baseTypeMod;
4608                         Oid                     baseTypeColl;
4609
4610                         baseTypeMod = typmod;
4611                         baseTypeId = getBaseTypeAndTypmod(typeOid, &baseTypeMod);
4612                         baseTypeColl = get_typcollation(baseTypeId);
4613                         defval = (Expr *) makeNullConst(baseTypeId, baseTypeMod, baseTypeColl);
4614                         defval = (Expr *) coerce_to_target_type(NULL,
4615                                                                                                         (Node *) defval,
4616                                                                                                         baseTypeId,
4617                                                                                                         typeOid,
4618                                                                                                         typmod,
4619                                                                                                         COERCION_ASSIGNMENT,
4620                                                                                                         COERCE_IMPLICIT_CAST,
4621                                                                                                         -1);
4622                         if (defval == NULL) /* should not happen */
4623                                 elog(ERROR, "failed to coerce base type to domain");
4624                 }
4625
4626                 if (defval)
4627                 {
4628                         NewColumnValue *newval;
4629
4630                         newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
4631                         newval->attnum = attribute.attnum;
4632                         newval->expr = expression_planner(defval);
4633
4634                         tab->newvals = lappend(tab->newvals, newval);
4635                         tab->rewrite = true;
4636                 }
4637
4638                 /*
4639                  * If the new column is NOT NULL, tell Phase 3 it needs to test that.
4640                  * (Note we don't do this for an OID column.  OID will be marked not
4641                  * null, but since it's filled specially, there's no need to test
4642                  * anything.)
4643                  */
4644                 tab->new_notnull |= colDef->is_not_null;
4645         }
4646
4647         /*
4648          * If we are adding an OID column, we have to tell Phase 3 to rewrite the
4649          * table to fix that.
4650          */
4651         if (isOid)
4652                 tab->rewrite = true;
4653
4654         /*
4655          * Add needed dependency entries for the new column.
4656          */
4657         add_column_datatype_dependency(myrelid, newattnum, attribute.atttypid);
4658         add_column_collation_dependency(myrelid, newattnum, attribute.attcollation);
4659
4660         /*
4661          * Propagate to children as appropriate.  Unlike most other ALTER
4662          * routines, we have to do this one level of recursion at a time; we can't
4663          * use find_all_inheritors to do it in one pass.
4664          */
4665         children = find_inheritance_children(RelationGetRelid(rel), lockmode);
4666
4667         /*
4668          * If we are told not to recurse, there had better not be any child
4669          * tables; else the addition would put them out of step.
4670          */
4671         if (children && !recurse)
4672                 ereport(ERROR,
4673                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4674                                  errmsg("column must be added to child tables too")));
4675
4676         /* Children should see column as singly inherited */
4677         if (!recursing)
4678         {
4679                 colDef = copyObject(colDef);
4680                 colDef->inhcount = 1;
4681                 colDef->is_local = false;
4682         }
4683
4684         foreach(child, children)
4685         {
4686                 Oid                     childrelid = lfirst_oid(child);
4687                 Relation        childrel;
4688                 AlteredTableInfo *childtab;
4689
4690                 /* find_inheritance_children already got lock */
4691                 childrel = heap_open(childrelid, NoLock);
4692                 CheckTableNotInUse(childrel, "ALTER TABLE");
4693
4694                 /* Find or create work queue entry for this table */
4695                 childtab = ATGetQueueEntry(wqueue, childrel);
4696
4697                 /* Recurse to child */
4698                 ATExecAddColumn(wqueue, childtab, childrel,
4699                                                 colDef, isOid, recurse, true, lockmode);
4700
4701                 heap_close(childrel, NoLock);
4702         }
4703 }
4704
4705 /*
4706  * If a new or renamed column will collide with the name of an existing
4707  * column, error out.
4708  */
4709 static void
4710 check_for_column_name_collision(Relation rel, const char *colname)
4711 {
4712         HeapTuple       attTuple;
4713         int                     attnum;
4714
4715         /*
4716          * this test is deliberately not attisdropped-aware, since if one tries to
4717          * add a column matching a dropped column name, it's gonna fail anyway.
4718          */
4719         attTuple = SearchSysCache2(ATTNAME,
4720                                                            ObjectIdGetDatum(RelationGetRelid(rel)),
4721                                                            PointerGetDatum(colname));
4722         if (!HeapTupleIsValid(attTuple))
4723                 return;
4724
4725         attnum = ((Form_pg_attribute) GETSTRUCT(attTuple))->attnum;
4726         ReleaseSysCache(attTuple);
4727
4728         /*
4729          * We throw a different error message for conflicts with system column
4730          * names, since they are normally not shown and the user might otherwise
4731          * be confused about the reason for the conflict.
4732          */
4733         if (attnum <= 0)
4734                 ereport(ERROR,
4735                                 (errcode(ERRCODE_DUPLICATE_COLUMN),
4736                          errmsg("column name \"%s\" conflicts with a system column name",
4737                                         colname)));
4738         else
4739                 ereport(ERROR,
4740                                 (errcode(ERRCODE_DUPLICATE_COLUMN),
4741                                  errmsg("column \"%s\" of relation \"%s\" already exists",
4742                                                 colname, RelationGetRelationName(rel))));
4743 }
4744
4745 /*
4746  * Install a column's dependency on its datatype.
4747  */
4748 static void
4749 add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid)
4750 {
4751         ObjectAddress myself,
4752                                 referenced;
4753
4754         myself.classId = RelationRelationId;
4755         myself.objectId = relid;
4756         myself.objectSubId = attnum;
4757         referenced.classId = TypeRelationId;
4758         referenced.objectId = typid;
4759         referenced.objectSubId = 0;
4760         recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
4761 }
4762
4763 /*
4764  * Install a column's dependency on its collation.
4765  */
4766 static void
4767 add_column_collation_dependency(Oid relid, int32 attnum, Oid collid)
4768 {
4769         ObjectAddress myself,
4770                                 referenced;
4771
4772         /* We know the default collation is pinned, so don't bother recording it */
4773         if (OidIsValid(collid) && collid != DEFAULT_COLLATION_OID)
4774         {
4775                 myself.classId = RelationRelationId;
4776                 myself.objectId = relid;
4777                 myself.objectSubId = attnum;
4778                 referenced.classId = CollationRelationId;
4779                 referenced.objectId = collid;
4780                 referenced.objectSubId = 0;
4781                 recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
4782         }
4783 }
4784
4785 /*
4786  * ALTER TABLE SET WITH OIDS
4787  *
4788  * Basically this is an ADD COLUMN for the special OID column.  We have
4789  * to cons up a ColumnDef node because the ADD COLUMN code needs one.
4790  */
4791 static void
4792 ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd, LOCKMODE lockmode)
4793 {
4794         /* If we're recursing to a child table, the ColumnDef is already set up */
4795         if (cmd->def == NULL)
4796         {
4797                 ColumnDef  *cdef = makeNode(ColumnDef);
4798
4799                 cdef->colname = pstrdup("oid");
4800                 cdef->typeName = makeTypeNameFromOid(OIDOID, -1);
4801                 cdef->inhcount = 0;
4802                 cdef->is_local = true;
4803                 cdef->is_not_null = true;
4804                 cdef->storage = 0;
4805                 cmd->def = (Node *) cdef;
4806         }
4807         ATPrepAddColumn(wqueue, rel, recurse, false, cmd, lockmode);
4808
4809         if (recurse)
4810                 cmd->subtype = AT_AddOidsRecurse;
4811 }
4812
4813 /*
4814  * ALTER TABLE ALTER COLUMN DROP NOT NULL
4815  */
4816 static void
4817 ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode)
4818 {
4819         HeapTuple       tuple;
4820         AttrNumber      attnum;
4821         Relation        attr_rel;
4822         List       *indexoidlist;
4823         ListCell   *indexoidscan;
4824
4825         /*
4826          * lookup the attribute
4827          */
4828         attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
4829
4830         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4831
4832         if (!HeapTupleIsValid(tuple))
4833                 ereport(ERROR,
4834                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
4835                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
4836                                                 colName, RelationGetRelationName(rel))));
4837
4838         attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
4839
4840         /* Prevent them from altering a system attribute */
4841         if (attnum <= 0)
4842                 ereport(ERROR,
4843                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4844                                  errmsg("cannot alter system column \"%s\"",
4845                                                 colName)));
4846
4847         /*
4848          * Check that the attribute is not in a primary key
4849          *
4850          * Note: we'll throw error even if the pkey index is not valid.
4851          */
4852
4853         /* Loop over all indexes on the relation */
4854         indexoidlist = RelationGetIndexList(rel);
4855
4856         foreach(indexoidscan, indexoidlist)
4857         {
4858                 Oid                     indexoid = lfirst_oid(indexoidscan);
4859                 HeapTuple       indexTuple;
4860                 Form_pg_index indexStruct;
4861                 int                     i;
4862
4863                 indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
4864                 if (!HeapTupleIsValid(indexTuple))
4865                         elog(ERROR, "cache lookup failed for index %u", indexoid);
4866                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
4867
4868                 /* If the index is not a primary key, skip the check */
4869                 if (indexStruct->indisprimary)
4870                 {
4871                         /*
4872                          * Loop over each attribute in the primary key and see if it
4873                          * matches the to-be-altered attribute
4874                          */
4875                         for (i = 0; i < indexStruct->indnatts; i++)
4876                         {
4877                                 if (indexStruct->indkey.values[i] == attnum)
4878                                         ereport(ERROR,
4879                                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
4880                                                          errmsg("column \"%s\" is in a primary key",
4881                                                                         colName)));
4882                         }
4883                 }
4884
4885                 ReleaseSysCache(indexTuple);
4886         }
4887
4888         list_free(indexoidlist);
4889
4890         /*
4891          * Okay, actually perform the catalog change ... if needed
4892          */
4893         if (((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
4894         {
4895                 ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = FALSE;
4896
4897                 simple_heap_update(attr_rel, &tuple->t_self, tuple);
4898
4899                 /* keep the system catalog indexes current */
4900                 CatalogUpdateIndexes(attr_rel, tuple);
4901         }
4902
4903         InvokeObjectPostAlterHook(RelationRelationId,
4904                                                           RelationGetRelid(rel), attnum);
4905
4906         heap_close(attr_rel, RowExclusiveLock);
4907 }
4908
4909 /*
4910  * ALTER TABLE ALTER COLUMN SET NOT NULL
4911  */
4912 static void
4913 ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
4914                                  const char *colName, LOCKMODE lockmode)
4915 {
4916         HeapTuple       tuple;
4917         AttrNumber      attnum;
4918         Relation        attr_rel;
4919
4920         /*
4921          * lookup the attribute
4922          */
4923         attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
4924
4925         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
4926
4927         if (!HeapTupleIsValid(tuple))
4928                 ereport(ERROR,
4929                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
4930                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
4931                                                 colName, RelationGetRelationName(rel))));
4932
4933         attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
4934
4935         /* Prevent them from altering a system attribute */
4936         if (attnum <= 0)
4937                 ereport(ERROR,
4938                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4939                                  errmsg("cannot alter system column \"%s\"",
4940                                                 colName)));
4941
4942         /*
4943          * Okay, actually perform the catalog change ... if needed
4944          */
4945         if (!((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull)
4946         {
4947                 ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = TRUE;
4948
4949                 simple_heap_update(attr_rel, &tuple->t_self, tuple);
4950
4951                 /* keep the system catalog indexes current */
4952                 CatalogUpdateIndexes(attr_rel, tuple);
4953
4954                 /* Tell Phase 3 it needs to test the constraint */
4955                 tab->new_notnull = true;
4956         }
4957
4958         InvokeObjectPostAlterHook(RelationRelationId,
4959                                                           RelationGetRelid(rel), attnum);
4960
4961         heap_close(attr_rel, RowExclusiveLock);
4962 }
4963
4964 /*
4965  * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
4966  */
4967 static void
4968 ATExecColumnDefault(Relation rel, const char *colName,
4969                                         Node *newDefault, LOCKMODE lockmode)
4970 {
4971         AttrNumber      attnum;
4972
4973         /*
4974          * get the number of the attribute
4975          */
4976         attnum = get_attnum(RelationGetRelid(rel), colName);
4977         if (attnum == InvalidAttrNumber)
4978                 ereport(ERROR,
4979                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
4980                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
4981                                                 colName, RelationGetRelationName(rel))));
4982
4983         /* Prevent them from altering a system attribute */
4984         if (attnum <= 0)
4985                 ereport(ERROR,
4986                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4987                                  errmsg("cannot alter system column \"%s\"",
4988                                                 colName)));
4989
4990         /*
4991          * Remove any old default for the column.  We use RESTRICT here for
4992          * safety, but at present we do not expect anything to depend on the
4993          * default.
4994          *
4995          * We treat removing the existing default as an internal operation when it
4996          * is preparatory to adding a new default, but as a user-initiated
4997          * operation when the user asked for a drop.
4998          */
4999         RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false,
5000                                           newDefault == NULL ? false : true);
5001
5002         if (newDefault)
5003         {
5004                 /* SET DEFAULT */
5005                 RawColumnDefault *rawEnt;
5006
5007                 rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
5008                 rawEnt->attnum = attnum;
5009                 rawEnt->raw_default = newDefault;
5010
5011                 /*
5012                  * This function is intended for CREATE TABLE, so it processes a
5013                  * _list_ of defaults, but we just do one.
5014                  */
5015                 AddRelationNewConstraints(rel, list_make1(rawEnt), NIL,
5016                                                                   false, true, false);
5017         }
5018 }
5019
5020 /*
5021  * ALTER TABLE ALTER COLUMN SET STATISTICS
5022  */
5023 static void
5024 ATPrepSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
5025 {
5026         /*
5027          * We do our own permission checking because (a) we want to allow SET
5028          * STATISTICS on indexes (for expressional index columns), and (b) we want
5029          * to allow SET STATISTICS on system catalogs without requiring
5030          * allowSystemTableMods to be turned on.
5031          */
5032         if (rel->rd_rel->relkind != RELKIND_RELATION &&
5033                 rel->rd_rel->relkind != RELKIND_MATVIEW &&
5034                 rel->rd_rel->relkind != RELKIND_INDEX &&
5035                 rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
5036                 ereport(ERROR,
5037                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5038                                  errmsg("\"%s\" is not a table, materialized view, index, or foreign table",
5039                                                 RelationGetRelationName(rel))));
5040
5041         /* Permissions checks */
5042         if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
5043                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
5044                                            RelationGetRelationName(rel));
5045 }
5046
5047 static void
5048 ATExecSetStatistics(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
5049 {
5050         int                     newtarget;
5051         Relation        attrelation;
5052         HeapTuple       tuple;
5053         Form_pg_attribute attrtuple;
5054
5055         Assert(IsA(newValue, Integer));
5056         newtarget = intVal(newValue);
5057
5058         /*
5059          * Limit target to a sane range
5060          */
5061         if (newtarget < -1)
5062         {
5063                 ereport(ERROR,
5064                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5065                                  errmsg("statistics target %d is too low",
5066                                                 newtarget)));
5067         }
5068         else if (newtarget > 10000)
5069         {
5070                 newtarget = 10000;
5071                 ereport(WARNING,
5072                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5073                                  errmsg("lowering statistics target to %d",
5074                                                 newtarget)));
5075         }
5076
5077         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
5078
5079         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
5080
5081         if (!HeapTupleIsValid(tuple))
5082                 ereport(ERROR,
5083                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
5084                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
5085                                                 colName, RelationGetRelationName(rel))));
5086         attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
5087
5088         if (attrtuple->attnum <= 0)
5089                 ereport(ERROR,
5090                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5091                                  errmsg("cannot alter system column \"%s\"",
5092                                                 colName)));
5093
5094         attrtuple->attstattarget = newtarget;
5095
5096         simple_heap_update(attrelation, &tuple->t_self, tuple);
5097
5098         /* keep system catalog indexes current */
5099         CatalogUpdateIndexes(attrelation, tuple);
5100
5101         InvokeObjectPostAlterHook(RelationRelationId,
5102                                                           RelationGetRelid(rel),
5103                                                           attrtuple->attnum);
5104         heap_freetuple(tuple);
5105
5106         heap_close(attrelation, RowExclusiveLock);
5107 }
5108
5109 static void
5110 ATExecSetOptions(Relation rel, const char *colName, Node *options,
5111                                  bool isReset, LOCKMODE lockmode)
5112 {
5113         Relation        attrelation;
5114         HeapTuple       tuple,
5115                                 newtuple;
5116         Form_pg_attribute attrtuple;
5117         Datum           datum,
5118                                 newOptions;
5119         bool            isnull;
5120         Datum           repl_val[Natts_pg_attribute];
5121         bool            repl_null[Natts_pg_attribute];
5122         bool            repl_repl[Natts_pg_attribute];
5123
5124         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
5125
5126         tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
5127
5128         if (!HeapTupleIsValid(tuple))
5129                 ereport(ERROR,
5130                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
5131                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
5132                                                 colName, RelationGetRelationName(rel))));
5133         attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
5134
5135         if (attrtuple->attnum <= 0)
5136                 ereport(ERROR,
5137                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5138                                  errmsg("cannot alter system column \"%s\"",
5139                                                 colName)));
5140
5141         /* Generate new proposed attoptions (text array) */
5142         Assert(IsA(options, List));
5143         datum = SysCacheGetAttr(ATTNAME, tuple, Anum_pg_attribute_attoptions,
5144                                                         &isnull);
5145         newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
5146                                                                          (List *) options, NULL, NULL, false,
5147                                                                          isReset);
5148         /* Validate new options */
5149         (void) attribute_reloptions(newOptions, true);
5150
5151         /* Build new tuple. */
5152         memset(repl_null, false, sizeof(repl_null));
5153         memset(repl_repl, false, sizeof(repl_repl));
5154         if (newOptions != (Datum) 0)
5155                 repl_val[Anum_pg_attribute_attoptions - 1] = newOptions;
5156         else
5157                 repl_null[Anum_pg_attribute_attoptions - 1] = true;
5158         repl_repl[Anum_pg_attribute_attoptions - 1] = true;
5159         newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrelation),
5160                                                                  repl_val, repl_null, repl_repl);
5161
5162         /* Update system catalog. */
5163         simple_heap_update(attrelation, &newtuple->t_self, newtuple);
5164         CatalogUpdateIndexes(attrelation, newtuple);
5165
5166         InvokeObjectPostAlterHook(RelationRelationId,
5167                                                           RelationGetRelid(rel),
5168                                                           attrtuple->attnum);
5169         heap_freetuple(newtuple);
5170
5171         ReleaseSysCache(tuple);
5172
5173         heap_close(attrelation, RowExclusiveLock);
5174 }
5175
5176 /*
5177  * ALTER TABLE ALTER COLUMN SET STORAGE
5178  */
5179 static void
5180 ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE lockmode)
5181 {
5182         char       *storagemode;
5183         char            newstorage;
5184         Relation        attrelation;
5185         HeapTuple       tuple;
5186         Form_pg_attribute attrtuple;
5187
5188         Assert(IsA(newValue, String));
5189         storagemode = strVal(newValue);
5190
5191         if (pg_strcasecmp(storagemode, "plain") == 0)
5192                 newstorage = 'p';
5193         else if (pg_strcasecmp(storagemode, "external") == 0)
5194                 newstorage = 'e';
5195         else if (pg_strcasecmp(storagemode, "extended") == 0)
5196                 newstorage = 'x';
5197         else if (pg_strcasecmp(storagemode, "main") == 0)
5198                 newstorage = 'm';
5199         else
5200         {
5201                 ereport(ERROR,
5202                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5203                                  errmsg("invalid storage type \"%s\"",
5204                                                 storagemode)));
5205                 newstorage = 0;                 /* keep compiler quiet */
5206         }
5207
5208         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
5209
5210         tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
5211
5212         if (!HeapTupleIsValid(tuple))
5213                 ereport(ERROR,
5214                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
5215                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
5216                                                 colName, RelationGetRelationName(rel))));
5217         attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
5218
5219         if (attrtuple->attnum <= 0)
5220                 ereport(ERROR,
5221                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5222                                  errmsg("cannot alter system column \"%s\"",
5223                                                 colName)));
5224
5225         /*
5226          * safety check: do not allow toasted storage modes unless column datatype
5227          * is TOAST-aware.
5228          */
5229         if (newstorage == 'p' || TypeIsToastable(attrtuple->atttypid))
5230                 attrtuple->attstorage = newstorage;
5231         else
5232                 ereport(ERROR,
5233                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5234                                  errmsg("column data type %s can only have storage PLAIN",
5235                                                 format_type_be(attrtuple->atttypid))));
5236
5237         simple_heap_update(attrelation, &tuple->t_self, tuple);
5238
5239         /* keep system catalog indexes current */
5240         CatalogUpdateIndexes(attrelation, tuple);
5241
5242         InvokeObjectPostAlterHook(RelationRelationId,
5243                                                           RelationGetRelid(rel),
5244                                                           attrtuple->attnum);
5245
5246         heap_freetuple(tuple);
5247
5248         heap_close(attrelation, RowExclusiveLock);
5249 }
5250
5251
5252 /*
5253  * ALTER TABLE DROP COLUMN
5254  *
5255  * DROP COLUMN cannot use the normal ALTER TABLE recursion mechanism,
5256  * because we have to decide at runtime whether to recurse or not depending
5257  * on whether attinhcount goes to zero or not.  (We can't check this in a
5258  * static pre-pass because it won't handle multiple inheritance situations
5259  * correctly.)
5260  */
5261 static void
5262 ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
5263                                  AlterTableCmd *cmd, LOCKMODE lockmode)
5264 {
5265         if (rel->rd_rel->reloftype && !recursing)
5266                 ereport(ERROR,
5267                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5268                                  errmsg("cannot drop column from typed table")));
5269
5270         if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
5271                 ATTypedTableRecursion(wqueue, rel, cmd, lockmode);
5272
5273         if (recurse)
5274                 cmd->subtype = AT_DropColumnRecurse;
5275 }
5276
5277 static void
5278 ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
5279                                  DropBehavior behavior,
5280                                  bool recurse, bool recursing,
5281                                  bool missing_ok, LOCKMODE lockmode)
5282 {
5283         HeapTuple       tuple;
5284         Form_pg_attribute targetatt;
5285         AttrNumber      attnum;
5286         List       *children;
5287         ObjectAddress object;
5288
5289         /* At top level, permission check was done in ATPrepCmd, else do it */
5290         if (recursing)
5291                 ATSimplePermissions(rel, ATT_TABLE);
5292
5293         /*
5294          * get the number of the attribute
5295          */
5296         tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
5297         if (!HeapTupleIsValid(tuple))
5298         {
5299                 if (!missing_ok)
5300                 {
5301                         ereport(ERROR,
5302                                         (errcode(ERRCODE_UNDEFINED_COLUMN),
5303                                          errmsg("column \"%s\" of relation \"%s\" does not exist",
5304                                                         colName, RelationGetRelationName(rel))));
5305                 }
5306                 else
5307                 {
5308                         ereport(NOTICE,
5309                                         (errmsg("column \"%s\" of relation \"%s\" does not exist, skipping",
5310                                                         colName, RelationGetRelationName(rel))));
5311                         return;
5312                 }
5313         }
5314         targetatt = (Form_pg_attribute) GETSTRUCT(tuple);
5315
5316         attnum = targetatt->attnum;
5317
5318         /* Can't drop a system attribute, except OID */
5319         if (attnum <= 0 && attnum != ObjectIdAttributeNumber)
5320                 ereport(ERROR,
5321                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5322                                  errmsg("cannot drop system column \"%s\"",
5323                                                 colName)));
5324
5325         /* Don't drop inherited columns */
5326         if (targetatt->attinhcount > 0 && !recursing)
5327                 ereport(ERROR,
5328                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5329                                  errmsg("cannot drop inherited column \"%s\"",
5330                                                 colName)));
5331
5332         ReleaseSysCache(tuple);
5333
5334         /*
5335          * Propagate to children as appropriate.  Unlike most other ALTER
5336          * routines, we have to do this one level of recursion at a time; we can't
5337          * use find_all_inheritors to do it in one pass.
5338          */
5339         children = find_inheritance_children(RelationGetRelid(rel), lockmode);
5340
5341         if (children)
5342         {
5343                 Relation        attr_rel;
5344                 ListCell   *child;
5345
5346                 attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);
5347                 foreach(child, children)
5348                 {
5349                         Oid                     childrelid = lfirst_oid(child);
5350                         Relation        childrel;
5351                         Form_pg_attribute childatt;
5352
5353                         /* find_inheritance_children already got lock */
5354                         childrel = heap_open(childrelid, NoLock);
5355                         CheckTableNotInUse(childrel, "ALTER TABLE");
5356
5357                         tuple = SearchSysCacheCopyAttName(childrelid, colName);
5358                         if (!HeapTupleIsValid(tuple))           /* shouldn't happen */
5359                                 elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
5360                                          colName, childrelid);
5361                         childatt = (Form_pg_attribute) GETSTRUCT(tuple);
5362
5363                         if (childatt->attinhcount <= 0)         /* shouldn't happen */
5364                                 elog(ERROR, "relation %u has non-inherited attribute \"%s\"",
5365                                          childrelid, colName);
5366
5367                         if (recurse)
5368                         {
5369                                 /*
5370                                  * If the child column has other definition sources, just
5371                                  * decrement its inheritance count; if not, recurse to delete
5372                                  * it.
5373                                  */
5374                                 if (childatt->attinhcount == 1 && !childatt->attislocal)
5375                                 {
5376                                         /* Time to delete this child column, too */
5377                                         ATExecDropColumn(wqueue, childrel, colName,
5378                                                                          behavior, true, true,
5379                                                                          false, lockmode);
5380                                 }
5381                                 else
5382                                 {
5383                                         /* Child column must survive my deletion */
5384                                         childatt->attinhcount--;
5385
5386                                         simple_heap_update(attr_rel, &tuple->t_self, tuple);
5387
5388                                         /* keep the system catalog indexes current */
5389                                         CatalogUpdateIndexes(attr_rel, tuple);
5390
5391                                         /* Make update visible */
5392                                         CommandCounterIncrement();
5393                                 }
5394                         }
5395                         else
5396                         {
5397                                 /*
5398                                  * If we were told to drop ONLY in this table (no recursion),
5399                                  * we need to mark the inheritors' attributes as locally
5400                                  * defined rather than inherited.
5401                                  */
5402                                 childatt->attinhcount--;
5403                                 childatt->attislocal = true;
5404
5405                                 simple_heap_update(attr_rel, &tuple->t_self, tuple);
5406
5407                                 /* keep the system catalog indexes current */
5408                                 CatalogUpdateIndexes(attr_rel, tuple);
5409
5410                                 /* Make update visible */
5411                                 CommandCounterIncrement();
5412                         }
5413
5414                         heap_freetuple(tuple);
5415
5416                         heap_close(childrel, NoLock);
5417                 }
5418                 heap_close(attr_rel, RowExclusiveLock);
5419         }
5420
5421         /*
5422          * Perform the actual column deletion
5423          */
5424         object.classId = RelationRelationId;
5425         object.objectId = RelationGetRelid(rel);
5426         object.objectSubId = attnum;
5427
5428         performDeletion(&object, behavior, 0);
5429
5430         /*
5431          * If we dropped the OID column, must adjust pg_class.relhasoids and tell
5432          * Phase 3 to physically get rid of the column.  We formerly left the
5433          * column in place physically, but this caused subtle problems.  See
5434          * http://archives.postgresql.org/pgsql-hackers/2009-02/msg00363.php
5435          */
5436         if (attnum == ObjectIdAttributeNumber)
5437         {
5438                 Relation        class_rel;
5439                 Form_pg_class tuple_class;
5440                 AlteredTableInfo *tab;
5441
5442                 class_rel = heap_open(RelationRelationId, RowExclusiveLock);
5443
5444                 tuple = SearchSysCacheCopy1(RELOID,
5445                                                                         ObjectIdGetDatum(RelationGetRelid(rel)));
5446                 if (!HeapTupleIsValid(tuple))
5447                         elog(ERROR, "cache lookup failed for relation %u",
5448                                  RelationGetRelid(rel));
5449                 tuple_class = (Form_pg_class) GETSTRUCT(tuple);
5450
5451                 tuple_class->relhasoids = false;
5452                 simple_heap_update(class_rel, &tuple->t_self, tuple);
5453
5454                 /* Keep the catalog indexes up to date */
5455                 CatalogUpdateIndexes(class_rel, tuple);
5456
5457                 heap_close(class_rel, RowExclusiveLock);
5458
5459                 /* Find or create work queue entry for this table */
5460                 tab = ATGetQueueEntry(wqueue, rel);
5461
5462                 /* Tell Phase 3 to physically remove the OID column */
5463                 tab->rewrite = true;
5464         }
5465 }
5466
5467 /*
5468  * ALTER TABLE ADD INDEX
5469  *
5470  * There is no such command in the grammar, but parse_utilcmd.c converts
5471  * UNIQUE and PRIMARY KEY constraints into AT_AddIndex subcommands.  This lets
5472  * us schedule creation of the index at the appropriate time during ALTER.
5473  */
5474 static void
5475 ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
5476                            IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode)
5477 {
5478         bool            check_rights;
5479         bool            skip_build;
5480         bool            quiet;
5481         Oid                     new_index;
5482
5483         Assert(IsA(stmt, IndexStmt));
5484         Assert(!stmt->concurrent);
5485
5486         /* suppress schema rights check when rebuilding existing index */
5487         check_rights = !is_rebuild;
5488         /* skip index build if phase 3 will do it or we're reusing an old one */
5489         skip_build = tab->rewrite || OidIsValid(stmt->oldNode);
5490         /* suppress notices when rebuilding existing index */
5491         quiet = is_rebuild;
5492
5493         /* The IndexStmt has already been through transformIndexStmt */
5494
5495         new_index = DefineIndex(stmt,
5496                                                         InvalidOid, /* no predefined OID */
5497                                                         true,           /* is_alter_table */
5498                                                         check_rights,
5499                                                         skip_build,
5500                                                         quiet);
5501
5502         /*
5503          * If TryReuseIndex() stashed a relfilenode for us, we used it for the new
5504          * index instead of building from scratch.      The DROP of the old edition of
5505          * this index will have scheduled the storage for deletion at commit, so
5506          * cancel that pending deletion.
5507          */
5508         if (OidIsValid(stmt->oldNode))
5509         {
5510                 Relation        irel = index_open(new_index, NoLock);
5511
5512                 RelationPreserveStorage(irel->rd_node, true);
5513                 index_close(irel, NoLock);
5514         }
5515 }
5516
5517 /*
5518  * ALTER TABLE ADD CONSTRAINT USING INDEX
5519  */
5520 static void
5521 ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
5522                                                  IndexStmt *stmt, LOCKMODE lockmode)
5523 {
5524         Oid                     index_oid = stmt->indexOid;
5525         Relation        indexRel;
5526         char       *indexName;
5527         IndexInfo  *indexInfo;
5528         char       *constraintName;
5529         char            constraintType;
5530
5531         Assert(IsA(stmt, IndexStmt));
5532         Assert(OidIsValid(index_oid));
5533         Assert(stmt->isconstraint);
5534
5535         indexRel = index_open(index_oid, AccessShareLock);
5536
5537         indexName = pstrdup(RelationGetRelationName(indexRel));
5538
5539         indexInfo = BuildIndexInfo(indexRel);
5540
5541         /* this should have been checked at parse time */
5542         if (!indexInfo->ii_Unique)
5543                 elog(ERROR, "index \"%s\" is not unique", indexName);
5544
5545         /*
5546          * Determine name to assign to constraint.      We require a constraint to
5547          * have the same name as the underlying index; therefore, use the index's
5548          * existing name as the default constraint name, and if the user
5549          * explicitly gives some other name for the constraint, rename the index
5550          * to match.
5551          */
5552         constraintName = stmt->idxname;
5553         if (constraintName == NULL)
5554                 constraintName = indexName;
5555         else if (strcmp(constraintName, indexName) != 0)
5556         {
5557                 ereport(NOTICE,
5558                                 (errmsg("ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"",
5559                                                 indexName, constraintName)));
5560                 RenameRelationInternal(index_oid, constraintName, false);
5561         }
5562
5563         /* Extra checks needed if making primary key */
5564         if (stmt->primary)
5565                 index_check_primary_key(rel, indexInfo, true);
5566
5567         /* Note we currently don't support EXCLUSION constraints here */
5568         if (stmt->primary)
5569                 constraintType = CONSTRAINT_PRIMARY;
5570         else
5571                 constraintType = CONSTRAINT_UNIQUE;
5572
5573         /* Create the catalog entries for the constraint */
5574         index_constraint_create(rel,
5575                                                         index_oid,
5576                                                         indexInfo,
5577                                                         constraintName,
5578                                                         constraintType,
5579                                                         stmt->deferrable,
5580                                                         stmt->initdeferred,
5581                                                         stmt->primary,
5582                                                         true,           /* update pg_index */
5583                                                         true,           /* remove old dependencies */
5584                                                         allowSystemTableMods,
5585                                                         false);         /* is_internal */
5586
5587         index_close(indexRel, NoLock);
5588 }
5589
5590 /*
5591  * ALTER TABLE ADD CONSTRAINT
5592  */
5593 static void
5594 ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
5595                                         Constraint *newConstraint, bool recurse, bool is_readd,
5596                                         LOCKMODE lockmode)
5597 {
5598         Assert(IsA(newConstraint, Constraint));
5599
5600         /*
5601          * Currently, we only expect to see CONSTR_CHECK and CONSTR_FOREIGN nodes
5602          * arriving here (see the preprocessing done in parse_utilcmd.c).  Use a
5603          * switch anyway to make it easier to add more code later.
5604          */
5605         switch (newConstraint->contype)
5606         {
5607                 case CONSTR_CHECK:
5608                         ATAddCheckConstraint(wqueue, tab, rel,
5609                                                                  newConstraint, recurse, false, is_readd,
5610                                                                  lockmode);
5611                         break;
5612
5613                 case CONSTR_FOREIGN:
5614
5615                         /*
5616                          * Note that we currently never recurse for FK constraints, so the
5617                          * "recurse" flag is silently ignored.
5618                          *
5619                          * Assign or validate constraint name
5620                          */
5621                         if (newConstraint->conname)
5622                         {
5623                                 if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
5624                                                                                  RelationGetRelid(rel),
5625                                                                                  RelationGetNamespace(rel),
5626                                                                                  newConstraint->conname))
5627                                         ereport(ERROR,
5628                                                         (errcode(ERRCODE_DUPLICATE_OBJECT),
5629                                                          errmsg("constraint \"%s\" for relation \"%s\" already exists",
5630                                                                         newConstraint->conname,
5631                                                                         RelationGetRelationName(rel))));
5632                         }
5633                         else
5634                                 newConstraint->conname =
5635                                         ChooseConstraintName(RelationGetRelationName(rel),
5636                                                                    strVal(linitial(newConstraint->fk_attrs)),
5637                                                                                  "fkey",
5638                                                                                  RelationGetNamespace(rel),
5639                                                                                  NIL);
5640
5641                         ATAddForeignKeyConstraint(tab, rel, newConstraint, lockmode);
5642                         break;
5643
5644                 default:
5645                         elog(ERROR, "unrecognized constraint type: %d",
5646                                  (int) newConstraint->contype);
5647         }
5648 }
5649
5650 /*
5651  * Add a check constraint to a single table and its children
5652  *
5653  * Subroutine for ATExecAddConstraint.
5654  *
5655  * We must recurse to child tables during execution, rather than using
5656  * ALTER TABLE's normal prep-time recursion.  The reason is that all the
5657  * constraints *must* be given the same name, else they won't be seen as
5658  * related later.  If the user didn't explicitly specify a name, then
5659  * AddRelationNewConstraints would normally assign different names to the
5660  * child constraints.  To fix that, we must capture the name assigned at
5661  * the parent table and pass that down.
5662  *
5663  * When re-adding a previously existing constraint (during ALTER COLUMN TYPE),
5664  * we don't need to recurse here, because recursion will be carried out at a
5665  * higher level; the constraint name issue doesn't apply because the names
5666  * have already been assigned and are just being re-used.  We need a separate
5667  * "is_readd" flag for that; just setting recurse=false would result in an
5668  * error if there are child tables.
5669  */
5670 static void
5671 ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
5672                                          Constraint *constr, bool recurse, bool recursing,
5673                                          bool is_readd, LOCKMODE lockmode)
5674 {
5675         List       *newcons;
5676         ListCell   *lcon;
5677         List       *children;
5678         ListCell   *child;
5679
5680         /* At top level, permission check was done in ATPrepCmd, else do it */
5681         if (recursing)
5682                 ATSimplePermissions(rel, ATT_TABLE);
5683
5684         /*
5685          * Call AddRelationNewConstraints to do the work, making sure it works on
5686          * a copy of the Constraint so transformExpr can't modify the original. It
5687          * returns a list of cooked constraints.
5688          *
5689          * If the constraint ends up getting merged with a pre-existing one, it's
5690          * omitted from the returned list, which is what we want: we do not need
5691          * to do any validation work.  That can only happen at child tables,
5692          * though, since we disallow merging at the top level.
5693          */
5694         newcons = AddRelationNewConstraints(rel, NIL,
5695                                                                                 list_make1(copyObject(constr)),
5696                                                                                 recursing,              /* allow_merge */
5697                                                                                 !recursing,             /* is_local */
5698                                                                                 is_readd);              /* is_internal */
5699
5700         /* Add each to-be-validated constraint to Phase 3's queue */
5701         foreach(lcon, newcons)
5702         {
5703                 CookedConstraint *ccon = (CookedConstraint *) lfirst(lcon);
5704
5705                 if (!ccon->skip_validation)
5706                 {
5707                         NewConstraint *newcon;
5708
5709                         newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
5710                         newcon->name = ccon->name;
5711                         newcon->contype = ccon->contype;
5712                         /* ExecQual wants implicit-AND format */
5713                         newcon->qual = (Node *) make_ands_implicit((Expr *) ccon->expr);
5714
5715                         tab->constraints = lappend(tab->constraints, newcon);
5716                 }
5717
5718                 /* Save the actually assigned name if it was defaulted */
5719                 if (constr->conname == NULL)
5720                         constr->conname = ccon->name;
5721         }
5722
5723         /* At this point we must have a locked-down name to use */
5724         Assert(constr->conname != NULL);
5725
5726         /* Advance command counter in case same table is visited multiple times */
5727         CommandCounterIncrement();
5728
5729         /*
5730          * If the constraint got merged with an existing constraint, we're done.
5731          * We mustn't recurse to child tables in this case, because they've
5732          * already got the constraint, and visiting them again would lead to an
5733          * incorrect value for coninhcount.
5734          */
5735         if (newcons == NIL)
5736                 return;
5737
5738         /*
5739          * If adding a NO INHERIT constraint, no need to find our children.
5740          * Likewise, in a re-add operation, we don't need to recurse (that will be
5741          * handled at higher levels).
5742          */
5743         if (constr->is_no_inherit || is_readd)
5744                 return;
5745
5746         /*
5747          * Propagate to children as appropriate.  Unlike most other ALTER
5748          * routines, we have to do this one level of recursion at a time; we can't
5749          * use find_all_inheritors to do it in one pass.
5750          */
5751         children = find_inheritance_children(RelationGetRelid(rel), lockmode);
5752
5753         /*
5754          * Check if ONLY was specified with ALTER TABLE.  If so, allow the
5755          * contraint creation only if there are no children currently.  Error out
5756          * otherwise.
5757          */
5758         if (!recurse && children != NIL)
5759                 ereport(ERROR,
5760                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5761                                  errmsg("constraint must be added to child tables too")));
5762
5763         foreach(child, children)
5764         {
5765                 Oid                     childrelid = lfirst_oid(child);
5766                 Relation        childrel;
5767                 AlteredTableInfo *childtab;
5768
5769                 /* find_inheritance_children already got lock */
5770                 childrel = heap_open(childrelid, NoLock);
5771                 CheckTableNotInUse(childrel, "ALTER TABLE");
5772
5773                 /* Find or create work queue entry for this table */
5774                 childtab = ATGetQueueEntry(wqueue, childrel);
5775
5776                 /* Recurse to child */
5777                 ATAddCheckConstraint(wqueue, childtab, childrel,
5778                                                          constr, recurse, true, is_readd, lockmode);
5779
5780                 heap_close(childrel, NoLock);
5781         }
5782 }
5783
5784 /*
5785  * Add a foreign-key constraint to a single table
5786  *
5787  * Subroutine for ATExecAddConstraint.  Must already hold exclusive
5788  * lock on the rel, and have done appropriate validity checks for it.
5789  * We do permissions checks here, however.
5790  */
5791 static void
5792 ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
5793                                                   Constraint *fkconstraint, LOCKMODE lockmode)
5794 {
5795         Relation        pkrel;
5796         int16           pkattnum[INDEX_MAX_KEYS];
5797         int16           fkattnum[INDEX_MAX_KEYS];
5798         Oid                     pktypoid[INDEX_MAX_KEYS];
5799         Oid                     fktypoid[INDEX_MAX_KEYS];
5800         Oid                     opclasses[INDEX_MAX_KEYS];
5801         Oid                     pfeqoperators[INDEX_MAX_KEYS];
5802         Oid                     ppeqoperators[INDEX_MAX_KEYS];
5803         Oid                     ffeqoperators[INDEX_MAX_KEYS];
5804         int                     i;
5805         int                     numfks,
5806                                 numpks;
5807         Oid                     indexOid;
5808         Oid                     constrOid;
5809         bool            old_check_ok;
5810         ListCell   *old_pfeqop_item = list_head(fkconstraint->old_conpfeqop);
5811
5812         /*
5813          * Grab an exclusive lock on the pk table, so that someone doesn't delete
5814          * rows out from under us. (Although a lesser lock would do for that
5815          * purpose, we'll need exclusive lock anyway to add triggers to the pk
5816          * table; trying to start with a lesser lock will just create a risk of
5817          * deadlock.)
5818          */
5819         pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock);
5820
5821         /*
5822          * Validity checks (permission checks wait till we have the column
5823          * numbers)
5824          */
5825         if (pkrel->rd_rel->relkind != RELKIND_RELATION)
5826                 ereport(ERROR,
5827                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5828                                  errmsg("referenced relation \"%s\" is not a table",
5829                                                 RelationGetRelationName(pkrel))));
5830
5831         if (!allowSystemTableMods && IsSystemRelation(pkrel))
5832                 ereport(ERROR,
5833                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5834                                  errmsg("permission denied: \"%s\" is a system catalog",
5835                                                 RelationGetRelationName(pkrel))));
5836
5837         /*
5838          * References from permanent or unlogged tables to temp tables, and from
5839          * permanent tables to unlogged tables, are disallowed because the
5840          * referenced data can vanish out from under us.  References from temp
5841          * tables to any other table type are also disallowed, because other
5842          * backends might need to run the RI triggers on the perm table, but they
5843          * can't reliably see tuples in the local buffers of other backends.
5844          */
5845         switch (rel->rd_rel->relpersistence)
5846         {
5847                 case RELPERSISTENCE_PERMANENT:
5848                         if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT)
5849                                 ereport(ERROR,
5850                                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5851                                                  errmsg("constraints on permanent tables may reference only permanent tables")));
5852                         break;
5853                 case RELPERSISTENCE_UNLOGGED:
5854                         if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT
5855                                 && pkrel->rd_rel->relpersistence != RELPERSISTENCE_UNLOGGED)
5856                                 ereport(ERROR,
5857                                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5858                                                  errmsg("constraints on unlogged tables may reference only permanent or unlogged tables")));
5859                         break;
5860                 case RELPERSISTENCE_TEMP:
5861                         if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_TEMP)
5862                                 ereport(ERROR,
5863                                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5864                                                  errmsg("constraints on temporary tables may reference only temporary tables")));
5865                         if (!pkrel->rd_islocaltemp || !rel->rd_islocaltemp)
5866                                 ereport(ERROR,
5867                                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
5868                                                  errmsg("constraints on temporary tables must involve temporary tables of this session")));
5869                         break;
5870         }
5871
5872         /*
5873          * Look up the referencing attributes to make sure they exist, and record
5874          * their attnums and type OIDs.
5875          */
5876         MemSet(pkattnum, 0, sizeof(pkattnum));
5877         MemSet(fkattnum, 0, sizeof(fkattnum));
5878         MemSet(pktypoid, 0, sizeof(pktypoid));
5879         MemSet(fktypoid, 0, sizeof(fktypoid));
5880         MemSet(opclasses, 0, sizeof(opclasses));
5881         MemSet(pfeqoperators, 0, sizeof(pfeqoperators));
5882         MemSet(ppeqoperators, 0, sizeof(ppeqoperators));
5883         MemSet(ffeqoperators, 0, sizeof(ffeqoperators));
5884
5885         numfks = transformColumnNameList(RelationGetRelid(rel),
5886                                                                          fkconstraint->fk_attrs,
5887                                                                          fkattnum, fktypoid);
5888
5889         /*
5890          * If the attribute list for the referenced table was omitted, lookup the
5891          * definition of the primary key and use it.  Otherwise, validate the
5892          * supplied attribute list.  In either case, discover the index OID and
5893          * index opclasses, and the attnums and type OIDs of the attributes.
5894          */
5895         if (fkconstraint->pk_attrs == NIL)
5896         {
5897                 numpks = transformFkeyGetPrimaryKey(pkrel, &indexOid,
5898                                                                                         &fkconstraint->pk_attrs,
5899                                                                                         pkattnum, pktypoid,
5900                                                                                         opclasses);
5901         }
5902         else
5903         {
5904                 numpks = transformColumnNameList(RelationGetRelid(pkrel),
5905                                                                                  fkconstraint->pk_attrs,
5906                                                                                  pkattnum, pktypoid);
5907                 /* Look for an index matching the column list */
5908                 indexOid = transformFkeyCheckAttrs(pkrel, numpks, pkattnum,
5909                                                                                    opclasses);
5910         }
5911
5912         /*
5913          * Now we can check permissions.
5914          */
5915         checkFkeyPermissions(pkrel, pkattnum, numpks);
5916         checkFkeyPermissions(rel, fkattnum, numfks);
5917
5918         /*
5919          * Look up the equality operators to use in the constraint.
5920          *
5921          * Note that we have to be careful about the difference between the actual
5922          * PK column type and the opclass' declared input type, which might be
5923          * only binary-compatible with it.      The declared opcintype is the right
5924          * thing to probe pg_amop with.
5925          */
5926         if (numfks != numpks)
5927                 ereport(ERROR,
5928                                 (errcode(ERRCODE_INVALID_FOREIGN_KEY),
5929                                  errmsg("number of referencing and referenced columns for foreign key disagree")));
5930
5931         /*
5932          * On the strength of a previous constraint, we might avoid scanning
5933          * tables to validate this one.  See below.
5934          */
5935         old_check_ok = (fkconstraint->old_conpfeqop != NIL);
5936         Assert(!old_check_ok || numfks == list_length(fkconstraint->old_conpfeqop));
5937
5938         for (i = 0; i < numpks; i++)
5939         {
5940                 Oid                     pktype = pktypoid[i];
5941                 Oid                     fktype = fktypoid[i];
5942                 Oid                     fktyped;
5943                 HeapTuple       cla_ht;
5944                 Form_pg_opclass cla_tup;
5945                 Oid                     amid;
5946                 Oid                     opfamily;
5947                 Oid                     opcintype;
5948                 Oid                     pfeqop;
5949                 Oid                     ppeqop;
5950                 Oid                     ffeqop;
5951                 int16           eqstrategy;
5952                 Oid                     pfeqop_right;
5953
5954                 /* We need several fields out of the pg_opclass entry */
5955                 cla_ht = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclasses[i]));
5956                 if (!HeapTupleIsValid(cla_ht))
5957                         elog(ERROR, "cache lookup failed for opclass %u", opclasses[i]);
5958                 cla_tup = (Form_pg_opclass) GETSTRUCT(cla_ht);
5959                 amid = cla_tup->opcmethod;
5960                 opfamily = cla_tup->opcfamily;
5961                 opcintype = cla_tup->opcintype;
5962                 ReleaseSysCache(cla_ht);
5963
5964                 /*
5965                  * Check it's a btree; currently this can never fail since no other
5966                  * index AMs support unique indexes.  If we ever did have other types
5967                  * of unique indexes, we'd need a way to determine which operator
5968                  * strategy number is equality.  (Is it reasonable to insist that
5969                  * every such index AM use btree's number for equality?)
5970                  */
5971                 if (amid != BTREE_AM_OID)
5972                         elog(ERROR, "only b-tree indexes are supported for foreign keys");
5973                 eqstrategy = BTEqualStrategyNumber;
5974
5975                 /*
5976                  * There had better be a primary equality operator for the index.
5977                  * We'll use it for PK = PK comparisons.
5978                  */
5979                 ppeqop = get_opfamily_member(opfamily, opcintype, opcintype,
5980                                                                          eqstrategy);
5981
5982                 if (!OidIsValid(ppeqop))
5983                         elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
5984                                  eqstrategy, opcintype, opcintype, opfamily);
5985
5986                 /*
5987                  * Are there equality operators that take exactly the FK type? Assume
5988                  * we should look through any domain here.
5989                  */
5990                 fktyped = getBaseType(fktype);
5991
5992                 pfeqop = get_opfamily_member(opfamily, opcintype, fktyped,
5993                                                                          eqstrategy);
5994                 if (OidIsValid(pfeqop))
5995                 {
5996                         pfeqop_right = fktyped;
5997                         ffeqop = get_opfamily_member(opfamily, fktyped, fktyped,
5998                                                                                  eqstrategy);
5999                 }
6000                 else
6001                 {
6002                         /* keep compiler quiet */
6003                         pfeqop_right = InvalidOid;
6004                         ffeqop = InvalidOid;
6005                 }
6006
6007                 if (!(OidIsValid(pfeqop) && OidIsValid(ffeqop)))
6008                 {
6009                         /*
6010                          * Otherwise, look for an implicit cast from the FK type to the
6011                          * opcintype, and if found, use the primary equality operator.
6012                          * This is a bit tricky because opcintype might be a polymorphic
6013                          * type such as ANYARRAY or ANYENUM; so what we have to test is
6014                          * whether the two actual column types can be concurrently cast to
6015                          * that type.  (Otherwise, we'd fail to reject combinations such
6016                          * as int[] and point[].)
6017                          */
6018                         Oid                     input_typeids[2];
6019                         Oid                     target_typeids[2];
6020
6021                         input_typeids[0] = pktype;
6022                         input_typeids[1] = fktype;
6023                         target_typeids[0] = opcintype;
6024                         target_typeids[1] = opcintype;
6025                         if (can_coerce_type(2, input_typeids, target_typeids,
6026                                                                 COERCION_IMPLICIT))
6027                         {
6028                                 pfeqop = ffeqop = ppeqop;
6029                                 pfeqop_right = opcintype;
6030                         }
6031                 }
6032
6033                 if (!(OidIsValid(pfeqop) && OidIsValid(ffeqop)))
6034                         ereport(ERROR,
6035                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
6036                                          errmsg("foreign key constraint \"%s\" "
6037                                                         "cannot be implemented",
6038                                                         fkconstraint->conname),
6039                                          errdetail("Key columns \"%s\" and \"%s\" "
6040                                                            "are of incompatible types: %s and %s.",
6041                                                            strVal(list_nth(fkconstraint->fk_attrs, i)),
6042                                                            strVal(list_nth(fkconstraint->pk_attrs, i)),
6043                                                            format_type_be(fktype),
6044                                                            format_type_be(pktype))));
6045
6046                 if (old_check_ok)
6047                 {
6048                         /*
6049                          * When a pfeqop changes, revalidate the constraint.  We could
6050                          * permit intra-opfamily changes, but that adds subtle complexity
6051                          * without any concrete benefit for core types.  We need not
6052                          * assess ppeqop or ffeqop, which RI_Initial_Check() does not use.
6053                          */
6054                         old_check_ok = (pfeqop == lfirst_oid(old_pfeqop_item));
6055                         old_pfeqop_item = lnext(old_pfeqop_item);
6056                 }
6057                 if (old_check_ok)
6058                 {
6059                         Oid                     old_fktype;
6060                         Oid                     new_fktype;
6061                         CoercionPathType old_pathtype;
6062                         CoercionPathType new_pathtype;
6063                         Oid                     old_castfunc;
6064                         Oid                     new_castfunc;
6065
6066                         /*
6067                          * Identify coercion pathways from each of the old and new FK-side
6068                          * column types to the right (foreign) operand type of the pfeqop.
6069                          * We may assume that pg_constraint.conkey is not changing.
6070                          */
6071                         old_fktype = tab->oldDesc->attrs[fkattnum[i] - 1]->atttypid;
6072                         new_fktype = fktype;
6073                         old_pathtype = findFkeyCast(pfeqop_right, old_fktype,
6074                                                                                 &old_castfunc);
6075                         new_pathtype = findFkeyCast(pfeqop_right, new_fktype,
6076                                                                                 &new_castfunc);
6077
6078                         /*
6079                          * Upon a change to the cast from the FK column to its pfeqop
6080                          * operand, revalidate the constraint.  For this evaluation, a
6081                          * binary coercion cast is equivalent to no cast at all.  While
6082                          * type implementors should design implicit casts with an eye
6083                          * toward consistency of operations like equality, we cannot
6084                          * assume here that they have done so.
6085                          *
6086                          * A function with a polymorphic argument could change behavior
6087                          * arbitrarily in response to get_fn_expr_argtype().  Therefore,
6088                          * when the cast destination is polymorphic, we only avoid
6089                          * revalidation if the input type has not changed at all.  Given
6090                          * just the core data types and operator classes, this requirement
6091                          * prevents no would-be optimizations.
6092                          *
6093                          * If the cast converts from a base type to a domain thereon, then
6094                          * that domain type must be the opcintype of the unique index.
6095                          * Necessarily, the primary key column must then be of the domain
6096                          * type.  Since the constraint was previously valid, all values on
6097                          * the foreign side necessarily exist on the primary side and in
6098                          * turn conform to the domain.  Consequently, we need not treat
6099                          * domains specially here.
6100                          *
6101                          * Since we require that all collations share the same notion of
6102                          * equality (which they do, because texteq reduces to bitwise
6103                          * equality), we don't compare collation here.
6104                          *
6105                          * We need not directly consider the PK type.  It's necessarily
6106                          * binary coercible to the opcintype of the unique index column,
6107                          * and ri_triggers.c will only deal with PK datums in terms of
6108                          * that opcintype.      Changing the opcintype also changes pfeqop.
6109                          */
6110                         old_check_ok = (new_pathtype == old_pathtype &&
6111                                                         new_castfunc == old_castfunc &&
6112                                                         (!IsPolymorphicType(pfeqop_right) ||
6113                                                          new_fktype == old_fktype));
6114
6115                 }
6116
6117                 pfeqoperators[i] = pfeqop;
6118                 ppeqoperators[i] = ppeqop;
6119                 ffeqoperators[i] = ffeqop;
6120         }
6121
6122         /*
6123          * Record the FK constraint in pg_constraint.
6124          */
6125         constrOid = CreateConstraintEntry(fkconstraint->conname,
6126                                                                           RelationGetNamespace(rel),
6127                                                                           CONSTRAINT_FOREIGN,
6128                                                                           fkconstraint->deferrable,
6129                                                                           fkconstraint->initdeferred,
6130                                                                           fkconstraint->initially_valid,
6131                                                                           RelationGetRelid(rel),
6132                                                                           fkattnum,
6133                                                                           numfks,
6134                                                                           InvalidOid,           /* not a domain
6135                                                                                                                  * constraint */
6136                                                                           indexOid,
6137                                                                           RelationGetRelid(pkrel),
6138                                                                           pkattnum,
6139                                                                           pfeqoperators,
6140                                                                           ppeqoperators,
6141                                                                           ffeqoperators,
6142                                                                           numpks,
6143                                                                           fkconstraint->fk_upd_action,
6144                                                                           fkconstraint->fk_del_action,
6145                                                                           fkconstraint->fk_matchtype,
6146                                                                           NULL,         /* no exclusion constraint */
6147                                                                           NULL,         /* no check constraint */
6148                                                                           NULL,
6149                                                                           NULL,
6150                                                                           true,         /* islocal */
6151                                                                           0,            /* inhcount */
6152                                                                           true,         /* isnoinherit */
6153                                                                           false);       /* is_internal */
6154
6155         /*
6156          * Create the triggers that will enforce the constraint.
6157          */
6158         createForeignKeyTriggers(rel, fkconstraint, constrOid, indexOid);
6159
6160         /*
6161          * Tell Phase 3 to check that the constraint is satisfied by existing
6162          * rows. We can skip this during table creation, when requested explicitly
6163          * by specifying NOT VALID in an ADD FOREIGN KEY command, and when we're
6164          * recreating a constraint following a SET DATA TYPE operation that did
6165          * not impugn its validity.
6166          */
6167         if (!old_check_ok && !fkconstraint->skip_validation)
6168         {
6169                 NewConstraint *newcon;
6170
6171                 newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
6172                 newcon->name = fkconstraint->conname;
6173                 newcon->contype = CONSTR_FOREIGN;
6174                 newcon->refrelid = RelationGetRelid(pkrel);
6175                 newcon->refindid = indexOid;
6176                 newcon->conid = constrOid;
6177                 newcon->qual = (Node *) fkconstraint;
6178
6179                 tab->constraints = lappend(tab->constraints, newcon);
6180         }
6181
6182         /*
6183          * Close pk table, but keep lock until we've committed.
6184          */
6185         heap_close(pkrel, NoLock);
6186 }
6187
6188 /*
6189  * ALTER TABLE ALTER CONSTRAINT
6190  *
6191  * Update the attributes of a constraint.
6192  *
6193  * Currently only works for Foreign Key constraints.
6194  * Foreign keys do not inherit, so we purposely ignore the
6195  * recursion bit here, but we keep the API the same for when
6196  * other constraint types are supported.
6197  */
6198 static void
6199 ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
6200                                                  bool recurse, bool recursing, LOCKMODE lockmode)
6201 {
6202         Relation        conrel;
6203         SysScanDesc scan;
6204         ScanKeyData key;
6205         HeapTuple       contuple;
6206         Form_pg_constraint currcon = NULL;
6207         Constraint      *cmdcon = NULL;
6208         bool            found = false;
6209
6210         Assert(IsA(cmd->def, Constraint));
6211         cmdcon = (Constraint *) cmd->def;
6212
6213         conrel = heap_open(ConstraintRelationId, RowExclusiveLock);
6214
6215         /*
6216          * Find and check the target constraint
6217          */
6218         ScanKeyInit(&key,
6219                                 Anum_pg_constraint_conrelid,
6220                                 BTEqualStrategyNumber, F_OIDEQ,
6221                                 ObjectIdGetDatum(RelationGetRelid(rel)));
6222         scan = systable_beginscan(conrel, ConstraintRelidIndexId,
6223                                                           true, SnapshotNow, 1, &key);
6224
6225         while (HeapTupleIsValid(contuple = systable_getnext(scan)))
6226         {
6227                 currcon = (Form_pg_constraint) GETSTRUCT(contuple);
6228                 if (strcmp(NameStr(currcon->conname), cmdcon->conname) == 0)
6229                 {
6230                         found = true;
6231                         break;
6232                 }
6233         }
6234
6235         if (!found)
6236                 ereport(ERROR,
6237                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
6238                                  errmsg("constraint \"%s\" of relation \"%s\" does not exist",
6239                                                 cmdcon->conname, RelationGetRelationName(rel))));
6240
6241         if (currcon->contype != CONSTRAINT_FOREIGN)
6242                 ereport(ERROR,
6243                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
6244                                  errmsg("constraint \"%s\" of relation \"%s\" is not a foreign key constraint",
6245                                                 cmdcon->conname, RelationGetRelationName(rel))));
6246
6247         if (currcon->condeferrable != cmdcon->deferrable ||
6248                 currcon->condeferred != cmdcon->initdeferred)
6249         {
6250                 HeapTuple       copyTuple;
6251                 HeapTuple       tgtuple;
6252                 Form_pg_constraint copy_con;
6253                 Form_pg_trigger copy_tg;
6254                 ScanKeyData tgkey;
6255                 SysScanDesc tgscan;
6256                 Relation        tgrel;
6257
6258                 /*
6259                  * Now update the catalog, while we have the door open.
6260                  */
6261                 copyTuple = heap_copytuple(contuple);
6262                 copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
6263                 copy_con->condeferrable = cmdcon->deferrable;
6264                 copy_con->condeferred = cmdcon->initdeferred;
6265                 simple_heap_update(conrel, &copyTuple->t_self, copyTuple);
6266                 CatalogUpdateIndexes(conrel, copyTuple);
6267
6268                 InvokeObjectPostAlterHook(ConstraintRelationId,
6269                                                                   HeapTupleGetOid(contuple), 0);
6270
6271                 heap_freetuple(copyTuple);
6272
6273                 /*
6274                  * Now we need to update the multiple entries in pg_trigger
6275                  * that implement the constraint.
6276                  */
6277                 tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
6278
6279                 ScanKeyInit(&tgkey,
6280                                         Anum_pg_trigger_tgconstraint,
6281                                         BTEqualStrategyNumber, F_OIDEQ,
6282                                         ObjectIdGetDatum(HeapTupleGetOid(contuple)));
6283
6284                 tgscan = systable_beginscan(tgrel, TriggerConstraintIndexId, true,
6285                                                                         SnapshotNow, 1, &tgkey);
6286
6287                 while (HeapTupleIsValid(tgtuple = systable_getnext(tgscan)))
6288                 {
6289                         copyTuple = heap_copytuple(tgtuple);
6290                         copy_tg = (Form_pg_trigger) GETSTRUCT(copyTuple);
6291                         copy_tg->tgdeferrable = cmdcon->deferrable;
6292                         copy_tg->tginitdeferred = cmdcon->initdeferred;
6293                         simple_heap_update(tgrel, &copyTuple->t_self, copyTuple);
6294                         CatalogUpdateIndexes(tgrel, copyTuple);
6295
6296                         InvokeObjectPostAlterHook(TriggerRelationId,
6297                                                                                 HeapTupleGetOid(tgtuple), 0);
6298
6299                         heap_freetuple(copyTuple);
6300                 }
6301
6302                 systable_endscan(tgscan);
6303
6304                 heap_close(tgrel, RowExclusiveLock);
6305
6306                 /*
6307                  * Invalidate relcache so that others see the new attributes.
6308                  */
6309                 CacheInvalidateRelcache(rel);
6310         }
6311
6312         systable_endscan(scan);
6313
6314         heap_close(conrel, RowExclusiveLock);
6315 }
6316
6317 /*
6318  * ALTER TABLE VALIDATE CONSTRAINT
6319  *
6320  * XXX The reason we handle recursion here rather than at Phase 1 is because
6321  * there's no good way to skip recursing when handling foreign keys: there is
6322  * no need to lock children in that case, yet we wouldn't be able to avoid
6323  * doing so at that level.
6324  */
6325 static void
6326 ATExecValidateConstraint(Relation rel, char *constrName, bool recurse,
6327                                                  bool recursing, LOCKMODE lockmode)
6328 {
6329         Relation        conrel;
6330         SysScanDesc scan;
6331         ScanKeyData key;
6332         HeapTuple       tuple;
6333         Form_pg_constraint con = NULL;
6334         bool            found = false;
6335
6336         conrel = heap_open(ConstraintRelationId, RowExclusiveLock);
6337
6338         /*
6339          * Find and check the target constraint
6340          */
6341         ScanKeyInit(&key,
6342                                 Anum_pg_constraint_conrelid,
6343                                 BTEqualStrategyNumber, F_OIDEQ,
6344                                 ObjectIdGetDatum(RelationGetRelid(rel)));
6345         scan = systable_beginscan(conrel, ConstraintRelidIndexId,
6346                                                           true, SnapshotNow, 1, &key);
6347
6348         while (HeapTupleIsValid(tuple = systable_getnext(scan)))
6349         {
6350                 con = (Form_pg_constraint) GETSTRUCT(tuple);
6351                 if (strcmp(NameStr(con->conname), constrName) == 0)
6352                 {
6353                         found = true;
6354                         break;
6355                 }
6356         }
6357
6358         if (!found)
6359                 ereport(ERROR,
6360                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
6361                                  errmsg("constraint \"%s\" of relation \"%s\" does not exist",
6362                                                 constrName, RelationGetRelationName(rel))));
6363
6364         if (con->contype != CONSTRAINT_FOREIGN &&
6365                 con->contype != CONSTRAINT_CHECK)
6366                 ereport(ERROR,
6367                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
6368                                  errmsg("constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint",
6369                                                 constrName, RelationGetRelationName(rel))));
6370
6371         if (!con->convalidated)
6372         {
6373                 HeapTuple       copyTuple;
6374                 Form_pg_constraint copy_con;
6375
6376                 if (con->contype == CONSTRAINT_FOREIGN)
6377                 {
6378                         Oid                     conid = HeapTupleGetOid(tuple);
6379                         Relation        refrel;
6380
6381                         /*
6382                          * Triggers are already in place on both tables, so a concurrent
6383                          * write that alters the result here is not possible. Normally we
6384                          * can run a query here to do the validation, which would only
6385                          * require AccessShareLock. In some cases, it is possible that we
6386                          * might need to fire triggers to perform the check, so we take a
6387                          * lock at RowShareLock level just in case.
6388                          */
6389                         refrel = heap_open(con->confrelid, RowShareLock);
6390
6391                         validateForeignKeyConstraint(constrName, rel, refrel,
6392                                                                                  con->conindid,
6393                                                                                  conid);
6394                         heap_close(refrel, NoLock);
6395
6396                         /*
6397                          * Foreign keys do not inherit, so we purposely ignore the
6398                          * recursion bit here
6399                          */
6400                 }
6401                 else if (con->contype == CONSTRAINT_CHECK)
6402                 {
6403                         List       *children = NIL;
6404                         ListCell   *child;
6405
6406                         /*
6407                          * If we're recursing, the parent has already done this, so skip
6408                          * it.
6409                          */
6410                         if (!recursing)
6411                                 children = find_all_inheritors(RelationGetRelid(rel),
6412                                                                                            lockmode, NULL);
6413
6414                         /*
6415                          * For CHECK constraints, we must ensure that we only mark the
6416                          * constraint as validated on the parent if it's already validated
6417                          * on the children.
6418                          *
6419                          * We recurse before validating on the parent, to reduce risk of
6420                          * deadlocks.
6421                          */
6422                         foreach(child, children)
6423                         {
6424                                 Oid                     childoid = lfirst_oid(child);
6425                                 Relation        childrel;
6426
6427                                 if (childoid == RelationGetRelid(rel))
6428                                         continue;
6429
6430                                 /*
6431                                  * If we are told not to recurse, there had better not be any
6432                                  * child tables; else the addition would put them out of step.
6433                                  */
6434                                 if (!recurse)
6435                                         ereport(ERROR,
6436                                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
6437                                                          errmsg("constraint must be validated on child tables too")));
6438
6439                                 /* find_all_inheritors already got lock */
6440                                 childrel = heap_open(childoid, NoLock);
6441
6442                                 ATExecValidateConstraint(childrel, constrName, false,
6443                                                                                  true, lockmode);
6444                                 heap_close(childrel, NoLock);
6445                         }
6446
6447                         validateCheckConstraint(rel, tuple);
6448
6449                         /*
6450                          * Invalidate relcache so that others see the new validated
6451                          * constraint.
6452                          */
6453                         CacheInvalidateRelcache(rel);
6454                 }
6455
6456                 /*
6457                  * Now update the catalog, while we have the door open.
6458                  */
6459                 copyTuple = heap_copytuple(tuple);
6460                 copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
6461                 copy_con->convalidated = true;
6462                 simple_heap_update(conrel, &copyTuple->t_self, copyTuple);
6463                 CatalogUpdateIndexes(conrel, copyTuple);
6464
6465                 InvokeObjectPostAlterHook(ConstraintRelationId,
6466                                                                   HeapTupleGetOid(tuple), 0);
6467
6468                 heap_freetuple(copyTuple);
6469         }
6470
6471         systable_endscan(scan);
6472
6473         heap_close(conrel, RowExclusiveLock);
6474 }
6475
6476
6477 /*
6478  * transformColumnNameList - transform list of column names
6479  *
6480  * Lookup each name and return its attnum and type OID
6481  */
6482 static int
6483 transformColumnNameList(Oid relId, List *colList,
6484                                                 int16 *attnums, Oid *atttypids)
6485 {
6486         ListCell   *l;
6487         int                     attnum;
6488
6489         attnum = 0;
6490         foreach(l, colList)
6491         {
6492                 char       *attname = strVal(lfirst(l));
6493                 HeapTuple       atttuple;
6494
6495                 atttuple = SearchSysCacheAttName(relId, attname);
6496                 if (!HeapTupleIsValid(atttuple))
6497                         ereport(ERROR,
6498                                         (errcode(ERRCODE_UNDEFINED_COLUMN),
6499                                          errmsg("column \"%s\" referenced in foreign key constraint does not exist",
6500                                                         attname)));
6501                 if (attnum >= INDEX_MAX_KEYS)
6502                         ereport(ERROR,
6503                                         (errcode(ERRCODE_TOO_MANY_COLUMNS),
6504                                          errmsg("cannot have more than %d keys in a foreign key",
6505                                                         INDEX_MAX_KEYS)));
6506                 attnums[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->attnum;
6507                 atttypids[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
6508                 ReleaseSysCache(atttuple);
6509                 attnum++;
6510         }
6511
6512         return attnum;
6513 }
6514
6515 /*
6516  * transformFkeyGetPrimaryKey -
6517  *
6518  *      Look up the names, attnums, and types of the primary key attributes
6519  *      for the pkrel.  Also return the index OID and index opclasses of the
6520  *      index supporting the primary key.
6521  *
6522  *      All parameters except pkrel are output parameters.      Also, the function
6523  *      return value is the number of attributes in the primary key.
6524  *
6525  *      Used when the column list in the REFERENCES specification is omitted.
6526  */
6527 static int
6528 transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
6529                                                    List **attnamelist,
6530                                                    int16 *attnums, Oid *atttypids,
6531                                                    Oid *opclasses)
6532 {
6533         List       *indexoidlist;
6534         ListCell   *indexoidscan;
6535         HeapTuple       indexTuple = NULL;
6536         Form_pg_index indexStruct = NULL;
6537         Datum           indclassDatum;
6538         bool            isnull;
6539         oidvector  *indclass;
6540         int                     i;
6541
6542         /*
6543          * Get the list of index OIDs for the table from the relcache, and look up
6544          * each one in the pg_index syscache until we find one marked primary key
6545          * (hopefully there isn't more than one such).  Insist it's valid, too.
6546          */
6547         *indexOid = InvalidOid;
6548
6549         indexoidlist = RelationGetIndexList(pkrel);
6550
6551         foreach(indexoidscan, indexoidlist)
6552         {
6553                 Oid                     indexoid = lfirst_oid(indexoidscan);
6554
6555                 indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
6556                 if (!HeapTupleIsValid(indexTuple))
6557                         elog(ERROR, "cache lookup failed for index %u", indexoid);
6558                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
6559                 if (indexStruct->indisprimary && IndexIsValid(indexStruct))
6560                 {
6561                         /*
6562                          * Refuse to use a deferrable primary key.      This is per SQL spec,
6563                          * and there would be a lot of interesting semantic problems if we
6564                          * tried to allow it.
6565                          */
6566                         if (!indexStruct->indimmediate)
6567                                 ereport(ERROR,
6568                                                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6569                                                  errmsg("cannot use a deferrable primary key for referenced table \"%s\"",
6570                                                                 RelationGetRelationName(pkrel))));
6571
6572                         *indexOid = indexoid;
6573                         break;
6574                 }
6575                 ReleaseSysCache(indexTuple);
6576         }
6577
6578         list_free(indexoidlist);
6579
6580         /*
6581          * Check that we found it
6582          */
6583         if (!OidIsValid(*indexOid))
6584                 ereport(ERROR,
6585                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
6586                                  errmsg("there is no primary key for referenced table \"%s\"",
6587                                                 RelationGetRelationName(pkrel))));
6588
6589         /* Must get indclass the hard way */
6590         indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
6591                                                                         Anum_pg_index_indclass, &isnull);
6592         Assert(!isnull);
6593         indclass = (oidvector *) DatumGetPointer(indclassDatum);
6594
6595         /*
6596          * Now build the list of PK attributes from the indkey definition (we
6597          * assume a primary key cannot have expressional elements)
6598          */
6599         *attnamelist = NIL;
6600         for (i = 0; i < indexStruct->indnatts; i++)
6601         {
6602                 int                     pkattno = indexStruct->indkey.values[i];
6603
6604                 attnums[i] = pkattno;
6605                 atttypids[i] = attnumTypeId(pkrel, pkattno);
6606                 opclasses[i] = indclass->values[i];
6607                 *attnamelist = lappend(*attnamelist,
6608                            makeString(pstrdup(NameStr(*attnumAttName(pkrel, pkattno)))));
6609         }
6610
6611         ReleaseSysCache(indexTuple);
6612
6613         return i;
6614 }
6615
6616 /*
6617  * transformFkeyCheckAttrs -
6618  *
6619  *      Make sure that the attributes of a referenced table belong to a unique
6620  *      (or primary key) constraint.  Return the OID of the index supporting
6621  *      the constraint, as well as the opclasses associated with the index
6622  *      columns.
6623  */
6624 static Oid
6625 transformFkeyCheckAttrs(Relation pkrel,
6626                                                 int numattrs, int16 *attnums,
6627                                                 Oid *opclasses) /* output parameter */
6628 {
6629         Oid                     indexoid = InvalidOid;
6630         bool            found = false;
6631         bool            found_deferrable = false;
6632         List       *indexoidlist;
6633         ListCell   *indexoidscan;
6634
6635         /*
6636          * Get the list of index OIDs for the table from the relcache, and look up
6637          * each one in the pg_index syscache, and match unique indexes to the list
6638          * of attnums we are given.
6639          */
6640         indexoidlist = RelationGetIndexList(pkrel);
6641
6642         foreach(indexoidscan, indexoidlist)
6643         {
6644                 HeapTuple       indexTuple;
6645                 Form_pg_index indexStruct;
6646                 int                     i,
6647                                         j;
6648
6649                 indexoid = lfirst_oid(indexoidscan);
6650                 indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
6651                 if (!HeapTupleIsValid(indexTuple))
6652                         elog(ERROR, "cache lookup failed for index %u", indexoid);
6653                 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
6654
6655                 /*
6656                  * Must have the right number of columns; must be unique and not a
6657                  * partial index; forget it if there are any expressions, too. Invalid
6658                  * indexes are out as well.
6659                  */
6660                 if (indexStruct->indnatts == numattrs &&
6661                         indexStruct->indisunique &&
6662                         IndexIsValid(indexStruct) &&
6663                         heap_attisnull(indexTuple, Anum_pg_index_indpred) &&
6664                         heap_attisnull(indexTuple, Anum_pg_index_indexprs))
6665                 {
6666                         /* Must get indclass the hard way */
6667                         Datum           indclassDatum;
6668                         bool            isnull;
6669                         oidvector  *indclass;
6670
6671                         indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple,
6672                                                                                         Anum_pg_index_indclass, &isnull);
6673                         Assert(!isnull);
6674                         indclass = (oidvector *) DatumGetPointer(indclassDatum);
6675
6676                         /*
6677                          * The given attnum list may match the index columns in any order.
6678                          * Check that each list is a subset of the other.
6679                          */
6680                         for (i = 0; i < numattrs; i++)
6681                         {
6682                                 found = false;
6683                                 for (j = 0; j < numattrs; j++)
6684                                 {
6685                                         if (attnums[i] == indexStruct->indkey.values[j])
6686                                         {
6687                                                 found = true;
6688                                                 break;
6689                                         }
6690                                 }
6691                                 if (!found)
6692                                         break;
6693                         }
6694                         if (found)
6695                         {
6696                                 for (i = 0; i < numattrs; i++)
6697                                 {
6698                                         found = false;
6699                                         for (j = 0; j < numattrs; j++)
6700                                         {
6701                                                 if (attnums[j] == indexStruct->indkey.values[i])
6702                                                 {
6703                                                         opclasses[j] = indclass->values[i];
6704                                                         found = true;
6705                                                         break;
6706                                                 }
6707                                         }
6708                                         if (!found)
6709                                                 break;
6710                                 }
6711                         }
6712
6713                         /*
6714                          * Refuse to use a deferrable unique/primary key.  This is per SQL
6715                          * spec, and there would be a lot of interesting semantic problems
6716                          * if we tried to allow it.
6717                          */
6718                         if (found && !indexStruct->indimmediate)
6719                         {
6720                                 /*
6721                                  * Remember that we found an otherwise matching index, so that
6722                                  * we can generate a more appropriate error message.
6723                                  */
6724                                 found_deferrable = true;
6725                                 found = false;
6726                         }
6727                 }
6728                 ReleaseSysCache(indexTuple);
6729                 if (found)
6730                         break;
6731         }
6732
6733         if (!found)
6734         {
6735                 if (found_deferrable)
6736                         ereport(ERROR,
6737                                         (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6738                                          errmsg("cannot use a deferrable unique constraint for referenced table \"%s\"",
6739                                                         RelationGetRelationName(pkrel))));
6740                 else
6741                         ereport(ERROR,
6742                                         (errcode(ERRCODE_INVALID_FOREIGN_KEY),
6743                                          errmsg("there is no unique constraint matching given keys for referenced table \"%s\"",
6744                                                         RelationGetRelationName(pkrel))));
6745         }
6746
6747         list_free(indexoidlist);
6748
6749         return indexoid;
6750 }
6751
6752 /*
6753  * findFkeyCast -
6754  *
6755  *      Wrapper around find_coercion_pathway() for ATAddForeignKeyConstraint().
6756  *      Caller has equal regard for binary coercibility and for an exact match.
6757 */
6758 static CoercionPathType
6759 findFkeyCast(Oid targetTypeId, Oid sourceTypeId, Oid *funcid)
6760 {
6761         CoercionPathType ret;
6762
6763         if (targetTypeId == sourceTypeId)
6764         {
6765                 ret = COERCION_PATH_RELABELTYPE;
6766                 *funcid = InvalidOid;
6767         }
6768         else
6769         {
6770                 ret = find_coercion_pathway(targetTypeId, sourceTypeId,
6771                                                                         COERCION_IMPLICIT, funcid);
6772                 if (ret == COERCION_PATH_NONE)
6773                         /* A previously-relied-upon cast is now gone. */
6774                         elog(ERROR, "could not find cast from %u to %u",
6775                                  sourceTypeId, targetTypeId);
6776         }
6777
6778         return ret;
6779 }
6780
6781 /* Permissions checks for ADD FOREIGN KEY */
6782 static void
6783 checkFkeyPermissions(Relation rel, int16 *attnums, int natts)
6784 {
6785         Oid                     roleid = GetUserId();
6786         AclResult       aclresult;
6787         int                     i;
6788
6789         /* Okay if we have relation-level REFERENCES permission */
6790         aclresult = pg_class_aclcheck(RelationGetRelid(rel), roleid,
6791                                                                   ACL_REFERENCES);
6792         if (aclresult == ACLCHECK_OK)
6793                 return;
6794         /* Else we must have REFERENCES on each column */
6795         for (i = 0; i < natts; i++)
6796         {
6797                 aclresult = pg_attribute_aclcheck(RelationGetRelid(rel), attnums[i],
6798                                                                                   roleid, ACL_REFERENCES);
6799                 if (aclresult != ACLCHECK_OK)
6800                         aclcheck_error(aclresult, ACL_KIND_CLASS,
6801                                                    RelationGetRelationName(rel));
6802         }
6803 }
6804
6805 /*
6806  * Scan the existing rows in a table to verify they meet a proposed
6807  * CHECK constraint.
6808  *
6809  * The caller must have opened and locked the relation appropriately.
6810  */
6811 static void
6812 validateCheckConstraint(Relation rel, HeapTuple constrtup)
6813 {
6814         EState     *estate;
6815         Datum           val;
6816         char       *conbin;
6817         Expr       *origexpr;
6818         List       *exprstate;
6819         TupleDesc       tupdesc;
6820         HeapScanDesc scan;
6821         HeapTuple       tuple;
6822         ExprContext *econtext;
6823         MemoryContext oldcxt;
6824         TupleTableSlot *slot;
6825         Form_pg_constraint constrForm;
6826         bool            isnull;
6827
6828         constrForm = (Form_pg_constraint) GETSTRUCT(constrtup);
6829
6830         estate = CreateExecutorState();
6831
6832         /*
6833          * XXX this tuple doesn't really come from a syscache, but this doesn't
6834          * matter to SysCacheGetAttr, because it only wants to be able to fetch
6835          * the tupdesc
6836          */
6837         val = SysCacheGetAttr(CONSTROID, constrtup, Anum_pg_constraint_conbin,
6838                                                   &isnull);
6839         if (isnull)
6840                 elog(ERROR, "null conbin for constraint %u",
6841                          HeapTupleGetOid(constrtup));
6842         conbin = TextDatumGetCString(val);
6843         origexpr = (Expr *) stringToNode(conbin);
6844         exprstate = (List *)
6845                 ExecPrepareExpr((Expr *) make_ands_implicit(origexpr), estate);
6846
6847         econtext = GetPerTupleExprContext(estate);
6848         tupdesc = RelationGetDescr(rel);
6849         slot = MakeSingleTupleTableSlot(tupdesc);
6850         econtext->ecxt_scantuple = slot;
6851
6852         scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
6853
6854         /*
6855          * Switch to per-tuple memory context and reset it for each tuple
6856          * produced, so we don't leak memory.
6857          */
6858         oldcxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
6859
6860         while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
6861         {
6862                 ExecStoreTuple(tuple, slot, InvalidBuffer, false);
6863
6864                 if (!ExecQual(exprstate, econtext, true))
6865                         ereport(ERROR,
6866                                         (errcode(ERRCODE_CHECK_VIOLATION),
6867                                          errmsg("check constraint \"%s\" is violated by some row",
6868                                                         NameStr(constrForm->conname)),
6869                                          errtableconstraint(rel, NameStr(constrForm->conname))));
6870
6871                 ResetExprContext(econtext);
6872         }
6873
6874         MemoryContextSwitchTo(oldcxt);
6875         heap_endscan(scan);
6876         ExecDropSingleTupleTableSlot(slot);
6877         FreeExecutorState(estate);
6878 }
6879
6880 /*
6881  * Scan the existing rows in a table to verify they meet a proposed FK
6882  * constraint.
6883  *
6884  * Caller must have opened and locked both relations appropriately.
6885  */
6886 static void
6887 validateForeignKeyConstraint(char *conname,
6888                                                          Relation rel,
6889                                                          Relation pkrel,
6890                                                          Oid pkindOid,
6891                                                          Oid constraintOid)
6892 {
6893         HeapScanDesc scan;
6894         HeapTuple       tuple;
6895         Trigger         trig;
6896
6897         ereport(DEBUG1,
6898                         (errmsg("validating foreign key constraint \"%s\"", conname)));
6899
6900         /*
6901          * Build a trigger call structure; we'll need it either way.
6902          */
6903         MemSet(&trig, 0, sizeof(trig));
6904         trig.tgoid = InvalidOid;
6905         trig.tgname = conname;
6906         trig.tgenabled = TRIGGER_FIRES_ON_ORIGIN;
6907         trig.tgisinternal = TRUE;
6908         trig.tgconstrrelid = RelationGetRelid(pkrel);
6909         trig.tgconstrindid = pkindOid;
6910         trig.tgconstraint = constraintOid;
6911         trig.tgdeferrable = FALSE;
6912         trig.tginitdeferred = FALSE;
6913         /* we needn't fill in tgargs or tgqual */
6914
6915         /*
6916          * See if we can do it with a single LEFT JOIN query.  A FALSE result
6917          * indicates we must proceed with the fire-the-trigger method.
6918          */
6919         if (RI_Initial_Check(&trig, rel, pkrel))
6920                 return;
6921
6922         /*
6923          * Scan through each tuple, calling RI_FKey_check_ins (insert trigger) as
6924          * if that tuple had just been inserted.  If any of those fail, it should
6925          * ereport(ERROR) and that's that.
6926          */
6927         scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
6928
6929         while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
6930         {
6931                 FunctionCallInfoData fcinfo;
6932                 TriggerData trigdata;
6933
6934                 /*
6935                  * Make a call to the trigger function
6936                  *
6937                  * No parameters are passed, but we do set a context
6938                  */
6939                 MemSet(&fcinfo, 0, sizeof(fcinfo));
6940
6941                 /*
6942                  * We assume RI_FKey_check_ins won't look at flinfo...
6943                  */
6944                 trigdata.type = T_TriggerData;
6945                 trigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
6946                 trigdata.tg_relation = rel;
6947                 trigdata.tg_trigtuple = tuple;
6948                 trigdata.tg_newtuple = NULL;
6949                 trigdata.tg_trigger = &trig;
6950                 trigdata.tg_trigtuplebuf = scan->rs_cbuf;
6951                 trigdata.tg_newtuplebuf = InvalidBuffer;
6952
6953                 fcinfo.context = (Node *) &trigdata;
6954
6955                 RI_FKey_check_ins(&fcinfo);
6956         }
6957
6958         heap_endscan(scan);
6959 }
6960
6961 static void
6962 CreateFKCheckTrigger(RangeVar *myRel, Constraint *fkconstraint,
6963                                          Oid constraintOid, Oid indexOid, bool on_insert)
6964 {
6965         CreateTrigStmt *fk_trigger;
6966
6967         /*
6968          * Note: for a self-referential FK (referencing and referenced tables are
6969          * the same), it is important that the ON UPDATE action fires before the
6970          * CHECK action, since both triggers will fire on the same row during an
6971          * UPDATE event; otherwise the CHECK trigger will be checking a non-final
6972          * state of the row.  Triggers fire in name order, so we ensure this by
6973          * using names like "RI_ConstraintTrigger_a_NNNN" for the action triggers
6974          * and "RI_ConstraintTrigger_c_NNNN" for the check triggers.
6975          */
6976         fk_trigger = makeNode(CreateTrigStmt);
6977         fk_trigger->trigname = "RI_ConstraintTrigger_c";
6978         fk_trigger->relation = myRel;
6979         fk_trigger->row = true;
6980         fk_trigger->timing = TRIGGER_TYPE_AFTER;
6981
6982         /* Either ON INSERT or ON UPDATE */
6983         if (on_insert)
6984         {
6985                 fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
6986                 fk_trigger->events = TRIGGER_TYPE_INSERT;
6987         }
6988         else
6989         {
6990                 fk_trigger->funcname = SystemFuncName("RI_FKey_check_upd");
6991                 fk_trigger->events = TRIGGER_TYPE_UPDATE;
6992         }
6993
6994         fk_trigger->columns = NIL;
6995         fk_trigger->whenClause = NULL;
6996         fk_trigger->isconstraint = true;
6997         fk_trigger->deferrable = fkconstraint->deferrable;
6998         fk_trigger->initdeferred = fkconstraint->initdeferred;
6999         fk_trigger->constrrel = fkconstraint->pktable;
7000         fk_trigger->args = NIL;
7001
7002         (void) CreateTrigger(fk_trigger, NULL, constraintOid, indexOid, true);
7003
7004         /* Make changes-so-far visible */
7005         CommandCounterIncrement();
7006 }
7007
7008 /*
7009  * Create the triggers that implement an FK constraint.
7010  */
7011 static void
7012 createForeignKeyTriggers(Relation rel, Constraint *fkconstraint,
7013                                                  Oid constraintOid, Oid indexOid)
7014 {
7015         RangeVar   *myRel;
7016         CreateTrigStmt *fk_trigger;
7017
7018         /*
7019          * Reconstruct a RangeVar for my relation (not passed in, unfortunately).
7020          */
7021         myRel = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
7022                                                  pstrdup(RelationGetRelationName(rel)),
7023                                                  -1);
7024
7025         /* Make changes-so-far visible */
7026         CommandCounterIncrement();
7027
7028         /*
7029          * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
7030          * DELETE action on the referenced table.
7031          */
7032         fk_trigger = makeNode(CreateTrigStmt);
7033         fk_trigger->trigname = "RI_ConstraintTrigger_a";
7034         fk_trigger->relation = fkconstraint->pktable;
7035         fk_trigger->row = true;
7036         fk_trigger->timing = TRIGGER_TYPE_AFTER;
7037         fk_trigger->events = TRIGGER_TYPE_DELETE;
7038         fk_trigger->columns = NIL;
7039         fk_trigger->whenClause = NULL;
7040         fk_trigger->isconstraint = true;
7041         fk_trigger->constrrel = myRel;
7042         switch (fkconstraint->fk_del_action)
7043         {
7044                 case FKCONSTR_ACTION_NOACTION:
7045                         fk_trigger->deferrable = fkconstraint->deferrable;
7046                         fk_trigger->initdeferred = fkconstraint->initdeferred;
7047                         fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_del");
7048                         break;
7049                 case FKCONSTR_ACTION_RESTRICT:
7050                         fk_trigger->deferrable = false;
7051                         fk_trigger->initdeferred = false;
7052                         fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_del");
7053                         break;
7054                 case FKCONSTR_ACTION_CASCADE:
7055                         fk_trigger->deferrable = false;
7056                         fk_trigger->initdeferred = false;
7057                         fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_del");
7058                         break;
7059                 case FKCONSTR_ACTION_SETNULL:
7060                         fk_trigger->deferrable = false;
7061                         fk_trigger->initdeferred = false;
7062                         fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_del");
7063                         break;
7064                 case FKCONSTR_ACTION_SETDEFAULT:
7065                         fk_trigger->deferrable = false;
7066                         fk_trigger->initdeferred = false;
7067                         fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_del");
7068                         break;
7069                 default:
7070                         elog(ERROR, "unrecognized FK action type: %d",
7071                                  (int) fkconstraint->fk_del_action);
7072                         break;
7073         }
7074         fk_trigger->args = NIL;
7075
7076         (void) CreateTrigger(fk_trigger, NULL, constraintOid, indexOid, true);
7077
7078         /* Make changes-so-far visible */
7079         CommandCounterIncrement();
7080
7081         /*
7082          * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON
7083          * UPDATE action on the referenced table.
7084          */
7085         fk_trigger = makeNode(CreateTrigStmt);
7086         fk_trigger->trigname = "RI_ConstraintTrigger_a";
7087         fk_trigger->relation = fkconstraint->pktable;
7088         fk_trigger->row = true;
7089         fk_trigger->timing = TRIGGER_TYPE_AFTER;
7090         fk_trigger->events = TRIGGER_TYPE_UPDATE;
7091         fk_trigger->columns = NIL;
7092         fk_trigger->whenClause = NULL;
7093         fk_trigger->isconstraint = true;
7094         fk_trigger->constrrel = myRel;
7095         switch (fkconstraint->fk_upd_action)
7096         {
7097                 case FKCONSTR_ACTION_NOACTION:
7098                         fk_trigger->deferrable = fkconstraint->deferrable;
7099                         fk_trigger->initdeferred = fkconstraint->initdeferred;
7100                         fk_trigger->funcname = SystemFuncName("RI_FKey_noaction_upd");
7101                         break;
7102                 case FKCONSTR_ACTION_RESTRICT:
7103                         fk_trigger->deferrable = false;
7104                         fk_trigger->initdeferred = false;
7105                         fk_trigger->funcname = SystemFuncName("RI_FKey_restrict_upd");
7106                         break;
7107                 case FKCONSTR_ACTION_CASCADE:
7108                         fk_trigger->deferrable = false;
7109                         fk_trigger->initdeferred = false;
7110                         fk_trigger->funcname = SystemFuncName("RI_FKey_cascade_upd");
7111                         break;
7112                 case FKCONSTR_ACTION_SETNULL:
7113                         fk_trigger->deferrable = false;
7114                         fk_trigger->initdeferred = false;
7115                         fk_trigger->funcname = SystemFuncName("RI_FKey_setnull_upd");
7116                         break;
7117                 case FKCONSTR_ACTION_SETDEFAULT:
7118                         fk_trigger->deferrable = false;
7119                         fk_trigger->initdeferred = false;
7120                         fk_trigger->funcname = SystemFuncName("RI_FKey_setdefault_upd");
7121                         break;
7122                 default:
7123                         elog(ERROR, "unrecognized FK action type: %d",
7124                                  (int) fkconstraint->fk_upd_action);
7125                         break;
7126         }
7127         fk_trigger->args = NIL;
7128
7129         (void) CreateTrigger(fk_trigger, NULL, constraintOid, indexOid, true);
7130
7131         /* Make changes-so-far visible */
7132         CommandCounterIncrement();
7133
7134         /*
7135          * Build and execute CREATE CONSTRAINT TRIGGER statements for the CHECK
7136          * action for both INSERTs and UPDATEs on the referencing table.
7137          */
7138         CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, indexOid, true);
7139         CreateFKCheckTrigger(myRel, fkconstraint, constraintOid, indexOid, false);
7140 }
7141
7142 /*
7143  * ALTER TABLE DROP CONSTRAINT
7144  *
7145  * Like DROP COLUMN, we can't use the normal ALTER TABLE recursion mechanism.
7146  */
7147 static void
7148 ATExecDropConstraint(Relation rel, const char *constrName,
7149                                          DropBehavior behavior,
7150                                          bool recurse, bool recursing,
7151                                          bool missing_ok, LOCKMODE lockmode)
7152 {
7153         List       *children;
7154         ListCell   *child;
7155         Relation        conrel;
7156         Form_pg_constraint con;
7157         SysScanDesc scan;
7158         ScanKeyData key;
7159         HeapTuple       tuple;
7160         bool            found = false;
7161         bool            is_no_inherit_constraint = false;
7162
7163         /* At top level, permission check was done in ATPrepCmd, else do it */
7164         if (recursing)
7165                 ATSimplePermissions(rel, ATT_TABLE);
7166
7167         conrel = heap_open(ConstraintRelationId, RowExclusiveLock);
7168
7169         /*
7170          * Find and drop the target constraint
7171          */
7172         ScanKeyInit(&key,
7173                                 Anum_pg_constraint_conrelid,
7174                                 BTEqualStrategyNumber, F_OIDEQ,
7175                                 ObjectIdGetDatum(RelationGetRelid(rel)));
7176         scan = systable_beginscan(conrel, ConstraintRelidIndexId,
7177                                                           true, SnapshotNow, 1, &key);
7178
7179         while (HeapTupleIsValid(tuple = systable_getnext(scan)))
7180         {
7181                 ObjectAddress conobj;
7182
7183                 con = (Form_pg_constraint) GETSTRUCT(tuple);
7184
7185                 if (strcmp(NameStr(con->conname), constrName) != 0)
7186                         continue;
7187
7188                 /* Don't drop inherited constraints */
7189                 if (con->coninhcount > 0 && !recursing)
7190                         ereport(ERROR,
7191                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
7192                                          errmsg("cannot drop inherited constraint \"%s\" of relation \"%s\"",
7193                                                         constrName, RelationGetRelationName(rel))));
7194
7195                 is_no_inherit_constraint = con->connoinherit;
7196
7197                 /*
7198                  * Perform the actual constraint deletion
7199                  */
7200                 conobj.classId = ConstraintRelationId;
7201                 conobj.objectId = HeapTupleGetOid(tuple);
7202                 conobj.objectSubId = 0;
7203
7204                 performDeletion(&conobj, behavior, 0);
7205
7206                 found = true;
7207
7208                 /* constraint found and dropped -- no need to keep looping */
7209                 break;
7210         }
7211
7212         systable_endscan(scan);
7213
7214         if (!found)
7215         {
7216                 if (!missing_ok)
7217                 {
7218                         ereport(ERROR,
7219                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
7220                                 errmsg("constraint \"%s\" of relation \"%s\" does not exist",
7221                                            constrName, RelationGetRelationName(rel))));
7222                 }
7223                 else
7224                 {
7225                         ereport(NOTICE,
7226                                         (errmsg("constraint \"%s\" of relation \"%s\" does not exist, skipping",
7227                                                         constrName, RelationGetRelationName(rel))));
7228                         heap_close(conrel, RowExclusiveLock);
7229                         return;
7230                 }
7231         }
7232
7233         /*
7234          * Propagate to children as appropriate.  Unlike most other ALTER
7235          * routines, we have to do this one level of recursion at a time; we can't
7236          * use find_all_inheritors to do it in one pass.
7237          */
7238         if (!is_no_inherit_constraint)
7239                 children = find_inheritance_children(RelationGetRelid(rel), lockmode);
7240         else
7241                 children = NIL;
7242
7243         foreach(child, children)
7244         {
7245                 Oid                     childrelid = lfirst_oid(child);
7246                 Relation        childrel;
7247                 HeapTuple       copy_tuple;
7248
7249                 /* find_inheritance_children already got lock */
7250                 childrel = heap_open(childrelid, NoLock);
7251                 CheckTableNotInUse(childrel, "ALTER TABLE");
7252
7253                 ScanKeyInit(&key,
7254                                         Anum_pg_constraint_conrelid,
7255                                         BTEqualStrategyNumber, F_OIDEQ,
7256                                         ObjectIdGetDatum(childrelid));
7257                 scan = systable_beginscan(conrel, ConstraintRelidIndexId,
7258                                                                   true, SnapshotNow, 1, &key);
7259
7260                 /* scan for matching tuple - there should only be one */
7261                 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
7262                 {
7263                         con = (Form_pg_constraint) GETSTRUCT(tuple);
7264
7265                         /* Right now only CHECK constraints can be inherited */
7266                         if (con->contype != CONSTRAINT_CHECK)
7267                                 continue;
7268
7269                         if (strcmp(NameStr(con->conname), constrName) == 0)
7270                                 break;
7271                 }
7272
7273                 if (!HeapTupleIsValid(tuple))
7274                         ereport(ERROR,
7275                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
7276                                 errmsg("constraint \"%s\" of relation \"%s\" does not exist",
7277                                            constrName,
7278                                            RelationGetRelationName(childrel))));
7279
7280                 copy_tuple = heap_copytuple(tuple);
7281
7282                 systable_endscan(scan);
7283
7284                 con = (Form_pg_constraint) GETSTRUCT(copy_tuple);
7285
7286                 if (con->coninhcount <= 0)              /* shouldn't happen */
7287                         elog(ERROR, "relation %u has non-inherited constraint \"%s\"",
7288                                  childrelid, constrName);
7289
7290                 if (recurse)
7291                 {
7292                         /*
7293                          * If the child constraint has other definition sources, just
7294                          * decrement its inheritance count; if not, recurse to delete it.
7295                          */
7296                         if (con->coninhcount == 1 && !con->conislocal)
7297                         {
7298                                 /* Time to delete this child constraint, too */
7299                                 ATExecDropConstraint(childrel, constrName, behavior,
7300                                                                          true, true,
7301                                                                          false, lockmode);
7302                         }
7303                         else
7304                         {
7305                                 /* Child constraint must survive my deletion */
7306                                 con->coninhcount--;
7307                                 simple_heap_update(conrel, &copy_tuple->t_self, copy_tuple);
7308                                 CatalogUpdateIndexes(conrel, copy_tuple);
7309
7310                                 /* Make update visible */
7311                                 CommandCounterIncrement();
7312                         }
7313                 }
7314                 else
7315                 {
7316                         /*
7317                          * If we were told to drop ONLY in this table (no recursion), we
7318                          * need to mark the inheritors' constraints as locally defined
7319                          * rather than inherited.
7320                          */
7321                         con->coninhcount--;
7322                         con->conislocal = true;
7323
7324                         simple_heap_update(conrel, &copy_tuple->t_self, copy_tuple);
7325                         CatalogUpdateIndexes(conrel, copy_tuple);
7326
7327                         /* Make update visible */
7328                         CommandCounterIncrement();
7329                 }
7330
7331                 heap_freetuple(copy_tuple);
7332
7333                 heap_close(childrel, NoLock);
7334         }
7335
7336         heap_close(conrel, RowExclusiveLock);
7337 }
7338
7339 /*
7340  * ALTER COLUMN TYPE
7341  */
7342 static void
7343 ATPrepAlterColumnType(List **wqueue,
7344                                           AlteredTableInfo *tab, Relation rel,
7345                                           bool recurse, bool recursing,
7346                                           AlterTableCmd *cmd, LOCKMODE lockmode)
7347 {
7348         char       *colName = cmd->name;
7349         ColumnDef  *def = (ColumnDef *) cmd->def;
7350         TypeName   *typeName = def->typeName;
7351         Node       *transform = def->raw_default;
7352         HeapTuple       tuple;
7353         Form_pg_attribute attTup;
7354         AttrNumber      attnum;
7355         Oid                     targettype;
7356         int32           targettypmod;
7357         Oid                     targetcollid;
7358         NewColumnValue *newval;
7359         ParseState *pstate = make_parsestate(NULL);
7360         AclResult       aclresult;
7361
7362         if (rel->rd_rel->reloftype && !recursing)
7363                 ereport(ERROR,
7364                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7365                                  errmsg("cannot alter column type of typed table")));
7366
7367         /* lookup the attribute so we can check inheritance status */
7368         tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
7369         if (!HeapTupleIsValid(tuple))
7370                 ereport(ERROR,
7371                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
7372                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
7373                                                 colName, RelationGetRelationName(rel))));
7374         attTup = (Form_pg_attribute) GETSTRUCT(tuple);
7375         attnum = attTup->attnum;
7376
7377         /* Can't alter a system attribute */
7378         if (attnum <= 0)
7379                 ereport(ERROR,
7380                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7381                                  errmsg("cannot alter system column \"%s\"",
7382                                                 colName)));
7383
7384         /* Don't alter inherited columns */
7385         if (attTup->attinhcount > 0 && !recursing)
7386                 ereport(ERROR,
7387                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
7388                                  errmsg("cannot alter inherited column \"%s\"",
7389                                                 colName)));
7390
7391         /* Look up the target type */
7392         typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod);
7393
7394         aclresult = pg_type_aclcheck(targettype, GetUserId(), ACL_USAGE);
7395         if (aclresult != ACLCHECK_OK)
7396                 aclcheck_error_type(aclresult, targettype);
7397
7398         /* And the collation */
7399         targetcollid = GetColumnDefCollation(NULL, def, targettype);
7400
7401         /* make sure datatype is legal for a column */
7402         CheckAttributeType(colName, targettype, targetcollid,
7403                                            list_make1_oid(rel->rd_rel->reltype),
7404                                            false);
7405
7406         if (tab->relkind == RELKIND_RELATION)
7407         {
7408                 /*
7409                  * Set up an expression to transform the old data value to the new
7410                  * type. If a USING option was given, transform and use that
7411                  * expression, else just take the old value and try to coerce it.  We
7412                  * do this first so that type incompatibility can be detected before
7413                  * we waste effort, and because we need the expression to be parsed
7414                  * against the original table row type.
7415                  */
7416                 if (transform)
7417                 {
7418                         RangeTblEntry *rte;
7419
7420                         /* Expression must be able to access vars of old table */
7421                         rte = addRangeTableEntryForRelation(pstate,
7422                                                                                                 rel,
7423                                                                                                 NULL,
7424                                                                                                 false,
7425                                                                                                 true);
7426                         addRTEtoQuery(pstate, rte, false, true, true);
7427
7428                         transform = transformExpr(pstate, transform,
7429                                                                           EXPR_KIND_ALTER_COL_TRANSFORM);
7430
7431                         /* It can't return a set */
7432                         if (expression_returns_set(transform))
7433                                 ereport(ERROR,
7434                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
7435                                           errmsg("transform expression must not return a set")));
7436                 }
7437                 else
7438                 {
7439                         transform = (Node *) makeVar(1, attnum,
7440                                                                                  attTup->atttypid, attTup->atttypmod,
7441                                                                                  attTup->attcollation,
7442                                                                                  0);
7443                 }
7444
7445                 transform = coerce_to_target_type(pstate,
7446                                                                                   transform, exprType(transform),
7447                                                                                   targettype, targettypmod,
7448                                                                                   COERCION_ASSIGNMENT,
7449                                                                                   COERCE_IMPLICIT_CAST,
7450                                                                                   -1);
7451                 if (transform == NULL)
7452                         ereport(ERROR,
7453                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
7454                           errmsg("column \"%s\" cannot be cast automatically to type %s",
7455                                          colName, format_type_be(targettype)),
7456                                          errhint("Specify a USING expression to perform the conversion.")));
7457
7458                 /* Fix collations after all else */
7459                 assign_expr_collations(pstate, transform);
7460
7461                 /* Plan the expr now so we can accurately assess the need to rewrite. */
7462                 transform = (Node *) expression_planner((Expr *) transform);
7463
7464                 /*
7465                  * Add a work queue item to make ATRewriteTable update the column
7466                  * contents.
7467                  */
7468                 newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
7469                 newval->attnum = attnum;
7470                 newval->expr = (Expr *) transform;
7471
7472                 tab->newvals = lappend(tab->newvals, newval);
7473                 if (ATColumnChangeRequiresRewrite(transform, attnum))
7474                         tab->rewrite = true;
7475         }
7476         else if (transform)
7477                 ereport(ERROR,
7478                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7479                                  errmsg("\"%s\" is not a table",
7480                                                 RelationGetRelationName(rel))));
7481
7482         if (tab->relkind == RELKIND_COMPOSITE_TYPE ||
7483                 tab->relkind == RELKIND_FOREIGN_TABLE)
7484         {
7485                 /*
7486                  * For composite types, do this check now.      Tables will check it later
7487                  * when the table is being rewritten.
7488                  */
7489                 find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL);
7490         }
7491
7492         ReleaseSysCache(tuple);
7493
7494         /*
7495          * The recursion case is handled by ATSimpleRecursion.  However, if we are
7496          * told not to recurse, there had better not be any child tables; else the
7497          * alter would put them out of step.
7498          */
7499         if (recurse)
7500                 ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
7501         else if (!recursing &&
7502                          find_inheritance_children(RelationGetRelid(rel), NoLock) != NIL)
7503                 ereport(ERROR,
7504                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
7505                                  errmsg("type of inherited column \"%s\" must be changed in child tables too",
7506                                                 colName)));
7507
7508         if (tab->relkind == RELKIND_COMPOSITE_TYPE)
7509                 ATTypedTableRecursion(wqueue, rel, cmd, lockmode);
7510 }
7511
7512 /*
7513  * When the data type of a column is changed, a rewrite might not be required
7514  * if the new type is sufficiently identical to the old one, and the USING
7515  * clause isn't trying to insert some other value.  It's safe to skip the
7516  * rewrite if the old type is binary coercible to the new type, or if the
7517  * new type is an unconstrained domain over the old type.  In the case of a
7518  * constrained domain, we could get by with scanning the table and checking
7519  * the constraint rather than actually rewriting it, but we don't currently
7520  * try to do that.
7521  */
7522 static bool
7523 ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno)
7524 {
7525         Assert(expr != NULL);
7526
7527         for (;;)
7528         {
7529                 /* only one varno, so no need to check that */
7530                 if (IsA(expr, Var) &&((Var *) expr)->varattno == varattno)
7531                         return false;
7532                 else if (IsA(expr, RelabelType))
7533                         expr = (Node *) ((RelabelType *) expr)->arg;
7534                 else if (IsA(expr, CoerceToDomain))
7535                 {
7536                         CoerceToDomain *d = (CoerceToDomain *) expr;
7537
7538                         if (GetDomainConstraints(d->resulttype) != NIL)
7539                                 return true;
7540                         expr = (Node *) d->arg;
7541                 }
7542                 else
7543                         return true;
7544         }
7545 }
7546
7547 static void
7548 ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
7549                                           AlterTableCmd *cmd, LOCKMODE lockmode)
7550 {
7551         char       *colName = cmd->name;
7552         ColumnDef  *def = (ColumnDef *) cmd->def;
7553         TypeName   *typeName = def->typeName;
7554         HeapTuple       heapTup;
7555         Form_pg_attribute attTup;
7556         AttrNumber      attnum;
7557         HeapTuple       typeTuple;
7558         Form_pg_type tform;
7559         Oid                     targettype;
7560         int32           targettypmod;
7561         Oid                     targetcollid;
7562         Node       *defaultexpr;
7563         Relation        attrelation;
7564         Relation        depRel;
7565         ScanKeyData key[3];
7566         SysScanDesc scan;
7567         HeapTuple       depTup;
7568
7569         attrelation = heap_open(AttributeRelationId, RowExclusiveLock);
7570
7571         /* Look up the target column */
7572         heapTup = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName);
7573         if (!HeapTupleIsValid(heapTup))         /* shouldn't happen */
7574                 ereport(ERROR,
7575                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
7576                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
7577                                                 colName, RelationGetRelationName(rel))));
7578         attTup = (Form_pg_attribute) GETSTRUCT(heapTup);
7579         attnum = attTup->attnum;
7580
7581         /* Check for multiple ALTER TYPE on same column --- can't cope */
7582         if (attTup->atttypid != tab->oldDesc->attrs[attnum - 1]->atttypid ||
7583                 attTup->atttypmod != tab->oldDesc->attrs[attnum - 1]->atttypmod)
7584                 ereport(ERROR,
7585                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7586                                  errmsg("cannot alter type of column \"%s\" twice",
7587                                                 colName)));
7588
7589         /* Look up the target type (should not fail, since prep found it) */
7590         typeTuple = typenameType(NULL, typeName, &targettypmod);
7591         tform = (Form_pg_type) GETSTRUCT(typeTuple);
7592         targettype = HeapTupleGetOid(typeTuple);
7593         /* And the collation */
7594         targetcollid = GetColumnDefCollation(NULL, def, targettype);
7595
7596         /*
7597          * If there is a default expression for the column, get it and ensure we
7598          * can coerce it to the new datatype.  (We must do this before changing
7599          * the column type, because build_column_default itself will try to
7600          * coerce, and will not issue the error message we want if it fails.)
7601          *
7602          * We remove any implicit coercion steps at the top level of the old
7603          * default expression; this has been agreed to satisfy the principle of
7604          * least surprise.      (The conversion to the new column type should act like
7605          * it started from what the user sees as the stored expression, and the
7606          * implicit coercions aren't going to be shown.)
7607          */
7608         if (attTup->atthasdef)
7609         {
7610                 defaultexpr = build_column_default(rel, attnum);
7611                 Assert(defaultexpr);
7612                 defaultexpr = strip_implicit_coercions(defaultexpr);
7613                 defaultexpr = coerce_to_target_type(NULL,               /* no UNKNOWN params */
7614                                                                                   defaultexpr, exprType(defaultexpr),
7615                                                                                         targettype, targettypmod,
7616                                                                                         COERCION_ASSIGNMENT,
7617                                                                                         COERCE_IMPLICIT_CAST,
7618                                                                                         -1);
7619                 if (defaultexpr == NULL)
7620                         ereport(ERROR,
7621                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
7622                                          errmsg("default for column \"%s\" cannot be cast automatically to type %s",
7623                                                         colName, format_type_be(targettype))));
7624         }
7625         else
7626                 defaultexpr = NULL;
7627
7628         /*
7629          * Find everything that depends on the column (constraints, indexes, etc),
7630          * and record enough information to let us recreate the objects.
7631          *
7632          * The actual recreation does not happen here, but only after we have
7633          * performed all the individual ALTER TYPE operations.  We have to save
7634          * the info before executing ALTER TYPE, though, else the deparser will
7635          * get confused.
7636          *
7637          * There could be multiple entries for the same object, so we must check
7638          * to ensure we process each one only once.  Note: we assume that an index
7639          * that implements a constraint will not show a direct dependency on the
7640          * column.
7641          */
7642         depRel = heap_open(DependRelationId, RowExclusiveLock);
7643
7644         ScanKeyInit(&key[0],
7645                                 Anum_pg_depend_refclassid,
7646                                 BTEqualStrategyNumber, F_OIDEQ,
7647                                 ObjectIdGetDatum(RelationRelationId));
7648         ScanKeyInit(&key[1],
7649                                 Anum_pg_depend_refobjid,
7650                                 BTEqualStrategyNumber, F_OIDEQ,
7651                                 ObjectIdGetDatum(RelationGetRelid(rel)));
7652         ScanKeyInit(&key[2],
7653                                 Anum_pg_depend_refobjsubid,
7654                                 BTEqualStrategyNumber, F_INT4EQ,
7655                                 Int32GetDatum((int32) attnum));
7656
7657         scan = systable_beginscan(depRel, DependReferenceIndexId, true,
7658                                                           SnapshotNow, 3, key);
7659
7660         while (HeapTupleIsValid(depTup = systable_getnext(scan)))
7661         {
7662                 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
7663                 ObjectAddress foundObject;
7664
7665                 /* We don't expect any PIN dependencies on columns */
7666                 if (foundDep->deptype == DEPENDENCY_PIN)
7667                         elog(ERROR, "cannot alter type of a pinned column");
7668
7669                 foundObject.classId = foundDep->classid;
7670                 foundObject.objectId = foundDep->objid;
7671                 foundObject.objectSubId = foundDep->objsubid;
7672
7673                 switch (getObjectClass(&foundObject))
7674                 {
7675                         case OCLASS_CLASS:
7676                                 {
7677                                         char            relKind = get_rel_relkind(foundObject.objectId);
7678
7679                                         if (relKind == RELKIND_INDEX)
7680                                         {
7681                                                 Assert(foundObject.objectSubId == 0);
7682                                                 if (!list_member_oid(tab->changedIndexOids, foundObject.objectId))
7683                                                 {
7684                                                         tab->changedIndexOids = lappend_oid(tab->changedIndexOids,
7685                                                                                                            foundObject.objectId);
7686                                                         tab->changedIndexDefs = lappend(tab->changedIndexDefs,
7687                                                            pg_get_indexdef_string(foundObject.objectId));
7688                                                 }
7689                                         }
7690                                         else if (relKind == RELKIND_SEQUENCE)
7691                                         {
7692                                                 /*
7693                                                  * This must be a SERIAL column's sequence.  We need
7694                                                  * not do anything to it.
7695                                                  */
7696                                                 Assert(foundObject.objectSubId == 0);
7697                                         }
7698                                         else
7699                                         {
7700                                                 /* Not expecting any other direct dependencies... */
7701                                                 elog(ERROR, "unexpected object depending on column: %s",
7702                                                          getObjectDescription(&foundObject));
7703                                         }
7704                                         break;
7705                                 }
7706
7707                         case OCLASS_CONSTRAINT:
7708                                 Assert(foundObject.objectSubId == 0);
7709                                 if (!list_member_oid(tab->changedConstraintOids,
7710                                                                          foundObject.objectId))
7711                                 {
7712                                         char       *defstring = pg_get_constraintdef_string(foundObject.objectId);
7713
7714                                         /*
7715                                          * Put NORMAL dependencies at the front of the list and
7716                                          * AUTO dependencies at the back.  This makes sure that
7717                                          * foreign-key constraints depending on this column will
7718                                          * be dropped before unique or primary-key constraints of
7719                                          * the column; which we must have because the FK
7720                                          * constraints depend on the indexes belonging to the
7721                                          * unique constraints.
7722                                          */
7723                                         if (foundDep->deptype == DEPENDENCY_NORMAL)
7724                                         {
7725                                                 tab->changedConstraintOids =
7726                                                         lcons_oid(foundObject.objectId,
7727                                                                           tab->changedConstraintOids);
7728                                                 tab->changedConstraintDefs =
7729                                                         lcons(defstring,
7730                                                                   tab->changedConstraintDefs);
7731                                         }
7732                                         else
7733                                         {
7734                                                 tab->changedConstraintOids =
7735                                                         lappend_oid(tab->changedConstraintOids,
7736                                                                                 foundObject.objectId);
7737                                                 tab->changedConstraintDefs =
7738                                                         lappend(tab->changedConstraintDefs,
7739                                                                         defstring);
7740                                         }
7741                                 }
7742                                 break;
7743
7744                         case OCLASS_REWRITE:
7745                                 /* XXX someday see if we can cope with revising views */
7746                                 ereport(ERROR,
7747                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7748                                                  errmsg("cannot alter type of a column used by a view or rule"),
7749                                                  errdetail("%s depends on column \"%s\"",
7750                                                                    getObjectDescription(&foundObject),
7751                                                                    colName)));
7752                                 break;
7753
7754                         case OCLASS_TRIGGER:
7755
7756                                 /*
7757                                  * A trigger can depend on a column because the column is
7758                                  * specified as an update target, or because the column is
7759                                  * used in the trigger's WHEN condition.  The first case would
7760                                  * not require any extra work, but the second case would
7761                                  * require updating the WHEN expression, which will take a
7762                                  * significant amount of new code.      Since we can't easily tell
7763                                  * which case applies, we punt for both.  FIXME someday.
7764                                  */
7765                                 ereport(ERROR,
7766                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7767                                                  errmsg("cannot alter type of a column used in a trigger definition"),
7768                                                  errdetail("%s depends on column \"%s\"",
7769                                                                    getObjectDescription(&foundObject),
7770                                                                    colName)));
7771                                 break;
7772
7773                         case OCLASS_DEFAULT:
7774
7775                                 /*
7776                                  * Ignore the column's default expression, since we will fix
7777                                  * it below.
7778                                  */
7779                                 Assert(defaultexpr);
7780                                 break;
7781
7782                         case OCLASS_PROC:
7783                         case OCLASS_TYPE:
7784                         case OCLASS_CAST:
7785                         case OCLASS_COLLATION:
7786                         case OCLASS_CONVERSION:
7787                         case OCLASS_LANGUAGE:
7788                         case OCLASS_LARGEOBJECT:
7789                         case OCLASS_OPERATOR:
7790                         case OCLASS_OPCLASS:
7791                         case OCLASS_OPFAMILY:
7792                         case OCLASS_AMOP:
7793                         case OCLASS_AMPROC:
7794                         case OCLASS_SCHEMA:
7795                         case OCLASS_TSPARSER:
7796                         case OCLASS_TSDICT:
7797                         case OCLASS_TSTEMPLATE:
7798                         case OCLASS_TSCONFIG:
7799                         case OCLASS_ROLE:
7800                         case OCLASS_DATABASE:
7801                         case OCLASS_TBLSPACE:
7802                         case OCLASS_FDW:
7803                         case OCLASS_FOREIGN_SERVER:
7804                         case OCLASS_USER_MAPPING:
7805                         case OCLASS_DEFACL:
7806                         case OCLASS_EXTENSION:
7807
7808                                 /*
7809                                  * We don't expect any of these sorts of objects to depend on
7810                                  * a column.
7811                                  */
7812                                 elog(ERROR, "unexpected object depending on column: %s",
7813                                          getObjectDescription(&foundObject));
7814                                 break;
7815
7816                         default:
7817                                 elog(ERROR, "unrecognized object class: %u",
7818                                          foundObject.classId);
7819                 }
7820         }
7821
7822         systable_endscan(scan);
7823
7824         /*
7825          * Now scan for dependencies of this column on other things.  The only
7826          * thing we should find is the dependency on the column datatype, which we
7827          * want to remove, and possibly a collation dependency.
7828          */
7829         ScanKeyInit(&key[0],
7830                                 Anum_pg_depend_classid,
7831                                 BTEqualStrategyNumber, F_OIDEQ,
7832                                 ObjectIdGetDatum(RelationRelationId));
7833         ScanKeyInit(&key[1],
7834                                 Anum_pg_depend_objid,
7835                                 BTEqualStrategyNumber, F_OIDEQ,
7836                                 ObjectIdGetDatum(RelationGetRelid(rel)));
7837         ScanKeyInit(&key[2],
7838                                 Anum_pg_depend_objsubid,
7839                                 BTEqualStrategyNumber, F_INT4EQ,
7840                                 Int32GetDatum((int32) attnum));
7841
7842         scan = systable_beginscan(depRel, DependDependerIndexId, true,
7843                                                           SnapshotNow, 3, key);
7844
7845         while (HeapTupleIsValid(depTup = systable_getnext(scan)))
7846         {
7847                 Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup);
7848
7849                 if (foundDep->deptype != DEPENDENCY_NORMAL)
7850                         elog(ERROR, "found unexpected dependency type '%c'",
7851                                  foundDep->deptype);
7852                 if (!(foundDep->refclassid == TypeRelationId &&
7853                           foundDep->refobjid == attTup->atttypid) &&
7854                         !(foundDep->refclassid == CollationRelationId &&
7855                           foundDep->refobjid == attTup->attcollation))
7856                         elog(ERROR, "found unexpected dependency for column");
7857
7858                 simple_heap_delete(depRel, &depTup->t_self);
7859         }
7860
7861         systable_endscan(scan);
7862
7863         heap_close(depRel, RowExclusiveLock);
7864
7865         /*
7866          * Here we go --- change the recorded column type and collation.  (Note
7867          * heapTup is a copy of the syscache entry, so okay to scribble on.)
7868          */
7869         attTup->atttypid = targettype;
7870         attTup->atttypmod = targettypmod;
7871         attTup->attcollation = targetcollid;
7872         attTup->attndims = list_length(typeName->arrayBounds);
7873         attTup->attlen = tform->typlen;
7874         attTup->attbyval = tform->typbyval;
7875         attTup->attalign = tform->typalign;
7876         attTup->attstorage = tform->typstorage;
7877
7878         ReleaseSysCache(typeTuple);
7879
7880         simple_heap_update(attrelation, &heapTup->t_self, heapTup);
7881
7882         /* keep system catalog indexes current */
7883         CatalogUpdateIndexes(attrelation, heapTup);
7884
7885         heap_close(attrelation, RowExclusiveLock);
7886
7887         /* Install dependencies on new datatype and collation */
7888         add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype);
7889         add_column_collation_dependency(RelationGetRelid(rel), attnum, targetcollid);
7890
7891         /*
7892          * Drop any pg_statistic entry for the column, since it's now wrong type
7893          */
7894         RemoveStatistics(RelationGetRelid(rel), attnum);
7895
7896         InvokeObjectPostAlterHook(RelationRelationId,
7897                                                           RelationGetRelid(rel), attnum);
7898
7899         /*
7900          * Update the default, if present, by brute force --- remove and re-add
7901          * the default.  Probably unsafe to take shortcuts, since the new version
7902          * may well have additional dependencies.  (It's okay to do this now,
7903          * rather than after other ALTER TYPE commands, since the default won't
7904          * depend on other column types.)
7905          */
7906         if (defaultexpr)
7907         {
7908                 /* Must make new row visible since it will be updated again */
7909                 CommandCounterIncrement();
7910
7911                 /*
7912                  * We use RESTRICT here for safety, but at present we do not expect
7913                  * anything to depend on the default.
7914                  */
7915                 RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true,
7916                                                   true);
7917
7918                 StoreAttrDefault(rel, attnum, defaultexpr, true);
7919         }
7920
7921         /* Cleanup */
7922         heap_freetuple(heapTup);
7923 }
7924
7925 static void
7926 ATExecAlterColumnGenericOptions(Relation rel,
7927                                                                 const char *colName,
7928                                                                 List *options,
7929                                                                 LOCKMODE lockmode)
7930 {
7931         Relation        ftrel;
7932         Relation        attrel;
7933         ForeignServer *server;
7934         ForeignDataWrapper *fdw;
7935         HeapTuple       tuple;
7936         HeapTuple       newtuple;
7937         bool            isnull;
7938         Datum           repl_val[Natts_pg_attribute];
7939         bool            repl_null[Natts_pg_attribute];
7940         bool            repl_repl[Natts_pg_attribute];
7941         Datum           datum;
7942         Form_pg_foreign_table fttableform;
7943         Form_pg_attribute atttableform;
7944
7945         if (options == NIL)
7946                 return;
7947
7948         /* First, determine FDW validator associated to the foreign table. */
7949         ftrel = heap_open(ForeignTableRelationId, AccessShareLock);
7950         tuple = SearchSysCache1(FOREIGNTABLEREL, rel->rd_id);
7951         if (!HeapTupleIsValid(tuple))
7952                 ereport(ERROR,
7953                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
7954                                  errmsg("foreign table \"%s\" does not exist",
7955                                                 RelationGetRelationName(rel))));
7956         fttableform = (Form_pg_foreign_table) GETSTRUCT(tuple);
7957         server = GetForeignServer(fttableform->ftserver);
7958         fdw = GetForeignDataWrapper(server->fdwid);
7959
7960         heap_close(ftrel, AccessShareLock);
7961         ReleaseSysCache(tuple);
7962
7963         attrel = heap_open(AttributeRelationId, RowExclusiveLock);
7964         tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
7965         if (!HeapTupleIsValid(tuple))
7966                 ereport(ERROR,
7967                                 (errcode(ERRCODE_UNDEFINED_COLUMN),
7968                                  errmsg("column \"%s\" of relation \"%s\" does not exist",
7969                                                 colName, RelationGetRelationName(rel))));
7970
7971         /* Prevent them from altering a system attribute */
7972         atttableform = (Form_pg_attribute) GETSTRUCT(tuple);
7973         if (atttableform->attnum <= 0)
7974                 ereport(ERROR,
7975                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
7976                                  errmsg("cannot alter system column \"%s\"", colName)));
7977
7978
7979         /* Initialize buffers for new tuple values */
7980         memset(repl_val, 0, sizeof(repl_val));
7981         memset(repl_null, false, sizeof(repl_null));
7982         memset(repl_repl, false, sizeof(repl_repl));
7983
7984         /* Extract the current options */
7985         datum = SysCacheGetAttr(ATTNAME,
7986                                                         tuple,
7987                                                         Anum_pg_attribute_attfdwoptions,
7988                                                         &isnull);
7989         if (isnull)
7990                 datum = PointerGetDatum(NULL);
7991
7992         /* Transform the options */
7993         datum = transformGenericOptions(AttributeRelationId,
7994                                                                         datum,
7995                                                                         options,
7996                                                                         fdw->fdwvalidator);
7997
7998         if (PointerIsValid(DatumGetPointer(datum)))
7999                 repl_val[Anum_pg_attribute_attfdwoptions - 1] = datum;
8000         else
8001                 repl_null[Anum_pg_attribute_attfdwoptions - 1] = true;
8002
8003         repl_repl[Anum_pg_attribute_attfdwoptions - 1] = true;
8004
8005         /* Everything looks good - update the tuple */
8006
8007         newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrel),
8008                                                                  repl_val, repl_null, repl_repl);
8009
8010         simple_heap_update(attrel, &newtuple->t_self, newtuple);
8011         CatalogUpdateIndexes(attrel, newtuple);
8012
8013         InvokeObjectPostAlterHook(RelationRelationId,
8014                                                           RelationGetRelid(rel),
8015                                                           atttableform->attnum);
8016
8017         ReleaseSysCache(tuple);
8018
8019         heap_close(attrel, RowExclusiveLock);
8020
8021         heap_freetuple(newtuple);
8022 }
8023
8024 /*
8025  * Cleanup after we've finished all the ALTER TYPE operations for a
8026  * particular relation.  We have to drop and recreate all the indexes
8027  * and constraints that depend on the altered columns.
8028  */
8029 static void
8030 ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
8031 {
8032         ObjectAddress obj;
8033         ListCell   *def_item;
8034         ListCell   *oid_item;
8035
8036         /*
8037          * Re-parse the index and constraint definitions, and attach them to the
8038          * appropriate work queue entries.      We do this before dropping because in
8039          * the case of a FOREIGN KEY constraint, we might not yet have exclusive
8040          * lock on the table the constraint is attached to, and we need to get
8041          * that before dropping.  It's safe because the parser won't actually look
8042          * at the catalogs to detect the existing entry.
8043          */
8044         forboth(oid_item, tab->changedConstraintOids,
8045                         def_item, tab->changedConstraintDefs)
8046                 ATPostAlterTypeParse(lfirst_oid(oid_item), (char *) lfirst(def_item),
8047                                                          wqueue, lockmode, tab->rewrite);
8048         forboth(oid_item, tab->changedIndexOids,
8049                         def_item, tab->changedIndexDefs)
8050                 ATPostAlterTypeParse(lfirst_oid(oid_item), (char *) lfirst(def_item),
8051                                                          wqueue, lockmode, tab->rewrite);
8052
8053         /*
8054          * Now we can drop the existing constraints and indexes --- constraints
8055          * first, since some of them might depend on the indexes.  In fact, we
8056          * have to delete FOREIGN KEY constraints before UNIQUE constraints, but
8057          * we already ordered the constraint list to ensure that would happen. It
8058          * should be okay to use DROP_RESTRICT here, since nothing else should be
8059          * depending on these objects.
8060          */
8061         foreach(oid_item, tab->changedConstraintOids)
8062         {
8063                 obj.classId = ConstraintRelationId;
8064                 obj.objectId = lfirst_oid(oid_item);
8065                 obj.objectSubId = 0;
8066                 performDeletion(&obj, DROP_RESTRICT, PERFORM_DELETION_INTERNAL);
8067         }
8068
8069         foreach(oid_item, tab->changedIndexOids)
8070         {
8071                 obj.classId = RelationRelationId;
8072                 obj.objectId = lfirst_oid(oid_item);
8073                 obj.objectSubId = 0;
8074                 performDeletion(&obj, DROP_RESTRICT, PERFORM_DELETION_INTERNAL);
8075         }
8076
8077         /*
8078          * The objects will get recreated during subsequent passes over the work
8079          * queue.
8080          */
8081 }
8082
8083 static void
8084 ATPostAlterTypeParse(Oid oldId, char *cmd,
8085                                          List **wqueue, LOCKMODE lockmode, bool rewrite)
8086 {
8087         List       *raw_parsetree_list;
8088         List       *querytree_list;
8089         ListCell   *list_item;
8090
8091         /*
8092          * We expect that we will get only ALTER TABLE and CREATE INDEX
8093          * statements. Hence, there is no need to pass them through
8094          * parse_analyze() or the rewriter, but instead we need to pass them
8095          * through parse_utilcmd.c to make them ready for execution.
8096          */
8097         raw_parsetree_list = raw_parser(cmd);
8098         querytree_list = NIL;
8099         foreach(list_item, raw_parsetree_list)
8100         {
8101                 Node       *stmt = (Node *) lfirst(list_item);
8102
8103                 if (IsA(stmt, IndexStmt))
8104                         querytree_list = lappend(querytree_list,
8105                                                                          transformIndexStmt((IndexStmt *) stmt,
8106                                                                                                                 cmd));
8107                 else if (IsA(stmt, AlterTableStmt))
8108                         querytree_list = list_concat(querytree_list,
8109                                                          transformAlterTableStmt((AlterTableStmt *) stmt,
8110                                                                                                          cmd));
8111                 else
8112                         querytree_list = lappend(querytree_list, stmt);
8113         }
8114
8115         /*
8116          * Attach each generated command to the proper place in the work queue.
8117          * Note this could result in creation of entirely new work-queue entries.
8118          *
8119          * Also note that we have to tweak the command subtypes, because it turns
8120          * out that re-creation of indexes and constraints has to act a bit
8121          * differently from initial creation.
8122          */
8123         foreach(list_item, querytree_list)
8124         {
8125                 Node       *stm = (Node *) lfirst(list_item);
8126                 Relation        rel;
8127                 AlteredTableInfo *tab;
8128
8129                 switch (nodeTag(stm))
8130                 {
8131                         case T_IndexStmt:
8132                                 {
8133                                         IndexStmt  *stmt = (IndexStmt *) stm;
8134                                         AlterTableCmd *newcmd;
8135
8136                                         if (!rewrite)
8137                                                 TryReuseIndex(oldId, stmt);
8138
8139                                         rel = relation_openrv(stmt->relation, lockmode);
8140                                         tab = ATGetQueueEntry(wqueue, rel);
8141                                         newcmd = makeNode(AlterTableCmd);
8142                                         newcmd->subtype = AT_ReAddIndex;
8143                                         newcmd->def = (Node *) stmt;
8144                                         tab->subcmds[AT_PASS_OLD_INDEX] =
8145                                                 lappend(tab->subcmds[AT_PASS_OLD_INDEX], newcmd);
8146                                         relation_close(rel, NoLock);
8147                                         break;
8148                                 }
8149                         case T_AlterTableStmt:
8150                                 {
8151                                         AlterTableStmt *stmt = (AlterTableStmt *) stm;
8152                                         ListCell   *lcmd;
8153
8154                                         rel = relation_openrv(stmt->relation, lockmode);
8155                                         tab = ATGetQueueEntry(wqueue, rel);
8156                                         foreach(lcmd, stmt->cmds)
8157                                         {
8158                                                 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
8159                                                 Constraint *con;
8160
8161                                                 switch (cmd->subtype)
8162                                                 {
8163                                                         case AT_AddIndex:
8164                                                                 Assert(IsA(cmd->def, IndexStmt));
8165                                                                 if (!rewrite)
8166                                                                         TryReuseIndex(get_constraint_index(oldId),
8167                                                                                                   (IndexStmt *) cmd->def);
8168                                                                 cmd->subtype = AT_ReAddIndex;
8169                                                                 tab->subcmds[AT_PASS_OLD_INDEX] =
8170                                                                         lappend(tab->subcmds[AT_PASS_OLD_INDEX], cmd);
8171                                                                 break;
8172                                                         case AT_AddConstraint:
8173                                                                 Assert(IsA(cmd->def, Constraint));
8174                                                                 con = (Constraint *) cmd->def;
8175                                                                 /* rewriting neither side of a FK */
8176                                                                 if (con->contype == CONSTR_FOREIGN &&
8177                                                                         !rewrite && !tab->rewrite)
8178                                                                         TryReuseForeignKey(oldId, con);
8179                                                                 cmd->subtype = AT_ReAddConstraint;
8180                                                                 tab->subcmds[AT_PASS_OLD_CONSTR] =
8181                                                                         lappend(tab->subcmds[AT_PASS_OLD_CONSTR], cmd);
8182                                                                 break;
8183                                                         default:
8184                                                                 elog(ERROR, "unexpected statement type: %d",
8185                                                                          (int) cmd->subtype);
8186                                                 }
8187                                         }
8188                                         relation_close(rel, NoLock);
8189                                         break;
8190                                 }
8191                         default:
8192                                 elog(ERROR, "unexpected statement type: %d",
8193                                          (int) nodeTag(stm));
8194                 }
8195         }
8196 }
8197
8198 /*
8199  * Subroutine for ATPostAlterTypeParse().  Calls out to CheckIndexCompatible()
8200  * for the real analysis, then mutates the IndexStmt based on that verdict.
8201  */
8202 static void
8203 TryReuseIndex(Oid oldId, IndexStmt *stmt)
8204 {
8205         if (CheckIndexCompatible(oldId,
8206                                                          stmt->relation,
8207                                                          stmt->accessMethod,
8208                                                          stmt->indexParams,
8209                                                          stmt->excludeOpNames))
8210         {
8211                 Relation        irel = index_open(oldId, NoLock);
8212
8213                 stmt->oldNode = irel->rd_node.relNode;
8214                 index_close(irel, NoLock);
8215         }
8216 }
8217
8218 /*
8219  * Subroutine for ATPostAlterTypeParse().
8220  *
8221  * Stash the old P-F equality operator into the Constraint node, for possible
8222  * use by ATAddForeignKeyConstraint() in determining whether revalidation of
8223  * this constraint can be skipped.
8224  */
8225 static void
8226 TryReuseForeignKey(Oid oldId, Constraint *con)
8227 {
8228         HeapTuple       tup;
8229         Datum           adatum;
8230         bool            isNull;
8231         ArrayType  *arr;
8232         Oid                *rawarr;
8233         int                     numkeys;
8234         int                     i;
8235
8236         Assert(con->contype == CONSTR_FOREIGN);
8237         Assert(con->old_conpfeqop == NIL);      /* already prepared this node */
8238
8239         tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(oldId));
8240         if (!HeapTupleIsValid(tup)) /* should not happen */
8241                 elog(ERROR, "cache lookup failed for constraint %u", oldId);
8242
8243         adatum = SysCacheGetAttr(CONSTROID, tup,
8244                                                          Anum_pg_constraint_conpfeqop, &isNull);
8245         if (isNull)
8246                 elog(ERROR, "null conpfeqop for constraint %u", oldId);
8247         arr = DatumGetArrayTypeP(adatum);       /* ensure not toasted */
8248         numkeys = ARR_DIMS(arr)[0];
8249         /* test follows the one in ri_FetchConstraintInfo() */
8250         if (ARR_NDIM(arr) != 1 ||
8251                 ARR_HASNULL(arr) ||
8252                 ARR_ELEMTYPE(arr) != OIDOID)
8253                 elog(ERROR, "conpfeqop is not a 1-D Oid array");
8254         rawarr = (Oid *) ARR_DATA_PTR(arr);
8255
8256         /* stash a List of the operator Oids in our Constraint node */
8257         for (i = 0; i < numkeys; i++)
8258                 con->old_conpfeqop = lcons_oid(rawarr[i], con->old_conpfeqop);
8259
8260         ReleaseSysCache(tup);
8261 }
8262
8263 /*
8264  * ALTER TABLE OWNER
8265  *
8266  * recursing is true if we are recursing from a table to its indexes,
8267  * sequences, or toast table.  We don't allow the ownership of those things to
8268  * be changed separately from the parent table.  Also, we can skip permission
8269  * checks (this is necessary not just an optimization, else we'd fail to
8270  * handle toast tables properly).
8271  *
8272  * recursing is also true if ALTER TYPE OWNER is calling us to fix up a
8273  * free-standing composite type.
8274  */
8275 void
8276 ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lockmode)
8277 {
8278         Relation        target_rel;
8279         Relation        class_rel;
8280         HeapTuple       tuple;
8281         Form_pg_class tuple_class;
8282
8283         /*
8284          * Get exclusive lock till end of transaction on the target table. Use
8285          * relation_open so that we can work on indexes and sequences.
8286          */
8287         target_rel = relation_open(relationOid, lockmode);
8288
8289         /* Get its pg_class tuple, too */
8290         class_rel = heap_open(RelationRelationId, RowExclusiveLock);
8291
8292         tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relationOid));
8293         if (!HeapTupleIsValid(tuple))
8294                 elog(ERROR, "cache lookup failed for relation %u", relationOid);
8295         tuple_class = (Form_pg_class) GETSTRUCT(tuple);
8296
8297         /* Can we change the ownership of this tuple? */
8298         switch (tuple_class->relkind)
8299         {
8300                 case RELKIND_RELATION:
8301                 case RELKIND_VIEW:
8302                 case RELKIND_MATVIEW:
8303                 case RELKIND_FOREIGN_TABLE:
8304                         /* ok to change owner */
8305                         break;
8306                 case RELKIND_INDEX:
8307                         if (!recursing)
8308                         {
8309                                 /*
8310                                  * Because ALTER INDEX OWNER used to be allowed, and in fact
8311                                  * is generated by old versions of pg_dump, we give a warning
8312                                  * and do nothing rather than erroring out.  Also, to avoid
8313                                  * unnecessary chatter while restoring those old dumps, say
8314                                  * nothing at all if the command would be a no-op anyway.
8315                                  */
8316                                 if (tuple_class->relowner != newOwnerId)
8317                                         ereport(WARNING,
8318                                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8319                                                          errmsg("cannot change owner of index \"%s\"",
8320                                                                         NameStr(tuple_class->relname)),
8321                                                          errhint("Change the ownership of the index's table, instead.")));
8322                                 /* quick hack to exit via the no-op path */
8323                                 newOwnerId = tuple_class->relowner;
8324                         }
8325                         break;
8326                 case RELKIND_SEQUENCE:
8327                         if (!recursing &&
8328                                 tuple_class->relowner != newOwnerId)
8329                         {
8330                                 /* if it's an owned sequence, disallow changing it by itself */
8331                                 Oid                     tableId;
8332                                 int32           colId;
8333
8334                                 if (sequenceIsOwned(relationOid, &tableId, &colId))
8335                                         ereport(ERROR,
8336                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8337                                                          errmsg("cannot change owner of sequence \"%s\"",
8338                                                                         NameStr(tuple_class->relname)),
8339                                           errdetail("Sequence \"%s\" is linked to table \"%s\".",
8340                                                                 NameStr(tuple_class->relname),
8341                                                                 get_rel_name(tableId))));
8342                         }
8343                         break;
8344                 case RELKIND_COMPOSITE_TYPE:
8345                         if (recursing)
8346                                 break;
8347                         ereport(ERROR,
8348                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8349                                          errmsg("\"%s\" is a composite type",
8350                                                         NameStr(tuple_class->relname)),
8351                                          errhint("Use ALTER TYPE instead.")));
8352                         break;
8353                 case RELKIND_TOASTVALUE:
8354                         if (recursing)
8355                                 break;
8356                         /* FALL THRU */
8357                 default:
8358                         ereport(ERROR,
8359                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8360                         errmsg("\"%s\" is not a table, view, sequence, or foreign table",
8361                                    NameStr(tuple_class->relname))));
8362         }
8363
8364         /*
8365          * If the new owner is the same as the existing owner, consider the
8366          * command to have succeeded.  This is for dump restoration purposes.
8367          */
8368         if (tuple_class->relowner != newOwnerId)
8369         {
8370                 Datum           repl_val[Natts_pg_class];
8371                 bool            repl_null[Natts_pg_class];
8372                 bool            repl_repl[Natts_pg_class];
8373                 Acl                *newAcl;
8374                 Datum           aclDatum;
8375                 bool            isNull;
8376                 HeapTuple       newtuple;
8377
8378                 /* skip permission checks when recursing to index or toast table */
8379                 if (!recursing)
8380                 {
8381                         /* Superusers can always do it */
8382                         if (!superuser())
8383                         {
8384                                 Oid                     namespaceOid = tuple_class->relnamespace;
8385                                 AclResult       aclresult;
8386
8387                                 /* Otherwise, must be owner of the existing object */
8388                                 if (!pg_class_ownercheck(relationOid, GetUserId()))
8389                                         aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
8390                                                                    RelationGetRelationName(target_rel));
8391
8392                                 /* Must be able to become new owner */
8393                                 check_is_member_of_role(GetUserId(), newOwnerId);
8394
8395                                 /* New owner must have CREATE privilege on namespace */
8396                                 aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
8397                                                                                                   ACL_CREATE);
8398                                 if (aclresult != ACLCHECK_OK)
8399                                         aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
8400                                                                    get_namespace_name(namespaceOid));
8401                         }
8402                 }
8403
8404                 memset(repl_null, false, sizeof(repl_null));
8405                 memset(repl_repl, false, sizeof(repl_repl));
8406
8407                 repl_repl[Anum_pg_class_relowner - 1] = true;
8408                 repl_val[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(newOwnerId);
8409
8410                 /*
8411                  * Determine the modified ACL for the new owner.  This is only
8412                  * necessary when the ACL is non-null.
8413                  */
8414                 aclDatum = SysCacheGetAttr(RELOID, tuple,
8415                                                                    Anum_pg_class_relacl,
8416                                                                    &isNull);
8417                 if (!isNull)
8418                 {
8419                         newAcl = aclnewowner(DatumGetAclP(aclDatum),
8420                                                                  tuple_class->relowner, newOwnerId);
8421                         repl_repl[Anum_pg_class_relacl - 1] = true;
8422                         repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl);
8423                 }
8424
8425                 newtuple = heap_modify_tuple(tuple, RelationGetDescr(class_rel), repl_val, repl_null, repl_repl);
8426
8427                 simple_heap_update(class_rel, &newtuple->t_self, newtuple);
8428                 CatalogUpdateIndexes(class_rel, newtuple);
8429
8430                 heap_freetuple(newtuple);
8431
8432                 /*
8433                  * We must similarly update any per-column ACLs to reflect the new
8434                  * owner; for neatness reasons that's split out as a subroutine.
8435                  */
8436                 change_owner_fix_column_acls(relationOid,
8437                                                                          tuple_class->relowner,
8438                                                                          newOwnerId);
8439
8440                 /*
8441                  * Update owner dependency reference, if any.  A composite type has
8442                  * none, because it's tracked for the pg_type entry instead of here;
8443                  * indexes and TOAST tables don't have their own entries either.
8444                  */
8445                 if (tuple_class->relkind != RELKIND_COMPOSITE_TYPE &&
8446                         tuple_class->relkind != RELKIND_INDEX &&
8447                         tuple_class->relkind != RELKIND_TOASTVALUE)
8448                         changeDependencyOnOwner(RelationRelationId, relationOid,
8449                                                                         newOwnerId);
8450
8451                 /*
8452                  * Also change the ownership of the table's row type, if it has one
8453                  */
8454                 if (tuple_class->relkind != RELKIND_INDEX)
8455                         AlterTypeOwnerInternal(tuple_class->reltype, newOwnerId,
8456                                                          tuple_class->relkind == RELKIND_COMPOSITE_TYPE);
8457
8458                 /*
8459                  * If we are operating on a table or materialized view, also change
8460                  * the ownership of any indexes and sequences that belong to the
8461                  * relation, as well as its toast table (if it has one).
8462                  */
8463                 if (tuple_class->relkind == RELKIND_RELATION ||
8464                         tuple_class->relkind == RELKIND_MATVIEW ||
8465                         tuple_class->relkind == RELKIND_TOASTVALUE)
8466                 {
8467                         List       *index_oid_list;
8468                         ListCell   *i;
8469
8470                         /* Find all the indexes belonging to this relation */
8471                         index_oid_list = RelationGetIndexList(target_rel);
8472
8473                         /* For each index, recursively change its ownership */
8474                         foreach(i, index_oid_list)
8475                                 ATExecChangeOwner(lfirst_oid(i), newOwnerId, true, lockmode);
8476
8477                         list_free(index_oid_list);
8478                 }
8479
8480                 if (tuple_class->relkind == RELKIND_RELATION ||
8481                         tuple_class->relkind == RELKIND_MATVIEW)
8482                 {
8483                         /* If it has a toast table, recurse to change its ownership */
8484                         if (tuple_class->reltoastrelid != InvalidOid)
8485                                 ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId,
8486                                                                   true, lockmode);
8487
8488                         /* If it has dependent sequences, recurse to change them too */
8489                         change_owner_recurse_to_sequences(relationOid, newOwnerId, lockmode);
8490                 }
8491         }
8492
8493         InvokeObjectPostAlterHook(RelationRelationId, relationOid, 0);
8494
8495         ReleaseSysCache(tuple);
8496         heap_close(class_rel, RowExclusiveLock);
8497         relation_close(target_rel, NoLock);
8498 }
8499
8500 /*
8501  * change_owner_fix_column_acls
8502  *
8503  * Helper function for ATExecChangeOwner.  Scan the columns of the table
8504  * and fix any non-null column ACLs to reflect the new owner.
8505  */
8506 static void
8507 change_owner_fix_column_acls(Oid relationOid, Oid oldOwnerId, Oid newOwnerId)
8508 {
8509         Relation        attRelation;
8510         SysScanDesc scan;
8511         ScanKeyData key[1];
8512         HeapTuple       attributeTuple;
8513
8514         attRelation = heap_open(AttributeRelationId, RowExclusiveLock);
8515         ScanKeyInit(&key[0],
8516                                 Anum_pg_attribute_attrelid,
8517                                 BTEqualStrategyNumber, F_OIDEQ,
8518                                 ObjectIdGetDatum(relationOid));
8519         scan = systable_beginscan(attRelation, AttributeRelidNumIndexId,
8520                                                           true, SnapshotNow, 1, key);
8521         while (HeapTupleIsValid(attributeTuple = systable_getnext(scan)))
8522         {
8523                 Form_pg_attribute att = (Form_pg_attribute) GETSTRUCT(attributeTuple);
8524                 Datum           repl_val[Natts_pg_attribute];
8525                 bool            repl_null[Natts_pg_attribute];
8526                 bool            repl_repl[Natts_pg_attribute];
8527                 Acl                *newAcl;
8528                 Datum           aclDatum;
8529                 bool            isNull;
8530                 HeapTuple       newtuple;
8531
8532                 /* Ignore dropped columns */
8533                 if (att->attisdropped)
8534                         continue;
8535
8536                 aclDatum = heap_getattr(attributeTuple,
8537                                                                 Anum_pg_attribute_attacl,
8538                                                                 RelationGetDescr(attRelation),
8539                                                                 &isNull);
8540                 /* Null ACLs do not require changes */
8541                 if (isNull)
8542                         continue;
8543
8544                 memset(repl_null, false, sizeof(repl_null));
8545                 memset(repl_repl, false, sizeof(repl_repl));
8546
8547                 newAcl = aclnewowner(DatumGetAclP(aclDatum),
8548                                                          oldOwnerId, newOwnerId);
8549                 repl_repl[Anum_pg_attribute_attacl - 1] = true;
8550                 repl_val[Anum_pg_attribute_attacl - 1] = PointerGetDatum(newAcl);
8551
8552                 newtuple = heap_modify_tuple(attributeTuple,
8553                                                                          RelationGetDescr(attRelation),
8554                                                                          repl_val, repl_null, repl_repl);
8555
8556                 simple_heap_update(attRelation, &newtuple->t_self, newtuple);
8557                 CatalogUpdateIndexes(attRelation, newtuple);
8558
8559                 heap_freetuple(newtuple);
8560         }
8561         systable_endscan(scan);
8562         heap_close(attRelation, RowExclusiveLock);
8563 }
8564
8565 /*
8566  * change_owner_recurse_to_sequences
8567  *
8568  * Helper function for ATExecChangeOwner.  Examines pg_depend searching
8569  * for sequences that are dependent on serial columns, and changes their
8570  * ownership.
8571  */
8572 static void
8573 change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId, LOCKMODE lockmode)
8574 {
8575         Relation        depRel;
8576         SysScanDesc scan;
8577         ScanKeyData key[2];
8578         HeapTuple       tup;
8579
8580         /*
8581          * SERIAL sequences are those having an auto dependency on one of the
8582          * table's columns (we don't care *which* column, exactly).
8583          */
8584         depRel = heap_open(DependRelationId, AccessShareLock);
8585
8586         ScanKeyInit(&key[0],
8587                                 Anum_pg_depend_refclassid,
8588                                 BTEqualStrategyNumber, F_OIDEQ,
8589                                 ObjectIdGetDatum(RelationRelationId));
8590         ScanKeyInit(&key[1],
8591                                 Anum_pg_depend_refobjid,
8592                                 BTEqualStrategyNumber, F_OIDEQ,
8593                                 ObjectIdGetDatum(relationOid));
8594         /* we leave refobjsubid unspecified */
8595
8596         scan = systable_beginscan(depRel, DependReferenceIndexId, true,
8597                                                           SnapshotNow, 2, key);
8598
8599         while (HeapTupleIsValid(tup = systable_getnext(scan)))
8600         {
8601                 Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
8602                 Relation        seqRel;
8603
8604                 /* skip dependencies other than auto dependencies on columns */
8605                 if (depForm->refobjsubid == 0 ||
8606                         depForm->classid != RelationRelationId ||
8607                         depForm->objsubid != 0 ||
8608                         depForm->deptype != DEPENDENCY_AUTO)
8609                         continue;
8610
8611                 /* Use relation_open just in case it's an index */
8612                 seqRel = relation_open(depForm->objid, lockmode);
8613
8614                 /* skip non-sequence relations */
8615                 if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
8616                 {
8617                         /* No need to keep the lock */
8618                         relation_close(seqRel, lockmode);
8619                         continue;
8620                 }
8621
8622                 /* We don't need to close the sequence while we alter it. */
8623                 ATExecChangeOwner(depForm->objid, newOwnerId, true, lockmode);
8624
8625                 /* Now we can close it.  Keep the lock till end of transaction. */
8626                 relation_close(seqRel, NoLock);
8627         }
8628
8629         systable_endscan(scan);
8630
8631         relation_close(depRel, AccessShareLock);
8632 }
8633
8634 /*
8635  * ALTER TABLE CLUSTER ON
8636  *
8637  * The only thing we have to do is to change the indisclustered bits.
8638  */
8639 static void
8640 ATExecClusterOn(Relation rel, const char *indexName, LOCKMODE lockmode)
8641 {
8642         Oid                     indexOid;
8643
8644         indexOid = get_relname_relid(indexName, rel->rd_rel->relnamespace);
8645
8646         if (!OidIsValid(indexOid))
8647                 ereport(ERROR,
8648                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
8649                                  errmsg("index \"%s\" for table \"%s\" does not exist",
8650                                                 indexName, RelationGetRelationName(rel))));
8651
8652         /* Check index is valid to cluster on */
8653         check_index_is_clusterable(rel, indexOid, false, lockmode);
8654
8655         /* And do the work */
8656         mark_index_clustered(rel, indexOid, false);
8657 }
8658
8659 /*
8660  * ALTER TABLE SET WITHOUT CLUSTER
8661  *
8662  * We have to find any indexes on the table that have indisclustered bit
8663  * set and turn it off.
8664  */
8665 static void
8666 ATExecDropCluster(Relation rel, LOCKMODE lockmode)
8667 {
8668         mark_index_clustered(rel, InvalidOid, false);
8669 }
8670
8671 /*
8672  * ALTER TABLE SET TABLESPACE
8673  */
8674 static void
8675 ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename, LOCKMODE lockmode)
8676 {
8677         Oid                     tablespaceId;
8678         AclResult       aclresult;
8679
8680         /* Check that the tablespace exists */
8681         tablespaceId = get_tablespace_oid(tablespacename, false);
8682
8683         /* Check its permissions */
8684         aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(), ACL_CREATE);
8685         if (aclresult != ACLCHECK_OK)
8686                 aclcheck_error(aclresult, ACL_KIND_TABLESPACE, tablespacename);
8687
8688         /* Save info for Phase 3 to do the real work */
8689         if (OidIsValid(tab->newTableSpace))
8690                 ereport(ERROR,
8691                                 (errcode(ERRCODE_SYNTAX_ERROR),
8692                                  errmsg("cannot have multiple SET TABLESPACE subcommands")));
8693         tab->newTableSpace = tablespaceId;
8694 }
8695
8696 /*
8697  * Set, reset, or replace reloptions.
8698  */
8699 static void
8700 ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
8701                                         LOCKMODE lockmode)
8702 {
8703         Oid                     relid;
8704         Relation        pgclass;
8705         HeapTuple       tuple;
8706         HeapTuple       newtuple;
8707         Datum           datum;
8708         bool            isnull;
8709         Datum           newOptions;
8710         Datum           repl_val[Natts_pg_class];
8711         bool            repl_null[Natts_pg_class];
8712         bool            repl_repl[Natts_pg_class];
8713         static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
8714
8715         if (defList == NIL && operation != AT_ReplaceRelOptions)
8716                 return;                                 /* nothing to do */
8717
8718         pgclass = heap_open(RelationRelationId, RowExclusiveLock);
8719
8720         /* Fetch heap tuple */
8721         relid = RelationGetRelid(rel);
8722         tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
8723         if (!HeapTupleIsValid(tuple))
8724                 elog(ERROR, "cache lookup failed for relation %u", relid);
8725
8726         if (operation == AT_ReplaceRelOptions)
8727         {
8728                 /*
8729                  * If we're supposed to replace the reloptions list, we just pretend
8730                  * there were none before.
8731                  */
8732                 datum = (Datum) 0;
8733                 isnull = true;
8734         }
8735         else
8736         {
8737                 /* Get the old reloptions */
8738                 datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,
8739                                                                 &isnull);
8740         }
8741
8742         /* Generate new proposed reloptions (text array) */
8743         newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
8744                                                                          defList, NULL, validnsps, false,
8745                                                                          operation == AT_ResetRelOptions);
8746
8747         /* Validate */
8748         switch (rel->rd_rel->relkind)
8749         {
8750                 case RELKIND_RELATION:
8751                 case RELKIND_TOASTVALUE:
8752                 case RELKIND_VIEW:
8753                 case RELKIND_MATVIEW:
8754                         (void) heap_reloptions(rel->rd_rel->relkind, newOptions, true);
8755                         break;
8756                 case RELKIND_INDEX:
8757                         (void) index_reloptions(rel->rd_am->amoptions, newOptions, true);
8758                         break;
8759                 default:
8760                         ereport(ERROR,
8761                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
8762                                          errmsg("\"%s\" is not a table, view, materialized view, index, or TOAST table",
8763                                                         RelationGetRelationName(rel))));
8764                         break;
8765         }
8766
8767         /*
8768          * All we need do here is update the pg_class row; the new options will be
8769          * propagated into relcaches during post-commit cache inval.
8770          */
8771         memset(repl_val, 0, sizeof(repl_val));
8772         memset(repl_null, false, sizeof(repl_null));
8773         memset(repl_repl, false, sizeof(repl_repl));
8774
8775         if (newOptions != (Datum) 0)
8776                 repl_val[Anum_pg_class_reloptions - 1] = newOptions;
8777         else
8778                 repl_null[Anum_pg_class_reloptions - 1] = true;
8779
8780         repl_repl[Anum_pg_class_reloptions - 1] = true;
8781
8782         newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass),
8783                                                                  repl_val, repl_null, repl_repl);
8784
8785         simple_heap_update(pgclass, &newtuple->t_self, newtuple);
8786
8787         CatalogUpdateIndexes(pgclass, newtuple);
8788
8789         InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), 0);
8790
8791         heap_freetuple(newtuple);
8792
8793         ReleaseSysCache(tuple);
8794
8795         /* repeat the whole exercise for the toast table, if there's one */
8796         if (OidIsValid(rel->rd_rel->reltoastrelid))
8797         {
8798                 Relation        toastrel;
8799                 Oid                     toastid = rel->rd_rel->reltoastrelid;
8800
8801                 toastrel = heap_open(toastid, lockmode);
8802
8803                 /* Fetch heap tuple */
8804                 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid));
8805                 if (!HeapTupleIsValid(tuple))
8806                         elog(ERROR, "cache lookup failed for relation %u", toastid);
8807
8808                 if (operation == AT_ReplaceRelOptions)
8809                 {
8810                         /*
8811                          * If we're supposed to replace the reloptions list, we just
8812                          * pretend there were none before.
8813                          */
8814                         datum = (Datum) 0;
8815                         isnull = true;
8816                 }
8817                 else
8818                 {
8819                         /* Get the old reloptions */
8820                         datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,
8821                                                                         &isnull);
8822                 }
8823
8824                 newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
8825                                                                                  defList, "toast", validnsps, false,
8826                                                                                  operation == AT_ResetRelOptions);
8827
8828                 (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true);
8829
8830                 memset(repl_val, 0, sizeof(repl_val));
8831                 memset(repl_null, false, sizeof(repl_null));
8832                 memset(repl_repl, false, sizeof(repl_repl));
8833
8834                 if (newOptions != (Datum) 0)
8835                         repl_val[Anum_pg_class_reloptions - 1] = newOptions;
8836                 else
8837                         repl_null[Anum_pg_class_reloptions - 1] = true;
8838
8839                 repl_repl[Anum_pg_class_reloptions - 1] = true;
8840
8841                 newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass),
8842                                                                          repl_val, repl_null, repl_repl);
8843
8844                 simple_heap_update(pgclass, &newtuple->t_self, newtuple);
8845
8846                 CatalogUpdateIndexes(pgclass, newtuple);
8847
8848                 InvokeObjectPostAlterHookArg(RelationRelationId,
8849                                                                          RelationGetRelid(toastrel), 0,
8850                                                                          InvalidOid, true);
8851
8852                 heap_freetuple(newtuple);
8853
8854                 ReleaseSysCache(tuple);
8855
8856                 heap_close(toastrel, NoLock);
8857         }
8858
8859         heap_close(pgclass, RowExclusiveLock);
8860 }
8861
8862 /*
8863  * Execute ALTER TABLE SET TABLESPACE for cases where there is no tuple
8864  * rewriting to be done, so we just want to copy the data as fast as possible.
8865  */
8866 static void
8867 ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
8868 {
8869         Relation        rel;
8870         Oid                     oldTableSpace;
8871         Oid                     reltoastrelid;
8872         Oid                     reltoastidxid;
8873         Oid                     newrelfilenode;
8874         RelFileNode newrnode;
8875         SMgrRelation dstrel;
8876         Relation        pg_class;
8877         HeapTuple       tuple;
8878         Form_pg_class rd_rel;
8879         ForkNumber      forkNum;
8880
8881         /*
8882          * Need lock here in case we are recursing to toast table or index
8883          */
8884         rel = relation_open(tableOid, lockmode);
8885
8886         /*
8887          * No work if no change in tablespace.
8888          */
8889         oldTableSpace = rel->rd_rel->reltablespace;
8890         if (newTableSpace == oldTableSpace ||
8891                 (newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0))
8892         {
8893                 InvokeObjectPostAlterHook(RelationRelationId,
8894                                                                   RelationGetRelid(rel), 0);
8895
8896                 relation_close(rel, NoLock);
8897                 return;
8898         }
8899
8900         /*
8901          * We cannot support moving mapped relations into different tablespaces.
8902          * (In particular this eliminates all shared catalogs.)
8903          */
8904         if (RelationIsMapped(rel))
8905                 ereport(ERROR,
8906                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8907                                  errmsg("cannot move system relation \"%s\"",
8908                                                 RelationGetRelationName(rel))));
8909
8910         /* Can't move a non-shared relation into pg_global */
8911         if (newTableSpace == GLOBALTABLESPACE_OID)
8912                 ereport(ERROR,
8913                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8914                                  errmsg("only shared relations can be placed in pg_global tablespace")));
8915
8916         /*
8917          * Don't allow moving temp tables of other backends ... their local buffer
8918          * manager is not going to cope.
8919          */
8920         if (RELATION_IS_OTHER_TEMP(rel))
8921                 ereport(ERROR,
8922                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8923                                  errmsg("cannot move temporary tables of other sessions")));
8924
8925         reltoastrelid = rel->rd_rel->reltoastrelid;
8926         reltoastidxid = rel->rd_rel->reltoastidxid;
8927
8928         /* Get a modifiable copy of the relation's pg_class row */
8929         pg_class = heap_open(RelationRelationId, RowExclusiveLock);
8930
8931         tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(tableOid));
8932         if (!HeapTupleIsValid(tuple))
8933                 elog(ERROR, "cache lookup failed for relation %u", tableOid);
8934         rd_rel = (Form_pg_class) GETSTRUCT(tuple);
8935
8936         /*
8937          * Since we copy the file directly without looking at the shared buffers,
8938          * we'd better first flush out any pages of the source relation that are
8939          * in shared buffers.  We assume no new changes will be made while we are
8940          * holding exclusive lock on the rel.
8941          */
8942         FlushRelationBuffers(rel);
8943
8944         /*
8945          * Relfilenodes are not unique across tablespaces, so we need to allocate
8946          * a new one in the new tablespace.
8947          */
8948         newrelfilenode = GetNewRelFileNode(newTableSpace, NULL,
8949                                                                            rel->rd_rel->relpersistence);
8950
8951         /* Open old and new relation */
8952         newrnode = rel->rd_node;
8953         newrnode.relNode = newrelfilenode;
8954         newrnode.spcNode = newTableSpace;
8955         dstrel = smgropen(newrnode, rel->rd_backend);
8956
8957         RelationOpenSmgr(rel);
8958
8959         /*
8960          * Create and copy all forks of the relation, and schedule unlinking of
8961          * old physical files.
8962          *
8963          * NOTE: any conflict in relfilenode value will be caught in
8964          * RelationCreateStorage().
8965          */
8966         RelationCreateStorage(newrnode, rel->rd_rel->relpersistence);
8967
8968         /* copy main fork */
8969         copy_relation_data(rel->rd_smgr, dstrel, MAIN_FORKNUM,
8970                                            rel->rd_rel->relpersistence);
8971
8972         /* copy those extra forks that exist */
8973         for (forkNum = MAIN_FORKNUM + 1; forkNum <= MAX_FORKNUM; forkNum++)
8974         {
8975                 if (smgrexists(rel->rd_smgr, forkNum))
8976                 {
8977                         smgrcreate(dstrel, forkNum, false);
8978                         copy_relation_data(rel->rd_smgr, dstrel, forkNum,
8979                                                            rel->rd_rel->relpersistence);
8980                 }
8981         }
8982
8983         /* drop old relation, and close new one */
8984         RelationDropStorage(rel);
8985         smgrclose(dstrel);
8986
8987         /* update the pg_class row */
8988         rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace;
8989         rd_rel->relfilenode = newrelfilenode;
8990         simple_heap_update(pg_class, &tuple->t_self, tuple);
8991         CatalogUpdateIndexes(pg_class, tuple);
8992
8993         InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), 0);
8994
8995         heap_freetuple(tuple);
8996
8997         heap_close(pg_class, RowExclusiveLock);
8998
8999         relation_close(rel, NoLock);
9000
9001         /* Make sure the reltablespace change is visible */
9002         CommandCounterIncrement();
9003
9004         /* Move associated toast relation and/or index, too */
9005         if (OidIsValid(reltoastrelid))
9006                 ATExecSetTableSpace(reltoastrelid, newTableSpace, lockmode);
9007         if (OidIsValid(reltoastidxid))
9008                 ATExecSetTableSpace(reltoastidxid, newTableSpace, lockmode);
9009 }
9010
9011 /*
9012  * Copy data, block by block
9013  */
9014 static void
9015 copy_relation_data(SMgrRelation src, SMgrRelation dst,
9016                                    ForkNumber forkNum, char relpersistence)
9017 {
9018         char       *buf;
9019         Page            page;
9020         bool            use_wal;
9021         BlockNumber nblocks;
9022         BlockNumber blkno;
9023
9024         /*
9025          * palloc the buffer so that it's MAXALIGN'd.  If it were just a local
9026          * char[] array, the compiler might align it on any byte boundary, which
9027          * can seriously hurt transfer speed to and from the kernel; not to
9028          * mention possibly making log_newpage's accesses to the page header fail.
9029          */
9030         buf = (char *) palloc(BLCKSZ);
9031         page = (Page) buf;
9032
9033         /*
9034          * We need to log the copied data in WAL iff WAL archiving/streaming is
9035          * enabled AND it's a permanent relation.
9036          */
9037         use_wal = XLogIsNeeded() && relpersistence == RELPERSISTENCE_PERMANENT;
9038
9039         nblocks = smgrnblocks(src, forkNum);
9040
9041         for (blkno = 0; blkno < nblocks; blkno++)
9042         {
9043                 /* If we got a cancel signal during the copy of the data, quit */
9044                 CHECK_FOR_INTERRUPTS();
9045
9046                 smgrread(src, forkNum, blkno, buf);
9047
9048                 if (!PageIsVerified(page, blkno))
9049                         ereport(ERROR,
9050                                         (errcode(ERRCODE_DATA_CORRUPTED),
9051                                          errmsg("invalid page in block %u of relation %s",
9052                                                         blkno,
9053                                                         relpathbackend(src->smgr_rnode.node,
9054                                                                                    src->smgr_rnode.backend,
9055                                                                                    forkNum))));
9056
9057                 /* XLOG stuff */
9058                 if (use_wal)
9059                         log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page);
9060
9061                 PageSetChecksumInplace(page, blkno);
9062
9063                 /*
9064                  * Now write the page.  We say isTemp = true even if it's not a temp
9065                  * rel, because there's no need for smgr to schedule an fsync for this
9066                  * write; we'll do it ourselves below.
9067                  */
9068                 smgrextend(dst, forkNum, blkno, buf, true);
9069         }
9070
9071         pfree(buf);
9072
9073         /*
9074          * If the rel is WAL-logged, must fsync before commit.  We use heap_sync
9075          * to ensure that the toast table gets fsync'd too.  (For a temp or
9076          * unlogged rel we don't care since the data will be gone after a crash
9077          * anyway.)
9078          *
9079          * It's obvious that we must do this when not WAL-logging the copy. It's
9080          * less obvious that we have to do it even if we did WAL-log the copied
9081          * pages. The reason is that since we're copying outside shared buffers, a
9082          * CHECKPOINT occurring during the copy has no way to flush the previously
9083          * written data to disk (indeed it won't know the new rel even exists).  A
9084          * crash later on would replay WAL from the checkpoint, therefore it
9085          * wouldn't replay our earlier WAL entries. If we do not fsync those pages
9086          * here, they might still not be on disk when the crash occurs.
9087          */
9088         if (relpersistence == RELPERSISTENCE_PERMANENT)
9089                 smgrimmedsync(dst, forkNum);
9090 }
9091
9092 /*
9093  * ALTER TABLE ENABLE/DISABLE TRIGGER
9094  *
9095  * We just pass this off to trigger.c.
9096  */
9097 static void
9098 ATExecEnableDisableTrigger(Relation rel, char *trigname,
9099                                                 char fires_when, bool skip_system, LOCKMODE lockmode)
9100 {
9101         EnableDisableTrigger(rel, trigname, fires_when, skip_system);
9102 }
9103
9104 /*
9105  * ALTER TABLE ENABLE/DISABLE RULE
9106  *
9107  * We just pass this off to rewriteDefine.c.
9108  */
9109 static void
9110 ATExecEnableDisableRule(Relation rel, char *trigname,
9111                                                 char fires_when, LOCKMODE lockmode)
9112 {
9113         EnableDisableRule(rel, trigname, fires_when);
9114 }
9115
9116 /*
9117  * ALTER TABLE INHERIT
9118  *
9119  * Add a parent to the child's parents. This verifies that all the columns and
9120  * check constraints of the parent appear in the child and that they have the
9121  * same data types and expressions.
9122  */
9123 static void
9124 ATPrepAddInherit(Relation child_rel)
9125 {
9126         if (child_rel->rd_rel->reloftype)
9127                 ereport(ERROR,
9128                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
9129                                  errmsg("cannot change inheritance of typed table")));
9130 }
9131
9132 static void
9133 ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode)
9134 {
9135         Relation        parent_rel,
9136                                 catalogRelation;
9137         SysScanDesc scan;
9138         ScanKeyData key;
9139         HeapTuple       inheritsTuple;
9140         int32           inhseqno;
9141         List       *children;
9142
9143         /*
9144          * A self-exclusive lock is needed here.  See the similar case in
9145          * MergeAttributes() for a full explanation.
9146          */
9147         parent_rel = heap_openrv(parent, ShareUpdateExclusiveLock);
9148
9149         /*
9150          * Must be owner of both parent and child -- child was checked by
9151          * ATSimplePermissions call in ATPrepCmd
9152          */
9153         ATSimplePermissions(parent_rel, ATT_TABLE);
9154
9155         /* Permanent rels cannot inherit from temporary ones */
9156         if (parent_rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP &&
9157                 child_rel->rd_rel->relpersistence != RELPERSISTENCE_TEMP)
9158                 ereport(ERROR,
9159                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
9160                                  errmsg("cannot inherit from temporary relation \"%s\"",
9161                                                 RelationGetRelationName(parent_rel))));
9162
9163         /* If parent rel is temp, it must belong to this session */
9164         if (parent_rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP &&
9165                 !parent_rel->rd_islocaltemp)
9166                 ereport(ERROR,
9167                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
9168                 errmsg("cannot inherit from temporary relation of another session")));
9169
9170         /* Ditto for the child */
9171         if (child_rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP &&
9172                 !child_rel->rd_islocaltemp)
9173                 ereport(ERROR,
9174                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
9175                  errmsg("cannot inherit to temporary relation of another session")));
9176
9177         /*
9178          * Check for duplicates in the list of parents, and determine the highest
9179          * inhseqno already present; we'll use the next one for the new parent.
9180          * (Note: get RowExclusiveLock because we will write pg_inherits below.)
9181          *
9182          * Note: we do not reject the case where the child already inherits from
9183          * the parent indirectly; CREATE TABLE doesn't reject comparable cases.
9184          */
9185         catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
9186         ScanKeyInit(&key,
9187                                 Anum_pg_inherits_inhrelid,
9188                                 BTEqualStrategyNumber, F_OIDEQ,
9189                                 ObjectIdGetDatum(RelationGetRelid(child_rel)));
9190         scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId,
9191                                                           true, SnapshotNow, 1, &key);
9192
9193         /* inhseqno sequences start at 1 */
9194         inhseqno = 0;
9195         while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan)))
9196         {
9197                 Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inheritsTuple);
9198
9199                 if (inh->inhparent == RelationGetRelid(parent_rel))
9200                         ereport(ERROR,
9201                                         (errcode(ERRCODE_DUPLICATE_TABLE),
9202                          errmsg("relation \"%s\" would be inherited from more than once",
9203                                         RelationGetRelationName(parent_rel))));
9204                 if (inh->inhseqno > inhseqno)
9205                         inhseqno = inh->inhseqno;
9206         }
9207         systable_endscan(scan);
9208
9209         /*
9210          * Prevent circularity by seeing if proposed parent inherits from child.
9211          * (In particular, this disallows making a rel inherit from itself.)
9212          *
9213          * This is not completely bulletproof because of race conditions: in
9214          * multi-level inheritance trees, someone else could concurrently be
9215          * making another inheritance link that closes the loop but does not join
9216          * either of the rels we have locked.  Preventing that seems to require
9217          * exclusive locks on the entire inheritance tree, which is a cure worse
9218          * than the disease.  find_all_inheritors() will cope with circularity
9219          * anyway, so don't sweat it too much.
9220          *
9221          * We use weakest lock we can on child's children, namely AccessShareLock.
9222          */
9223         children = find_all_inheritors(RelationGetRelid(child_rel),
9224                                                                    AccessShareLock, NULL);
9225
9226         if (list_member_oid(children, RelationGetRelid(parent_rel)))
9227                 ereport(ERROR,
9228                                 (errcode(ERRCODE_DUPLICATE_TABLE),
9229                                  errmsg("circular inheritance not allowed"),
9230                                  errdetail("\"%s\" is already a child of \"%s\".",
9231                                                    parent->relname,
9232                                                    RelationGetRelationName(child_rel))));
9233
9234         /* If parent has OIDs then child must have OIDs */
9235         if (parent_rel->rd_rel->relhasoids && !child_rel->rd_rel->relhasoids)
9236                 ereport(ERROR,
9237                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
9238                                  errmsg("table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs",
9239                                                 RelationGetRelationName(child_rel),
9240                                                 RelationGetRelationName(parent_rel))));
9241
9242         /* Match up the columns and bump attinhcount as needed */
9243         MergeAttributesIntoExisting(child_rel, parent_rel);
9244
9245         /* Match up the constraints and bump coninhcount as needed */
9246         MergeConstraintsIntoExisting(child_rel, parent_rel);
9247
9248         /*
9249          * OK, it looks valid.  Make the catalog entries that show inheritance.
9250          */
9251         StoreCatalogInheritance1(RelationGetRelid(child_rel),
9252                                                          RelationGetRelid(parent_rel),
9253                                                          inhseqno + 1,
9254                                                          catalogRelation);
9255
9256         /* Now we're done with pg_inherits */
9257         heap_close(catalogRelation, RowExclusiveLock);
9258
9259         /* keep our lock on the parent relation until commit */
9260         heap_close(parent_rel, NoLock);
9261 }
9262
9263 /*
9264  * Obtain the source-text form of the constraint expression for a check
9265  * constraint, given its pg_constraint tuple
9266  */
9267 static char *
9268 decompile_conbin(HeapTuple contup, TupleDesc tupdesc)
9269 {
9270         Form_pg_constraint con;
9271         bool            isnull;
9272         Datum           attr;
9273         Datum           expr;
9274
9275         con = (Form_pg_constraint) GETSTRUCT(contup);
9276         attr = heap_getattr(contup, Anum_pg_constraint_conbin, tupdesc, &isnull);
9277         if (isnull)
9278                 elog(ERROR, "null conbin for constraint %u", HeapTupleGetOid(contup));
9279
9280         expr = DirectFunctionCall2(pg_get_expr, attr,
9281                                                            ObjectIdGetDatum(con->conrelid));
9282         return TextDatumGetCString(expr);
9283 }
9284
9285 /*
9286  * Determine whether two check constraints are functionally equivalent
9287  *
9288  * The test we apply is to see whether they reverse-compile to the same
9289  * source string.  This insulates us from issues like whether attributes
9290  * have the same physical column numbers in parent and child relations.
9291  */
9292 static bool
9293 constraints_equivalent(HeapTuple a, HeapTuple b, TupleDesc tupleDesc)
9294 {
9295         Form_pg_constraint acon = (Form_pg_constraint) GETSTRUCT(a);
9296         Form_pg_constraint bcon = (Form_pg_constraint) GETSTRUCT(b);
9297
9298         if (acon->condeferrable != bcon->condeferrable ||
9299                 acon->condeferred != bcon->condeferred ||
9300                 strcmp(decompile_conbin(a, tupleDesc),
9301                            decompile_conbin(b, tupleDesc)) != 0)
9302                 return false;
9303         else
9304                 return true;
9305 }
9306
9307 /*
9308  * Check columns in child table match up with columns in parent, and increment
9309  * their attinhcount.
9310  *
9311  * Called by ATExecAddInherit
9312  *
9313  * Currently all parent columns must be found in child. Missing columns are an
9314  * error.  One day we might consider creating new columns like CREATE TABLE
9315  * does.  However, that is widely unpopular --- in the common use case of
9316  * partitioned tables it's a foot-gun.
9317  *
9318  * The data type must match exactly. If the parent column is NOT NULL then
9319  * the child must be as well. Defaults are not compared, however.
9320  */
9321 static void
9322 MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel)
9323 {
9324         Relation        attrrel;
9325         AttrNumber      parent_attno;
9326         int                     parent_natts;
9327         TupleDesc       tupleDesc;
9328         HeapTuple       tuple;
9329
9330         attrrel = heap_open(AttributeRelationId, RowExclusiveLock);
9331
9332         tupleDesc = RelationGetDescr(parent_rel);
9333         parent_natts = tupleDesc->natts;
9334
9335         for (parent_attno = 1; parent_attno <= parent_natts; parent_attno++)
9336         {
9337                 Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
9338                 char       *attributeName = NameStr(attribute->attname);
9339
9340                 /* Ignore dropped columns in the parent. */
9341                 if (attribute->attisdropped)
9342                         continue;
9343
9344                 /* Find same column in child (matching on column name). */
9345                 tuple = SearchSysCacheCopyAttName(RelationGetRelid(child_rel),
9346                                                                                   attributeName);
9347                 if (HeapTupleIsValid(tuple))
9348                 {
9349                         /* Check they are same type, typmod, and collation */
9350                         Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
9351
9352                         if (attribute->atttypid != childatt->atttypid ||
9353                                 attribute->atttypmod != childatt->atttypmod)
9354                                 ereport(ERROR,
9355                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
9356                                                  errmsg("child table \"%s\" has different type for column \"%s\"",
9357                                                                 RelationGetRelationName(child_rel),
9358                                                                 attributeName)));
9359
9360                         if (attribute->attcollation != childatt->attcollation)
9361                                 ereport(ERROR,
9362                                                 (errcode(ERRCODE_COLLATION_MISMATCH),
9363                                                  errmsg("child table \"%s\" has different collation for column \"%s\"",
9364                                                                 RelationGetRelationName(child_rel),
9365                                                                 attributeName)));
9366
9367                         /*
9368                          * Check child doesn't discard NOT NULL property.  (Other
9369                          * constraints are checked elsewhere.)
9370                          */
9371                         if (attribute->attnotnull && !childatt->attnotnull)
9372                                 ereport(ERROR,
9373                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
9374                                 errmsg("column \"%s\" in child table must be marked NOT NULL",
9375                                            attributeName)));
9376
9377                         /*
9378                          * OK, bump the child column's inheritance count.  (If we fail
9379                          * later on, this change will just roll back.)
9380                          */
9381                         childatt->attinhcount++;
9382                         simple_heap_update(attrrel, &tuple->t_self, tuple);
9383                         CatalogUpdateIndexes(attrrel, tuple);
9384                         heap_freetuple(tuple);
9385                 }
9386                 else
9387                 {
9388                         ereport(ERROR,
9389                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
9390                                          errmsg("child table is missing column \"%s\"",
9391                                                         attributeName)));
9392                 }
9393         }
9394
9395         heap_close(attrrel, RowExclusiveLock);
9396 }
9397
9398 /*
9399  * Check constraints in child table match up with constraints in parent,
9400  * and increment their coninhcount.
9401  *
9402  * Constraints that are marked ONLY in the parent are ignored.
9403  *
9404  * Called by ATExecAddInherit
9405  *
9406  * Currently all constraints in parent must be present in the child. One day we
9407  * may consider adding new constraints like CREATE TABLE does.
9408  *
9409  * XXX This is O(N^2) which may be an issue with tables with hundreds of
9410  * constraints. As long as tables have more like 10 constraints it shouldn't be
9411  * a problem though. Even 100 constraints ought not be the end of the world.
9412  *
9413  * XXX See MergeWithExistingConstraint too if you change this code.
9414  */
9415 static void
9416 MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
9417 {
9418         Relation        catalog_relation;
9419         TupleDesc       tuple_desc;
9420         SysScanDesc parent_scan;
9421         ScanKeyData parent_key;
9422         HeapTuple       parent_tuple;
9423
9424         catalog_relation = heap_open(ConstraintRelationId, RowExclusiveLock);
9425         tuple_desc = RelationGetDescr(catalog_relation);
9426
9427         /* Outer loop scans through the parent's constraint definitions */
9428         ScanKeyInit(&parent_key,
9429                                 Anum_pg_constraint_conrelid,
9430                                 BTEqualStrategyNumber, F_OIDEQ,
9431                                 ObjectIdGetDatum(RelationGetRelid(parent_rel)));
9432         parent_scan = systable_beginscan(catalog_relation, ConstraintRelidIndexId,
9433                                                                          true, SnapshotNow, 1, &parent_key);
9434
9435         while (HeapTupleIsValid(parent_tuple = systable_getnext(parent_scan)))
9436         {
9437                 Form_pg_constraint parent_con = (Form_pg_constraint) GETSTRUCT(parent_tuple);
9438                 SysScanDesc child_scan;
9439                 ScanKeyData child_key;
9440                 HeapTuple       child_tuple;
9441                 bool            found = false;
9442
9443                 if (parent_con->contype != CONSTRAINT_CHECK)
9444                         continue;
9445
9446                 /* if the parent's constraint is marked NO INHERIT, it's not inherited */
9447                 if (parent_con->connoinherit)
9448                         continue;
9449
9450                 /* Search for a child constraint matching this one */
9451                 ScanKeyInit(&child_key,
9452                                         Anum_pg_constraint_conrelid,
9453                                         BTEqualStrategyNumber, F_OIDEQ,
9454                                         ObjectIdGetDatum(RelationGetRelid(child_rel)));
9455                 child_scan = systable_beginscan(catalog_relation, ConstraintRelidIndexId,
9456                                                                                 true, SnapshotNow, 1, &child_key);
9457
9458                 while (HeapTupleIsValid(child_tuple = systable_getnext(child_scan)))
9459                 {
9460                         Form_pg_constraint child_con = (Form_pg_constraint) GETSTRUCT(child_tuple);
9461                         HeapTuple       child_copy;
9462
9463                         if (child_con->contype != CONSTRAINT_CHECK)
9464                                 continue;
9465
9466                         if (strcmp(NameStr(parent_con->conname),
9467                                            NameStr(child_con->conname)) != 0)
9468                                 continue;
9469
9470                         if (!constraints_equivalent(parent_tuple, child_tuple, tuple_desc))
9471                                 ereport(ERROR,
9472                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
9473                                                  errmsg("child table \"%s\" has different definition for check constraint \"%s\"",
9474                                                                 RelationGetRelationName(child_rel),
9475                                                                 NameStr(parent_con->conname))));
9476
9477                         /* If the constraint is "no inherit" then cannot merge */
9478                         if (child_con->connoinherit)
9479                                 ereport(ERROR,
9480                                                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
9481                                                  errmsg("constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"",
9482                                                                 NameStr(child_con->conname),
9483                                                                 RelationGetRelationName(child_rel))));
9484
9485                         /*
9486                          * OK, bump the child constraint's inheritance count.  (If we fail
9487                          * later on, this change will just roll back.)
9488                          */
9489                         child_copy = heap_copytuple(child_tuple);
9490                         child_con = (Form_pg_constraint) GETSTRUCT(child_copy);
9491                         child_con->coninhcount++;
9492                         simple_heap_update(catalog_relation, &child_copy->t_self, child_copy);
9493                         CatalogUpdateIndexes(catalog_relation, child_copy);
9494                         heap_freetuple(child_copy);
9495
9496                         found = true;
9497                         break;
9498                 }
9499
9500                 systable_endscan(child_scan);
9501
9502                 if (!found)
9503                         ereport(ERROR,
9504                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
9505                                          errmsg("child table is missing constraint \"%s\"",
9506                                                         NameStr(parent_con->conname))));
9507         }
9508
9509         systable_endscan(parent_scan);
9510         heap_close(catalog_relation, RowExclusiveLock);
9511 }
9512
9513 /*
9514  * ALTER TABLE NO INHERIT
9515  *
9516  * Drop a parent from the child's parents. This just adjusts the attinhcount
9517  * and attislocal of the columns and removes the pg_inherit and pg_depend
9518  * entries.
9519  *
9520  * If attinhcount goes to 0 then attislocal gets set to true. If it goes back
9521  * up attislocal stays true, which means if a child is ever removed from a
9522  * parent then its columns will never be automatically dropped which may
9523  * surprise. But at least we'll never surprise by dropping columns someone
9524  * isn't expecting to be dropped which would actually mean data loss.
9525  *
9526  * coninhcount and conislocal for inherited constraints are adjusted in
9527  * exactly the same way.
9528  */
9529 static void
9530 ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode)
9531 {
9532         Relation        parent_rel;
9533         Relation        catalogRelation;
9534         SysScanDesc scan;
9535         ScanKeyData key[3];
9536         HeapTuple       inheritsTuple,
9537                                 attributeTuple,
9538                                 constraintTuple;
9539         List       *connames;
9540         bool            found = false;
9541
9542         /*
9543          * AccessShareLock on the parent is probably enough, seeing that DROP
9544          * TABLE doesn't lock parent tables at all.  We need some lock since we'll
9545          * be inspecting the parent's schema.
9546          */
9547         parent_rel = heap_openrv(parent, AccessShareLock);
9548
9549         /*
9550          * We don't bother to check ownership of the parent table --- ownership of
9551          * the child is presumed enough rights.
9552          */
9553
9554         /*
9555          * Find and destroy the pg_inherits entry linking the two, or error out if
9556          * there is none.
9557          */
9558         catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);
9559         ScanKeyInit(&key[0],
9560                                 Anum_pg_inherits_inhrelid,
9561                                 BTEqualStrategyNumber, F_OIDEQ,
9562                                 ObjectIdGetDatum(RelationGetRelid(rel)));
9563         scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId,
9564                                                           true, SnapshotNow, 1, key);
9565
9566         while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan)))
9567         {
9568                 Oid                     inhparent;
9569
9570                 inhparent = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhparent;
9571                 if (inhparent == RelationGetRelid(parent_rel))
9572                 {
9573                         simple_heap_delete(catalogRelation, &inheritsTuple->t_self);
9574                         found = true;
9575                         break;
9576                 }
9577         }
9578
9579         systable_endscan(scan);
9580         heap_close(catalogRelation, RowExclusiveLock);
9581
9582         if (!found)
9583                 ereport(ERROR,
9584                                 (errcode(ERRCODE_UNDEFINED_TABLE),
9585                                  errmsg("relation \"%s\" is not a parent of relation \"%s\"",
9586                                                 RelationGetRelationName(parent_rel),
9587                                                 RelationGetRelationName(rel))));
9588
9589         /*
9590          * Search through child columns looking for ones matching parent rel
9591          */
9592         catalogRelation = heap_open(AttributeRelationId, RowExclusiveLock);
9593         ScanKeyInit(&key[0],
9594                                 Anum_pg_attribute_attrelid,
9595                                 BTEqualStrategyNumber, F_OIDEQ,
9596                                 ObjectIdGetDatum(RelationGetRelid(rel)));
9597         scan = systable_beginscan(catalogRelation, AttributeRelidNumIndexId,
9598                                                           true, SnapshotNow, 1, key);
9599         while (HeapTupleIsValid(attributeTuple = systable_getnext(scan)))
9600         {
9601                 Form_pg_attribute att = (Form_pg_attribute) GETSTRUCT(attributeTuple);
9602
9603                 /* Ignore if dropped or not inherited */
9604                 if (att->attisdropped)
9605                         continue;
9606                 if (att->attinhcount <= 0)
9607                         continue;
9608
9609                 if (SearchSysCacheExistsAttName(RelationGetRelid(parent_rel),
9610                                                                                 NameStr(att->attname)))
9611                 {
9612                         /* Decrement inhcount and possibly set islocal to true */
9613                         HeapTuple       copyTuple = heap_copytuple(attributeTuple);
9614                         Form_pg_attribute copy_att = (Form_pg_attribute) GETSTRUCT(copyTuple);
9615
9616                         copy_att->attinhcount--;
9617                         if (copy_att->attinhcount == 0)
9618                                 copy_att->attislocal = true;
9619
9620                         simple_heap_update(catalogRelation, &copyTuple->t_self, copyTuple);
9621                         CatalogUpdateIndexes(catalogRelation, copyTuple);
9622                         heap_freetuple(copyTuple);
9623                 }
9624         }
9625         systable_endscan(scan);
9626         heap_close(catalogRelation, RowExclusiveLock);
9627
9628         /*
9629          * Likewise, find inherited check constraints and disinherit them. To do
9630          * this, we first need a list of the names of the parent's check
9631          * constraints.  (We cheat a bit by only checking for name matches,
9632          * assuming that the expressions will match.)
9633          */
9634         catalogRelation = heap_open(ConstraintRelationId, RowExclusiveLock);
9635         ScanKeyInit(&key[0],
9636                                 Anum_pg_constraint_conrelid,
9637                                 BTEqualStrategyNumber, F_OIDEQ,
9638                                 ObjectIdGetDatum(RelationGetRelid(parent_rel)));
9639         scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId,
9640                                                           true, SnapshotNow, 1, key);
9641
9642         connames = NIL;
9643
9644         while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
9645         {
9646                 Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
9647
9648                 if (con->contype == CONSTRAINT_CHECK)
9649                         connames = lappend(connames, pstrdup(NameStr(con->conname)));
9650         }
9651
9652         systable_endscan(scan);
9653
9654         /* Now scan the child's constraints */
9655         ScanKeyInit(&key[0],
9656                                 Anum_pg_constraint_conrelid,
9657                                 BTEqualStrategyNumber, F_OIDEQ,
9658                                 ObjectIdGetDatum(RelationGetRelid(rel)));
9659         scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId,
9660                                                           true, SnapshotNow, 1, key);
9661
9662         while (HeapTupleIsValid(constraintTuple = systable_getnext(scan)))
9663         {
9664                 Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(constraintTuple);
9665                 bool            match;
9666                 ListCell   *lc;
9667
9668                 if (con->contype != CONSTRAINT_CHECK)
9669                         continue;
9670
9671                 match = false;
9672                 foreach(lc, connames)
9673                 {
9674                         if (strcmp(NameStr(con->conname), (char *) lfirst(lc)) == 0)
9675                         {
9676                                 match = true;
9677                                 break;
9678                         }
9679                 }
9680
9681                 if (match)
9682                 {
9683                         /* Decrement inhcount and possibly set islocal to true */
9684                         HeapTuple       copyTuple = heap_copytuple(constraintTuple);
9685                         Form_pg_constraint copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple);
9686
9687                         if (copy_con->coninhcount <= 0)         /* shouldn't happen */
9688                                 elog(ERROR, "relation %u has non-inherited constraint \"%s\"",
9689                                          RelationGetRelid(rel), NameStr(copy_con->conname));
9690
9691                         copy_con->coninhcount--;
9692                         if (copy_con->coninhcount == 0)
9693                                 copy_con->conislocal = true;
9694
9695                         simple_heap_update(catalogRelation, &copyTuple->t_self, copyTuple);
9696                         CatalogUpdateIndexes(catalogRelation, copyTuple);
9697                         heap_freetuple(copyTuple);
9698                 }
9699         }
9700
9701         systable_endscan(scan);
9702         heap_close(catalogRelation, RowExclusiveLock);
9703
9704         drop_parent_dependency(RelationGetRelid(rel),
9705                                                    RelationRelationId,
9706                                                    RelationGetRelid(parent_rel));
9707
9708         /*
9709          * Post alter hook of this inherits. Since object_access_hook doesn't take
9710          * multiple object identifiers, we relay oid of parent relation using
9711          * auxiliary_id argument.
9712          */
9713         InvokeObjectPostAlterHookArg(InheritsRelationId,
9714                                                                  RelationGetRelid(rel), 0,
9715                                                                  RelationGetRelid(parent_rel), false);
9716
9717         /* keep our lock on the parent relation until commit */
9718         heap_close(parent_rel, NoLock);
9719 }
9720
9721 /*
9722  * Drop the dependency created by StoreCatalogInheritance1 (CREATE TABLE
9723  * INHERITS/ALTER TABLE INHERIT -- refclassid will be RelationRelationId) or
9724  * heap_create_with_catalog (CREATE TABLE OF/ALTER TABLE OF -- refclassid will
9725  * be TypeRelationId).  There's no convenient way to do this, so go trawling
9726  * through pg_depend.
9727  */
9728 static void
9729 drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid)
9730 {
9731         Relation        catalogRelation;
9732         SysScanDesc scan;
9733         ScanKeyData key[3];
9734         HeapTuple       depTuple;
9735
9736         catalogRelation = heap_open(DependRelationId, RowExclusiveLock);
9737
9738         ScanKeyInit(&key[0],
9739                                 Anum_pg_depend_classid,
9740                                 BTEqualStrategyNumber, F_OIDEQ,
9741                                 ObjectIdGetDatum(RelationRelationId));
9742         ScanKeyInit(&key[1],
9743                                 Anum_pg_depend_objid,
9744                                 BTEqualStrategyNumber, F_OIDEQ,
9745                                 ObjectIdGetDatum(relid));
9746         ScanKeyInit(&key[2],
9747                                 Anum_pg_depend_objsubid,
9748                                 BTEqualStrategyNumber, F_INT4EQ,
9749                                 Int32GetDatum(0));
9750
9751         scan = systable_beginscan(catalogRelation, DependDependerIndexId, true,
9752                                                           SnapshotNow, 3, key);
9753
9754         while (HeapTupleIsValid(depTuple = systable_getnext(scan)))
9755         {
9756                 Form_pg_depend dep = (Form_pg_depend) GETSTRUCT(depTuple);
9757
9758                 if (dep->refclassid == refclassid &&
9759                         dep->refobjid == refobjid &&
9760                         dep->refobjsubid == 0 &&
9761                         dep->deptype == DEPENDENCY_NORMAL)
9762                         simple_heap_delete(catalogRelation, &depTuple->t_self);
9763         }
9764
9765         systable_endscan(scan);
9766         heap_close(catalogRelation, RowExclusiveLock);
9767 }
9768
9769 /*
9770  * ALTER TABLE OF
9771  *
9772  * Attach a table to a composite type, as though it had been created with CREATE
9773  * TABLE OF.  All attname, atttypid, atttypmod and attcollation must match.  The
9774  * subject table must not have inheritance parents.  These restrictions ensure
9775  * that you cannot create a configuration impossible with CREATE TABLE OF alone.
9776  */
9777 static void
9778 ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode)
9779 {
9780         Oid                     relid = RelationGetRelid(rel);
9781         Type            typetuple;
9782         Oid                     typeid;
9783         Relation        inheritsRelation,
9784                                 relationRelation;
9785         SysScanDesc scan;
9786         ScanKeyData key;
9787         AttrNumber      table_attno,
9788                                 type_attno;
9789         TupleDesc       typeTupleDesc,
9790                                 tableTupleDesc;
9791         ObjectAddress tableobj,
9792                                 typeobj;
9793         HeapTuple       classtuple;
9794
9795         /* Validate the type. */
9796         typetuple = typenameType(NULL, ofTypename, NULL);
9797         check_of_type(typetuple);
9798         typeid = HeapTupleGetOid(typetuple);
9799
9800         /* Fail if the table has any inheritance parents. */
9801         inheritsRelation = heap_open(InheritsRelationId, AccessShareLock);
9802         ScanKeyInit(&key,
9803                                 Anum_pg_inherits_inhrelid,
9804                                 BTEqualStrategyNumber, F_OIDEQ,
9805                                 ObjectIdGetDatum(relid));
9806         scan = systable_beginscan(inheritsRelation, InheritsRelidSeqnoIndexId,
9807                                                           true, SnapshotNow, 1, &key);
9808         if (HeapTupleIsValid(systable_getnext(scan)))
9809                 ereport(ERROR,
9810                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
9811                                  errmsg("typed tables cannot inherit")));
9812         systable_endscan(scan);
9813         heap_close(inheritsRelation, AccessShareLock);
9814
9815         /*
9816          * Check the tuple descriptors for compatibility.  Unlike inheritance, we
9817          * require that the order also match.  However, attnotnull need not match.
9818          * Also unlike inheritance, we do not require matching relhasoids.
9819          */
9820         typeTupleDesc = lookup_rowtype_tupdesc(typeid, -1);
9821         tableTupleDesc = RelationGetDescr(rel);
9822         table_attno = 1;
9823         for (type_attno = 1; type_attno <= typeTupleDesc->natts; type_attno++)
9824         {
9825                 Form_pg_attribute type_attr,
9826                                         table_attr;
9827                 const char *type_attname,
9828                                    *table_attname;
9829
9830                 /* Get the next non-dropped type attribute. */
9831                 type_attr = typeTupleDesc->attrs[type_attno - 1];
9832                 if (type_attr->attisdropped)
9833                         continue;
9834                 type_attname = NameStr(type_attr->attname);
9835
9836                 /* Get the next non-dropped table attribute. */
9837                 do
9838                 {
9839                         if (table_attno > tableTupleDesc->natts)
9840                                 ereport(ERROR,
9841                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
9842                                                  errmsg("table is missing column \"%s\"",
9843                                                                 type_attname)));
9844                         table_attr = tableTupleDesc->attrs[table_attno++ - 1];
9845                 } while (table_attr->attisdropped);
9846                 table_attname = NameStr(table_attr->attname);
9847
9848                 /* Compare name. */
9849                 if (strncmp(table_attname, type_attname, NAMEDATALEN) != 0)
9850                         ereport(ERROR,
9851                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
9852                                  errmsg("table has column \"%s\" where type requires \"%s\"",
9853                                                 table_attname, type_attname)));
9854
9855                 /* Compare type. */
9856                 if (table_attr->atttypid != type_attr->atttypid ||
9857                         table_attr->atttypmod != type_attr->atttypmod ||
9858                         table_attr->attcollation != type_attr->attcollation)
9859                         ereport(ERROR,
9860                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
9861                                   errmsg("table \"%s\" has different type for column \"%s\"",
9862                                                  RelationGetRelationName(rel), type_attname)));
9863         }
9864         DecrTupleDescRefCount(typeTupleDesc);
9865
9866         /* Any remaining columns at the end of the table had better be dropped. */
9867         for (; table_attno <= tableTupleDesc->natts; table_attno++)
9868         {
9869                 Form_pg_attribute table_attr = tableTupleDesc->attrs[table_attno - 1];
9870
9871                 if (!table_attr->attisdropped)
9872                         ereport(ERROR,
9873                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
9874                                          errmsg("table has extra column \"%s\"",
9875                                                         NameStr(table_attr->attname))));
9876         }
9877
9878         /* If the table was already typed, drop the existing dependency. */
9879         if (rel->rd_rel->reloftype)
9880                 drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype);
9881
9882         /* Record a dependency on the new type. */
9883         tableobj.classId = RelationRelationId;
9884         tableobj.objectId = relid;
9885         tableobj.objectSubId = 0;
9886         typeobj.classId = TypeRelationId;
9887         typeobj.objectId = typeid;
9888         typeobj.objectSubId = 0;
9889         recordDependencyOn(&tableobj, &typeobj, DEPENDENCY_NORMAL);
9890
9891         /* Update pg_class.reloftype */
9892         relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
9893         classtuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
9894         if (!HeapTupleIsValid(classtuple))
9895                 elog(ERROR, "cache lookup failed for relation %u", relid);
9896         ((Form_pg_class) GETSTRUCT(classtuple))->reloftype = typeid;
9897         simple_heap_update(relationRelation, &classtuple->t_self, classtuple);
9898         CatalogUpdateIndexes(relationRelation, classtuple);
9899
9900         InvokeObjectPostAlterHook(RelationRelationId, relid, 0);
9901
9902         heap_freetuple(classtuple);
9903         heap_close(relationRelation, RowExclusiveLock);
9904
9905         ReleaseSysCache(typetuple);
9906 }
9907
9908 /*
9909  * ALTER TABLE NOT OF
9910  *
9911  * Detach a typed table from its originating type.      Just clear reloftype and
9912  * remove the dependency.
9913  */
9914 static void
9915 ATExecDropOf(Relation rel, LOCKMODE lockmode)
9916 {
9917         Oid                     relid = RelationGetRelid(rel);
9918         Relation        relationRelation;
9919         HeapTuple       tuple;
9920
9921         if (!OidIsValid(rel->rd_rel->reloftype))
9922                 ereport(ERROR,
9923                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
9924                                  errmsg("\"%s\" is not a typed table",
9925                                                 RelationGetRelationName(rel))));
9926
9927         /*
9928          * We don't bother to check ownership of the type --- ownership of the
9929          * table is presumed enough rights.  No lock required on the type, either.
9930          */
9931
9932         drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype);
9933
9934         /* Clear pg_class.reloftype */
9935         relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
9936         tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
9937         if (!HeapTupleIsValid(tuple))
9938                 elog(ERROR, "cache lookup failed for relation %u", relid);
9939         ((Form_pg_class) GETSTRUCT(tuple))->reloftype = InvalidOid;
9940         simple_heap_update(relationRelation, &tuple->t_self, tuple);
9941         CatalogUpdateIndexes(relationRelation, tuple);
9942
9943         InvokeObjectPostAlterHook(RelationRelationId, relid, 0);
9944
9945         heap_freetuple(tuple);
9946         heap_close(relationRelation, RowExclusiveLock);
9947 }
9948
9949 /*
9950  * ALTER FOREIGN TABLE <name> OPTIONS (...)
9951  */
9952 static void
9953 ATExecGenericOptions(Relation rel, List *options)
9954 {
9955         Relation        ftrel;
9956         ForeignServer *server;
9957         ForeignDataWrapper *fdw;
9958         HeapTuple       tuple;
9959         bool            isnull;
9960         Datum           repl_val[Natts_pg_foreign_table];
9961         bool            repl_null[Natts_pg_foreign_table];
9962         bool            repl_repl[Natts_pg_foreign_table];
9963         Datum           datum;
9964         Form_pg_foreign_table tableform;
9965
9966         if (options == NIL)
9967                 return;
9968
9969         ftrel = heap_open(ForeignTableRelationId, RowExclusiveLock);
9970
9971         tuple = SearchSysCacheCopy1(FOREIGNTABLEREL, rel->rd_id);
9972         if (!HeapTupleIsValid(tuple))
9973                 ereport(ERROR,
9974                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
9975                                  errmsg("foreign table \"%s\" does not exist",
9976                                                 RelationGetRelationName(rel))));
9977         tableform = (Form_pg_foreign_table) GETSTRUCT(tuple);
9978         server = GetForeignServer(tableform->ftserver);
9979         fdw = GetForeignDataWrapper(server->fdwid);
9980
9981         memset(repl_val, 0, sizeof(repl_val));
9982         memset(repl_null, false, sizeof(repl_null));
9983         memset(repl_repl, false, sizeof(repl_repl));
9984
9985         /* Extract the current options */
9986         datum = SysCacheGetAttr(FOREIGNTABLEREL,
9987                                                         tuple,
9988                                                         Anum_pg_foreign_table_ftoptions,
9989                                                         &isnull);
9990         if (isnull)
9991                 datum = PointerGetDatum(NULL);
9992
9993         /* Transform the options */
9994         datum = transformGenericOptions(ForeignTableRelationId,
9995                                                                         datum,
9996                                                                         options,
9997                                                                         fdw->fdwvalidator);
9998
9999         if (PointerIsValid(DatumGetPointer(datum)))
10000                 repl_val[Anum_pg_foreign_table_ftoptions - 1] = datum;
10001         else
10002                 repl_null[Anum_pg_foreign_table_ftoptions - 1] = true;
10003
10004         repl_repl[Anum_pg_foreign_table_ftoptions - 1] = true;
10005
10006         /* Everything looks good - update the tuple */
10007
10008         tuple = heap_modify_tuple(tuple, RelationGetDescr(ftrel),
10009                                                           repl_val, repl_null, repl_repl);
10010
10011         simple_heap_update(ftrel, &tuple->t_self, tuple);
10012         CatalogUpdateIndexes(ftrel, tuple);
10013
10014         InvokeObjectPostAlterHook(ForeignTableRelationId,
10015                                                           RelationGetRelid(rel), 0);
10016
10017         heap_close(ftrel, RowExclusiveLock);
10018
10019         heap_freetuple(tuple);
10020 }
10021
10022 /*
10023  * Execute ALTER TABLE SET SCHEMA
10024  */
10025 Oid
10026 AlterTableNamespace(AlterObjectSchemaStmt *stmt)
10027 {
10028         Relation        rel;
10029         Oid                     relid;
10030         Oid                     oldNspOid;
10031         Oid                     nspOid;
10032         RangeVar   *newrv;
10033         ObjectAddresses *objsMoved;
10034
10035         relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
10036                                                                          stmt->missing_ok, false,
10037                                                                          RangeVarCallbackForAlterRelation,
10038                                                                          (void *) stmt);
10039
10040         if (!OidIsValid(relid))
10041         {
10042                 ereport(NOTICE,
10043                                 (errmsg("relation \"%s\" does not exist, skipping",
10044                                                 stmt->relation->relname)));
10045                 return InvalidOid;
10046         }
10047
10048         rel = relation_open(relid, NoLock);
10049
10050         oldNspOid = RelationGetNamespace(rel);
10051
10052         /* If it's an owned sequence, disallow moving it by itself. */
10053         if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
10054         {
10055                 Oid                     tableId;
10056                 int32           colId;
10057
10058                 if (sequenceIsOwned(relid, &tableId, &colId))
10059                         ereport(ERROR,
10060                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
10061                                  errmsg("cannot move an owned sequence into another schema"),
10062                                          errdetail("Sequence \"%s\" is linked to table \"%s\".",
10063                                                            RelationGetRelationName(rel),
10064                                                            get_rel_name(tableId))));
10065         }
10066
10067         /* Get and lock schema OID and check its permissions. */
10068         newrv = makeRangeVar(stmt->newschema, RelationGetRelationName(rel), -1);
10069         nspOid = RangeVarGetAndCheckCreationNamespace(newrv, NoLock, NULL);
10070
10071         /* common checks on switching namespaces */
10072         CheckSetNamespace(oldNspOid, nspOid, RelationRelationId, relid);
10073
10074         objsMoved = new_object_addresses();
10075         AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved);
10076         free_object_addresses(objsMoved);
10077
10078         /* close rel, but keep lock until commit */
10079         relation_close(rel, NoLock);
10080
10081         return relid;
10082 }
10083
10084 /*
10085  * The guts of relocating a table or materialized view to another namespace:
10086  * besides moving the relation itself, its dependent objects are relocated to
10087  * the new schema.
10088  */
10089 void
10090 AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid,
10091                                                         ObjectAddresses *objsMoved)
10092 {
10093         Relation        classRel;
10094
10095         Assert(objsMoved != NULL);
10096
10097         /* OK, modify the pg_class row and pg_depend entry */
10098         classRel = heap_open(RelationRelationId, RowExclusiveLock);
10099
10100         AlterRelationNamespaceInternal(classRel, RelationGetRelid(rel), oldNspOid,
10101                                                                    nspOid, true, objsMoved);
10102
10103         /* Fix the table's row type too */
10104         AlterTypeNamespaceInternal(rel->rd_rel->reltype,
10105                                                            nspOid, false, false, objsMoved);
10106
10107         /* Fix other dependent stuff */
10108         if (rel->rd_rel->relkind == RELKIND_RELATION ||
10109                 rel->rd_rel->relkind == RELKIND_MATVIEW)
10110         {
10111                 AlterIndexNamespaces(classRel, rel, oldNspOid, nspOid, objsMoved);
10112                 AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid,
10113                                                    objsMoved, AccessExclusiveLock);
10114                 AlterConstraintNamespaces(RelationGetRelid(rel), oldNspOid, nspOid,
10115                                                                   false, objsMoved);
10116         }
10117
10118         heap_close(classRel, RowExclusiveLock);
10119 }
10120
10121 /*
10122  * The guts of relocating a relation to another namespace: fix the pg_class
10123  * entry, and the pg_depend entry if any.  Caller must already have
10124  * opened and write-locked pg_class.
10125  */
10126 void
10127 AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
10128                                                            Oid oldNspOid, Oid newNspOid,
10129                                                            bool hasDependEntry,
10130                                                            ObjectAddresses *objsMoved)
10131 {
10132         HeapTuple       classTup;
10133         Form_pg_class classForm;
10134         ObjectAddress thisobj;
10135
10136         classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relOid));
10137         if (!HeapTupleIsValid(classTup))
10138                 elog(ERROR, "cache lookup failed for relation %u", relOid);
10139         classForm = (Form_pg_class) GETSTRUCT(classTup);
10140
10141         Assert(classForm->relnamespace == oldNspOid);
10142
10143         thisobj.classId = RelationRelationId;
10144         thisobj.objectId = relOid;
10145         thisobj.objectSubId = 0;
10146
10147         /*
10148          * Do nothing when there's nothing to do.
10149          */
10150         if (!object_address_present(&thisobj, objsMoved))
10151         {
10152                 /* check for duplicate name (more friendly than unique-index failure) */
10153                 if (get_relname_relid(NameStr(classForm->relname),
10154                                                           newNspOid) != InvalidOid)
10155                         ereport(ERROR,
10156                                         (errcode(ERRCODE_DUPLICATE_TABLE),
10157                                          errmsg("relation \"%s\" already exists in schema \"%s\"",
10158                                                         NameStr(classForm->relname),
10159                                                         get_namespace_name(newNspOid))));
10160
10161                 /* classTup is a copy, so OK to scribble on */
10162                 classForm->relnamespace = newNspOid;
10163
10164                 simple_heap_update(classRel, &classTup->t_self, classTup);
10165                 CatalogUpdateIndexes(classRel, classTup);
10166
10167                 /* Update dependency on schema if caller said so */
10168                 if (hasDependEntry &&
10169                         changeDependencyFor(RelationRelationId,
10170                                                                 relOid,
10171                                                                 NamespaceRelationId,
10172                                                                 oldNspOid,
10173                                                                 newNspOid) != 1)
10174                         elog(ERROR, "failed to change schema dependency for relation \"%s\"",
10175                                  NameStr(classForm->relname));
10176
10177                 add_exact_object_address(&thisobj, objsMoved);
10178
10179                 InvokeObjectPostAlterHook(RelationRelationId, relOid, 0);
10180         }
10181
10182         heap_freetuple(classTup);
10183 }
10184
10185 /*
10186  * Move all indexes for the specified relation to another namespace.
10187  *
10188  * Note: we assume adequate permission checking was done by the caller,
10189  * and that the caller has a suitable lock on the owning relation.
10190  */
10191 static void
10192 AlterIndexNamespaces(Relation classRel, Relation rel,
10193                                          Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved)
10194 {
10195         List       *indexList;
10196         ListCell   *l;
10197
10198         indexList = RelationGetIndexList(rel);
10199
10200         foreach(l, indexList)
10201         {
10202                 Oid                     indexOid = lfirst_oid(l);
10203                 ObjectAddress thisobj;
10204
10205                 thisobj.classId = RelationRelationId;
10206                 thisobj.objectId = indexOid;
10207                 thisobj.objectSubId = 0;
10208
10209                 /*
10210                  * Note: currently, the index will not have its own dependency on the
10211                  * namespace, so we don't need to do changeDependencyFor(). There's no
10212                  * row type in pg_type, either.
10213                  *
10214                  * XXX this objsMoved test may be pointless -- surely we have a single
10215                  * dependency link from a relation to each index?
10216                  */
10217                 if (!object_address_present(&thisobj, objsMoved))
10218                 {
10219                         AlterRelationNamespaceInternal(classRel, indexOid,
10220                                                                                    oldNspOid, newNspOid,
10221                                                                                    false, objsMoved);
10222                         add_exact_object_address(&thisobj, objsMoved);
10223                 }
10224         }
10225
10226         list_free(indexList);
10227 }
10228
10229 /*
10230  * Move all SERIAL-column sequences of the specified relation to another
10231  * namespace.
10232  *
10233  * Note: we assume adequate permission checking was done by the caller,
10234  * and that the caller has a suitable lock on the owning relation.
10235  */
10236 static void
10237 AlterSeqNamespaces(Relation classRel, Relation rel,
10238                                    Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved,
10239                                    LOCKMODE lockmode)
10240 {
10241         Relation        depRel;
10242         SysScanDesc scan;
10243         ScanKeyData key[2];
10244         HeapTuple       tup;
10245
10246         /*
10247          * SERIAL sequences are those having an auto dependency on one of the
10248          * table's columns (we don't care *which* column, exactly).
10249          */
10250         depRel = heap_open(DependRelationId, AccessShareLock);
10251
10252         ScanKeyInit(&key[0],
10253                                 Anum_pg_depend_refclassid,
10254                                 BTEqualStrategyNumber, F_OIDEQ,
10255                                 ObjectIdGetDatum(RelationRelationId));
10256         ScanKeyInit(&key[1],
10257                                 Anum_pg_depend_refobjid,
10258                                 BTEqualStrategyNumber, F_OIDEQ,
10259                                 ObjectIdGetDatum(RelationGetRelid(rel)));
10260         /* we leave refobjsubid unspecified */
10261
10262         scan = systable_beginscan(depRel, DependReferenceIndexId, true,
10263                                                           SnapshotNow, 2, key);
10264
10265         while (HeapTupleIsValid(tup = systable_getnext(scan)))
10266         {
10267                 Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
10268                 Relation        seqRel;
10269
10270                 /* skip dependencies other than auto dependencies on columns */
10271                 if (depForm->refobjsubid == 0 ||
10272                         depForm->classid != RelationRelationId ||
10273                         depForm->objsubid != 0 ||
10274                         depForm->deptype != DEPENDENCY_AUTO)
10275                         continue;
10276
10277                 /* Use relation_open just in case it's an index */
10278                 seqRel = relation_open(depForm->objid, lockmode);
10279
10280                 /* skip non-sequence relations */
10281                 if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
10282                 {
10283                         /* No need to keep the lock */
10284                         relation_close(seqRel, lockmode);
10285                         continue;
10286                 }
10287
10288                 /* Fix the pg_class and pg_depend entries */
10289                 AlterRelationNamespaceInternal(classRel, depForm->objid,
10290                                                                            oldNspOid, newNspOid,
10291                                                                            true, objsMoved);
10292
10293                 /*
10294                  * Sequences have entries in pg_type. We need to be careful to move
10295                  * them to the new namespace, too.
10296                  */
10297                 AlterTypeNamespaceInternal(RelationGetForm(seqRel)->reltype,
10298                                                                    newNspOid, false, false, objsMoved);
10299
10300                 /* Now we can close it.  Keep the lock till end of transaction. */
10301                 relation_close(seqRel, NoLock);
10302         }
10303
10304         systable_endscan(scan);
10305
10306         relation_close(depRel, AccessShareLock);
10307 }
10308
10309
10310 /*
10311  * This code supports
10312  *      CREATE TEMP TABLE ... ON COMMIT { DROP | PRESERVE ROWS | DELETE ROWS }
10313  *
10314  * Because we only support this for TEMP tables, it's sufficient to remember
10315  * the state in a backend-local data structure.
10316  */
10317
10318 /*
10319  * Register a newly-created relation's ON COMMIT action.
10320  */
10321 void
10322 register_on_commit_action(Oid relid, OnCommitAction action)
10323 {
10324         OnCommitItem *oc;
10325         MemoryContext oldcxt;
10326
10327         /*
10328          * We needn't bother registering the relation unless there is an ON COMMIT
10329          * action we need to take.
10330          */
10331         if (action == ONCOMMIT_NOOP || action == ONCOMMIT_PRESERVE_ROWS)
10332                 return;
10333
10334         oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
10335
10336         oc = (OnCommitItem *) palloc(sizeof(OnCommitItem));
10337         oc->relid = relid;
10338         oc->oncommit = action;
10339         oc->creating_subid = GetCurrentSubTransactionId();
10340         oc->deleting_subid = InvalidSubTransactionId;
10341
10342         on_commits = lcons(oc, on_commits);
10343
10344         MemoryContextSwitchTo(oldcxt);
10345 }
10346
10347 /*
10348  * Unregister any ON COMMIT action when a relation is deleted.
10349  *
10350  * Actually, we only mark the OnCommitItem entry as to be deleted after commit.
10351  */
10352 void
10353 remove_on_commit_action(Oid relid)
10354 {
10355         ListCell   *l;
10356
10357         foreach(l, on_commits)
10358         {
10359                 OnCommitItem *oc = (OnCommitItem *) lfirst(l);
10360
10361                 if (oc->relid == relid)
10362                 {
10363                         oc->deleting_subid = GetCurrentSubTransactionId();
10364                         break;
10365                 }
10366         }
10367 }
10368
10369 /*
10370  * Perform ON COMMIT actions.
10371  *
10372  * This is invoked just before actually committing, since it's possible
10373  * to encounter errors.
10374  */
10375 void
10376 PreCommit_on_commit_actions(void)
10377 {
10378         ListCell   *l;
10379         List       *oids_to_truncate = NIL;
10380
10381         foreach(l, on_commits)
10382         {
10383                 OnCommitItem *oc = (OnCommitItem *) lfirst(l);
10384
10385                 /* Ignore entry if already dropped in this xact */
10386                 if (oc->deleting_subid != InvalidSubTransactionId)
10387                         continue;
10388
10389                 switch (oc->oncommit)
10390                 {
10391                         case ONCOMMIT_NOOP:
10392                         case ONCOMMIT_PRESERVE_ROWS:
10393                                 /* Do nothing (there shouldn't be such entries, actually) */
10394                                 break;
10395                         case ONCOMMIT_DELETE_ROWS:
10396
10397                                 /*
10398                                  * If this transaction hasn't accessed any temporary
10399                                  * relations, we can skip truncating ON COMMIT DELETE ROWS
10400                                  * tables, as they must still be empty.
10401                                  */
10402                                 if (MyXactAccessedTempRel)
10403                                         oids_to_truncate = lappend_oid(oids_to_truncate, oc->relid);
10404                                 break;
10405                         case ONCOMMIT_DROP:
10406                                 {
10407                                         ObjectAddress object;
10408
10409                                         object.classId = RelationRelationId;
10410                                         object.objectId = oc->relid;
10411                                         object.objectSubId = 0;
10412
10413                                         /*
10414                                          * Since this is an automatic drop, rather than one
10415                                          * directly initiated by the user, we pass the
10416                                          * PERFORM_DELETION_INTERNAL flag.
10417                                          */
10418                                         performDeletion(&object,
10419                                                                         DROP_CASCADE, PERFORM_DELETION_INTERNAL);
10420
10421                                         /*
10422                                          * Note that table deletion will call
10423                                          * remove_on_commit_action, so the entry should get marked
10424                                          * as deleted.
10425                                          */
10426                                         Assert(oc->deleting_subid != InvalidSubTransactionId);
10427                                         break;
10428                                 }
10429                 }
10430         }
10431         if (oids_to_truncate != NIL)
10432         {
10433                 heap_truncate(oids_to_truncate);
10434                 CommandCounterIncrement();              /* XXX needed? */
10435         }
10436 }
10437
10438 /*
10439  * Post-commit or post-abort cleanup for ON COMMIT management.
10440  *
10441  * All we do here is remove no-longer-needed OnCommitItem entries.
10442  *
10443  * During commit, remove entries that were deleted during this transaction;
10444  * during abort, remove those created during this transaction.
10445  */
10446 void
10447 AtEOXact_on_commit_actions(bool isCommit)
10448 {
10449         ListCell   *cur_item;
10450         ListCell   *prev_item;
10451
10452         prev_item = NULL;
10453         cur_item = list_head(on_commits);
10454
10455         while (cur_item != NULL)
10456         {
10457                 OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
10458
10459                 if (isCommit ? oc->deleting_subid != InvalidSubTransactionId :
10460                         oc->creating_subid != InvalidSubTransactionId)
10461                 {
10462                         /* cur_item must be removed */
10463                         on_commits = list_delete_cell(on_commits, cur_item, prev_item);
10464                         pfree(oc);
10465                         if (prev_item)
10466                                 cur_item = lnext(prev_item);
10467                         else
10468                                 cur_item = list_head(on_commits);
10469                 }
10470                 else
10471                 {
10472                         /* cur_item must be preserved */
10473                         oc->creating_subid = InvalidSubTransactionId;
10474                         oc->deleting_subid = InvalidSubTransactionId;
10475                         prev_item = cur_item;
10476                         cur_item = lnext(prev_item);
10477                 }
10478         }
10479 }
10480
10481 /*
10482  * Post-subcommit or post-subabort cleanup for ON COMMIT management.
10483  *
10484  * During subabort, we can immediately remove entries created during this
10485  * subtransaction.      During subcommit, just relabel entries marked during
10486  * this subtransaction as being the parent's responsibility.
10487  */
10488 void
10489 AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid,
10490                                                           SubTransactionId parentSubid)
10491 {
10492         ListCell   *cur_item;
10493         ListCell   *prev_item;
10494
10495         prev_item = NULL;
10496         cur_item = list_head(on_commits);
10497
10498         while (cur_item != NULL)
10499         {
10500                 OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
10501
10502                 if (!isCommit && oc->creating_subid == mySubid)
10503                 {
10504                         /* cur_item must be removed */
10505                         on_commits = list_delete_cell(on_commits, cur_item, prev_item);
10506                         pfree(oc);
10507                         if (prev_item)
10508                                 cur_item = lnext(prev_item);
10509                         else
10510                                 cur_item = list_head(on_commits);
10511                 }
10512                 else
10513                 {
10514                         /* cur_item must be preserved */
10515                         if (oc->creating_subid == mySubid)
10516                                 oc->creating_subid = parentSubid;
10517                         if (oc->deleting_subid == mySubid)
10518                                 oc->deleting_subid = isCommit ? parentSubid : InvalidSubTransactionId;
10519                         prev_item = cur_item;
10520                         cur_item = lnext(prev_item);
10521                 }
10522         }
10523 }
10524
10525 /*
10526  * This is intended as a callback for RangeVarGetRelidExtended().  It allows
10527  * the relation to be locked only if (1) it's a plain table, materialized
10528  * view, or TOAST table and (2) the current user is the owner (or the
10529  * superuser).  This meets the permission-checking needs of CLUSTER, REINDEX
10530  * TABLE, and REFRESH MATERIALIZED VIEW; we expose it here so that it can be
10531  * used by all.
10532  */
10533 void
10534 RangeVarCallbackOwnsTable(const RangeVar *relation,
10535                                                   Oid relId, Oid oldRelId, void *arg)
10536 {
10537         char            relkind;
10538
10539         /* Nothing to do if the relation was not found. */
10540         if (!OidIsValid(relId))
10541                 return;
10542
10543         /*
10544          * If the relation does exist, check whether it's an index.  But note that
10545          * the relation might have been dropped between the time we did the name
10546          * lookup and now.      In that case, there's nothing to do.
10547          */
10548         relkind = get_rel_relkind(relId);
10549         if (!relkind)
10550                 return;
10551         if (relkind != RELKIND_RELATION && relkind != RELKIND_TOASTVALUE &&
10552                 relkind != RELKIND_MATVIEW)
10553                 ereport(ERROR,
10554                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
10555                                  errmsg("\"%s\" is not a table or materialized view", relation->relname)));
10556
10557         /* Check permissions */
10558         if (!pg_class_ownercheck(relId, GetUserId()))
10559                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, relation->relname);
10560 }
10561
10562 /*
10563  * Common RangeVarGetRelid callback for rename, set schema, and alter table
10564  * processing.
10565  */
10566 static void
10567 RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid,
10568                                                                  void *arg)
10569 {
10570         Node       *stmt = (Node *) arg;
10571         ObjectType      reltype;
10572         HeapTuple       tuple;
10573         Form_pg_class classform;
10574         AclResult       aclresult;
10575         char            relkind;
10576
10577         tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
10578         if (!HeapTupleIsValid(tuple))
10579                 return;                                 /* concurrently dropped */
10580         classform = (Form_pg_class) GETSTRUCT(tuple);
10581         relkind = classform->relkind;
10582
10583         /* Must own relation. */
10584         if (!pg_class_ownercheck(relid, GetUserId()))
10585                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, rv->relname);
10586
10587         /* No system table modifications unless explicitly allowed. */
10588         if (!allowSystemTableMods && IsSystemClass(classform))
10589                 ereport(ERROR,
10590                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
10591                                  errmsg("permission denied: \"%s\" is a system catalog",
10592                                                 rv->relname)));
10593
10594         /*
10595          * Extract the specified relation type from the statement parse tree.
10596          *
10597          * Also, for ALTER .. RENAME, check permissions: the user must (still)
10598          * have CREATE rights on the containing namespace.
10599          */
10600         if (IsA(stmt, RenameStmt))
10601         {
10602                 aclresult = pg_namespace_aclcheck(classform->relnamespace,
10603                                                                                   GetUserId(), ACL_CREATE);
10604                 if (aclresult != ACLCHECK_OK)
10605                         aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
10606                                                    get_namespace_name(classform->relnamespace));
10607                 reltype = ((RenameStmt *) stmt)->renameType;
10608         }
10609         else if (IsA(stmt, AlterObjectSchemaStmt))
10610                 reltype = ((AlterObjectSchemaStmt *) stmt)->objectType;
10611
10612         else if (IsA(stmt, AlterTableStmt))
10613                 reltype = ((AlterTableStmt *) stmt)->relkind;
10614         else
10615         {
10616                 reltype = OBJECT_TABLE; /* placate compiler */
10617                 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(stmt));
10618         }
10619
10620         /*
10621          * For compatibility with prior releases, we allow ALTER TABLE to be used
10622          * with most other types of relations (but not composite types). We allow
10623          * similar flexibility for ALTER INDEX in the case of RENAME, but not
10624          * otherwise.  Otherwise, the user must select the correct form of the
10625          * command for the relation at issue.
10626          */
10627         if (reltype == OBJECT_SEQUENCE && relkind != RELKIND_SEQUENCE)
10628                 ereport(ERROR,
10629                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
10630                                  errmsg("\"%s\" is not a sequence", rv->relname)));
10631
10632         if (reltype == OBJECT_VIEW && relkind != RELKIND_VIEW)
10633                 ereport(ERROR,
10634                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
10635                                  errmsg("\"%s\" is not a view", rv->relname)));
10636
10637         if (reltype == OBJECT_MATVIEW && relkind != RELKIND_MATVIEW)
10638                 ereport(ERROR,
10639                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
10640                                  errmsg("\"%s\" is not a materialized view", rv->relname)));
10641
10642         if (reltype == OBJECT_FOREIGN_TABLE && relkind != RELKIND_FOREIGN_TABLE)
10643                 ereport(ERROR,
10644                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
10645                                  errmsg("\"%s\" is not a foreign table", rv->relname)));
10646
10647         if (reltype == OBJECT_TYPE && relkind != RELKIND_COMPOSITE_TYPE)
10648                 ereport(ERROR,
10649                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
10650                                  errmsg("\"%s\" is not a composite type", rv->relname)));
10651
10652         if (reltype == OBJECT_INDEX && relkind != RELKIND_INDEX
10653                 && !IsA(stmt, RenameStmt))
10654                 ereport(ERROR,
10655                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
10656                                  errmsg("\"%s\" is not an index", rv->relname)));
10657
10658         /*
10659          * Don't allow ALTER TABLE on composite types. We want people to use ALTER
10660          * TYPE for that.
10661          */
10662         if (reltype != OBJECT_TYPE && relkind == RELKIND_COMPOSITE_TYPE)
10663                 ereport(ERROR,
10664                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
10665                                  errmsg("\"%s\" is a composite type", rv->relname),
10666                                  errhint("Use ALTER TYPE instead.")));
10667
10668         /*
10669          * Don't allow ALTER TABLE .. SET SCHEMA on relations that can't be moved
10670          * to a different schema, such as indexes and TOAST tables.
10671          */
10672         if (IsA(stmt, AlterObjectSchemaStmt) &&
10673                 relkind != RELKIND_RELATION &&
10674                 relkind != RELKIND_VIEW &&
10675                 relkind != RELKIND_MATVIEW &&
10676                 relkind != RELKIND_SEQUENCE &&
10677                 relkind != RELKIND_FOREIGN_TABLE)
10678                 ereport(ERROR,
10679                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
10680                         errmsg("\"%s\" is not a table, view, sequence, or foreign table",
10681                                    rv->relname)));
10682
10683         ReleaseSysCache(tuple);
10684 }